Skip to content

Wayfinder map: cdd v0.1.0 #2

Description

@hammadmajid

Destination

v0.1.0 tagged on main with a GitHub Release carrying Linux and macOS binaries (amd64 and arm64) built by GoReleaser under GitHub Actions. The binary ships a Picker, cdd scan, and cdd init fish|bash|zsh Wrappers that Jump. The repo's Community Standards checklist is fully green.

Notes

This map executes. Task tickets build the tool, not just decide it. Each task is done by a sub-agent on its own branch: micro commits in Conventional Commits format, a PR opened against main, merged by the driving session. Never push to main. No file over 300 lines. Every package has tests. Use the tdd skill for task tickets and the codebase-design skill for layout questions.

Domain. CONTEXT.md is the glossary; use its terms (Root, Kind, Project, Jump, Visit, History, Scan, Picker, Wrapper) verbatim in code, issues, and docs.

Settled while charting.

  • History is the sole ordering source. Never-visited Projects sort after visited ones, alphabetically, with an empty last-worked cell. No git mtime in the ordering.
  • Scan seeds one Visit per Project from its last commit time, or directory mtime when it is not a repository. It is idempotent and never overwrites a newer real Visit. The Picker hints to run cdd scan when History is empty.
  • Wrapper pattern follows starship: cdd init <shell> | source. The binary prints the chosen path; the Wrapper performs the Jump.
  • Stack: Go 1.26, Bubble Tea, Lip Gloss, Bubbles, a small fuzzy library (sahilm/fuzzy or equivalent). Git status by shelling out to git status --porcelain=v2 --branch; no go-git. Projects that are not repositories show no status.
  • Look: gh-dash style. Filter input on top, aligned table with highlighted selected row, relative times, colored status glyphs with a plain-word legend in the footer, adaptive to light and dark terminals.
  • Release: GoReleaser on v* tags. Linux and macOS, amd64 and arm64.
  • Community standards: MIT, Contributor Covenant 2.1, CONTRIBUTING.md stating the micro-commit and PR-only rules, SECURITY.md pointing at GitHub private vulnerability reporting, bug and feature issue templates, one PR template.
  • PR workflow is a convention, not enforced. No branch protection, no required checks.

