Package managers, Clone-in-WSL recovery, WinUI.TableView table (#9, #8, #33) #59

Merged
KofTwentyTwo merged 4 commits from dev into main 2026-10-09 13:55:02 +00:00
KofTwentyTwo commented 2026-10-09 13:43:05 +00:00 (Migrated from github.com)

Three features that were deferred until after the known-issues sweep, now ready for the v1.0.1-beta.1 rehearsal (#55).

#9 — Scoop bucket, Chocolatey package, SHA256SUMS.txt

  • This repository is its own Scoop bucket (bucket/gclo.json, verified with a real scoop install of the v1.0.0 CLI zip on the development machine); packaging/chocolatey ships the Chocolatey package source.
  • .github/scripts/Update-PackageManifests.ps1 re-points both at a stable release from one source of truth (refuses prereleases).
  • Release workflow: writes, attests and attaches SHA256SUMS.txt on every release; on stable tags it updates the manifests, choco packs, pushes when CHOCO_API_KEY is set, and opens a PR against main (Scoop reads the manifest from the default branch; a PR against dev would leave scoop install on the previous version until the next dev→main merge). RELEASING.md and README document the flow; CHOCO_API_KEY is listed on #7.
  • gclo.Cli.Tests/PackagingManifestTests.cs keeps both manifests valid, stable, and in agreement.

#8 — "Clone in WSL instead"

  • gclo.Engine/WslCloner.cs: probe (wsl.exe -e git --version) and clone (a POSIX script fed to sh -s on stdin with org/repo/url as positional parameters, so nothing is re-parsed by wsl.exe). The token reaches git only as GCLO_GIT_TOKEN via WSLENV through an inline credential helper: never argv, never a file. Destination ~/gclo/<org>/<repo> in the default distribution; an existing clone is fast-forwarded. Verified end to end in WSL here (clone, then re-run as pull).
  • View model: PathRecoveryDecision (Apply | CloneInWsl); WSL is probed once, lazily, before the recovery dialog opens (IsWslCloneAvailable); the clone runs under the same lock as path recovery; success marks the row Done with a note naming the \wsl.localhost\... path; failure keeps the payload so the rename/skip route stays open.
  • Dialog offers "Clone in WSL instead" as its secondary button when available. README documents it.

#33 — WinUI.TableView 1.5.0

  • The hand-rolled header + ListView become one TableView (pinned 1.5.0). The view model still owns sort and filter: Sorting/ClearSorting are routed into SortCommand, the indicator and the header's composed automation name are written back from SortColumn; the control's Excel filters are off and each header hosts the same funnel flyout as before. Error line / WSL note / Resolve link live in an always-on row-details template.
  • Accessibility finding: TableView 1.5.0's peer inherits ListViewAutomationPeer children (rows only), so the header row and anything inside it are invisible to UIA tree walking and the Table pattern's ColumnHeaders fails. gclo/AccessibleTableView.cs prepends the column header peers; ColumnHeaderContent gives cells proper "Name, Row 3, alpha" names. Worth reporting upstream.
  • Offline UI fixture: gclo/UiTestFixture.cs (active only with GCLO_UITEST_FIXTURE=1 and the magic token) lets gclo.UiTests/RepoTableTests.cs load a fixed organization and assert the table renders, headers sort via Invoke, and the Name funnel filters/clears. UI test collections now run one at a time (two app sessions).

Verification

  • dotnet build gclo.slnx clean; Engine 419 / CLI 129 tests green; line coverage 100% on Engine and ViewModels; dotnet format clean.
  • FlaUI: 11/11 (8 smoke + 3 table) locally on x64.
  • Not done / for the owner: a manual Narrator + keyboard pass over the new table (synthesized Tab did not move focus inside the TableView header under FlaUI, so funnel keyboard reachability is unverified); the always-on row-details mode leaves a thin empty strip under rows with nothing to show (cosmetic).
  • Found along the way: the UI suite picks up a developer's saved default token from Credential Manager (filed separately).

Closes #8
Closes #9
Closes #33

🤖 Generated with Claude Code

Three features that were deferred until after the known-issues sweep, now ready for the `v1.0.1-beta.1` rehearsal (#55). ## #9 — Scoop bucket, Chocolatey package, SHA256SUMS.txt - This repository is its own Scoop bucket (`bucket/gclo.json`, verified with a real `scoop install` of the v1.0.0 CLI zip on the development machine); `packaging/chocolatey` ships the Chocolatey package source. - `.github/scripts/Update-PackageManifests.ps1` re-points both at a stable release from one source of truth (refuses prereleases). - Release workflow: writes, attests and attaches `SHA256SUMS.txt` on every release; on stable tags it updates the manifests, `choco pack`s, pushes when `CHOCO_API_KEY` is set, and opens a PR **against `main`** (Scoop reads the manifest from the default branch; a PR against dev would leave `scoop install` on the previous version until the next dev→main merge). RELEASING.md and README document the flow; `CHOCO_API_KEY` is listed on #7. - `gclo.Cli.Tests/PackagingManifestTests.cs` keeps both manifests valid, stable, and in agreement. ## #8 — "Clone in WSL instead" - `gclo.Engine/WslCloner.cs`: probe (`wsl.exe -e git --version`) and clone (a POSIX script fed to `sh -s` on stdin with org/repo/url as positional parameters, so nothing is re-parsed by wsl.exe). The token reaches git only as `GCLO_GIT_TOKEN` via `WSLENV` through an inline credential helper: never argv, never a file. Destination `~/gclo/<org>/<repo>` in the default distribution; an existing clone is fast-forwarded. Verified end to end in WSL here (clone, then re-run as pull). - View model: `PathRecoveryDecision` (Apply | CloneInWsl); WSL is probed once, lazily, before the recovery dialog opens (`IsWslCloneAvailable`); the clone runs under the same lock as path recovery; success marks the row Done with a note naming the `\wsl.localhost\...` path; failure keeps the payload so the rename/skip route stays open. - Dialog offers "Clone in WSL instead" as its secondary button when available. README documents it. ## #33 — WinUI.TableView 1.5.0 - The hand-rolled header + ListView become one `TableView` (pinned 1.5.0). The view model still owns sort and filter: `Sorting`/`ClearSorting` are routed into `SortCommand`, the indicator and the header's composed automation name are written back from `SortColumn`; the control's Excel filters are off and each header hosts the same funnel flyout as before. Error line / WSL note / Resolve link live in an always-on row-details template. - **Accessibility finding:** TableView 1.5.0's peer inherits `ListViewAutomationPeer` children (rows only), so the header row and anything inside it are invisible to UIA tree walking and the Table pattern's `ColumnHeaders` fails. `gclo/AccessibleTableView.cs` prepends the column header peers; `ColumnHeaderContent` gives cells proper "Name, Row 3, alpha" names. Worth reporting upstream. - **Offline UI fixture:** `gclo/UiTestFixture.cs` (active only with `GCLO_UITEST_FIXTURE=1` **and** the magic token) lets `gclo.UiTests/RepoTableTests.cs` load a fixed organization and assert the table renders, headers sort via Invoke, and the Name funnel filters/clears. UI test collections now run one at a time (two app sessions). ## Verification - `dotnet build gclo.slnx` clean; Engine 419 / CLI 129 tests green; line coverage 100% on Engine and ViewModels; `dotnet format` clean. - FlaUI: 11/11 (8 smoke + 3 table) locally on x64. - Not done / for the owner: a manual Narrator + keyboard pass over the new table (synthesized Tab did not move focus inside the TableView header under FlaUI, so funnel keyboard reachability is unverified); the always-on row-details mode leaves a thin empty strip under rows with nothing to show (cosmetic). - Found along the way: the UI suite picks up a developer's saved default token from Credential Manager (filed separately). Closes #8 Closes #9 Closes #33 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.