Conversation
* fix(ship): fall back to gh auth token (parity with parsec doctor) (#281) parsec ship 이 PARSEC_GITHUB_TOKEN / GITHUB_TOKEN / GH_TOKEN env var 모두 비어있을 때 PR 생성을 거부했지만 parsec doctor 와 tracker 레이어는 이미 `gh auth token` fallback 적용. parity 깨져 사용자가 수동 `gh pr create` 로 추가 작업 필요. 해결: - src/env.rs: github_token() 의 4번째 우선순위로 gh_auth_token() 추가. 신규 gh_auth_token() helper 는 `gh auth token` shell out — 실패 시 None (binary 없음 / exit code != 0 / non-UTF8 / 빈 출력 모두 graceful). - src/github/mod.rs: resolve_github_token 의 env-var/gh fallback 을 GitHub host (github.com / *.ghe.com / *.github.* GHE) 에만 적용. 신규 is_github_host() helper. Bitbucket / GitLab remote 가 `gh auth login` 한 환경에서 GitHub 토큰을 잘못 픽업하지 않도록 가드. - src/cli/commands/doctor.rs: 중복 `gh auth token` shell-out 코드 제거 → env::gh_auth_token() 공통 helper 호출. parity at the helper level. 신규 테스트 (src/env.rs): github_token_priority_order — PARSEC > GITHUB > GH 우선순위 + 빈값 fallback 4 시나리오 sequential 검사. EnvGuard 로 process-wide env 보존+복원. gh_auth_token_returns_option_string_or_none — gh binary 가용성에 무관하게 trim 보장. github_token_returns_none_when_all_missing_and_gh_fails — env 모두 미설정 시 None 또는 valid Some 모두 허용 (CI 와 dev 환경 양립). 검증: - cargo test: 79 tests PASS (env tests 6 + integration 73) - cargo clippy --all-targets -- -D warnings: clean - cargo fmt --check: clean - bitbucket integration tests: 5/5 PASS (이전 발견된 host-gated 이슈 해결) 회귀 위험: 매우 낮음 - 환경에 gh CLI 미로그인 / 미설치 → 기존과 동일 (None 반환) - 환경에 gh 로그인됨 + GitHub remote → 신규 fallback 활용 (issue #281 의도) - 환경에 gh 로그인됨 + Bitbucket/GitLab remote → is_github_host 로 차단, 기존과 동일 Closes #281 * docs(v0.5): open roadmap milestone — visualization release vision v0.5 마일스톤 공식 출발 마커. README 와 CHANGELOG 양쪽에 향후 비전 명시. README.md (## Roadmap 섹션 신설, ## Why use it 과 ## Install 사이): - vision tagline: "parsec = AI agents + human devs both — worktree-native git CLI" - 4단계 milestone: · v0.4.0 ✅ Released (2026-05-04): Multi-forge + multi-tracker foundation · v0.5 🚧 Next — _The visualization release_: smartlog · TUI dashboard · speculative merge · parsec test · AI PR descriptions · v1.0 🔜 — _AI-Native Standard_: MCP server signature, Claude/Cursor/Copilot 가 parsec 을 first-class tool 로 invoke · v2.0+ 🔮 — _Ecosystem Hub_: plugins · VS Code extension · Linear tracker - v0.5 milestone link (github.com/erishforG/git-parsec/milestone/3) CHANGELOG.md (## [Unreleased] 확장): - ### Added: v0.5 milestone opened, README Roadmap 참조 - ### Fixed: #281 ship gh auth token fallback 노트 (별 commit ae1a2d3 와 동일 entry) 회귀 위험: 0 (문서 변경만) * fix(env): serialize env-touching tests via process-wide mutex (Windows CI) PR #289 Windows CI 1건 fail. macOS / Ubuntu Test 통과, Windows Test 만 실패. 원인: - env::tests 의 github_token_priority_order 와 github_token_returns_none_when_all_ missing_and_gh_fails 가 cargo test 병렬 실행 시 process-wide env vars 를 race. - priority_order 가 PARSEC=p / GITHUB=g / GH=h 셋업 후 assert 사이에 sibling 테스트의 EnvGuard::new() 가 모든 env 를 clear → assert 가 PARSEC 못 보고 GH=h 반환. - macOS/Ubuntu 는 timing 우연히 안전, Windows 는 다른 thread scheduling 으로 race 발현 (Some("h") vs Some("p") at src/env.rs:205). 수정: - std::sync::OnceLock<Mutex<()>> 의 env_lock() 신규 — env 만지는 테스트들 직렬화. std 만 사용 (외부 deps 추가 X 제약 준수). - github_token_priority_order 와 github_token_returns_none_when_all_missing_and_gh_fails 를 단일 함수 github_token_priority_order_and_fallback 로 통합 + env_lock() 의 Mutex guard 획득. 5 시나리오 (PARSEC 우선 / GITHUB / GH / 빈값 / 모두 미설정) 직렬 실행. - gh_auth_token_returns_option_string_or_none 은 env 미터치라 lock 불필요 — 그대로 유지. - production 로직 (env::github_token / env::gh_auth_token) 변경 0. 검증: - 로컬 cargo test 78 PASS (env tests 5 + integration 73), clippy clean, fmt clean. - Windows CI 검증은 force-push 후 PR #289 워크플로우에서 확인.
…utput (#305) Phase 1 of #245. Establishes the command surface and rendering path without any forge-side enrichment. Adds `parsec smartlog` (alias `sl`): - `SmartlogNode` per active worktree: ticket, branch, base, commits, plus `pr` / `ci` placeholder fields gated on `skip_serializing_if` so the JSON output stays clean until follow-up PRs populate them. - `collect_commits` shells out to `git log <base>..<branch>` (no `git2` dependency — matches the rest of `git/`). Soft-fails per worktree so a corrupt worktree can't take the whole command down. - `render_text` groups nodes by base branch and draws ASCII tree glyphs (○ │ ├─● └─). Returns the rendered string for testability. - `--json` emits the same structure for tooling. - `--depth N` caps commits per worktree (default 10). Out of scope for this PR (follow-ups on the same epic): - PR overlay (open/draft/merged) - CI overlay (passed/failed/running) - Review state (approved / changes requested) - Stack relationship visualization - Color / smarter wrapping Tests (9 new in `cli::commands::smartlog::tests`): - `parse_commit_line` happy path + tab-in-subject + garbage + empty SHA - `render_text` empty / single / no-commits / multi-base grouping - JSON serialization omits placeholder overlay fields Smoke run on parsec's own worktrees produces: ○ develop (base) ├─● 207 #207 [feature/207] │ └─ (no commits since develop) └─● 279 #279 [feature/279] └─ (no commits since develop)
…lp) (#306) * [303] refactor(errors): adopt 3-line standard (error / caused by / help) Issue #303. Add the infrastructure for the standard error format and wire main.rs to render it. Existing call sites keep rendering as a single line — migration is gradual (see docs/error-format.md). Changes: - `ParsecError` gains `caused_by: Option<String>` and `help: Option<String>` fields plus builder-style setters (`with_caused_by`, `with_help`). `Display` now writes one to three lines depending on which fields are populated. - `JsonError` gains the same two fields with `skip_serializing_if = "Option::is_none"` so existing `--json` consumers see no schema change. - `extract_full(&anyhow::Error) -> Option<&ParsecError>` helper for new callers; the legacy `extract_code` is kept untouched. - `main.rs` prefers the typed error: when the error is a `ParsecError`, print it directly (its `Display` already includes the `error:` prefix + code); otherwise fall back to the legacy single-line `error: {err:#}`. - `bail_code!` macro unchanged (for the "summary only" case). - `docs/error-format.md` documents the format, builder API, JSON shape, recipes, and what NOT to do. Tests: +9 in `errors::tests` covering 1/2/3-line display, help-only, extract_full happy/None, backward-compat extract_code, JSON skip-if-none, JSON with-fields, bail_code macro round-trip. Full suite 53 + 5 + 40 = 98 pass, fmt clean. Migration: any existing `ParsecError::new(...)` site can opt in by chaining `.with_caused_by(...)` and/or `.with_help(...)`. Prioritize cli/commands/ and worktree/ first (highest user contact). * [303] chore(errors): allow dead_code on Phase 1 builder + legacy extract_code Clippy `-D warnings` flagged `with_caused_by`, `with_help`, and `extract_code` as never-used. Phase 1 of #303 is the infra-only PR — call sites land in follow-up PRs. Annotation matches the existing `#[allow(dead_code)]` on `ErrorCode` for the same forward-looking reason.
Adds an informational windows-2025-vs2026 job that runs cargo build/test on the new Visual Studio 2026 default image ahead of the GitHub Actions runner migration window (2026-06-08 ~ 06-15). continue-on-error: true keeps it advisory only — main matrix stays gated on existing windows-latest. After the migration window closes we either delete this job (if main matrix passes) or pin windows-2022 here (if it fails). Refs: #307
Adds `parsec __complete <worktrees|branches>` — a hidden subcommand that shell completion scripts can call to enumerate candidates dynamically. Failure paths (no repo / no config) silently emit nothing so completion never errors at the prompt. Also adds `git::list_local_branches`, a helper for enumerating local branch names via `git for-each-ref refs/heads/`. This is the **foundation only**. The follow-up work — post-processing clap-generated completion scripts (zsh/bash/fish) so that ticket-shaped arguments call `parsec __complete worktrees` and branch-shaped arguments call `parsec __complete branches` — lands in a separate PR. Refs: #291
* test(cli): add integration tests for compress, config schema, log --export Cover three commands added in v0.4.0 that had zero test coverage: - test_compress_nothing_to_do: single-commit worktree exits cleanly - test_compress_squashes_commits: 2-commit branch is reduced to 1 - test_config_schema_outputs_json: output is valid JSON Schema - test_history_log_export_empty: empty log exits 0 with no stdout Closes #314 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ci: re-trigger Branch Policy (base now develop) --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…317) develop에 머지됐지만 CHANGELOG.md [Unreleased]에 누락된 항목 4개를 추가한다: - parsec smartlog (alias sl): commit DAG 시각화 (#245, #305) - parsec __complete: 동적 shell completion 헬퍼 (#291, #312) - 에러 메시지 3줄 표준화 (error/caused by/help) (#303, #306) - Windows VS2026 pre-validation CI job (#307, #311) Closes #316 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
parsec smartlog (#305)과 sl 별칭이 develop에 머지됐지만 CLI 통합 테스트가 전혀 없었음. 5개 시나리오 추가: - test_smartlog_empty_repo: 빈 repo → 'No active worktrees' 확인 - test_sl_alias_works_like_smartlog: sl == smartlog 동일 출력 확인 - test_smartlog_json_empty_is_array: --json 빈 repo → [] JSON 배열 - test_smartlog_shows_worktree: worktree 1개 → 티켓·(base) 마커 표시 - test_smartlog_json_one_worktree: --json 1 worktree → 필드 검증 (ticket, branch, base_branch, commits, pr/ci 미노출) Closes #318 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
diff.rs, history.rs에 module-level(//!) 및 function-level(///) RustDoc을 추가. 인접한 smartlog.rs·complete.rs와 일관성 맞춤. - diff.rs: //! 모듈 헤더(diff/conflicts/sync 역할·관련 이슈), pub async fn diff/conflicts/sync에 파라미터·출력모드·동작 설명 추가 - history.rs: //! 모듈 헤더(OpLog·ExecLog 구조 설명), pub async fn log/log_export/undo에 동작·edge-case 설명 추가 프로덕션 코드 변경 없음 (주석 전용). Closes #320 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
stack.rs: //! 모듈 헤더 + stack/stack_sync/stack_submit 함수 doc ci.rs: //! 모듈 헤더 + ci/fetch_bitbucket_ci 함수 doc 프로덕션 코드 변경 없음 — 주석 73줄 추가만. Closes #322 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…eleton (#324) (#325) Add `parsec health` command that scans all active worktrees for three lightweight health indicators: - has_lock — .git/index.lock exists (interrupted git process) - uncommitted — count of staged + unstaged files - stale — last commit older than 7 days Output (human mode): colored table with ✓/⚠/✗ per worktree and a summary line. JSON mode emits a structured array with `all_healthy` flag. Files changed: - src/cli/commands/health.rs (new, ~99 lines) - src/cli/commands/mod.rs (+2 lines, re-export) - src/cli/mod.rs (+11 lines, Health variant + dispatch) - src/output/mod.rs (+15 lines, HealthRecord + dispatch_output!) - src/output/human.rs (+66 lines, colored table renderer) - src/output/json.rs (+34 lines, JSON renderer) CI-status overlay deferred to Phase 2 (depends on #309/#310). All checks are read-only; no worktree state is modified. Closes #324 Refs #299 Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Phase 1 구현(#325)을 커버하는 통합 테스트: - test_health_empty_repo: 빈 repo → 'No active worktrees.' 확인 - test_health_empty_repo_json: 빈 repo → --json 시 '[]' 출력 확인 - test_health_shows_worktree: 워크트리 1개 → 티켓명 포함 출력 확인 - test_health_json_one_worktree: --json 구조 검증 (worktrees 배열, all_healthy 불리언, ticket/has_lock/uncommitted/stale_days/stale 필드) - test_health_exit_zero_with_issues: lock 파일 존재해도 exit 0 (정보성 only) Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(health): parsec health CLI 통합 테스트 5개 추가 (#324) Phase 1 구현(#325)을 커버하는 통합 테스트: - test_health_empty_repo: 빈 repo → 'No active worktrees.' 확인 - test_health_empty_repo_json: 빈 repo → --json 시 '[]' 출력 확인 - test_health_shows_worktree: 워크트리 1개 → 티켓명 포함 출력 확인 - test_health_json_one_worktree: --json 구조 검증 (worktrees 배열, all_healthy 불리언, ticket/has_lock/uncommitted/stale_days/stale 필드) - test_health_exit_zero_with_issues: lock 파일 존재해도 exit 0 (정보성 only) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(smartlog): Phase 2 — PR/CI status overlay (Refs #245) Phase 1 (#305) skeleton에서 `SmartlogNode.pr` 가 placeholder로 남아있던 걸 실제 GitHub PR/CI 데이터로 채움. Issue #245 의 예시 (`[PR #42 ✓ CI passed, ✓ approved]`) 가 이제 ASCII 트리에 그대로 렌더링됨. ## 변경 - `SmartlogPrOverlay` struct 신설 (number/state/ci_status/review_status/url) - `smartlog()` 가 GitHubClient 통해 brach → PR 매칭 + PrStatus 조회 후 node.pr 채움. 토큰 없거나 비-GitHub remote거나 HTTP 실패 = 그냥 overlay 생략 (best-effort, 명령 실패 안 함) - `--no-overlay` 플래그 추가 (강제 offline 모드) - ASCII 렌더러: ticket 라인 아래 `├─ [PR #N ● open ✓ CI ✓ approved]` 한 줄 - 글리프 규칙: 기존 `parsec pr status` / `parsec ci` 와 동일 (✓/✗/●/○) ## CI 필드는? `SmartlogNode.ci` 는 일단 None 유지. Phase 2 는 CI 요약을 overlay 안에 포함시켜 한 줄로 표시 (스마트로그 본질은 한눈 — per-check 디테일은 `parsec ci` 가 이미 담당). ## 드라이브-바이 tests/cli_tests.rs:1725 에 `assert_eq!(bool, false)` clippy 경고 (#326 회귀) → `assert!(!...)` 로 수정. develop 의 clippy strict 빌드 회복. ## 테스트 - 신규 unit 5개 (format_pr_badge × 3 + render_text overlay + JSON 직렬화) - 기존 9개 smartlog unit + 5개 통합 테스트 모두 통과 - cargo build / clippy -D warnings / fmt --check / test 전체 clean ## 다음 Phase 힌트 - Phase 3: per-worktree filtering (`--ticket CL-2283` 등) - Phase 4: stack 관계 시각화 (PR base = 다른 PR head) - Phase 5: review state 색상 강조 (terminal color) Refs #245 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…291) (#328) Phase 1 (#312) 가 `parsec __complete <kind>` 내부 명령을 만들어 shell completion 스크립트가 동적으로 worktree/branch 후보를 가져올 수 있게 했음. 이번에는 그 위에 실제 zsh/bash/fish 스크립트 3개를 추가해서 사용자가 sourcing 만 하면 `parsec switch <Tab>` 처럼 live ticket 자동완성을 받을 수 있게 함. ## 변경 - `completions/_parsec` (zsh, #compdef) — `_parsec_worktrees` / `_parsec_branches` helper + 모든 주요 subcommand 의 positional/option 자동완성 - `completions/parsec.bash` — `complete -F _parsec parsec`. bash-completion 의존 (`_init_completion`). prev word 기반 dispatch + `compgen -W` - `completions/parsec.fish` — `__fish_seen_subcommand_from` 기반. per-subcommand 옵션 (`--base`, `--on`, `--branch`) 도 동적 branch/worktree 후보 연결 - README "Install > Shell completion" 섹션 추가 (3개 shell install 명령) ## 커버 범위 (Tier 1 + 2) - ticket 받는 subcommand: start, switch, ship, open, clean, status, ticket, pr-status, ci, merge, diff, sync, log, compress, adopt, rename - branch 받는 옵션: `start --base|--on|--branch`, `ship --base`, `adopt --branch` - smartlog: `--depth`, `--no-overlay` (PR #327 와 호환) ## __complete kind 추가 없음. Phase 1 의 `worktrees` / `branches` 두 개로 충분 — future Phase 3 에서 필요하면 추가 (예: `tickets` 트래커, `reviewers` GitHub 사용자). ## 드라이브-바이 PR #327 에서 같이 잡았던 `tests/cli_tests.rs:1725` clippy 회귀 (#326) develop 머지 전이라 또 한 번 적용. PR #327 머지되면 충돌 안 남. ## 테스트 - 신규 4개 통합 테스트: - `completion_zsh_present_and_dynamic` — `#compdef parsec` + `__complete` 호출 + 핵심 sub 7개 - `completion_bash_present_and_dynamic` — `complete -F _parsec parsec` + 동일 - `completion_fish_present_and_dynamic` — `__parsec_worktrees` 함수 + 동일 - `completion_scripts_reference_phase1_subcommand_signature` — 스크립트가 Phase 1 가 지원하지 않는 kind 부르지 않는지 (silent fail 방지) - 전체 62 통합 테스트 + smartlog 14 단위 + health 5 통과 - cargo build / clippy -D warnings / fmt --check 전부 clean ## 다음 Phase 힌트 - Phase 3: `__complete tickets` (트래커 미해결 티켓), `__complete reviewers` (GitHub mention) - Phase 4: shell auto-install hook (parsec init 에서 자동 설치 옵션) Refs #291 Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…old (Refs #299) ## 무엇 parsec health Phase 2: GitHub CI 상태 오버레이 + 설정 가능한 stale 임계값. ## 변경 - health.rs: --stale-days <N> 플래그로 stale 임계값 설정 (기본 7일) - health.rs: --no-overlay 플래그로 오프라인 모드 지원 - health.rs: fetch_ci_overlay() — 브랜치 → PR 번호 → CI 상태 (best-effort) - output/mod.rs: HealthRecord에 ci_status: Option<String>, pr_number: Option<u64> 추가 - output/human.rs: CI 상태를 색상 아이콘으로 표시 (✓/✗/● CI) - output/json.rs: ci_status, pr_number, ci_failing 필드를 JSON 출력에 포함 - cli/mod.rs: Health 명령을 struct variant로 변경 (--stale-days, --no-overlay) - tests/cli_tests.rs: Phase 2 플래그 검증 테스트 3개 추가 (8/8 통과) ## 다음 Phase 힌트 Phase 3: threshold config (parsec.toml [health] stale_days), 경고 exit code 옵션 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat(health): Phase 2 — CI status overlay + configurable stale threshold
#301) (#331) Adds `parsec reviews` (alias `rv`) — a new command that scans every active worktree, resolves its open GitHub PR by branch name, and prints a unified review table with per-PR review decisions and CI status. ## What - New `src/cli/commands/reviews.rs` with `reviews()` async function - `ReviewEntry` struct added to `src/output/mod.rs` - Human table renderer in `src/output/human.rs` (color-coded review/CI badges) - JSON array renderer in `src/output/json.rs` - `Reviews` CLI variant wired in `src/cli/mod.rs` (alias `rv`) - 3 unit tests for ReviewEntry construction ## Phase 2 hint Add `--requested` flag: use GitHub Search API (`/search/issues?q=review-requested:{login}`) to show PRs from *others* where the current user is a requested reviewer. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…nt (#290) * feat(sync): stale-threshold filter, dry-run behind-count, conflict hint (#290) - Add --min-behind N flag (default: 1) to skip worktrees fewer than N commits behind origin/<base_branch>; skipped entries shown in output - dry-run now fetches behind-count and reports per-worktree before exit - Conflict detection: append "(conflict detected — resolve manually)" hint to failed sync reason when git output contains "conflict" - Extend print_sync signature with skipped: &[(String, u32)] across human/json/mod output layers; stack_sync passes &[] (no change) - Add 3 CLI integration tests: up-to-date skip, dry-run output, rebase Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * style: cargo fmt Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
#333) Refs #245 ## What - Add `--worktree <pattern>` flag (-w) to `parsec smartlog` / `sl`: case- insensitive substring match on ticket or branch name so users can focus on a subset of worktrees without noise from unrelated ones. - ANSI color in the PR/CI badge: green for success/approved/merged, red for failure/changes-requested, yellow for pending, blue for open PR, dim for draft/closed. Automatically disabled when `NO_COLOR` is set or stdout is not a TTY; force-enable via `PARSEC_COLOR=always`. - Stack indicator: when a worktree's base branch matches another active worktree's branch name, the base-group header now reads `○ <branch> (stacked on <ticket>)` instead of `(base)`, making stacked-PR flows immediately visible without extra commands. ## Tests added (5 new) - `worktree_filter_matches_ticket_substring` - `worktree_filter_branch_fallback` - `stack_indicator_appears_when_base_is_sibling_branch` - `color_badge_contains_ansi_codes_when_enabled` - `color_badge_failure_ci_is_red` All 138 tests pass (cargo build / clippy / fmt / test ✓). Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…301) (#334) Add `--requested` flag to `parsec reviews` (alias `rv -r`) that shows open PRs *from others* in this repo where the authenticated user is a requested reviewer. ## What changed - `src/github/mod.rs`: add `get_authenticated_user()` (GET /user) and `search_review_requested_prs(login)` (GET /search/issues with review-requested query). Reqwest .query() handles URL encoding — no new dependencies. - `src/cli/commands/reviews.rs`: split into `collect_authored_reviews` (Phase 1 logic) and `collect_requested_reviews` (Phase 2). Each returns Vec<ReviewEntry>; the caller merges and dispatches. - `src/cli/mod.rs`: add `requested: bool` field to `Reviews` variant, pass through to command handler. - 4 unit tests: existing 3 preserved + 1 new for reviewer-mode ticket placeholder. ## Phase 3 hint - Add `--all` flag to include closed/merged PRs. - Add author filter (`--author`) to narrow results. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…oses #246) (#335) `parsec conflicts --simulate`로 실제 in-memory three-way 머지를 수행해 라인-레벨 충돌을 사전 탐지. 기존 filename overlap 휴리스틱 (`parsec conflicts`)을 보완. ## 추가 모듈 - `src/conflict/simulator.rs` (240줄) - `MergeSimulation { vs_base, cross, skipped }` 결과 구조 - `simulate(repo, &workspaces)` 진입점 - Pass 1: 각 워크트리 HEAD vs origin/<base> (`merge-base` → fallback to local base) - Pass 2: 워크트리 페어 cross-simulate - 도구: `git merge-tree --write-tree --name-only --merge-base=<mb>` (git 2.38+) - read-only — 워킹디렉터리/index 무수정, merge tree 객체는 DB에 남되 참조 없음 ## CLI - `Command::Conflicts` variant에 `--simulate` bool 플래그 추가 - 디스패치 시 simulate true이면 `conflict::simulate(...)`, false면 기존 `conflict::detect(...)` ## Output - Human: 'Worktree → base conflicts' + 'Cross-worktree conflicts' 섹션, 파일 목록 ●로 표시 - JSON: `{ vs_base: [...], cross: [...], skipped: [...] }` 머신 readable ## 가드레일 - WorkspaceStatus::Active 만 처리 - merge-base 계산 실패시 skipped로 다운그레이드 (전체 리포트 중단 방지) - `merge-tree` 비-0 exit + 빈 출력은 transient로 간주 ## 검증 - cargo build clean - cargo clippy -D warnings clean - cargo fmt clean - cargo test: 66 lib + 5 simulator + 71 cli = 142 통과 (이전 138 + 신규 4 simulate) ## 신규 테스트 (tests/cli_tests.rs) - test_conflicts_simulate_empty_repo - test_conflicts_simulate_json_empty_is_object - test_conflicts_simulate_single_clean_worktree - test_conflicts_simulate_detects_cross_worktree_line_conflict (실제 충돌 시드) v0.5 마일스톤. Co-authored-by: Pochacco <noreply@anthropic.com>
…Closes #247) (#336) * feat(test): parsec test — parallel test runner with tree-hash caching Implements `parsec test` (issue #247): runs a configurable shell command inside one or every parsec-managed worktree, with optional parallelism (`--jobs N`) and tree-hash result caching (`--cache`). - New `[test]` section in ParsecConfig (command / jobs / cache defaults). - New `Command::Test` variant with --all / --jobs / --cache / --command flags plus auto-detect of the current worktree from CWD. - Cache files live under `<repo>/.parsec/test-cache/<tree-hash>.json`; only successful runs are persisted. - Output dispatched through `print_test_results` (human table + JSON array with from_cache / exit_code / duration_ms / stdout_tail). - Tail of stdout/stderr (40 lines) surfaced on failure for fast triage. - Six new CLI integration tests covering help, single-worktree, --all, cache hit replay, non-zero propagation, and parallel completion. Closes #247 * fix(test): cross-platform shell + Windows test gating Windows CI fail 원인: bash가 WSL로 해석되는데 distro 미설치 → exec 실패. - 러너: `bash -c` → 플랫폼별로 `sh -c` (Unix) / `cmd /C` (Windows) - 테스트 명령: `true` → `exit 0` (cmd.exe + sh 양쪽 동작) - `test_test_jobs_parallel_completes`는 sleep 의존 → `#[cfg(unix)]` 게이트 cargo test 73 cli + 5 bitbucket + 69 unit = 147 통과. Co-Authored-By: Pochacco <noreply@anthropic.com> --------- Co-authored-by: Pochacco <noreply@anthropic.com>
…#337) Introduce `parsec dashboard` (alias `dash`), a `ratatui` + `crossterm` based terminal UI that aggregates worktree, CI, and GitHub PR status into a single live view. Layout (three panes + status bar): - Worktrees pane (top-left): list of every active worktree with a color-coded CI dot, ticket ID, title/branch, and status. - CI pane (top-right): per-worktree `PR #N · ✓/✗/●` summary. - PRs pane (bottom): table — PR · title · state · review · CI. - Status bar: key hints + last-update timestamp + last-error badge. Concurrency: a single background `tokio::task` refreshes the shared `Arc<Mutex<DashboardSnapshot>>` every `--refresh` seconds (default 10). The UI loop never blocks on network — it redraws the latest snapshot on each tick or key event via `tokio::select!`. Keys: `q` / Esc quit · `r` force refresh · `?` / F1 help overlay · `↑/↓` (or `j/k`) move selection · Ctrl-C quit. Robustness: - Terminal state (alternate screen + raw mode) is restored by a `Drop` guard that runs on every exit path, including panic. - `--no-overlay` (or missing GitHub token) renders `–` placeholders instead of erroring. - `--json` / `--quiet` are rejected early with an actionable message pointing to `parsec list --json` / `parsec reviews --json`. Tests: four new integration tests for help text (both `dashboard` and `dash`), `--json` rejection, and `--quiet` rejection, plus five new unit tests for the rendering helpers. Deps: ratatui 0.28, crossterm 0.28. Closes #248 Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* chore(release): v0.5.0 — visualization release - Cargo.toml: 0.4.0 → 0.5.0 (release.yml이 main push 시 자동 tag/publish 트리거) - CHANGELOG: Unreleased → [0.5.0] 정리 (v0.5 마일스톤 16개 항목 반영) - README: Roadmap v0.5.0 ✅ Released 마킹, v1.0 'Next'. 신규 'Visualization & power-user tools' 섹션 (8개 신규 명령). command count 33+ - docs/llms.txt: 버전 0.5.0, v0.5 명령 quick reference cargo build/clippy/fmt clean · test 142/142. Co-Authored-By: Pochacco <noreply@anthropic.com> * ci: RUST_MIN_STACK=8MB to fix Windows stack overflow after TUI deps landed #248 (TUI dashboard) added ratatui + crossterm. Windows 기본 main-thread stack 1MB가 tokio + reqwest + ratatui + crossterm 결합 후 overflow → bitbucket integration test 5개 panic. 워크플로우 env에 RUST_MIN_STACK=8388608 (8MB) 추가. 모든 test/build job에 적용. macOS/Linux는 변경 영향 없음. Co-Authored-By: Pochacco <noreply@anthropic.com> * build: Windows linker /STACK:16MB — fix bitbucket integration test overflow RUST_MIN_STACK은 Rust 스레드만 영향. Windows main-thread stack(기본 1MB)은 linker 옵션이 결정. v0.5 TUI dashboard 진입 후 ratatui + crossterm + tokio + reqwest 결합으로 1MB 초과 → parsec.exe subprocess가 overflow → bitbucket integration 테스트 5개 panic. .cargo/config.toml에 Windows 타겟 한정 `/STACK:16777216` 추가. macOS/Linux 기본은 이미 8MB라 변경 영향 없음. Co-Authored-By: Pochacco <noreply@anthropic.com> --------- Co-authored-by: Pochacco <noreply@anthropic.com>
…ease job) (#342) * release: v0.5.0 — The visualization release (#340) * chore(v0.5): roadmap section + ship gh auth token fallback (#281) (#289) * fix(ship): fall back to gh auth token (parity with parsec doctor) (#281) parsec ship 이 PARSEC_GITHUB_TOKEN / GITHUB_TOKEN / GH_TOKEN env var 모두 비어있을 때 PR 생성을 거부했지만 parsec doctor 와 tracker 레이어는 이미 `gh auth token` fallback 적용. parity 깨져 사용자가 수동 `gh pr create` 로 추가 작업 필요. 해결: - src/env.rs: github_token() 의 4번째 우선순위로 gh_auth_token() 추가. 신규 gh_auth_token() helper 는 `gh auth token` shell out — 실패 시 None (binary 없음 / exit code != 0 / non-UTF8 / 빈 출력 모두 graceful). - src/github/mod.rs: resolve_github_token 의 env-var/gh fallback 을 GitHub host (github.com / *.ghe.com / *.github.* GHE) 에만 적용. 신규 is_github_host() helper. Bitbucket / GitLab remote 가 `gh auth login` 한 환경에서 GitHub 토큰을 잘못 픽업하지 않도록 가드. - src/cli/commands/doctor.rs: 중복 `gh auth token` shell-out 코드 제거 → env::gh_auth_token() 공통 helper 호출. parity at the helper level. 신규 테스트 (src/env.rs): github_token_priority_order — PARSEC > GITHUB > GH 우선순위 + 빈값 fallback 4 시나리오 sequential 검사. EnvGuard 로 process-wide env 보존+복원. gh_auth_token_returns_option_string_or_none — gh binary 가용성에 무관하게 trim 보장. github_token_returns_none_when_all_missing_and_gh_fails — env 모두 미설정 시 None 또는 valid Some 모두 허용 (CI 와 dev 환경 양립). 검증: - cargo test: 79 tests PASS (env tests 6 + integration 73) - cargo clippy --all-targets -- -D warnings: clean - cargo fmt --check: clean - bitbucket integration tests: 5/5 PASS (이전 발견된 host-gated 이슈 해결) 회귀 위험: 매우 낮음 - 환경에 gh CLI 미로그인 / 미설치 → 기존과 동일 (None 반환) - 환경에 gh 로그인됨 + GitHub remote → 신규 fallback 활용 (issue #281 의도) - 환경에 gh 로그인됨 + Bitbucket/GitLab remote → is_github_host 로 차단, 기존과 동일 Closes #281 * docs(v0.5): open roadmap milestone — visualization release vision v0.5 마일스톤 공식 출발 마커. README 와 CHANGELOG 양쪽에 향후 비전 명시. README.md (## Roadmap 섹션 신설, ## Why use it 과 ## Install 사이): - vision tagline: "parsec = AI agents + human devs both — worktree-native git CLI" - 4단계 milestone: · v0.4.0 ✅ Released (2026-05-04): Multi-forge + multi-tracker foundation · v0.5 🚧 Next — _The visualization release_: smartlog · TUI dashboard · speculative merge · parsec test · AI PR descriptions · v1.0 🔜 — _AI-Native Standard_: MCP server signature, Claude/Cursor/Copilot 가 parsec 을 first-class tool 로 invoke · v2.0+ 🔮 — _Ecosystem Hub_: plugins · VS Code extension · Linear tracker - v0.5 milestone link (github.com/erishforG/git-parsec/milestone/3) CHANGELOG.md (## [Unreleased] 확장): - ### Added: v0.5 milestone opened, README Roadmap 참조 - ### Fixed: #281 ship gh auth token fallback 노트 (별 commit ae1a2d3 와 동일 entry) 회귀 위험: 0 (문서 변경만) * fix(env): serialize env-touching tests via process-wide mutex (Windows CI) PR #289 Windows CI 1건 fail. macOS / Ubuntu Test 통과, Windows Test 만 실패. 원인: - env::tests 의 github_token_priority_order 와 github_token_returns_none_when_all_ missing_and_gh_fails 가 cargo test 병렬 실행 시 process-wide env vars 를 race. - priority_order 가 PARSEC=p / GITHUB=g / GH=h 셋업 후 assert 사이에 sibling 테스트의 EnvGuard::new() 가 모든 env 를 clear → assert 가 PARSEC 못 보고 GH=h 반환. - macOS/Ubuntu 는 timing 우연히 안전, Windows 는 다른 thread scheduling 으로 race 발현 (Some("h") vs Some("p") at src/env.rs:205). 수정: - std::sync::OnceLock<Mutex<()>> 의 env_lock() 신규 — env 만지는 테스트들 직렬화. std 만 사용 (외부 deps 추가 X 제약 준수). - github_token_priority_order 와 github_token_returns_none_when_all_missing_and_gh_fails 를 단일 함수 github_token_priority_order_and_fallback 로 통합 + env_lock() 의 Mutex guard 획득. 5 시나리오 (PARSEC 우선 / GITHUB / GH / 빈값 / 모두 미설정) 직렬 실행. - gh_auth_token_returns_option_string_or_none 은 env 미터치라 lock 불필요 — 그대로 유지. - production 로직 (env::github_token / env::gh_auth_token) 변경 0. 검증: - 로컬 cargo test 78 PASS (env tests 5 + integration 73), clippy clean, fmt clean. - Windows CI 검증은 force-push 후 PR #289 워크플로우에서 확인. * [245] feat(smartlog): skeleton — DAG data model + ASCII tree + JSON output (#305) Phase 1 of #245. Establishes the command surface and rendering path without any forge-side enrichment. Adds `parsec smartlog` (alias `sl`): - `SmartlogNode` per active worktree: ticket, branch, base, commits, plus `pr` / `ci` placeholder fields gated on `skip_serializing_if` so the JSON output stays clean until follow-up PRs populate them. - `collect_commits` shells out to `git log <base>..<branch>` (no `git2` dependency — matches the rest of `git/`). Soft-fails per worktree so a corrupt worktree can't take the whole command down. - `render_text` groups nodes by base branch and draws ASCII tree glyphs (○ │ ├─● └─). Returns the rendered string for testability. - `--json` emits the same structure for tooling. - `--depth N` caps commits per worktree (default 10). Out of scope for this PR (follow-ups on the same epic): - PR overlay (open/draft/merged) - CI overlay (passed/failed/running) - Review state (approved / changes requested) - Stack relationship visualization - Color / smarter wrapping Tests (9 new in `cli::commands::smartlog::tests`): - `parse_commit_line` happy path + tab-in-subject + garbage + empty SHA - `render_text` empty / single / no-commits / multi-base grouping - JSON serialization omits placeholder overlay fields Smoke run on parsec's own worktrees produces: ○ develop (base) ├─● 207 #207 [feature/207] │ └─ (no commits since develop) └─● 279 #279 [feature/279] └─ (no commits since develop) * [303] refactor(errors): adopt 3-line standard (error / caused by / help) (#306) * [303] refactor(errors): adopt 3-line standard (error / caused by / help) Issue #303. Add the infrastructure for the standard error format and wire main.rs to render it. Existing call sites keep rendering as a single line — migration is gradual (see docs/error-format.md). Changes: - `ParsecError` gains `caused_by: Option<String>` and `help: Option<String>` fields plus builder-style setters (`with_caused_by`, `with_help`). `Display` now writes one to three lines depending on which fields are populated. - `JsonError` gains the same two fields with `skip_serializing_if = "Option::is_none"` so existing `--json` consumers see no schema change. - `extract_full(&anyhow::Error) -> Option<&ParsecError>` helper for new callers; the legacy `extract_code` is kept untouched. - `main.rs` prefers the typed error: when the error is a `ParsecError`, print it directly (its `Display` already includes the `error:` prefix + code); otherwise fall back to the legacy single-line `error: {err:#}`. - `bail_code!` macro unchanged (for the "summary only" case). - `docs/error-format.md` documents the format, builder API, JSON shape, recipes, and what NOT to do. Tests: +9 in `errors::tests` covering 1/2/3-line display, help-only, extract_full happy/None, backward-compat extract_code, JSON skip-if-none, JSON with-fields, bail_code macro round-trip. Full suite 53 + 5 + 40 = 98 pass, fmt clean. Migration: any existing `ParsecError::new(...)` site can opt in by chaining `.with_caused_by(...)` and/or `.with_help(...)`. Prioritize cli/commands/ and worktree/ first (highest user contact). * [303] chore(errors): allow dead_code on Phase 1 builder + legacy extract_code Clippy `-D warnings` flagged `with_caused_by`, `with_help`, and `extract_code` as never-used. Phase 1 of #303 is the infra-only PR — call sites land in follow-up PRs. Annotation matches the existing `#[allow(dead_code)]` on `ErrorCode` for the same forward-looking reason. * ci(windows): add VS2026 pre-validation job (#307) (#311) Adds an informational windows-2025-vs2026 job that runs cargo build/test on the new Visual Studio 2026 default image ahead of the GitHub Actions runner migration window (2026-06-08 ~ 06-15). continue-on-error: true keeps it advisory only — main matrix stays gated on existing windows-latest. After the migration window closes we either delete this job (if main matrix passes) or pin windows-2022 here (if it fails). Refs: #307 * feat(completion): hidden __complete subcommand foundation (#291) (#312) Adds `parsec __complete <worktrees|branches>` — a hidden subcommand that shell completion scripts can call to enumerate candidates dynamically. Failure paths (no repo / no config) silently emit nothing so completion never errors at the prompt. Also adds `git::list_local_branches`, a helper for enumerating local branch names via `git for-each-ref refs/heads/`. This is the **foundation only**. The follow-up work — post-processing clap-generated completion scripts (zsh/bash/fish) so that ticket-shaped arguments call `parsec __complete worktrees` and branch-shaped arguments call `parsec __complete branches` — lands in a separate PR. Refs: #291 * test(cli): compress / config schema / log --export 통합 테스트 추가 (#315) * test(cli): add integration tests for compress, config schema, log --export Cover three commands added in v0.4.0 that had zero test coverage: - test_compress_nothing_to_do: single-commit worktree exits cleanly - test_compress_squashes_commits: 2-commit branch is reduced to 1 - test_config_schema_outputs_json: output is valid JSON Schema - test_history_log_export_empty: empty log exits 0 with no stdout Closes #314 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ci: re-trigger Branch Policy (base now develop) --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * docs(changelog): [Unreleased]에 smartlog·complete·errors·win-ci 항목 추가 (#317) develop에 머지됐지만 CHANGELOG.md [Unreleased]에 누락된 항목 4개를 추가한다: - parsec smartlog (alias sl): commit DAG 시각화 (#245, #305) - parsec __complete: 동적 shell completion 헬퍼 (#291, #312) - 에러 메시지 3줄 표준화 (error/caused by/help) (#303, #306) - Windows VS2026 pre-validation CI job (#307, #311) Closes #316 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * test(cli): parsec smartlog / sl 통합 테스트 추가 (#318) (#319) parsec smartlog (#305)과 sl 별칭이 develop에 머지됐지만 CLI 통합 테스트가 전혀 없었음. 5개 시나리오 추가: - test_smartlog_empty_repo: 빈 repo → 'No active worktrees' 확인 - test_sl_alias_works_like_smartlog: sl == smartlog 동일 출력 확인 - test_smartlog_json_empty_is_array: --json 빈 repo → [] JSON 배열 - test_smartlog_shows_worktree: worktree 1개 → 티켓·(base) 마커 표시 - test_smartlog_json_one_worktree: --json 1 worktree → 필드 검증 (ticket, branch, base_branch, commits, pr/ci 미노출) Closes #318 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(commands): diff·history 모듈 RustDoc 추가 (#321) diff.rs, history.rs에 module-level(//!) 및 function-level(///) RustDoc을 추가. 인접한 smartlog.rs·complete.rs와 일관성 맞춤. - diff.rs: //! 모듈 헤더(diff/conflicts/sync 역할·관련 이슈), pub async fn diff/conflicts/sync에 파라미터·출력모드·동작 설명 추가 - history.rs: //! 모듈 헤더(OpLog·ExecLog 구조 설명), pub async fn log/log_export/undo에 동작·edge-case 설명 추가 프로덕션 코드 변경 없음 (주석 전용). Closes #320 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(commands): stack·ci 모듈 RustDoc 추가 (#323) stack.rs: //! 모듈 헤더 + stack/stack_sync/stack_submit 함수 doc ci.rs: //! 모듈 헤더 + ci/fetch_bitbucket_ci 함수 doc 프로덕션 코드 변경 없음 — 주석 73줄 추가만. Closes #322 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(health): parsec health Phase 1 — lock/uncommitted/stale check skeleton (#324) (#325) Add `parsec health` command that scans all active worktrees for three lightweight health indicators: - has_lock — .git/index.lock exists (interrupted git process) - uncommitted — count of staged + unstaged files - stale — last commit older than 7 days Output (human mode): colored table with ✓/⚠/✗ per worktree and a summary line. JSON mode emits a structured array with `all_healthy` flag. Files changed: - src/cli/commands/health.rs (new, ~99 lines) - src/cli/commands/mod.rs (+2 lines, re-export) - src/cli/mod.rs (+11 lines, Health variant + dispatch) - src/output/mod.rs (+15 lines, HealthRecord + dispatch_output!) - src/output/human.rs (+66 lines, colored table renderer) - src/output/json.rs (+34 lines, JSON renderer) CI-status overlay deferred to Phase 2 (depends on #309/#310). All checks are read-only; no worktree state is modified. Closes #324 Refs #299 Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * test(health): parsec health CLI 통합 테스트 5개 추가 (#324) (#326) Phase 1 구현(#325)을 커버하는 통합 테스트: - test_health_empty_repo: 빈 repo → 'No active worktrees.' 확인 - test_health_empty_repo_json: 빈 repo → --json 시 '[]' 출력 확인 - test_health_shows_worktree: 워크트리 1개 → 티켓명 포함 출력 확인 - test_health_json_one_worktree: --json 구조 검증 (worktrees 배열, all_healthy 불리언, ticket/has_lock/uncommitted/stale_days/stale 필드) - test_health_exit_zero_with_issues: lock 파일 존재해도 exit 0 (정보성 only) Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(smartlog): Phase 2 — PR/CI status overlay (#327) * test(health): parsec health CLI 통합 테스트 5개 추가 (#324) Phase 1 구현(#325)을 커버하는 통합 테스트: - test_health_empty_repo: 빈 repo → 'No active worktrees.' 확인 - test_health_empty_repo_json: 빈 repo → --json 시 '[]' 출력 확인 - test_health_shows_worktree: 워크트리 1개 → 티켓명 포함 출력 확인 - test_health_json_one_worktree: --json 구조 검증 (worktrees 배열, all_healthy 불리언, ticket/has_lock/uncommitted/stale_days/stale 필드) - test_health_exit_zero_with_issues: lock 파일 존재해도 exit 0 (정보성 only) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(smartlog): Phase 2 — PR/CI status overlay (Refs #245) Phase 1 (#305) skeleton에서 `SmartlogNode.pr` 가 placeholder로 남아있던 걸 실제 GitHub PR/CI 데이터로 채움. Issue #245 의 예시 (`[PR #42 ✓ CI passed, ✓ approved]`) 가 이제 ASCII 트리에 그대로 렌더링됨. ## 변경 - `SmartlogPrOverlay` struct 신설 (number/state/ci_status/review_status/url) - `smartlog()` 가 GitHubClient 통해 brach → PR 매칭 + PrStatus 조회 후 node.pr 채움. 토큰 없거나 비-GitHub remote거나 HTTP 실패 = 그냥 overlay 생략 (best-effort, 명령 실패 안 함) - `--no-overlay` 플래그 추가 (강제 offline 모드) - ASCII 렌더러: ticket 라인 아래 `├─ [PR #N ● open ✓ CI ✓ approved]` 한 줄 - 글리프 규칙: 기존 `parsec pr status` / `parsec ci` 와 동일 (✓/✗/●/○) ## CI 필드는? `SmartlogNode.ci` 는 일단 None 유지. Phase 2 는 CI 요약을 overlay 안에 포함시켜 한 줄로 표시 (스마트로그 본질은 한눈 — per-check 디테일은 `parsec ci` 가 이미 담당). ## 드라이브-바이 tests/cli_tests.rs:1725 에 `assert_eq!(bool, false)` clippy 경고 (#326 회귀) → `assert!(!...)` 로 수정. develop 의 clippy strict 빌드 회복. ## 테스트 - 신규 unit 5개 (format_pr_badge × 3 + render_text overlay + JSON 직렬화) - 기존 9개 smartlog unit + 5개 통합 테스트 모두 통과 - cargo build / clippy -D warnings / fmt --check / test 전체 clean ## 다음 Phase 힌트 - Phase 3: per-worktree filtering (`--ticket CL-2283` 등) - Phase 4: stack 관계 시각화 (PR base = 다른 PR head) - Phase 5: review state 색상 강조 (terminal color) Refs #245 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(completion): Phase 2 — dynamic zsh/bash/fish shell scripts (Refs #291) (#328) Phase 1 (#312) 가 `parsec __complete <kind>` 내부 명령을 만들어 shell completion 스크립트가 동적으로 worktree/branch 후보를 가져올 수 있게 했음. 이번에는 그 위에 실제 zsh/bash/fish 스크립트 3개를 추가해서 사용자가 sourcing 만 하면 `parsec switch <Tab>` 처럼 live ticket 자동완성을 받을 수 있게 함. ## 변경 - `completions/_parsec` (zsh, #compdef) — `_parsec_worktrees` / `_parsec_branches` helper + 모든 주요 subcommand 의 positional/option 자동완성 - `completions/parsec.bash` — `complete -F _parsec parsec`. bash-completion 의존 (`_init_completion`). prev word 기반 dispatch + `compgen -W` - `completions/parsec.fish` — `__fish_seen_subcommand_from` 기반. per-subcommand 옵션 (`--base`, `--on`, `--branch`) 도 동적 branch/worktree 후보 연결 - README "Install > Shell completion" 섹션 추가 (3개 shell install 명령) ## 커버 범위 (Tier 1 + 2) - ticket 받는 subcommand: start, switch, ship, open, clean, status, ticket, pr-status, ci, merge, diff, sync, log, compress, adopt, rename - branch 받는 옵션: `start --base|--on|--branch`, `ship --base`, `adopt --branch` - smartlog: `--depth`, `--no-overlay` (PR #327 와 호환) ## __complete kind 추가 없음. Phase 1 의 `worktrees` / `branches` 두 개로 충분 — future Phase 3 에서 필요하면 추가 (예: `tickets` 트래커, `reviewers` GitHub 사용자). ## 드라이브-바이 PR #327 에서 같이 잡았던 `tests/cli_tests.rs:1725` clippy 회귀 (#326) develop 머지 전이라 또 한 번 적용. PR #327 머지되면 충돌 안 남. ## 테스트 - 신규 4개 통합 테스트: - `completion_zsh_present_and_dynamic` — `#compdef parsec` + `__complete` 호출 + 핵심 sub 7개 - `completion_bash_present_and_dynamic` — `complete -F _parsec parsec` + 동일 - `completion_fish_present_and_dynamic` — `__parsec_worktrees` 함수 + 동일 - `completion_scripts_reference_phase1_subcommand_signature` — 스크립트가 Phase 1 가 지원하지 않는 kind 부르지 않는지 (silent fail 방지) - 전체 62 통합 테스트 + smartlog 14 단위 + health 5 통과 - cargo build / clippy -D warnings / fmt --check 전부 clean ## 다음 Phase 힌트 - Phase 3: `__complete tickets` (트래커 미해결 티켓), `__complete reviewers` (GitHub mention) - Phase 4: shell auto-install hook (parsec init 에서 자동 설치 옵션) Refs #291 Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * feat(health): Phase 2 — CI status overlay + configurable stale threshold (Refs #299) ## 무엇 parsec health Phase 2: GitHub CI 상태 오버레이 + 설정 가능한 stale 임계값. ## 변경 - health.rs: --stale-days <N> 플래그로 stale 임계값 설정 (기본 7일) - health.rs: --no-overlay 플래그로 오프라인 모드 지원 - health.rs: fetch_ci_overlay() — 브랜치 → PR 번호 → CI 상태 (best-effort) - output/mod.rs: HealthRecord에 ci_status: Option<String>, pr_number: Option<u64> 추가 - output/human.rs: CI 상태를 색상 아이콘으로 표시 (✓/✗/● CI) - output/json.rs: ci_status, pr_number, ci_failing 필드를 JSON 출력에 포함 - cli/mod.rs: Health 명령을 struct variant로 변경 (--stale-days, --no-overlay) - tests/cli_tests.rs: Phase 2 플래그 검증 테스트 3개 추가 (8/8 통과) ## 다음 Phase 힌트 Phase 3: threshold config (parsec.toml [health] stale_days), 경고 exit code 옵션 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(reviews): Phase 1 — unified PR review table across worktrees (Refs #301) (#331) Adds `parsec reviews` (alias `rv`) — a new command that scans every active worktree, resolves its open GitHub PR by branch name, and prints a unified review table with per-PR review decisions and CI status. ## What - New `src/cli/commands/reviews.rs` with `reviews()` async function - `ReviewEntry` struct added to `src/output/mod.rs` - Human table renderer in `src/output/human.rs` (color-coded review/CI badges) - JSON array renderer in `src/output/json.rs` - `Reviews` CLI variant wired in `src/cli/mod.rs` (alias `rv`) - 3 unit tests for ReviewEntry construction ## Phase 2 hint Add `--requested` flag: use GitHub Search API (`/search/issues?q=review-requested:{login}`) to show PRs from *others* where the current user is a requested reviewer. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(sync): stale-threshold filter, dry-run behind-count, conflict hint (#290) * feat(sync): stale-threshold filter, dry-run behind-count, conflict hint (#290) - Add --min-behind N flag (default: 1) to skip worktrees fewer than N commits behind origin/<base_branch>; skipped entries shown in output - dry-run now fetches behind-count and reports per-worktree before exit - Conflict detection: append "(conflict detected — resolve manually)" hint to failed sync reason when git output contains "conflict" - Extend print_sync signature with skipped: &[(String, u32)] across human/json/mod output layers; stack_sync passes &[] (no change) - Add 3 CLI integration tests: up-to-date skip, dry-run output, rebase Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * style: cargo fmt Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * feat(smartlog): Phase 3 — worktree filter, ANSI color, stack indicator (#333) Refs #245 ## What - Add `--worktree <pattern>` flag (-w) to `parsec smartlog` / `sl`: case- insensitive substring match on ticket or branch name so users can focus on a subset of worktrees without noise from unrelated ones. - ANSI color in the PR/CI badge: green for success/approved/merged, red for failure/changes-requested, yellow for pending, blue for open PR, dim for draft/closed. Automatically disabled when `NO_COLOR` is set or stdout is not a TTY; force-enable via `PARSEC_COLOR=always`. - Stack indicator: when a worktree's base branch matches another active worktree's branch name, the base-group header now reads `○ <branch> (stacked on <ticket>)` instead of `(base)`, making stacked-PR flows immediately visible without extra commands. ## Tests added (5 new) - `worktree_filter_matches_ticket_substring` - `worktree_filter_branch_fallback` - `stack_indicator_appears_when_base_is_sibling_branch` - `color_badge_contains_ansi_codes_when_enabled` - `color_badge_failure_ci_is_red` All 138 tests pass (cargo build / clippy / fmt / test ✓). Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(reviews): Phase 2 — --requested flag via GitHub Search API (Refs #301) (#334) Add `--requested` flag to `parsec reviews` (alias `rv -r`) that shows open PRs *from others* in this repo where the authenticated user is a requested reviewer. ## What changed - `src/github/mod.rs`: add `get_authenticated_user()` (GET /user) and `search_review_requested_prs(login)` (GET /search/issues with review-requested query). Reqwest .query() handles URL encoding — no new dependencies. - `src/cli/commands/reviews.rs`: split into `collect_authored_reviews` (Phase 1 logic) and `collect_requested_reviews` (Phase 2). Each returns Vec<ReviewEntry>; the caller merges and dispatches. - `src/cli/mod.rs`: add `requested: bool` field to `Reviews` variant, pass through to command handler. - 4 unit tests: existing 3 preserved + 1 new for reviewer-mode ticket placeholder. ## Phase 3 hint - Add `--all` flag to include closed/merged PRs. - Add author filter (`--author`) to narrow results. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(conflicts): --simulate flag for line-level speculative merge (Closes #246) (#335) `parsec conflicts --simulate`로 실제 in-memory three-way 머지를 수행해 라인-레벨 충돌을 사전 탐지. 기존 filename overlap 휴리스틱 (`parsec conflicts`)을 보완. ## 추가 모듈 - `src/conflict/simulator.rs` (240줄) - `MergeSimulation { vs_base, cross, skipped }` 결과 구조 - `simulate(repo, &workspaces)` 진입점 - Pass 1: 각 워크트리 HEAD vs origin/<base> (`merge-base` → fallback to local base) - Pass 2: 워크트리 페어 cross-simulate - 도구: `git merge-tree --write-tree --name-only --merge-base=<mb>` (git 2.38+) - read-only — 워킹디렉터리/index 무수정, merge tree 객체는 DB에 남되 참조 없음 ## CLI - `Command::Conflicts` variant에 `--simulate` bool 플래그 추가 - 디스패치 시 simulate true이면 `conflict::simulate(...)`, false면 기존 `conflict::detect(...)` ## Output - Human: 'Worktree → base conflicts' + 'Cross-worktree conflicts' 섹션, 파일 목록 ●로 표시 - JSON: `{ vs_base: [...], cross: [...], skipped: [...] }` 머신 readable ## 가드레일 - WorkspaceStatus::Active 만 처리 - merge-base 계산 실패시 skipped로 다운그레이드 (전체 리포트 중단 방지) - `merge-tree` 비-0 exit + 빈 출력은 transient로 간주 ## 검증 - cargo build clean - cargo clippy -D warnings clean - cargo fmt clean - cargo test: 66 lib + 5 simulator + 71 cli = 142 통과 (이전 138 + 신규 4 simulate) ## 신규 테스트 (tests/cli_tests.rs) - test_conflicts_simulate_empty_repo - test_conflicts_simulate_json_empty_is_object - test_conflicts_simulate_single_clean_worktree - test_conflicts_simulate_detects_cross_worktree_line_conflict (실제 충돌 시드) v0.5 마일스톤. Co-authored-by: Pochacco <noreply@anthropic.com> * feat(test): parsec test — parallel test runner with tree-hash caching (Closes #247) (#336) * feat(test): parsec test — parallel test runner with tree-hash caching Implements `parsec test` (issue #247): runs a configurable shell command inside one or every parsec-managed worktree, with optional parallelism (`--jobs N`) and tree-hash result caching (`--cache`). - New `[test]` section in ParsecConfig (command / jobs / cache defaults). - New `Command::Test` variant with --all / --jobs / --cache / --command flags plus auto-detect of the current worktree from CWD. - Cache files live under `<repo>/.parsec/test-cache/<tree-hash>.json`; only successful runs are persisted. - Output dispatched through `print_test_results` (human table + JSON array with from_cache / exit_code / duration_ms / stdout_tail). - Tail of stdout/stderr (40 lines) surfaced on failure for fast triage. - Six new CLI integration tests covering help, single-worktree, --all, cache hit replay, non-zero propagation, and parallel completion. Closes #247 * fix(test): cross-platform shell + Windows test gating Windows CI fail 원인: bash가 WSL로 해석되는데 distro 미설치 → exec 실패. - 러너: `bash -c` → 플랫폼별로 `sh -c` (Unix) / `cmd /C` (Windows) - 테스트 명령: `true` → `exit 0` (cmd.exe + sh 양쪽 동작) - `test_test_jobs_parallel_completes`는 sleep 의존 → `#[cfg(unix)]` 게이트 cargo test 73 cli + 5 bitbucket + 69 unit = 147 통과. Co-Authored-By: Pochacco <noreply@anthropic.com> --------- Co-authored-by: Pochacco <noreply@anthropic.com> * feat(dashboard): interactive TUI dashboard for worktrees, CI, and PRs (#337) Introduce `parsec dashboard` (alias `dash`), a `ratatui` + `crossterm` based terminal UI that aggregates worktree, CI, and GitHub PR status into a single live view. Layout (three panes + status bar): - Worktrees pane (top-left): list of every active worktree with a color-coded CI dot, ticket ID, title/branch, and status. - CI pane (top-right): per-worktree `PR #N · ✓/✗/●` summary. - PRs pane (bottom): table — PR · title · state · review · CI. - Status bar: key hints + last-update timestamp + last-error badge. Concurrency: a single background `tokio::task` refreshes the shared `Arc<Mutex<DashboardSnapshot>>` every `--refresh` seconds (default 10). The UI loop never blocks on network — it redraws the latest snapshot on each tick or key event via `tokio::select!`. Keys: `q` / Esc quit · `r` force refresh · `?` / F1 help overlay · `↑/↓` (or `j/k`) move selection · Ctrl-C quit. Robustness: - Terminal state (alternate screen + raw mode) is restored by a `Drop` guard that runs on every exit path, including panic. - `--no-overlay` (or missing GitHub token) renders `–` placeholders instead of erroring. - `--json` / `--quiet` are rejected early with an actionable message pointing to `parsec list --json` / `parsec reviews --json`. Tests: four new integration tests for help text (both `dashboard` and `dash`), `--json` rejection, and `--quiet` rejection, plus five new unit tests for the rendering helpers. Deps: ratatui 0.28, crossterm 0.28. Closes #248 Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * release-prep: bump version + CHANGELOG + README for v0.5.0 (#339) * chore(release): v0.5.0 — visualization release - Cargo.toml: 0.4.0 → 0.5.0 (release.yml이 main push 시 자동 tag/publish 트리거) - CHANGELOG: Unreleased → [0.5.0] 정리 (v0.5 마일스톤 16개 항목 반영) - README: Roadmap v0.5.0 ✅ Released 마킹, v1.0 'Next'. 신규 'Visualization & power-user tools' 섹션 (8개 신규 명령). command count 33+ - docs/llms.txt: 버전 0.5.0, v0.5 명령 quick reference cargo build/clippy/fmt clean · test 142/142. Co-Authored-By: Pochacco <noreply@anthropic.com> * ci: RUST_MIN_STACK=8MB to fix Windows stack overflow after TUI deps landed #248 (TUI dashboard) added ratatui + crossterm. Windows 기본 main-thread stack 1MB가 tokio + reqwest + ratatui + crossterm 결합 후 overflow → bitbucket integration test 5개 panic. 워크플로우 env에 RUST_MIN_STACK=8388608 (8MB) 추가. 모든 test/build job에 적용. macOS/Linux는 변경 영향 없음. Co-Authored-By: Pochacco <noreply@anthropic.com> * build: Windows linker /STACK:16MB — fix bitbucket integration test overflow RUST_MIN_STACK은 Rust 스레드만 영향. Windows main-thread stack(기본 1MB)은 linker 옵션이 결정. v0.5 TUI dashboard 진입 후 ratatui + crossterm + tokio + reqwest 결합으로 1MB 초과 → parsec.exe subprocess가 overflow → bitbucket integration 테스트 5개 panic. .cargo/config.toml에 Windows 타겟 한정 `/STACK:16777216` 추가. macOS/Linux 기본은 이미 8MB라 변경 영향 없음. Co-Authored-By: Pochacco <noreply@anthropic.com> --------- Co-authored-by: Pochacco <noreply@anthropic.com> * chore: back-merge main into develop (sync for release PR #340) (#341) --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * docs: snapshot versioned docs for v0.5.0 Manual replay of release.yml `Snapshot Versioned Docs` job that failed on v0.5.0 release run (couldn't direct-push to protected main branch). - docs/v/0.5.0/{index.html, guide/index.html, reference/index.html} 신규 — latest docs를 sed transform (data-doc-version, noindex, /v/0.5.0/ prefix) - docs/versions.json: latest 0.4.0 → 0.5.0, versions list 맨 앞 추가 - docs/sitemap.xml: v0.5.0 3개 URL entry 추가 이후 부터는 release.yml 패치로 자동화될 예정 (별도 PR). Co-Authored-By: Pochacco <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…sh (#343) v0.5.0 release run의 `Snapshot Versioned Docs` job이 main 브랜치 protection (`Changes must be made through a pull request`) 때문에 직접 push 실패. ## 변경 - `.github/workflows/release.yml`: `git push origin main` → `peter-evans/create-pull-request`로 `docs/snapshot-v<ver>` 브랜치 자동 생성 + PR 오픈. `pull-requests: write` 권한 추가. - `.github/workflows/ci.yml`: Branch Policy가 `docs/snapshot-v*` 브랜치도 main에 머지 허용 (data-only 변경이므로 develop 우회 안전). ## 효과 다음 릴리스부터 자동으로 `docs/snapshot-vX.Y.Z` 브랜치 + auto-snapshot 라벨이 붙은 PR이 생성됨. Eric이 머지하면 versioned docs가 main에 반영. push 실패 0. Co-authored-by: Pochacco <noreply@anthropic.com>
2 tasks
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What
v0.5.0 release follow-up — main에 반영해야 라이브:
이미 develop에 머지된 두 PR을 main으로 전달.
Trigger 영향
이 PR이 main에 머지되면 `release.yml`이 다시 실행되지만:
0.5.0그대로 → tag checkexists == 'false'가 false → 모든 job skip (no-op)효과
🤖 Generated with Claude Code