After review with unfixed findings (autofix declined/partial/N/A),
suggest "type fix these issues" so the LLM can interactively fix
each finding using the edit tool without re-running the review.
Follow-up tips now cover the complete post-review flow:
- Unfixed findings → "fix these issues"
- PR with findings → "post comments"
- Local all clear → "commit"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After local review with no critical issues, suggest "type commit to
commit your changes" — the follow-up system picks this up as ghost
text so users can Tab to commit.
PR reviews keep the existing "post comments" tip.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Comment template: replace **[{severity}]** with {prefix} placeholder
so auto-fixed prefix is not dropped
- Agent 5: run exactly one build + one test command using precedence
order to avoid duplicates (e.g., Makefile wrapping npm)
- Clarify timeout as 120000ms for run_shell_command
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Changed the tip from "/review <number> --comment" (which re-runs the
full review) to "post comments" (which reuses existing findings in
the same conversation and jumps directly to Step 4).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The tip placeholder <number> was being output literally, causing the
follow-up suggestion system to generate commands with wrong PR IDs.
Now explicitly instructs the LLM to substitute the real PR number.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace ambiguous {prefix} placeholder with concrete examples showing
the full Markdown bold + severity tag format for normal and auto-fixed
findings.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Low-confidence findings now appear only in the terminal "Needs Human
Review" section and are never posted as PR inline comments. This
resolves the contradiction between "silence > noise" and posting
uncertain findings on PRs.
Also clarified that "confirmed (low confidence)" is for issues likely
real but needing human judgment, not vague suspicions (those should
be rejected).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Deleted/renamed files in the diff would cause per-file linters to fail
on non-existent paths, producing false deterministic failures. Now uses
--diff-filter=d to exclude deletions from the changed files list.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rename "should use unknown when model is not available" to
"when getModel returns undefined" — the mock config does define
getModel, it just returns undefined.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Copilot-instructions.md precedence: prefer .github/ path, do not
load both when both exist
- Simplify getModel() call: remove unnecessary typeof guard since
Config already defines getModel()
- Fix TS2352 type error in test: use proper mock cast pattern
- Add getModel to base mockConfig for test consistency
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add {{model}} template variable support in BundledSkillLoader. When a
skill body contains {{model}}, it is replaced with the runtime model ID
from config.getModel(). Only skills that use the variable are affected.
The /review skill now appends a model attribution footer to PR review
summaries: "Reviewed by {model} via Qwen Code /review"
This enables cross-model review workflows (e.g., develop with model A,
review with model B) with accurate attribution in PR comments.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Step 1.5 said "the diff output" (singular) but local reviews produce
two diffs (git diff + git diff --staged). Changed files list now
explicitly takes the union of both.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When deduplication merges findings with different severities (e.g.,
a Critical typecheck error with a Suggestion from LLM review), the
merged finding now uses the highest severity. Deterministic severity
is treated as authoritative and cannot be downgraded.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When PR checkout fails or incremental review finds no new changes,
restore the environment (checkout original branch, pop stash) before
stopping. Previously these early exits left the stash orphaned.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix Source vs Issue field inconsistency: deterministic findings now
use Source field ([linter]/[typecheck]) consistently with the schema
- Add base branch ref resolution with origin/<base> fallback and
git fetch for fresh/non-standard checkouts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After presenting findings for a PR review, append a tip:
"Tip: run /review <number> --comment to post these as PR inline comments."
This leverages the existing follow-up suggestion system — it will
read the tip in context and likely suggest the command as ghost text,
letting users discover the feature via Tab without blocking prompts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Source field to Step 2 output schema (Agents 1-4: [review],
Agent 5: [build]/[test]) so Step 2.5 dedup can detect pre-confirmed
- Require Agent 5 to emit [build]/[test] tags explicitly
- Use grep -F (fixed-string) instead of -E regex for cross-file search
to avoid metacharacter issues with JS symbols like $
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix golangci-lint: use ./... (package pattern) instead of file paths
- Unify PR comment prefix format: define canonical prefixes for normal,
auto-fixed, and low-confidence findings in the template
- Stop workflow entirely on autofix commit failure (dirty tree would
block Step 5 branch restore)
- Accept broader .gitignore patterns like .qwen/* for cache/reviews dirs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The autofix step (Step 3.5) needs targeted text replacement to apply
fixes safely. Without the edit tool, only full-file rewrites via
write_file would be available, which is risky for partial fixes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix Step 1.5 intro: clarify whole-project vs per-file tool handling
and filter-then-report approach
- Fix dedup + deterministic finding ambiguity: merged findings with any
deterministic source are pre-confirmed and skip verification
- Fix autofix stash orphan: stop and let user handle commit failure
instead of silently stashing (which Step 5 wouldn't pop)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix filter-then-truncate ordering: capture full linter output first,
filter to changed files, then truncate (not head before filter)
- Record informational notes for skipped checks instead of silent skip
- Agent 5: capture full build/test output, keep first 50 + last 100
lines instead of tail-only (preserves error context)
- Fix [Needs Review] vs severity tag contradiction: use both
[Needs Review][Suggestion] format
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Per maintainer review (tanzhenxin): default verboseMode reverted to true
to preserve existing behavior — compact mode is opt-in via Ctrl+O.
Also addresses wenshao's security concern: in compact mode, tool groups
now force-expand on Error status (in addition to existing Confirming
handling), and ToolMessage force-shows result for both Confirming and
Error statuses so users always see diffs before approval and error
details for debugging.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add tsc --incremental flag to speed up repeated type checks
- Increase type checker timeout to 120s (linters remain 60s)
- Improve cross-file grep patterns to cover .functionName, import { functionName }
- Don't truncate Critical pattern groups — list all locations
- Clarify pre-commit hook as a commit failure scenario in autofix
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comprehensive improvements to the /review skill based on competitive analysis
of Copilot Code Review, Claude Code /ultrareview, and Gemini CLI async-pr-review.
Key changes (all prompt-only, no TypeScript code changes):
- P0: Integrate linter/typecheck (Step 1.5) — run project tools before LLM agents,
with error/warning severity distinction
- P1: Add Agent 5 for build & test verification with env/code failure distinction
- P1: Cross-file impact analysis for Agents 1-4 with 10-symbol prioritization limit
- P1: Project custom review rules (.qwen/review-rules.md, copilot-instructions.md,
AGENTS.md, QWEN.md) with base-branch reading for PR security
- P2: Autofix with user confirmation, PR branch commit, and verdict split
(terminal vs PR submission)
- P2: Pattern aggregation for same-type findings across locations
- P2: Confidence levels (high/low) with "Needs Human Review" section
- P2: Skip "Nice to have" from PR inline comments to reduce noise
- P3: Incremental review via .qwen/review-cache/ with rebase fallback
- P3: Report persistence to .qwen/reviews/ with timestamp filenames
Security hardening:
- PR description prompt injection defense (untrusted DATA marker)
- Base-branch rule loading prevents review-bypass injection
- Concurrency-safe temp file paths with {target} suffix
- Safe git stash handling (conditional pop)
- Argument disambiguation (integer vs URL vs file path)
Audited through 14 rounds of undirected review with 40 issues found and fixed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
"Use the Agent tool with subagent_type" is more direct than
"Create an Agent", reducing ambiguity for the model.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Inline shell snippets need sh -c to execute via pipe, matching how
child_process.exec() runs the configured command.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Footer comment now accurately states only the "? for shortcuts"
hint is suppressed, not all left-section items
- Docs now note that Windows uses cmd.exe by default and suggest
wrapping commands with bash -c or using a bash script
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PS1 \n should be removed or replaced with a space since the status
line only displays the first line of stdout. Also added a guideline
that commands must produce exactly one line of output.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use echo "$input" instead of echo $input for proper shell variable
quoting, consistent with the script file example.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix "three distinct permission modes" → "four" (Plan was always listed)
- Update refactor example to use /plan command instead of /approval-mode
- Fix grammar in example description
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The settings parser uses stripJsonComments + JSON.parse, which does
not support trailing commas. Changed the config example from jsonc
to json and removed trailing commas so users can copy-paste safely.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add size > 0 check before computing context percentage to prevent
division by zero when context_window_size is unavailable.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add jq prerequisite section
- Clarify that settings changes take effect without restart
- Provide complete JSON in troubleshooting test command
- Move script filename out of code block to avoid shebang confusion
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Save approved plans to ~/.qwen/plans/{sessionId}.md so they can be
referenced later in the session or reviewed outside the CLI.
Changes:
- Storage: add getPlansDir() and getPlanFilePath()
- Config: add savePlan(), loadPlan(), getPlanFilePath() methods
- ExitPlanModeTool: persist plan to disk when user approves
- Tests: 4 new Config tests, 2 new ExitPlanModeTool assertions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When entering plan mode, Config now saves the previous approval mode
(e.g. AUTO_EDIT, YOLO) so it can be restored when exiting. Previously,
/plan execute and ExitPlanModeTool both hardcoded a return to DEFAULT,
losing the user's prior mode.
Changes:
- Config: add prePlanMode field, getPrePlanMode(), auto-track in
setApprovalMode()
- planCommand: /plan execute restores prePlanMode instead of DEFAULT
- ExitPlanModeTool: ProceedOnce restores prePlanMode instead of DEFAULT
- Tests: 4 new Config tests, 1 new planCommand test, 1 new
ExitPlanModeTool test
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix default value: compact mode (verboseMode=false) is now the default,
matching PR description and intended UX
- Extract shared ToolStatusIndicator component to eliminate duplicate
status icon rendering between ToolMessage and CompactToolGroupDisplay
- Memoize VerboseModeProvider context value to prevent unnecessary
re-renders of all consumer components
- Clear frozenSnapshot on WaitingForConfirmation state to ensure tool
confirmation UI remains interactive during mid-stream toggle
- Replace magic string 'Shell' with SHELL_NAME constant in ToolMessage
- Remove unused i18n translation keys (verbose/compact mode messages)
- Update snapshots for Footer and ToolGroupMessage tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Agent can now ask for clarification when PS1 is not found
- Clear pending debounce timer before immediate doUpdate on command
change to prevent redundant second execution
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When statusLineCommand becomes undefined (user removes the setting),
kill any in-flight child process, bump generation counter, and clear
the debounce timer so stale callbacks cannot resurrect the output.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Set cwd to config.getTargetDir() so commands like pwd/git run in the
correct workspace directory
- Strip only trailing newline instead of trim() to preserve intentional
leading/trailing whitespace in command output
- Match footer's marginLeft/marginRight on the status line row so it
aligns with the rest of the footer content
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When vim mode is toggled off, vimMode stays the same but the status
line should stop including vim data. Use effectiveVim (undefined when
disabled) as the tracked value instead of raw vimMode.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Validate padding is finite number >= 0 instead of blind cast
- Initialize prevStateRef with current values to prevent double exec on mount
- Kill previous child process before starting new one; kill on unmount
- Fix agent prompt: settings path is ui.statusLine, not root-level
- Fix agent prompt: remove multi-cat examples, stdin can only be read once
- Update Footer left-section comment to reflect new behavior
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
useStatusLine hook requires SettingsContext, which was missing from
the test render wrapper, causing all Footer tests to crash.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrite the status line feature (originally by Gemini 3.1 Pro) to align
with the upstream design:
- Settings: change from plain string to object `{ type, command, padding? }`
- Hook: event-driven with 300ms debounce instead of 5s polling; pass
structured JSON context (session, model, tokens, vim) via stdin;
generation counter to ignore stale exec callbacks; EPIPE guard on stdin
- Footer: render status line as dedicated row with dimColor + truncate;
suppress "? for shortcuts" hint when status line is active
- Add `/statusline` slash command that delegates to a statusline-setup agent
- Add `statusline-setup` built-in agent with PS1 conversion instructions
- Remove unrelated changes (whitespace, formatting, package-lock, test file)
- Fix copyright headers (Google LLC → Qwen)
- Fix config path references (~/.qwen-code → ~/.qwen)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>