feat(walkthrough): guided AI walkthrough for diffs, branches, and PRs (#2572)

A diff is ordered by file path, which is almost never the order in which a
change makes sense. This adds a Walkthrough surface that reorders it: the model
groups related hunks into stops, explains what each group changes about
behavior, and orders the stops so each builds on the last. It explains and
orders; judging code stays with the existing Review action.

Reviews uncommitted work (all, staged, unstaged), a branch against its base, or
a pull request. Generation is always user-initiated — nothing runs on a timer,
on a file change, or as a side effect of opening a panel.

Invariants worth preserving:

- Hunk identity is derived on the server and only there. Ids are content
  hashes, so an anchor that no longer resolves is proof the code it described
  changed, and staleness needs no heuristics. The client matches ids to ids and
  never recomputes them; two implementations would have to agree forever.
- The digest is never truncated. A diff that does not fit the model's context
  is refused with an actionable reason, because a walkthrough written against
  half a diff reads as confident and is wrong.
- Nothing disappears. Lockfiles and other generated output are excluded from
  the model's input by name — never by size — and everything no stop covers is
  listed at the end, so "have I seen all of it" stays answerable.
- Cost is explicit. Results are content-addressed, so returning the working
  tree to an earlier state costs nothing; generation outlives its request, so a
  refresh detaches the client rather than discarding paid-for work, and only an
  explicit cancel stops it.

Supporting changes to shared modules:

- git: expose the existing getRangeDiff as GET /api/git
  listUntrackedPaths and getUntrackedDiffs. The latter resolve the repository
  once for a batch instead of per file, taking a panel
  ~340ms on an 80-file working tree.
- small-model: structured output across four wire forma
  and abort signal, and an onOverflow policy so an oversized prompt fails
  loudly instead of being silently clipped. A provider
  remembered so the prompt-side fallback goes first next time.
- models.dev metadata: surface structured_output as tri
  false blocks a model, a missing field does not, because the catalog omits it
  for roughly half of all models.

Desktop and tablet only: VS Code serves Git through its
these routes, and the mobile shell does not consume the surface registry.

Docs: packages/docs walkthrough page in English and all eight locales.
This commit is contained in:
Bohdan Triapitsyn
2026-08-02 16:22:55 +03:00
committed by GitHub
parent b1ec34162e
commit 34d0ff7383
99 changed files with 7316 additions and 53 deletions
+50
View File
@@ -1096,6 +1096,56 @@ export const dict: Record<I18nKey, string> = {
'contextRail.surface.git.description': '커밋, 브랜치, 풀 리퀘스트',
'contextRail.surface.terminal.description': '내장 터미널',
'contextRail.surface.diff.description': '작업 중인 변경 사항 검토',
'contextPanel.mode.walkthrough': '워크스루',
'contextRail.surface.walkthrough.description': 'AI가 안내하는 변경 사항 워크스루',
'walkthrough.scope.all': '커밋되지 않은 전체',
'walkthrough.scope.group.workingTree': '작업 트리',
'walkthrough.scope.group.committed': '커밋됨',
'walkthrough.scope.staged': '스테이지됨',
'walkthrough.scope.working': '스테이지 안 됨',
'walkthrough.scope.branch': '이 브랜치',
'walkthrough.scope.selectorAria': '리뷰 대상 선택',
'walkthrough.scope.pullRequest': 'PR #{number}',
'walkthrough.action.generate': '워크스루 생성',
'walkthrough.action.regenerate': '다시 생성',
'walkthrough.action.cancel': '취소',
'walkthrough.action.next': '다음 단계',
'walkthrough.action.previous': '이전 단계',
'walkthrough.action.refresh': '새로 고침',
'walkthrough.action.open': 'AI 워크스루',
'walkthrough.stage.collecting': '변경 사항을 모으는 중',
'walkthrough.stage.asking': '모델을 기다리는 중',
'walkthrough.stage.assembling': '워크스루를 조립하는 중',
'walkthrough.empty.title': '아직 워크스루가 없습니다',
'walkthrough.empty.description': '이 변경 사항을 따라 읽을 수 있는 경로를 만듭니다. 스몰 모델을 호출해 토큰을 사용하므로 요청할 때만 실행됩니다.',
'walkthrough.stale.banner': '이 리뷰 이후에 코드가 바뀌었습니다. 오래된 단계: {count}',
'walkthrough.stop.staleAll': '이 단계가 설명하던 코드가 모두 바뀌었습니다.',
'walkthrough.stop.stalePartial': '이 단계가 설명하던 코드 일부가 바뀌었습니다. 사라진 부분: {count}',
'walkthrough.stop.staleShort': '오래됨',
'walkthrough.stop.noCode': '이 단계의 코드는 현재 diff에 없습니다.',
'walkthrough.uncovered.title': '리뷰가 다루지 않은 변경: {count}',
'walkthrough.uncovered.description': '리뷰가 일상적인 변경으로 판단했습니다. 펼쳐서 직접 확인하세요.',
'walkthrough.toc.moreFiles': '다른 파일: {count}',
'walkthrough.toc.uncovered': '미포함: {count}',
'walkthrough.toc.resize': '목차 열 너비 조절',
'walkthrough.importance.critical': '중요',
'walkthrough.importance.context': '참고',
'walkthrough.blocked.noModel.title': '사용할 수 있는 스몰 모델이 없습니다',
'walkthrough.blocked.noModel.description': '리뷰를 생성하려면 모델 제공자에 로그인하세요.',
'walkthrough.blocked.emptyDiff.title': '리뷰할 내용이 없습니다',
'walkthrough.blocked.emptyDiff.description': '이 범위에는 아직 변경 사항이 없습니다.',
'walkthrough.blocked.contextTooSmall.title': '이 diff는 현재 모델에 너무 큽니다',
'walkthrough.blocked.contextTooSmall.description': '{model}은 약 {available}천 자를 담을 수 있는데 이 diff에는 약 {required}천 자가 필요합니다. 잘라내지 않으니 컨텍스트가 더 큰 모델을 선택하세요.',
'walkthrough.blocked.structuredOutput.title': '이 모델은 구조화된 출력을 지원하지 않습니다',
'walkthrough.blocked.structuredOutput.description': '{model}은 워크스루에 필요한 구조화된 응답을 지원하지 않습니다.',
'walkthrough.blocked.chooseModel': '스몰 모델 선택',
'walkthrough.blocked.outputExhausted.title': '모델의 응답 예산이 바닥났습니다',
'walkthrough.blocked.outputExhausted.description': '{model}이(가) 출력 예산을 모두 추론에 쓰고 아무것도 반환하지 않았습니다. 추론 모델은 큰 diff에서 흔히 이렇게 됩니다. 덜 추론하는 모델을 고르거나 범위를 좁혀 보세요.',
'walkthrough.blocked.outputExhausted.descriptionUnknownModel': '스몰 모델이 출력 예산을 모두 추론에 쓰고 아무것도 반환하지 않았습니다. 추론 모델은 큰 diff에서 흔히 이렇게 됩니다. 덜 추론하는 모델을 고르거나 범위를 좁혀 보세요.',
'walkthrough.blocked.onlyGenerated.title': '생성된 파일만 변경되었습니다',
'walkthrough.blocked.onlyGenerated.description': '여기의 변경은 모두 잠금 파일이거나 도구가 만든 산출물이며, 리뷰는 이런 파일을 의도적으로 건너뜁니다.',
'walkthrough.blocked.contextTooSmall.descriptionUnknownModel': '스몰 모델은 약 {available}천 자를 담을 수 있는데 이 diff에는 약 {required}천 자가 필요합니다. 잘라내지 않으니 컨텍스트가 더 큰 모델을 선택하세요.',
'walkthrough.blocked.structuredOutput.descriptionUnknownModel': '스몰 모델은 워크스루에 필요한 구조화된 응답을 지원하지 않습니다.',
'contextRail.surface.plan.description': '현재 계획 보기',
'contextRail.surface.pr.description': '현재 브랜치의 풀 리퀘스트를 생성, 검토, 병합',
'contextRail.surface.notes.description': '프로젝트의 노트, 할 일, 계획',