Decisions so far

  • History file format and location: append-only TSV log at ~/.local/share/cdd/history (XDG data dir, same on macOS), one Visit per line as RFC3339-UTC<TAB>jump|scan<TAB>kind/project; history.max_visits (default 1000) bounds lines kept, compaction by temp-and-rename when 10% over, flock around append and compaction; Scan seeds scan lines and never overwrites a jump.
  • Config schema for config.toml: root required with ~ expansion, exclude globs relative to Root, include_hidden = false, [history] max_visits = 1000; Kinds discovered, no column config; pelletier/go-toml/v2 strict, unknown keys and bad values are errors; no config path override.
  • Stale History: Visits whose Project is no longer under Root: one case, the Stale Visit (term added to the glossary in docs: add Stale Visit to glossary #26); it contributes no Picker row, nothing prunes it, it ages out via max_visits; byte-exact kind/project comparison.
  • Command surface and Wrapper contract: cobra; cdd, pick [query], init <shell>, scan, version, plus cobra's help and completion; pick prints one absolute path on stdout, TUI on /dev/tty, exit 0/130 cancel/1 error/2 usage; binary writes the Visit before printing; exact name or kind/project match Jumps without the Picker, else prefilled filter; bare cdd on a terminal hints to install the Wrapper; Wrapper named cdd via command cdd, pass-through list generated from the command tree.
  • Package layout for the module: cmd/cdd/main.go plus nine internal/ packages: config, project, history, git, scan, picker, jump, shell, cli; the pick flow and ordering rule live in jump, Picker takes an injected StatusFunc, no filesystem abstraction, external test packages on stdlib testing, 300-line rule enforced in CI.
  • GoReleaser release workflow for a Go CLI on tag push: version: 2 config, one build from ./cmd/cdd for linux and darwin on amd64 and arm64 with CGO_ENABLED=0 and -trimpath, tar.gz archives and sha256 checksums; a v* tag workflow with checkout v7, setup-go v7 and goreleaser-action v7 under contents: write. Detail on the research/goreleaser-workflow branch.
  • Parsing git status porcelain v2 for clean, dirty, untracked, ahead and behind: first byte of each record decides: 1/2/u dirty, only ? untracked, none clean; # branch.ab +A -B gives ahead-behind, absent or +? -? means no upstream. Invoke GIT_OPTIONAL_LOCKS=0 git -C <dir> status --porcelain=v2 --branch -unormal -z with a 2 s timeout, render timeout as unknown, exit 128 means not a repository. Check for .git since git walks up from subdirectories. Detail on the research/git-status-porcelain branch.
  • Bubble Tea stack: versions to pin and the async row-update pattern: pin the v2 line on the charm.land path: charm.land/bubbletea/v2 v2.0.9, charm.land/lipgloss/v2 v2.0.6, charm.land/bubbles/v2 v2.2.1 (the github path fails with a module mismatch). Fill the status column with tea.Batch of one tea.Cmd per row from Init, each result arriving as its own message keyed by Project path, fan-out bounded by a semaphore. Fuzzy: github.com/sahilm/fuzzy v0.1.3, stdlib-only with match positions, also what Bubbles' list uses. Detail on the research/bubbletea-stack branch.
  • How starship and zoxide implement shell init for fish, bash and zsh: zoxide's zi is result=$(\command zoxide query --interactive) && cd "$result", TUI on /dev/tty, stdout carries only the path, cancel is exit 130 with empty stdout. Recommended Wrapper: a same-named function passing non-Jump subcommands to command cdd, otherwise capture command cdd pick, guard non-empty (fish cd with an empty list goes to $HOME), then cd --. Binary draws via tea.OpenTTY, prints one path, exits 130 silently on cancel, and records the Visit itself. zsh snippet is manual-derived, untested locally. Detail on the research/shell-init-patterns branch.
  • Picker look: runnable mock to react to: rows grouped by Kind (History order inside a Kind, Kinds by most recent Visit), caret-selected row with no background, aligned status glyph cluster with ahead/behind counts, right-aligned relative time, a preview pane on the right (path, branch, status words, sync, last visit, visit count), glyph legend plus keys in the footer; GitHub Primer accents via lipgloss.LightDark. Adds [keys] vim = true to config: j/k move, f focuses the filter, esc returns to the list keeping the query. Mock on the prototype/picker-look branch.
  • Narrow terminals: when the preview pane hides and how rows truncate: preview hides when fewer than 30 columns remain after the list takes its natural width (capped at 55%), automatic only, branch goes with it, long preview values wrap; below the list width the relative time compresses first (2h, 3d), then the name truncates with to a floor of 8, status never shrinks, no hard minimum; under 15 rows the legend drops, under 10 the keys line too.
  • Scaffold repo: CI workflow, .gitignore, lint config: merged as PR #30; CI with build, vet, test, lint and a 300-line check; cmd/cdd stub.
  • Add community standards files: merged as PR #29; MIT, Contributor Covenant 2.1, CONTRIBUTING, SECURITY, issue forms, PR template.
  • Implement the config package: merged as PR #31; internal/config with go-toml/v2, strict keys, example config.
  • Implement the history package: merged as PR #32; internal/history TSV log, flock, compaction, Seed rules.
  • Implement project discovery under Root: merged as PR #33; internal/project Discover with hidden and glob exclusions.
  • Implement the git package: status and last commit: merged as PR #36; internal/git porcelain v2 parser with 2 s timeout and NotRepo.
  • Implement cdd init for fish, bash and zsh: merged as PR #34; internal/shell embedded Wrapper templates, executed in tests.
  • Add GoReleaser config and release workflow: merged as PR #35; .goreleaser.yaml v2 and tag-triggered release workflow, snapshot check in CI.
  • Implement cdd scan: merged as PR #39; internal/scan seeds from last commit or mtime with a worker pool.
  • Implement the Picker: merged as PR #38; internal/picker on Bubble Tea v2, grouped list, preview, vim keys, narrow-terminal rules.
  • Implement the jump flow: merged as PR #40; internal/jump ordering rule, exact-match shortcut, Visit recording.
  • Wire the CLI: cdd, init, scan, version: merged as PR #41; internal/cli on cobra with the decided exit codes and hint.
  • Write the README: merged as PR #42; README with install, shell setup, config reference; demo placeholder for the maintainer.
  • Lint follow-up: PR #43 cleared errcheck and staticcheck findings so CI on main is green.
  • Cut v0.1.0: tagged 4c2025f; Release v0.1.0 carries four binaries plus checksums, verified by installing the Linux amd64 build and Jumping with it. Destination reached.

Not yet specified

Nothing. Every fog item graduated into a ticket and was resolved. The README shape landed with the README task.

Out of scope

  • Reconnecting History across a Project rename or move (git remote, inode, or similar heuristics). A renamed Project starts with no History. Ruled out while resolving Stale History.
  • Configurable Picker columns (a columns key in config). Columns are fixed, decided by the Picker prototype. Ruled out while resolving Config schema for config.toml.
  • Wrappers for PowerShell, nushell, and elvish. All feasible (starship and zoxide do it); planned for a future release, no release committed. Windows binaries follow PowerShell.
  • Git commit or index mtime as a live ordering source. History is the source; git time only seeds via Scan.
  • Package manager distribution (Homebrew tap, AUR, nix). The destination is Release binaries.
  • Branch protection and required CI checks on main.
  • go-git or any in-process git implementation.
  • Research branches (research/*) were deleted after the tasks consuming them merged; their findings are quoted in each ticket's resolution comment. The prototype/picker-look branch is kept as the Picker's visual reference.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    wayfinder:mapWayfinder map: notes, decisions so far, and fog

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions