qwen-code/docs/users/features
Shaojin Wen dc7e234876
feat(review): absorb prose gh commands into platform-backed subcommands (#9096)
* docs(design): /review platform provider abstraction (GitHub + Aone Code)

* feat(review): absorb prose gh commands into platform-backed subcommands

The skill prose and agent briefs carried raw gh commands for the model to
execute (repo resolution, head-SHA fetches, issue evidence, lightweight
diffs, truncated-body refetches) — the prose-carried class that keeps
shipping parsing bugs and drops the Enterprise host unless a prose rule
remembers GH_HOST.

Four new subcommands absorb them, built on a review-platform reader seam
(lib/platform) whose first provider is GitHub over lib/gh.ts:

- meta: repo identity + live headSha/webUrl (was gh repo view / gh pr view)
- issue-context: closing-issue evidence file for Agent 0, incl. cross-repo
  issues and --issue for referenced-but-unlinked targets
- fetch-diff: lightweight-mode diff to file (was gh pr diff redirects)
- comment-body: one comment body by kind; pr-context truncation notes now
  name this command (with --host baked in) instead of a gh api route

SKILL.md, the Agent 0 brief, and the role-0 generated prompt no longer
contain model-executed gh calls; the GH_HOST prefixing prose rule is gone.

* test(review): pin the bare-number host source as review meta

Step 1 now derives a bare PR number's owner/repo/host with the meta
subcommand instead of a prose gh repo view; the pin follows.

* fix(review): address PR #9096 review findings

Critical:
- tests: resolve() expectations on Windows-asserted --out paths
- issue-context: same-repo-keyed closing/extra dedup, extras self-dedup,
  and a failed single-issue fetch degrades to an explicit section instead
  of aborting the whole evidence file
- meta: apply the URL-discovered host to gh routing before the PR call,
  validate --repo without requiring a number, usage errors exit 2
- agent-prompt: shellQuotePath the welded --out evidence path; plan-diff
  gains --host so a lightweight run welds it into the Agent 0 command
- lib/gh: ghRaw (no trim) for diff/comment-body payloads whose edges are
  content; resolveGhHost normalizes an empty --host flag
- SKILL.md: restore the constructable Posted:-link fallback; scope the
  no-model-run-gh-calls claim (Step 4 scratch-repo carve-out named)
- issue-context: actionable error when gh < 2.72.0 lacks
  closingIssuesReferences

Suggestions: drop dead host fields from run-function arg interfaces,
exit-2 consistency, pin the previously unpinned contracts (setGhHost
ordering x4, buildMarkdown host baking, welded GHE command, mkdirSync
guards, no-comments placeholder, GH_HOST save/restore, 422 meta pin),
fetch-diff handler tests, ClosingIssueRef dead fields removed, design-doc
corrections (D1 subset note, D2 cell, D7 amend-delta rule, testing
strategy wording, carve-out exemption), code-review.md --out fix.

* fix(review): address PR #9096 round-2 review findings

Critical:
- lib/gh: ghRaw now returns bytes untouched — the unconditional CRLF
  rewrite would strip blob-content \r from every hunk of a CRLF-file diff
  (heavy mode's raw-bytes policy; the justification comment was wrong)
- SKILL.md: Step 7's head-SHA fallback meta call carries the Enterprise
  --host annotation like every sibling call site
- SKILL.md: the render-adjudication carve-out runs in a verifier
  subagent's shell — the Enterprise note now says exported-GH_HOST only,
  otherwise adjudication is unavailable (a --host note here cannot reach
  the subagent); the GHE enumeration also names submit

Suggestions:
- agent-prompt welds the plan's pr/ownerRepo/host only after re-validation
  (the plan is a file on disk; compose-review already re-validates)
- plan-diff validates --host against HOSTNAME_RE before recording it
- pins: full emitted-command prefix at all three sites, setGhHost ordering
  now includes ensureAuthenticated (x4), ghRaw no-trim/no-rewrite,
  plan-diff host write side, closing-ref repository-less fallback,
  --issue handler wiring, comment-body --out JSON marker + malformed-repo
  exit 2 + usage-error preempts auth, meta cwd-branch flag precedence,
  buildMarkdown host baking for inline/issue kinds
- agent-briefs: --issue extras fetch from the PR's own repo — disclosed
- pr-context: fix the resolveGhHost comment (env host IS baked)
- docs: design doc corrections (gh.ts not-unchanged note, plan-diff in
  the inventory + D8, Phase 1 is new-implementation-not-refactor note,
  carve-out row/phase-3 ownership), review DESIGN.md issue-fetch path

* fix(review): address PR #9096 round-3 review findings

Critical:
- lib/gh: HOSTNAME_RE now requires an alphanumeric first char and
  REPO_SEGMENT rejects a leading dash — flag-shaped values (--help,
  -evil/repo) no longer pass validation only to be misparsed as CLI
  options downstream of the unquoted weld

Suggestions:
- agent-prompt weld: the plan re-validation (digit prNumber, isOwnerRepo,
  HOSTNAME_RE-gated host) is now pinned by tampered-plan tests
- setGhHost trims once so raw and resolved --host inputs agree
- all four subcommands validate --repo before the auth gate (usage error
  exit 2, never preempted by an auth failure), pinned with
  ensureAuthenticated-not-called assertions
- issue-context: bodies render untrimmed (leading-indent log pastes keep
  their code block); closing/extra dedup compares repos case-insensitively;
  a failed closing-issue discovery degrades into a named section (with the
  gh >= 2.72.0 hint) while --issue extras still fetch; numeric args get
  positive-integer validation with exit 2 (also --issue, id, --pr)
- agent-briefs: retry-once guidance extended — unfetchable sections mean
  re-run with --issue before declaring evidence unavailable
- SKILL.md: Step 5's lightweight block no longer re-fetches the diff
  Step 1 already wrote (one fetch, no head-advance race); SKILL.test.ts
  gains the revert guard for the lightweight capture + host note
- meta: env-GH_HOST label for explicit --repo pinned

* fix(review): address PR #9096 round-4 review findings

Critical:
- agent-briefs: the retry rule no longer sends unfetchable CLOSING refs
  through --issue (extras resolve in the PR's own repo — a cross-repo
  closing number would fetch the same-numbered unrelated issue); a plain
  re-run is the retry, closing refs are re-fetched every run
- fetch-diff: an empty PR diff writes a 0-byte file, not a one-blank-line
  file that plan-diff dies on with a coverage error instead of taking the
  designed empty-plan branch

Suggestions:
- setGhHost: only genuinely-absent input resets; a non-empty
  all-whitespace --host now fails validation instead of silently
  restoring the default
- agent-prompt weld trims the plan host before re-validating (fetch-pr
  records the raw flag); pr-context validates the resolved host against
  HOSTNAME_RE before baking it into emitted refetch commands
- empty --out is a usage error (exit 2) classified before any fetch, in
  comment-body/fetch-diff/issue-context; plan-diff's handler maps the new
  --host usage error to exit 2 instead of an uncaught crash
- issue-context: extras section header no longer claims NOT-in-closing
  when the closing set is UNKNOWN (discovery failed)
- SKILL.md: Step 1's lightweight item spells out the fetch-diff failure
  stop rule; the Enterprise enumeration now lists every --host subcommand
  (adds plan-diff, test-plan, publish-assets); code-review.md matches
- design doc: D1 names the ensureAuthenticated gate; the D2 carve-out row
  describes the shipped behavior (exported-GH_HOST only), not a welded
  prefix that never existed
- pins: full-wrapper assertions extended, numeric usage gates at all
  three remaining handlers, --pr success-path plumbing, --out JSON marker,
  setGhHost TypeError class + trim/whitespace behavior, ghRaw byte
  fidelity, unfetchable extras in the JSON, cross-repo ownerRepo in the
  JSON, untrimmed body rendering, extras-section absence, discovery-failed
  header wording, runPrContext-level host baking (flag + env + rejected
  alias), SKILL revert guards for Step 7's meta rewiring

* fix(review): address PR #9096 round-5 review findings

Critical:
- fetch-pr records the TRIMMED host into the fetch report, so the two
  downstream readers that re-validate it (compose-review's plan identity,
  the agent-prompt weld) see the canonical form — a padded-but-valid
  GHE host no longer drops to github.com anchor links
- a non-empty all-whitespace --host no longer silently falls through to the
  env/default in resolveGhHost (it is returned as '', not swallowed), and
  publish-assets validates the raw flag via setGhHost before resolving —
  the Contents-API write can no longer be retargeted at github.com by a
  whitespace-only flag; match-remote now fails closed (exit 6) on the same
  input instead of matching github.com

Suggestions:
- plan-diff: drop the doubled `plan-diff:` prefix from the two thrown
  TypeErrors (the handler prepends it once); reject a whitespace-only
  --host instead of dropping it from the plan
- new shared assertWritableOutPath (lib/paths): empty/whitespace AND
  directory --out targets are classified as usage errors BEFORE any fetch
  in comment-body/fetch-diff/issue-context (the directory case previously
  died EISDIR after the fetches and exit-coded as a runtime failure)
- resolveRepo fetches `parent` and prefers it when the resolved repo is a
  fork — gh's default-repo preference is a remote literally named
  `upstream`, not an API fork check, so an origin-only fork clone no longer
  targets a fork's same-numbered PR
- scope the comment-body exit-2 comment to the handler-level guards (yargs
  -layer missing-arg / invalid-choice failures exit 1 — a known gap)
- SKILL.test revert guards: rule-4 issue-context weld + absence of the
  pre-absorption `--json closingIssuesReferences` syntax; the 422
  `commit_id` comparison clause and the `fetch-diff`-output rename; the
  Step 6 tail-fetch `--out` sentence and the Posted: fallback grounding;
  the lightweight-capture host note
- pins: malformed-host handler exit-2 in fetch-diff/issue-context/meta;
  issue-context exit-1 auth branch; padded-host weld trim; pr-context
  setGhHost routing (flag + env); whitespace-only --out in all three;
  numeric-gate tests reset process.exitCode between invocations and add
  non-integer cases; plan-diff asserts the metacharacter host is never
  recorded into the plan

* fix(review): address PR #9096 round-5 findings (meta host guard, plan-diff stderr)

- meta's discovery branch validates the routed host against HOSTNAME_RE
  before setGhHost: a host gh tolerates but the subcommands reject
  (underscore intranet aliases, IPv6 literals) is an environmental
  condition, so it now names the actual source (--host flag vs discovered
  repo-URL host) and fails exit 1, never as a usage error blaming a flag
  the caller never passed
- plan-diff's handler catch uses writeStderrLineSafe (a broken stderr must
  not let the throw escape and lose the exit-2/exit-1 classification)

* fix(review): address PR #9096 round-6 Critical findings

- lib/gh: split the byte/text raw modes. execGhWithRetry gains a
  mode ('default' | 'bytes' | 'text'); the bytes mode runs with encoding
  'buffer' and decodes latin1, so a diff of a non-UTF-8 (Latin-1/Shift-JIS)
  file no longer loses every invalid byte to U+FFFD. ghRaw is the bytes
  mode (fetch-diff writes it back with latin1 — byte fidelity end to end);
  new ghRawText is UTF-8-with-edges-preserved, which comment-body uses
  (comment bodies are always valid UTF-8 from the API; the leading-indent
  code-block fidelity holds, but bytes are not corrupted into mojibake)
- lib/gh: split the leading-dash ban per segment — owners cannot start
  with a hyphen but REPO names can (yezhaodan/-Git exists), so a leading
  dash on the repo half is no longer rejected (the ban only protected
  against the flag-shaped OWNER half anyway)
- github resolveRepo: take the host from the resolved repo's OWN url —
  gh's `parent` field carries no url (only id/name/owner), so reading
  target.url crashed every origin-only fork clone with TypeError; the
  meta.test fork fixture now matches the real gh shape
- publish-assets: the round-5 raw-flag validation guarded on
  `trim() !== ''`, which skipped exactly the whitespace-only host it
  exists to refuse — guard on presence instead so setGhHost(' ') throws
  the documented TypeError (exit-3 refusal, no silent Contents-API
  retarget at the env/default host)

* fix(review): address PR #9096 round-6 gpt-5.6-sol Critical findings

- agent-prompt weld: a present-but-invalid plan host now fails closed
  (throws) instead of being silently dropped to null — a tampered host can
  no longer quietly reroute the evidence fetch to github.com's same-named
  repo (a missing host stays optional)
- comment-body: read `.body` off the JSON-parsed response instead of
  `--jq '.body // ""'` — the jq form appends a trailing newline (a body
  not ending in one gained a byte; an empty body became "\n"); JSON parse
  returns the exact bytes GitHub stores
- issue-context: --issue now accepts `owner/repo#123` as well as `123`, so
  a referenced issue living in a DIFFERENT repo is fetched there instead
  of silently reading the PR repo's same-numbered unrelated issue; dedup
  is by (repo, number) pair, case-insensitively, which also fixes the
  cross-repo-closing-shadows-same-repo-extra edge uniformly
- lib/gh: drop the now-unused ghRawText text mode (comment-body moved to
  the JSON parse)

* fix(review): address PR #9096 round-7 review findings

Critical:
- R7-1: the Agent 0 brief, SKILL.md rule 4, and code-review.md still taught
  "issue-context cannot fetch a referenced issue in a different repo —
  declare it unavailable", contradicting the cross-repo `--issue
  owner/repo#123` capability shipped in round 6. All three carriers now
  teach the qualified form, and the wrong-issue warning / retry ban is
  narrowed to bare numbers (a qualified retry is a correct retry)

Suggestions (all directly pin or harden this PR's changes):
- agent-prompt weld fails closed on a present-but-NON-STRING host and on a
  present-but-whitespace-only host (both were silently dropped to null,
  rerouting the evidence fetch), matching the sibling identity fields
- gh.test.ts: the ghRaw byte-fidelity test now returns a real Buffer with
  an invalid-UTF-8 byte (0xE9) — the latin1 decode genuinely executes (the
  previous string mock made String.prototype.toString an identity call)
- meta: the explicit-`--repo` branch gates the emitted host with
  HOSTNAME_RE, same as the discovery branch (an unroutable GH_HOST env
  value no longer emits a host label every sibling rejects)
- publish-assets: pin the round-6 whitespace-host refusal (exit 3, no gh
  call, `(from --host)` in stderr)
- issue-context: pin the documented `--issue owner/repo#n` grammar end to
  end through the handler regex
- code-review.md: the GHE `--host` enumeration adds match-remote (the
  pipeline's first host-sensitive step)

* fix(review): address PR #9096 round-8 review findings

Critical:
- R8-1: the round-7 non-string-host guard threw on `host: null` — which
  fetch-pr writes unconditionally into every same-repo github.com plan
  (`args.host?.trim() || null`), so every ordinary review would have
  failed at the roster build. null is now tolerated (only a present
  non-null non-string host throws); regression test added
- R8-2: comment-body validates `--kind` is a single admitted token before
  any platform call — a duplicated `--kind` arrives as an array that
  passes yargs' element-wise choices, and String() would coerce it to
  'review,inline' into the wrong API collection

Suggestions:
- assertWritableOutPath rejects a trailing-separator --out (the POSIX
  directory spelling that resolve() normalizes away)
- comment-body prints the body via process.stdout.write (byte-exact, no
  invented trailing newline)
- agent-prompt weld prNumber guard strengthened (rejects 0 and unsafe
  integers, matching the welded handler's contract)
- pins: meta explicit-branch HOSTNAME_RE gate, isOwnerRepo dash asymmetry
  both directions, ghRaw retry with buffer stderr, whitespace-only and
  null plan hosts, issue-context qualified-grammar rejection side,
  corrected the misleading case-insensitive dedup test, fs mocks no longer
  consult ambient /tmp state (existsSync/statSync overridden)
- R8-13 (extras-header double-render assertion) deferred to #9194 per the
  reviewer's own note
2026-08-15 09:16:48 +00:00
..
channels feat(web-shell): redesign Channel policy and workspace management (#8848) 2026-08-14 07:41:44 +00:00
_meta.ts feat(cli): add native multi-agent coordination (#8804) 2026-08-12 17:39:03 +00:00
approval-mode.md feat(cli): change default approval mode from default to auto (#6899) 2026-07-15 04:55:32 +00:00
arena.md feat(cli): add native multi-agent coordination (#8804) 2026-08-12 17:39:03 +00:00
auto-mode.md fix: ask when auto classifier is unavailable (#7331) 2026-07-21 03:27:17 +00:00
code-review.md feat(review): absorb prose gh commands into platform-backed subcommands (#9096) 2026-08-15 09:16:48 +00:00
commands.md feat(cli): add native multi-agent coordination (#8804) 2026-08-12 17:39:03 +00:00
computer-use.md Fix long session timeline scrolling (#6526) 2026-07-09 11:43:21 +00:00
dual-output.md fix(cli): bound headless tool result content (#9012) 2026-08-12 16:22:36 +00:00
followup-suggestions.md feat(cli): show follow-up suggestion in input placeholder (#5145) 2026-06-19 13:39:12 +08:00
headless.md fix(cli): bound headless tool result content (#9012) 2026-08-12 16:22:36 +00:00
hooks.md fix(core): separate hook context from transcript display (#7948) 2026-08-08 02:03:20 +00:00
language.md refactor(cli): revert dynamic slash command LLM translation (#4145) 2026-05-15 16:01:16 +08:00
lsp.md fix(lsp): expose status and startup diagnostics (#3649) 2026-05-17 01:42:28 +08:00
markdown-rendering.md feat(cli): support /copy N to copy Nth-last AI message (#4761) 2026-06-08 10:08:45 +08:00
mcp.md fix(core): Avoid replaying unsafe MCP tool calls (#8387) 2026-08-03 11:04:38 +00:00
memory.md feat(memory): protect pinned files during forked Dream (#7714) 2026-08-01 00:55:45 +00:00
multi-agent-coordination.md feat(cli): add native multi-agent coordination (#8804) 2026-08-12 17:39:03 +00:00
sandbox.md fix(cli): avoid updating active CLI processes (#6874) 2026-07-15 00:33:17 +00:00
scheduled-tasks.md docs(channels): Document loops and proactive delivery (#7628) 2026-07-26 07:32:18 +00:00
skills.md docs: document skill learning and live reload (#8298) 2026-08-01 15:23:08 +00:00
status-line.md fix(cli): avoid duplicate context usage in footer and status line (#8749) 2026-08-11 07:18:48 +00:00
structured-output.md docs: user + design docs for --json-schema structured output (#4051) 2026-05-17 23:10:34 +08:00
sub-agents.md feat(core): add project-level fork profiles (#8148) 2026-08-01 02:20:51 +00:00
tips.md feat: add contextual tips system with post-response context awareness (#2904) 2026-04-13 17:40:27 +08:00
token-caching.md feat: update docs 2025-12-12 19:37:36 +08:00
tool-use-summaries.md fix(cli): stabilize thinking block height, replace transcript overlay with inline Ctrl+O toggle (#8077) 2026-08-01 02:39:53 +00:00
worktree.md feat(core): improve subagent delegation defaults and guardrails (#7048) 2026-07-18 08:52:48 +00:00