diff --git a/.STATUS b/.STATUS index 776d9710a..c945b08d6 100644 --- a/.STATUS +++ b/.STATUS @@ -5,11 +5,37 @@ ## Type: zsh-plugin ## Status: active ## Focus: --help -## Phase: Released (v7.13.0) +## Phase: Releasing (v7.15.0) ## Priority: 2 ## Progress: 100 -## Current Session (2026-07-02) — planning-coordination: shared accessors + dark-ready atlas agenda + .STATUS enforcer ✅ +## Current Session (2026-07-02) — retired code-workspace spec, closed 3 stale issues, triaged real backlog ✅ + +**Session activity (part 4):** +- **Retired `SPEC-code-workspace-2026-02-13.md`** (`code ws` dispatcher) — draft, 4.5mo untouched, zero implementation, zero demand signal; overloading the `code` binary carries real risk without a validated need. Moved to `docs/specs/_archive/`, marked retired. Cleared the (now-empty) `.STATUS` Next Action queue. +- **Audited the remaining 4 open issues the same way #423 was checked** (4 parallel agents, one per issue, grep + git log + doc cross-check): + - **#298** (Teaching config consolidation) — FULLY_SHIPPED (`_teach_get_style()`/`_teach_get_command_override()`/schema/doctor reporting, commits `970f3f4b2`/`795f86ad7`). Closed. + - **#331** (Himalaya email integration) — FULLY_SHIPPED, exceeds scope (the `em` dispatcher implements it + AI drafting, safety gates, calendar extraction, etc. that #331 never proposed; dozens of commits tag `(#331)`). Closed. One minor gap noted, not blocking: no shipped Tokyo Night color-theme `config.toml` preset. + - **#359** (`teach check` cross-tool validation) — **NOT_STARTED**, genuine backlog. No dispatcher case, no function, zero commits, explicitly flagged as unbuilt future work in `SPEC-teach-map-2026-02-08.md`. + - **#275** (`teach dashboard` website content) — **NOT_STARTED**, genuine backlog. Spec was written + approved (2026-01-19, v5.15.0 target) then archived/deleted in a stale-spec cleanup without any code landing. +- **Net result**: 3 stale-but-shipped issues closed this session (#423, #298, #331), 2 genuine backlog items surfaced and confirmed real (#359, #275) — down from 5 open issues to 2, both accurately scoped. + +## Previous Session (2026-07-02) — closed stale issue #423, filled 4 command doc gaps ✅ + +**Session activity (part 3):** +- **Stress-tested issue #423** ("Scholar Config Sync wiring + new teach wrappers") against v7.14.0 — found it was already fully shipped (3 commits explicitly tagged `#423`: config injection, `config check/diff/show/scaffold`, `solution`/`sync`/`validate-r` wrappers, doctor config-sync check, docs). Closed with evidence linking the implementing commits. Writeup: `docs/specs/BRAINSTORM-issue-423-stress-test-2026-07-02.md`. +- **Audited command/dispatcher doc coverage** — all 14 dispatchers fully documented; found 4 genuinely undocumented user-facing commands (`ref`, `setup`, `tutorial`, `sec tutorial`) confirmed against `docs/DOC-DASHBOARD.md`'s missing-doc tracker and absence from `mkdocs.yml` nav. Also found 8 teach-* "missing doc" dashboard entries were false positives (documented collectively, not 1:1). +- **Dispatched 2 parallel agents**: one wrote `docs/commands/ref.md`, `setup.md`, `tutorial.md` + a `sec tutorial` subsection in `SECRET-MANAGEMENT.md` (sourced from full `.zsh` reads, no invented flags) and wired all 3 new pages into `mkdocs.yml` nav; the other audited the last 2 weeks of `commands/`/`lib/dispatchers/` commits against docs — found `MASTER-DISPATCHER-GUIDE.md`'s `claude` section stale at C1–C6 (v7.13.0's C7–C11 checks + `flow claude watch` daemon, PR #475, never propagated there). +- **Fixed the stale `claude` section** — synced synopsis, C7–C11 table, watch-daemon description, exit codes, dependencies. Fixed 8 MD029 ordered-list lint errors in `tutorial.md`. Verified: `mkdocs build --strict` → 0 warnings, `markdownlint-cli2` → 0 errors. + +## Previous Session (2026-07-02) — Homebrew man-page fix + doctor INSTALLATION checks ✅ + +**Session activity (part 2, continued from planning-coordination below):** +- **Diagnosed + fixed a real Homebrew distribution bug**: flow-cli's `r`-dispatcher man page (`r.1`) collided case-insensitively with the `r` (R-language) formula's `R.1` on APFS, silently breaking `brew link`/`brew upgrade` for anyone with both installed — `brew upgrade flow-cli` reported "already installed" while actually broken. Fixed in `homebrew-tap` (`Formula/flow-cli.rb`, PR #135, merged `05a2e17c`): exclude `r.1` unconditionally from the Homebrew install. Verified via `brew reinstall flow-cli` — clean, 0 errors. +- **Added `doctor` INSTALLATION section** (PR #485, merged squash `352d6f6ea`) to catch this class of bug going forward: opt/Cellar symlink integrity, shell-loaded version vs. installed Cellar keg drift, and flow-cli's own man pages resolving cleanly (scoped to flow-cli's pages specifically — avoids false positives from Homebrew's own keg-only convention, e.g. `lua`/`lua@5.4`, discovered by testing live against this machine's real install). New `tests/e2e-doctor-install.zsh` (7 scenarios). Along the way found + worked around a zsh quirk: redeclaring `local` inside a glob-driven `for` loop spuriously echoes `name=value` to stdout on this machine's zsh build — hoisted `local` out of the loop. +- **homebrew-tap**: worktree `fix/flow-cli-r-man-conflict` removed, branch deleted (squash-merged); `.STATUS` updated (left uncommitted — `main` is PR-only in that repo). + +## Previous Session (2026-07-02) — planning-coordination: shared accessors + dark-ready atlas agenda + .STATUS enforcer ✅ **Session activity:** - **Brainstormed + grilled** (16 decisions, D1-D16) the flow-cli slice of a 3-repo (flow-cli/atlas/obsidian-cli-ops) daily-planning coordination proposal — `docs/specs/BRAINSTORM-planning-coordination-2026-07-01.md` + `docs/specs/SPEC-planning-coordination-2026-07-01.md`. Hard-scoped to flow-cli only this cycle; atlas Track B and obs Track D deferred to their own specs. @@ -21,6 +47,9 @@ - **Updated** docs (API reference, agenda/schedule guide with a real captured multi-source transcript, dispatcher guide, CHANGELOG, CONTRIBUTING, CLAUDE.md counts) - **Caught a real CI-only bug** before merge: a test hid `jq` via `PATH="$STUB_BIN:/bin"`, correct on macOS (`/bin` has no `jq`) but wrong on Ubuntu's usr-merged `/bin` (→ `/usr/bin/jq`, preinstalled on `ubuntu-latest`) — fixed to `PATH="$STUB_BIN"` alone, no system-directory assumption. - **Merged** PR #483 → dev (squash, `8012aaea`), both CI checks green. Worktree + local/remote feature branch cleaned up. +- **Released v7.14.0**: reconciled a pre-existing CHANGELOG mirror drift (missing `tok mint` entry, restored to root) → `release.sh 7.14.0` (version bump: `flow.plugin.zsh`, `package.json`, `CLAUDE.md`, 23 man pages, guard 12/12) → CHANGELOG `[Unreleased]`→`[7.14.0]` (mirrored) → refreshed `docs/index.md` What's New (was 3 releases stale at v7.10.2) → PR #484 (`dev`→`main`) → CI green (4/4 jobs) → merged (squash, `769d744a`) → tagged `v7.14.0` → GitHub release published → Homebrew formula verified (`v7.14.0.tar.gz`) → docs deployed (200 OK) → `dev` synced with `main`. +- **Scheduled + disabled a cloud-agent routine** (`flow-cli doc gap & staleness sweep`) — created as a 1-hour backup while the release was still in flight, then disabled once the release finished locally instead (never fired; confirmed via timestamp — disabled at 07:01 UTC, scheduled for 07:51 UTC). +- **Post-release audit**: checked for session interference (reflog/commit-author review — all commits accounted for, no concurrent/unexpected activity) and secret leaks (pattern-scanned the full release diff, the published GitHub release body, and file list — clean; the `ghs_`/`github_app_private_key` mentions in the `tok mint` changelog entry are prose describing the feature, not actual credential values). ## Previous Session (2026-06-30) — mkdocs improvements + Dependabot maintenance ✅ @@ -475,13 +504,20 @@ ## Next Action -1. API documentation push (50% → 80% coverage of 348 functions) -2. Code workspace manager — `code ws` dispatcher (`SPEC-code-workspace-2026-02-13.md`, ~4mo old — review before impl) +1. Issue #359 — `teach check` cross-tool validation summary (2-3h, verified not started) +2. Issue #275 — `teach dashboard` subcommand for dynamic website content (8-12h, verified not started; original spec archived, would need a fresh spec) + +## Parked + +- API documentation push (50% → 80% coverage of 348 functions) — parked 2026-07-02, no active driver +- ~~Code workspace manager (`code ws` dispatcher)~~ — retired 2026-07-02, spec moved to `docs/specs/_archive/SPEC-code-workspace-2026-02-13.md` (never implemented, no demand signal in 4.5mo) --- -**Last Updated:** 2026-06-30 -**Status:** v7.13.0 active | mkdocs improvements (breadcrumbs, validation, not_in_nav) + Dependabot deps current | full suite REQUIRED on main — 64 passed / 0 failed / 1 skipped | 14 dispatchers + at bridge | 219 test files | 12000+ test functions | 0 lint errors | 0 broken links -## wins: Fixed the regression bug (2026-06-19), --category fix squashed the bug (2026-06-19), fixed the bug (2026-06-19), Fixed the regression bug (2026-06-19), --category fix squashed the bug (2026-06-19) +**Last Updated:** 2026-07-02 +**Status:** v7.14.0 active (Homebrew man-page fix live via homebrew-tap PR #135) | doctor INSTALLATION checks added (PR #485) | full suite — 75 passed / 0 failed / 1 timeout (interactive/tmux baseline) / 1 skipped (himalaya absent) | 14 dispatchers + at bridge | 231 test files | 76 registered suites | 0 lint errors | 0 broken links +## wins: Fixed the regression bug (2026-07-02), --category fix squashed the bug (2026-07-02), fixed the bug (2026-07-02), Fixed the regression bug (2026-07-02), --category fix squashed the bug (2026-07-02) ## streak: 1 -## last_active: 2026-06-19 10:30 +## last_active: 2026-07-02 12:31 + +# Last teach config: 2026-07-02 diff --git a/CHANGELOG.md b/CHANGELOG.md index 65d96feb0..a01a9d485 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [7.15.0] — 2026-07-02 — Homebrew distribution health + doc gap fills + +### Added + +- **`doctor` INSTALLATION section** — detects Homebrew distribution failures that leave a user silently on a broken or stale install: opt/Cellar symlink integrity (installed-but-unlinked), shell-loaded version vs. installed Cellar keg drift, and flow-cli's own man pages losing a case-insensitive name collision to another formula (the class of bug fixed in homebrew-tap PR #135). Skips silently for non-Homebrew installs. +- **`docs/guides/WORKFLOW-COOKBOOK.md`** — daily and weekly routine cookbook with a Mermaid diagram, 13 recipes (7 daily, 6 weekly) each sourced from the real command it documents. +- **Command docs for `ref`, `setup`, `tutorial`** (`docs/commands/`) — the last 3 user-facing commands flagged undocumented by `docs/DOC-DASHBOARD.md`, now wired into the MkDocs nav. +- **`sec tutorial` subsection** (`docs/SECRET-MANAGEMENT.md`) — documents the 7-lesson interactive token/secret management tutorial. + +### Fixed + +- **`MASTER-DISPATCHER-GUIDE.md` `claude` section** — was stale at checks C1-C6 since v7.13.0 shipped C7-C11 and the `flow claude watch` daemon (PR #475); synced synopsis, check table, exit codes, and dependencies. + +### Changed + +- **Homepage (`docs/index.md`) reorganized for scan-ability** — the flat 8-card "Next Steps" grid is now three labeled clusters ("New here?" / "Solve a specific problem" / "Already using it?"); surfaced `setup`, `tutorial`, `ref`, and the new Workflow Cookbook, none of which were linked from the homepage; trimmed the "What's New" admonition from 5 dense bullets to 2 headline items + a changelog pointer. + ## [7.14.0] — 2026-07-02 — planning-coordination: shared accessors + dark-ready atlas agenda + .STATUS enforcer ### Added diff --git a/CLAUDE.md b/CLAUDE.md index 4b55f59f4..96c4eae5b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,7 +7,7 @@ This file provides guidance to Claude Code when working with code in this reposi **flow-cli** - Pure ZSH plugin for ADHD-optimized workflow management. Zero dependencies. Standalone (works without Oh-My-Zsh or any plugin manager). - **Architecture:** Pure ZSH plugin (no Node.js runtime required) -- **Current Version:** v7.14.0 +- **Current Version:** v7.15.0 - **Install:** Homebrew (recommended), or any plugin manager - **Source:** `source /opt/homebrew/opt/flow-cli/flow.plugin.zsh` (via Homebrew) - **Optional:** Atlas integration for enhanced state management @@ -130,7 +130,7 @@ flow-cli/ │ ├── keychain-helpers.zsh # macOS Keychain secrets │ ├── tui.zsh # Terminal UI components │ └── dispatchers/ # 14 smart command dispatchers -├── commands/ # 32 command files (work, dash, agenda, doctor, teach-*, etc.) +├── commands/ # 33 command files (work, dash, agenda, doctor, teach-*, etc.) ├── setup/ # Installation & setup ├── completions/ # ZSH completions ├── hooks/ # ZSH hooks @@ -138,7 +138,7 @@ flow-cli/ │ └── internal/ # Internal conventions & contributor templates ├── scripts/ # Standalone validators (check-math.zsh, check-status.zsh) ├── templates/ # .STATUS.template (canonical shape reference) -├── tests/ # 245 test files, 12000+ test functions +├── tests/ # 231 test files, 12000+ test functions │ └── fixtures/demo-course/ # STAT-101 demo course for E2E └── .archive/ # Archived Node.js CLI ``` @@ -183,7 +183,7 @@ flow-cli/ ## Testing -**245 test files, 12000+ test functions.** Run: `./tests/run-all.sh` (74/74 passing, 1 skipped — required external tool absent, e.g. himalaya) or individual suites in `tests/`. +**231 test files, 76 registered suites, 12000+ test functions.** Run: `./tests/run-all.sh` (75/75 passing, 1 skipped — required external tool absent, e.g. himalaya) or individual suites in `tests/`. See `docs/guides/TESTING.md` for patterns, mocks, assertions, TDD workflow. @@ -217,8 +217,8 @@ export FLOW_FORCE_DISPATCHER_OBS=1 # Force-keep one dispatcher (FLOW_F ## Current Status -**Version:** v7.14.0 | **Tests:** 12000+ (74/74 suite, 1 skipped — tool absence) | **Docs:** https://Data-Wise.github.io/flow-cli/ +**Version:** v7.15.0 | **Tests:** 12000+ (75/75 suite, 1 skipped — tool absence) | **Docs:** https://Data-Wise.github.io/flow-cli/ --- -**Last Updated:** 2026-07-02 (v7.14.0) +**Last Updated:** 2026-07-02 diff --git a/commands/doctor.zsh b/commands/doctor.zsh index 45802c36a..fd3383561 100644 --- a/commands/doctor.zsh +++ b/commands/doctor.zsh @@ -129,6 +129,11 @@ doctor() { _doctor_check_cmd "git" "" "shell" _doctor_log_quiet "" + # ────────────────────────────────────────────────────────────── + # INSTALLATION (Homebrew distribution health) + # ────────────────────────────────────────────────────────────── + _doctor_check_installation + # ────────────────────────────────────────────────────────────── # REQUIRED # ────────────────────────────────────────────────────────────── @@ -1160,6 +1165,88 @@ _doctor_update_docs() { # HELPER FUNCTIONS # ============================================================================ +# ============================================================================= +# INSTALLATION / DISTRIBUTION HEALTH +# ============================================================================= +# Catches the class of bug fixed in homebrew-tap PR #135: a Homebrew formula +# install that silently fails to link (man-page name collision, stale Cellar +# keg after a formula fix) leaves the user on an old version with no error +# message — `brew upgrade` reports "already installed" even when broken. +# Checks are read-only and only apply when flow-cli was installed via brew; +# git-clone / plugin-manager installs skip silently (nothing to check). + +_doctor_check_installation() { + _doctor_log_quiet "${FLOW_COLORS[bold]}📦 INSTALLATION${FLOW_COLORS[reset]}" + + if ! command -v brew >/dev/null 2>&1; then + _doctor_log_quiet " ${FLOW_COLORS[muted]}○ Homebrew not present — skipping${FLOW_COLORS[reset]}" + _doctor_log_quiet "" + return 0 + fi + + if ! brew list --formula 2>/dev/null | grep -qx "flow-cli"; then + _doctor_log_quiet " ${FLOW_COLORS[muted]}○ flow-cli not installed via Homebrew — skipping${FLOW_COLORS[reset]}" + _doctor_log_quiet "" + return 0 + fi + + local brew_prefix + brew_prefix=$(brew --prefix 2>/dev/null) + local opt_path="${brew_prefix}/opt/flow-cli" + local installed_version + installed_version=$(brew list --versions flow-cli 2>/dev/null | awk '{print $2}') + + # 1. Link integrity — installed-but-unlinked is the exact symptom of the + # man-page-collision bug: `brew install`/`upgrade` "succeeds" but the + # opt symlink is never created, so `source $(brew --prefix)/opt/flow-cli/...` fails. + if [[ -L "$opt_path" && -d "${opt_path}/." ]]; then + _doctor_log_quiet " ${FLOW_COLORS[success]}✓${FLOW_COLORS[reset]} Homebrew link ${FLOW_COLORS[muted]}(v${installed_version})${FLOW_COLORS[reset]}" + else + _doctor_log_quiet " ${FLOW_COLORS[error]}✗${FLOW_COLORS[reset]} flow-cli installed but not linked ${FLOW_COLORS[muted]}← brew link flow-cli (or: brew reinstall flow-cli)${FLOW_COLORS[reset]}" + fi + + # 2. Version drift — the shell's already-sourced $FLOW_VERSION vs. what + # Homebrew currently has installed. Catches "reinstalled/upgraded but + # forgot to restart the shell" silently running stale code. + if [[ -n "$installed_version" && -n "$FLOW_VERSION" && "$installed_version" != "$FLOW_VERSION" ]]; then + _doctor_log_quiet " ${FLOW_COLORS[warning]}⚠${FLOW_COLORS[reset]} Shell has v${FLOW_VERSION} loaded, Homebrew has v${installed_version} installed ${FLOW_COLORS[muted]}← restart your shell${FLOW_COLORS[reset]}" + fi + + # 3. Man-page link check — does every man page flow-cli's own Cellar keg + # ships actually resolve (via the shared man1 symlink) back into + # flow-cli's keg? A page that "exists" at the shared path but resolves + # into a DIFFERENT formula's Cellar dir means flow-cli's own page lost + # a case-insensitive name collision and was silently never linked (the + # PR #135 class of bug — deliberately scoped to flow-cli's own pages, + # not a whole-Cellar audit: Homebrew's own keg-only-formula convention + # (e.g. lua vs lua@5.4) produces same-name kegs constantly and is not a + # bug — only formulae that both actually attempt to link collide). + local _doctor_brew_cellar + _doctor_brew_cellar=$(brew --cellar 2>/dev/null) + local flow_man1_dir="${_doctor_brew_cellar}/flow-cli/${installed_version}/share/man/man1" + if [[ -d "$flow_man1_dir" ]]; then + local shared_man1="${brew_prefix}/share/man/man1" + local not_linked=() + # `local` is hoisted OUT of the loop deliberately: redeclaring a local + # var on every glob-driven iteration triggers a spurious "name=value" + # echo to stdout on some zsh builds (reproduced independent of this + # codebase — a fresh `zsh -f` script with the same shape shows it too). + local mp_name link_target + for manpage in "$flow_man1_dir"/*.1(N); do + mp_name="${manpage:t}" + link_target=$(readlink "${shared_man1}/${mp_name}" 2>/dev/null) + [[ "$link_target" == *"/flow-cli/"* ]] || not_linked+=("$mp_name") + done + if (( ${#not_linked[@]} > 0 )); then + _doctor_log_quiet " ${FLOW_COLORS[warning]}⚠${FLOW_COLORS[reset]} flow-cli man page(s) not linked (collision with another formula) ${FLOW_COLORS[muted]}${not_linked[*]}${FLOW_COLORS[reset]}" + else + _doctor_log_quiet " ${FLOW_COLORS[success]}✓${FLOW_COLORS[reset]} All flow-cli man pages linked cleanly" + fi + fi + + _doctor_log_quiet "" +} + _doctor_check_cmd() { local cmd="$1" local install_spec="$2" # Format: "brew" or "brew:package" or "npm:package" or "pip" diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 702242d73..677ef3513 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -8,6 +8,23 @@ The format follows [Keep a Changelog](https://keepachangelog.com/), and this pro ## [Unreleased] +## [7.15.0] — 2026-07-02 — Homebrew distribution health + doc gap fills + +### Added + +- **`doctor` INSTALLATION section** — detects Homebrew distribution failures that leave a user silently on a broken or stale install: opt/Cellar symlink integrity (installed-but-unlinked), shell-loaded version vs. installed Cellar keg drift, and flow-cli's own man pages losing a case-insensitive name collision to another formula (the class of bug fixed in homebrew-tap PR #135). Skips silently for non-Homebrew installs. +- **`docs/guides/WORKFLOW-COOKBOOK.md`** — daily and weekly routine cookbook with a Mermaid diagram, 13 recipes (7 daily, 6 weekly) each sourced from the real command it documents. +- **Command docs for `ref`, `setup`, `tutorial`** (`docs/commands/`) — the last 3 user-facing commands flagged undocumented by `docs/DOC-DASHBOARD.md`, now wired into the MkDocs nav. +- **`sec tutorial` subsection** (`docs/SECRET-MANAGEMENT.md`) — documents the 7-lesson interactive token/secret management tutorial. + +### Fixed + +- **`MASTER-DISPATCHER-GUIDE.md` `claude` section** — was stale at checks C1-C6 since v7.13.0 shipped C7-C11 and the `flow claude watch` daemon (PR #475); synced synopsis, check table, exit codes, and dependencies. + +### Changed + +- **Homepage (`docs/index.md`) reorganized for scan-ability** — the flat 8-card "Next Steps" grid is now three labeled clusters ("New here?" / "Solve a specific problem" / "Already using it?"); surfaced `setup`, `tutorial`, `ref`, and the new Workflow Cookbook, none of which were linked from the homepage; trimmed the "What's New" admonition from 5 dense bullets to 2 headline items + a changelog pointer. + ## [7.14.0] — 2026-07-02 — planning-coordination: shared accessors + dark-ready atlas agenda + .STATUS enforcer ### Added diff --git a/docs/SECRET-MANAGEMENT.md b/docs/SECRET-MANAGEMENT.md index 70dd981ab..95d955d1d 100644 --- a/docs/SECRET-MANAGEMENT.md +++ b/docs/SECRET-MANAGEMENT.md @@ -166,6 +166,40 @@ $ sec list ℹ Usage: sec ``` +## Interactive Tutorial (`sec tutorial`) + +New to token and secret management? `sec tutorial` runs an interactive, ADHD-friendly walkthrough — 7 lessons, each with a real (but safe) example, plus progress tracking so you can stop and resume. + +```bash +sec tutorial +``` + +**Estimated time:** 10-15 minutes. + +### Safe Demo Mode + +The tutorial creates a **fake** demo token (`demo-github-token`, value `ghp_DEMO_TOKEN_NOT_REAL_...`) in Keychain to practice with — no real GitHub/npm/PyPI token is ever created or contacted. The demo token is deleted again in the final lesson. + +### The 7 Lessons + +| # | Lesson | Covers | +|---|--------|--------| +| 1 | **Introduction** | What the tutorial teaches, prerequisites (flow-cli, Bitwarden CLI, Keychain access), estimated time | +| 2 | **Architecture Overview** | Dual-storage model — Bitwarden (cloud sync, source of truth) + Keychain (instant, Touch ID cache); the metadata JSON format; why the `-j` flag is safe to read without a Touch ID prompt | +| 3 | **Adding a Token (Demo)** | Walks through `sec add`, then actually stores the fake demo token in Keychain so you can see a real `security add-generic-password` call succeed (or the Accessibility-permission fix if it fails) | +| 4 | **Retrieving Tokens** | `sec ` usage patterns — exporting as an env var, `gh auth login --with-token`, `curl` auth headers, `npm config set` — then retrieves the demo token live | +| 5 | **Checking Expiration** | How `tok expiring` reads the Keychain metadata (no Touch ID needed) to compute token age; computes and prints the demo token's age | +| 6 | **Rotating Tokens** | What `tok rotate` does end to end — backup, browser handoff to the provider's token-creation page, validation, dual-backend update, manual revoke-old-token step. Explained only; the fake demo token is not rotated | +| 7 | **Cleanup & Best Practices** | Deletes the demo token (`sec delete`), then reviews token hygiene, Keychain security, Bitwarden security, and automation patterns (`tok expiring --quiet`, `export TOKEN=$(sec )`, monthly `sec list` audits) | + +### Progress Tracking + +Progress is stored as JSON in `~/.flow/tutorial-secret-state.json` (`completed_steps`, `current_step`, `started`, `last_accessed`). Each run walks all 7 steps in order top to bottom; the conclusion screen reports how many of the 7 you've completed so far and offers to reset progress interactively. + +At the end, the tutorial prints next steps: create a real token (`tok github`), set a 90-day rotation reminder, and pointers to the full guide (`docs/guides/TOKEN-MANAGEMENT-COMPLETE.md`) and quick reference (`docs/reference/REFCARD-TOKEN-SECRETS.md`). + +--- + ## Using Secrets in Chezmoi Templates Chezmoi supports Bitwarden integration natively. Your secrets can be used in templates. diff --git a/docs/commands/ref.md b/docs/commands/ref.md new file mode 100644 index 000000000..93091936f --- /dev/null +++ b/docs/commands/ref.md @@ -0,0 +1,103 @@ +# ref + +> Quick-reference card viewer for commands and workflows + +The `ref` command displays flow-cli's quick-reference cards directly in your terminal — no need to open a browser or find the docs directory. It renders `docs/reference/COMMAND-QUICK-REFERENCE.md` or `docs/reference/WORKFLOW-QUICK-REFERENCE.md` using the best available viewer (`bat`, `glow`, or `less`). + +--- + +## Usage + +```bash +ref [type] +``` + +## Commands + +| Command | Alias | Description | +| -------------------- | ---------------- | ------------------------------------- | +| `ref` / `ref command` | `ref cmd`, `ref c` | Show command quick reference (default) | +| `ref workflow` | `ref work`, `ref w` | Show workflow quick reference | +| `ref help` | `-h` | Show help | + +Any unrecognized argument falls back to the command reference (the default). + +--- + +## Examples + +### Command Reference (Default) + +```bash +# Quick lookup of all commands +ref + +# Same, explicit +ref command +ref cmd +ref c +``` + +### Workflow Reference + +```bash +# See common workflows +ref workflow +ref work +ref w +``` + +### Help + +```bash +ref help +ref -h +``` + +--- + +## How It Resolves the Reference File + +`ref` locates the flow-cli plugin root via `$FLOW_PLUGIN_DIR` (falling back to the script's own location if unset), then reads: + +- `docs/reference/COMMAND-QUICK-REFERENCE.md` — for `command`/`cmd`/`c` (and the default) +- `docs/reference/WORKFLOW-QUICK-REFERENCE.md` — for `workflow`/`work`/`w` + +If the resolved file doesn't exist, `ref` prints an error with the full path it looked for and returns a non-zero exit code. + +--- + +## Display Tool Fallback + +`ref` picks the best available renderer, in this order: + +1. **`bat`** — syntax-highlighted, paged (`--style=plain --paging=always --language=markdown`) +2. **`glow`** — rendered markdown (`glow -p`) +3. **`less`** — plain paging of the raw file +4. **`cat`** — last resort if `less` isn't available either + +No extra configuration needed — install `bat` or `glow` via Homebrew for a nicer view; `ref` works without either. + +--- + +## Related Commands + +| Command | Description | +| ------------------------ | -------------------------------- | +| `flow help` | Full help system | +| ` help` | Command-specific help | +| [`dash`](dash.md) | Project dashboard | +| [`doctor`](doctor.md) | System-wide health check | + +--- + +## See Also + +- [Master Dispatcher Guide](../reference/MASTER-DISPATCHER-GUIDE.md) +- `docs/reference/COMMAND-QUICK-REFERENCE.md` +- `docs/reference/WORKFLOW-QUICK-REFERENCE.md` + +--- + +**Last Updated:** 2026-07-02 +**Status:** Implemented in `commands/ref.zsh` diff --git a/docs/commands/setup.md b/docs/commands/setup.md new file mode 100644 index 000000000..d643d5730 --- /dev/null +++ b/docs/commands/setup.md @@ -0,0 +1,131 @@ +# setup + +> Interactive first-time setup wizard + +The `setup` command walks you through getting flow-cli fully configured — checking for recommended tools, offering to install anything missing, and verifying core environment variables. It's the ADHD-friendly on-ramp for new installs. + +--- + +## Usage + +```bash +setup [option] +``` + +## Options + +| Option | Description | +| ------------- | ------------------------------------- | +| *(none)* | Interactive wizard (default) | +| `-q, --quick` | Quick non-interactive install | +| `-f, --full` | Full setup with all options | +| `-h, --help` | Show help | + +**Alias:** `flow-setup` (same as `setup`) + +--- + +## Examples + +```bash +# Interactive wizard +setup + +# Auto-install everything, no prompts +setup --quick + +# Full setup + optional extras +setup --full + +# Help +setup --help +``` + +--- + +## Interactive Mode (default) + +`setup` (no arguments) runs a four-step wizard: + +### Step 1 — Health Check + +Checks for six recommended CLI tools: `fzf`, `eza`, `bat`, `fd`, `rg` (ripgrep), `zoxide`. If all are already installed, the wizard exits early with a success message and suggests running `dash`. + +### Step 2 — Install Tools (only if tools are missing) + +Presents three choices: + +1. **Install all recommended tools (Homebrew)** — runs `brew bundle` against `setup/Brewfile` if present, otherwise installs each missing tool individually via `brew install`. +2. **Choose which tools to install** — walks through each of the six tools one at a time, showing what's already installed and prompting `y/N` to install what's missing. +3. **Skip for now** — leaves tools as-is; you can re-run `setup` anytime. + +If Homebrew itself isn't installed, `setup` reports that and shows the official install command instead of attempting to install tools. + +### Step 3 — Configuration + +Checks two things and reports pass/fail for each: + +- `$FLOW_PROJECTS_ROOT` is set (shows the export line to add to `.zshrc` if not) +- flow-cli is actually loaded (checks `$FLOW_PLUGIN_LOADED` and reports the version) + +### Step 4 — Next Steps + +Prints a short list of commands to try next: `dash`, `work `, `doctor`, `flow help`. + +--- + +## Quick Mode (`--quick` / `-q`) + +Skips all prompts and runs `doctor --fix -y` directly — the non-interactive equivalent of "just fix everything you can." + +```bash +setup --quick +``` + +--- + +## Full Mode (`--full` / `-f`) + +Runs the full interactive wizard (Steps 1–4 above), then shows an additional "Additional Configuration" section listing optional integrations: + +- `npm install -g @data-wise/atlas` — enhanced state management +- `pip install radian` — better R console + +```bash +setup --full +``` + +--- + +## What Gets Installed + +| Tool | Purpose | +| --------- | ---------------------------------------------------- | +| `fzf` | Fuzzy finder (**required** for the project picker) | +| `eza` | Modern `ls` replacement (prettier file listings) | +| `bat` | `cat` with syntax highlighting | +| `fd` | Fast `find` replacement | +| `ripgrep` | Fast `grep` replacement (binary: `rg`) | +| `zoxide` | Smart `cd` with history | + +--- + +## Related Commands + +| Command | Description | +| ------------------------ | ------------------------------------ | +| [`doctor`](doctor.md) | System-wide health check | +| [`tutorial`](tutorial.md) | Interactive hands-on tutorial | +| [`dash`](dash.md) | Project dashboard | +| [`work`](work.md) | Start a focused work session | + +--- + +## See Also + +- [Master Dispatcher Guide](../reference/MASTER-DISPATCHER-GUIDE.md) + +--- + +**Last Updated:** 2026-07-02 +**Status:** Implemented in `commands/setup.zsh` diff --git a/docs/commands/tutorial.md b/docs/commands/tutorial.md new file mode 100644 index 000000000..19cdab3d0 --- /dev/null +++ b/docs/commands/tutorial.md @@ -0,0 +1,137 @@ +# tutorial + +> Interactive, hands-on flow-cli tutorial with progress tracking + +The `tutorial` command teaches flow-cli step by step through three graduated levels — Beginner, Medium, and Advanced. Each lesson explains a command, shows an example, and (for some lessons) offers to run it live. Progress is saved so you can stop and resume later. + +--- + +## Usage + +```bash +tutorial [level|action] +``` + +**Alias:** `tut` (same as `tutorial`) + +## Levels + +| Level | Covers | +| ----------- | --------------------------------------------------------------- | +| `beginner` (or `1`) | Core workflow: `pick`, `work`, `dash`, `finish` | +| `medium` (or `2`) | Productivity tools: `catch`/`crumb`, `status`, `timer`, ADHD helpers | +| `advanced` (or `3`) | Power features: Atlas integration, smart dispatchers, customization, `morning` | + +## Actions + +| Action | Description | +| ----------- | -------------------------------------- | +| `reset` | Reset progress and start over | +| `progress` | Show current progress | +| `help` / `--help` / `-h` | Show help | + +--- + +## Examples + +```bash +# Start from wherever you left off (or the beginning, if never run) +tutorial + +# Jump straight to a specific level +tutorial beginner +tutorial medium +tutorial advanced + +# Check where you are +tutorial progress + +# Start completely fresh +tutorial reset + +# Help +tutorial help +``` + +--- + +## Auto-Resume Behavior + +Running `tutorial` with no arguments checks your saved progress and picks up where you left off: + +| Saved progress | What runs next | +| --------------- | -------------------- | +| *(none / `0`)* | Beginner lessons | +| `beginner` | Medium lessons | +| `medium` | Advanced lessons | +| `advanced` | Prints a "you've completed everything" message with options to reset or revisit a level | + +At the end of each level, the tutorial asks `y/n` whether to continue straight into the next level. + +--- + +## Beginner Lessons + +1. **`pick`** — interactive project picker (fzf-based; filter, Ctrl-S for `.STATUS`, Ctrl-L for git log) +2. **`work`** — start a focused work session (cd + context + session timer) +3. **`dash`** — project dashboard (git status, `.STATUS` contents, active tasks) +4. **`finish`** — end the session cleanly (optional commit, duration recorded, note prompt) + +Some lessons offer to run the real command (e.g., `pick --help`, `dash`) if you answer `y` to the prompt. + +## Medium Lessons + +1. **`catch`/`crumb`** — quick capture of ideas without breaking flow; also covers `inbox` and `win` +2. **`status`** — manage `.STATUS` files (`status`, `status set X`, `status next X`, `status all`) +3. **`timer`** — Pomodoro-style focus timers (`timer 25`, `timer status`, `timer stop`, `brk [mins]`) +4. **ADHD helpers** — `js` (Just Start), `stuck`, `focus `, `next`, `why` + +## Advanced Lessons + +1. **Atlas integration** — optional state engine (`npm install -g @data-wise/atlas`, `atlas status`) +2. **Smart dispatchers** — `g`, `v`, `mcp`, `obs` (context-aware shortcuts per project type) +3. **Customization** — key environment variables (`FLOW_PROJECTS_ROOT`, `FLOW_ATLAS_ENABLED`, `FLOW_LOAD_DISPATCHERS`, `FLOW_QUIET`) and config/data locations (`~/.config/flow/`, `~/.local/share/flow/`) +4. **Morning routine** — the `morning` command (inbox review, active project statuses, suggested first task) + +--- + +## Progress Tracking + +Progress is stored as a single plain-text marker in: + +```text +${FLOW_DATA_DIR:-$HOME/.local/share/flow}/tutorial-progress +``` + +The file contains one of: `0` (not started), `beginner`, `medium`, or `advanced` — whichever level you most recently completed. + +```bash +tutorial progress +# 📊 Tutorial Progress: medium +# Status: Medium complete, ready for Advanced +``` + +`tutorial reset` deletes this file, returning you to the very beginning. + +--- + +## Related Commands + +| Command | Description | +| ------------------------ | ------------------------------------ | +| [`setup`](setup.md) | Interactive first-time setup wizard | +| [`pick`](pick.md) | Interactive project picker | +| [`work`](work.md) | Start a focused work session | +| [`dash`](dash.md) | Project dashboard | +| [`timer`](timer.md) | Focus and break timer | + +--- + +## See Also + +- [Master Dispatcher Guide](../reference/MASTER-DISPATCHER-GUIDE.md) + +--- + +**Last Updated:** 2026-07-02 +**Status:** Implemented in `commands/tutorial.zsh` diff --git a/docs/guides/TESTING.md b/docs/guides/TESTING.md index 1847ea2c2..7051446ea 100644 --- a/docs/guides/TESTING.md +++ b/docs/guides/TESTING.md @@ -23,8 +23,8 @@ flow-cli uses a **shared test framework** (`tests/test-framework.zsh`) with comp | Metric | Count | |--------|-------| -| Test files | 219 | -| Test suites (run-all.sh) | 67 total — 66 passed, 1 skipped, 0 failed | +| Test files | 231 | +| Test suites (run-all.sh) | 76 total — 75 passed, 1 skipped, 0 failed | | Test functions | 12,000+ | | Expected skips | 1 (`e2e-em-dispatcher` — needs configured IMAP account) | | CI | runs the full suite on every PR (green on the Ubuntu runner) | @@ -408,4 +408,4 @@ When adding new functionality: **Established:** v5.0.0 (2026-01-11) **Overhauled:** v7.4.0 (2026-02-16) — shared framework, mock registry, dogfood scanner -**Test Count:** 219 test files, 12000+ assertions, 67/67 suites passing +**Test Count:** 231 test files, 12000+ assertions, 75/75 suites passing (1 skipped — tool absence) diff --git a/docs/guides/WORKFLOW-COOKBOOK.md b/docs/guides/WORKFLOW-COOKBOOK.md new file mode 100644 index 000000000..f42c9fb28 --- /dev/null +++ b/docs/guides/WORKFLOW-COOKBOOK.md @@ -0,0 +1,317 @@ +# Workflow Cookbook — Daily & Weekly flow-cli Recipes + +> Copy-paste routines for the two cadences flow-cli is built around: the daily loop and the +> weekly review. +> +> **Version:** v7.15.0 | **Last Updated:** 2026-07-02 + +Each recipe follows the same structure: **When** — **Commands** — **Why**. +For full command reference see [`docs/help/QUICK-REFERENCE.md`](../help/QUICK-REFERENCE.md) and +[`docs/reference/MASTER-DISPATCHER-GUIDE.md`](../reference/MASTER-DISPATCHER-GUIDE.md). + +!!! tip "Interactive version" + This cookbook also exists as a click-through walkthrough — a Daily/Weekly toggle, a + step-by-step card per recipe, and a big-picture panel showing both loops as ring diagrams so + you can see where a step sits in the overall cycle. It was generated as a Claude Artifact + during the session that authored this doc; regenerate it by asking Claude to rebuild the + interactive workflow cookbook from this file if the link has expired. + +--- + +## The Two Cadences at a Glance + +```mermaid +flowchart TD + subgraph Daily["🌅 Daily Loop"] + direction TB + M["morning
inbox, active projects, yesterday's wins"] + A1["agenda
next 7 days + overdue"] + P["pick / work <project>
choose + start session"] + D["dash
check status mid-session"] + T["timer 25
focus block, optional"] + W["win "..."
log a dopamine hit"] + F["finish [note]
end session, optional commit"] + M --> A1 --> P --> D + D --> T --> D + D --> W --> F + end + + subgraph Weekly["📅 Weekly Review"] + direction TB + AW["agenda -w
full week forward view"] + DS["dash
status sweep across all projects"] + WT["wt status / wt prune
worktree health + cleanup"] + SY["g sync
dev ⇄ main drift check"] + YY["yay --week
weekly wins summary"] + DR["doctor
environment health check"] + AW --> DS --> WT --> SY --> YY --> DR + end + + F -.->|"Fri / end of week"| AW + + style Daily fill:#1a1a2e,stroke:#4a90d9,color:#fff + style Weekly fill:#2e1a1a,stroke:#d97a4a,color:#fff +``` + +--- + +## Table of Contents + +**Daily** + +- [1. Morning Startup](#1-morning-startup) +- [2. Picking What to Work On](#2-picking-what-to-work-on) +- [3. Starting a Focused Session](#3-starting-a-focused-session) +- [4. Mid-Session Check-In](#4-mid-session-check-in) +- [5. Focus Blocks with the Timer](#5-focus-blocks-with-the-timer) +- [6. Logging Wins](#6-logging-wins) +- [7. Ending the Session](#7-ending-the-session) + +**Weekly** + +- [8. Weekly Forward Look](#8-weekly-forward-look) +- [9. Full Project Status Sweep](#9-full-project-status-sweep) +- [10. Worktree Health and Cleanup](#10-worktree-health-and-cleanup) +- [11. Branch Sync Check](#11-branch-sync-check) +- [12. Weekly Wins Review](#12-weekly-wins-review) +- [13. Environment Health Check](#13-environment-health-check) + +--- + +## Daily + +### 1. Morning Startup + +**When:** First terminal session of the day, before picking any specific task. + +**Commands:** + +```zsh +morning +``` + +**Why:** Reduces decision fatigue at the start of the day — one command shows your inbox, active +projects, yesterday's wins, and suggests what to work on, instead of you reconstructing context +from memory. See [`docs/commands/morning.md`](../commands/morning.md). + +--- + +### 2. Picking What to Work On + +**When:** `morning` gave you a suggestion but you want to browse, or you're returning +mid-day and need to switch projects. + +**Commands:** + +```zsh +pick # interactive fzf picker across all projects +# or, if you already know the project: +work +``` + +**Why:** `pick` is the ADHD-friendly "just show me the list" fallback when the suggested project +isn't the right one — filterable, with `.STATUS`/git-log previews inline so you don't have to +`cd` around to remember what a project is. + +--- + +### 3. Starting a Focused Session + +**When:** You've chosen a project and are ready to work. + +**Commands:** + +```zsh +work # cd + context + session timer, no editor +work -e # same, plus opens $EDITOR +``` + +**Why:** `work` bundles the context-switch cost — `cd`, reading `.STATUS`, starting a session +timer — into one command so switching projects mid-day doesn't cost you the 2-3 minutes of manual +orientation each time. + +--- + +### 4. Mid-Session Check-In + +**When:** You've been heads-down and want a quick "where am I" without breaking flow, or you're +about to context-switch and want to leave a clean marker. + +**Commands:** + +```zsh +dash # full dashboard: git status, .STATUS, active tasks +status # just the .STATUS summary for the current project +``` + +**Why:** `dash` is a zero-typing snapshot — no need to run `git status` + open `.STATUS` + check +task lists separately. + +--- + +### 5. Focus Blocks with the Timer + +**When:** You want Pomodoro-style structure inside a work session — optional, use only if timeboxing helps. + +**Commands:** + +```zsh +timer 25 # start a 25-minute focus block +timer status # check remaining time +brk 5 # 5-minute break timer +timer stop # cancel early +``` + +**Why:** External time pressure reduces the "how long have I actually been doing this" ADHD blind +spot — the timer notifies you rather than requiring you to self-monitor. + +--- + +### 6. Logging Wins + +**When:** Any time you complete something, however small — don't wait for "big" accomplishments. + +**Commands:** + +```zsh +win "Fixed the flaky test" +yay # show recent wins (dopamine hit) +``` + +**Why:** Auto-categorized progress logging — the `yay` feedback loop is deliberately immediate and +cheap to trigger, which is the point (see +[`docs/guides/DOPAMINE-FEATURES-GUIDE.md`](DOPAMINE-FEATURES-GUIDE.md)). + +--- + +### 7. Ending the Session + +**When:** Wrapping up for the day, or switching to a different project. + +**Commands:** + +```zsh +finish # end session, no commit +finish "short note" # end session + optional commit prompt with note +``` + +**Why:** Closes the loop cleanly — records session duration, prompts for a commit if there are +uncommitted changes, so the next `morning` or `work` has an accurate "yesterday's activity" to +show you. + +--- + +## Weekly + +### 8. Weekly Forward Look + +**When:** Start of the week, or Friday planning-ahead — before diving into daily work. + +**Commands:** + +```zsh +agenda -w # next 7 days + overdue, across all projects +agenda --month # next 30 days if you need to plan further out +``` + +**Why:** `agenda` is flow-cli's forward-looking layer (as opposed to `dash`/`morning`, which are +present/backward-looking) — surfaces deadlines, due dates, and milestones that live in project +configs, not in your head. See +[`docs/guides/AGENDA-SCHEDULE-GUIDE.md`](AGENDA-SCHEDULE-GUIDE.md). + +--- + +### 9. Full Project Status Sweep + +**When:** Weekly review — checking every active project, not just the one you're in. + +**Commands:** + +```zsh +dash # from any project root — shows cross-project view +dash -i # interactive fzf picker over the dashboard +``` + +**Why:** Catches projects that have gone stale (`.STATUS` says "active" but no recent commits) or +projects whose `Progress`/`Focus` fields are out of date — the kind of drift that's invisible day +to day but obvious on a weekly zoom-out. + +--- + +### 10. Worktree Health and Cleanup + +**When:** Weekly — worktrees accumulate from feature work across the week and need pruning. + +**Commands:** + +```zsh +wt status # disk usage, merge status, session tracking per worktree +wt prune --dry-run # preview what would be cleaned +wt prune # remove merged worktrees +wt prune -b # also delete the now-merged branches +``` + +**Why:** Stale worktrees silently consume disk and clutter `git worktree list` output; `wt prune` +only removes worktrees whose branch is actually merged, so it's safe to run routinely rather than +only when you notice the clutter. + +--- + +### 11. Branch Sync Check + +**When:** Weekly, for any repo using the multi-branch pattern (`main` ← `dev` ← `feature/*`) — to +catch drift before it compounds. + +**Commands:** + +```zsh +g sync # smart sync check against remote +``` + +**Why:** Catches `dev` falling behind `main` (or vice versa) early — a weekly check is cheap; +discovering drift mid-release is not. + +--- + +### 12. Weekly Wins Review + +**When:** End of week — a reflective pass, not just a productivity metric. + +**Commands:** + +```zsh +yay --week # weekly summary + graph +flow goal set 3 # (re)set daily win target for the coming week if it's not fitting +``` + +**Why:** Turns the day-to-day `win` logging into a shape you can actually reflect on — useful both +for morale (ADHD-friendly positive reinforcement) and for spotting which days/projects are +consistently low-output. + +--- + +### 13. Environment Health Check + +**When:** Weekly, or any time something feels "off" (a dispatcher misbehaves, Claude Code seems +to have stale context). + +**Commands:** + +```zsh +flow doctor # dependency + tool health +flow doctor --fix # interactive install of missing tools +flow claude check # Claude Code environment health (C1-C11) +``` + +**Why:** Cheaper to catch configuration drift (missing tools, stale hooks, Homebrew keg drift) on +a weekly cadence than to debug it reactively when it blocks actual work. + +--- + +## See Also + +- [`docs/help/QUICK-REFERENCE.md`](../help/QUICK-REFERENCE.md) — full command reference +- [`docs/reference/MASTER-DISPATCHER-GUIDE.md`](../reference/MASTER-DISPATCHER-GUIDE.md) — all 14 dispatchers +- [`docs/guides/AGENDA-SCHEDULE-GUIDE.md`](AGENDA-SCHEDULE-GUIDE.md) — the forward-looking layer in depth +- [`docs/guides/DOPAMINE-FEATURES-GUIDE.md`](DOPAMINE-FEATURES-GUIDE.md) — `win`/`yay`/`js` design rationale +- [`docs/commands/work.md`](../commands/work.md), [`morning.md`](../commands/morning.md), [`finish.md`](../commands/finish.md), [`dash.md`](../commands/dash.md) diff --git a/docs/index.md b/docs/index.md index acd50fb19..671d3186c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,14 +26,14 @@ tags: ``` **That's it!** No configuration required. -!!! success "🎉 What's New in v7.14.0" - **Agenda now spans three data sources.** Alongside `.STATUS` `## Schedule:` blocks and teaching dates, the engine gained a third, capability-probed source for atlas-tracked deadlines (`Task.dueDate`) — shipped **dark-ready** (tested, silent no-op until an atlas release implements the `agenda` command; see the [Atlas Contract](ATLAS-CONTRACT.md)). - **De-duplicated planning internals:** `dash`, `morning`, `next`, `capture`, and `agenda` now share one `.STATUS` field accessor, one project-path resolver, and one project-suggestion scan instead of five divergent implementations — plus a fix for a bug that silently blanked focus/progress/icon for every project. - **New `.STATUS` schema checker:** `templates/.STATUS.template` + a warn-only `check-status.zsh` pre-commit validator (prints violations, never blocks). - **74 suites** passing (245 files, 12000+ assertions). - [→ Agenda & Schedule Guide](guides/AGENDA-SCHEDULE-GUIDE.md){ .md-button .md-button--primary } - [→ Atlas Contract](ATLAS-CONTRACT.md){ .md-button } - [→ Changelog](CHANGELOG.md){ .md-button } + **New here?** `setup` walks you through configuration interactively, or run `tutorial` for + 12 hands-on lessons at your own pace — both are guided, no docs required to start. + +!!! success "🎉 What's New in v7.15.0" + **`doctor` now catches Homebrew distribution failures** — opt/Cellar symlink drift, stale kegs, and man-page collisions that silently break `brew upgrade`. + **Doc gaps filled** — `ref`, `setup`, `tutorial` now have full command docs, plus a new [Daily & Weekly Cookbook](guides/WORKFLOW-COOKBOOK.md). + Full details → [Changelog](CHANGELOG.md). + [→ Cookbook](guides/WORKFLOW-COOKBOOK.md){ .md-button .md-button--primary } --- @@ -144,7 +144,9 @@ flow goal # Daily progress (🌱🔥🔥🔥 streaks!) ## 🧭 Next Steps -Choose your path based on what you need right now: +Three questions, pick the one that matches where you are — not eight options at once. + +### 🆕 New here?
@@ -157,12 +159,21 @@ Choose your path based on what you need right now: [→ Quick Start](getting-started/quick-start.md) +- :wrench:{ .lg .middle } + **Interactive Setup Wizard** + + --- + + Guided configuration — run `setup` in your terminal + + [→ Setup Command](commands/setup.md) + - :books:{ .lg .middle } **Step-by-Step Tutorials** --- - 30-minute guided learning path + 12 hands-on lessons — run `tutorial`, or read online [→ Tutorial 01](tutorials/01-first-session.md) @@ -171,10 +182,16 @@ Choose your path based on what you need right now: --- - Win tracking, streaks, goals + How the win/streak/goal loop works [→ Dopamine Guide](tutorials/06-dopamine-features.md) +
+ +### 🔧 Solve a specific problem + +
+ - :email:{ .lg .middle } **Email Management** @@ -195,15 +212,6 @@ Choose your path based on what you need right now: [→ Token Cookbook](guides/TOKEN-COOKBOOK.md) · [→ Auto-sync Tutorial](tutorials/47-tok-auto-sync.md) -- :compass:{ .lg .middle } - **Command Reference** - - --- - - Quick lookup for all commands - - [→ Reference](help/QUICK-REFERENCE.md) - - :teacher:{ .lg .middle } **Teaching Workflow** @@ -224,6 +232,30 @@ Choose your path based on what you need right now:
+### 📚 Already using it? Look something up + +
+ +- :compass:{ .lg .middle } + **Command Reference** + + --- + + Quick lookup for all commands — also try `ref` in your terminal + + [→ Reference](help/QUICK-REFERENCE.md) + +- :calendar:{ .lg .middle } + **Daily & Weekly Cookbook** + + --- + + Copy-paste routines for the two cadences flow-cli is built around + + [→ Cookbook](guides/WORKFLOW-COOKBOOK.md) + +
+ --- ## 🔌 Command Architecture @@ -262,6 +294,7 @@ hop # Quick switch (tmux) dash # Dashboard (what's happening now) agenda # What's due soon (deadlines, exams, milestones) catch "idea" # Quick capture +ref # Quick-reference card (forgot the syntax? this is faster than docs) ``` [→ All commands](help/QUICK-REFERENCE.md){ .md-button } @@ -293,4 +326,4 @@ catch "idea" # Quick capture --- -**v7.14.0** · Pure ZSH · Zero Dependencies · MIT License +**v7.15.0** · Pure ZSH · Zero Dependencies · MIT License diff --git a/docs/reference/MASTER-DISPATCHER-GUIDE.md b/docs/reference/MASTER-DISPATCHER-GUIDE.md index 86b179991..f332e9ad3 100644 --- a/docs/reference/MASTER-DISPATCHER-GUIDE.md +++ b/docs/reference/MASTER-DISPATCHER-GUIDE.md @@ -3132,12 +3132,16 @@ The `flow claude` command inspects the Claude Code environment for configuration ### Synopsis ```bash -flow claude check # Run all 6 checks, print report +flow claude check # Run all 11 checks, print report flow claude check --fix # Run checks + auto-repair C1 and C6 flow claude doctor # Alias for check +flow claude watch # Start background health daemon (notifies on change) +flow claude watch --interval N # Poll every N seconds (default: 60) +flow claude watch --stop # Stop the daemon +flow claude watch --status # Show daemon state and last check result ``` -### Checks (C1–C6) +### Checks (C1–C11) | ID | Name | Logic | Severity | `--fix` | |----|------|-------|----------|---------| @@ -3147,6 +3151,17 @@ flow claude doctor # Alias for check | C4 | CLAUDE.md length | `~/.claude/CLAUDE.md` ≤ 100 lines | WARN | ✗ | | C5 | Shell env parity | `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE` exported in shell | INFO | ✗ | | C6 | Output token limit | `CLAUDE_CODE_MAX_OUTPUT_TOKENS` set and > 8192 | WARN | ✓ | +| C7 | Per-project CLAUDE.md | Scans `$FLOW_CLAUDE_PROJECTS_ROOT` (depth 4); warns on >180 lines or stale version refs | WARN | ✗ | +| C8 | Orphaned memory dirs | Decodes each memory slug back to a filesystem path; warns if the project no longer exists | WARN | ✗ | +| C9 | Rules drift | Every `~/.claude/rules/*.md` stem must appear in main `~/.claude/CLAUDE.md` | WARN | ✗ | +| C10 | Missing hook files | Parses `settings.json` hook commands; errors on absent absolute-path scripts | ERROR | ✗ | +| C11 | Plugin health | Checks `~/.claude/plugins/*/plugin.json` exists and is valid JSON (skips `cache/`) | WARN | ✗ | + +`flow claude watch` runs `flow claude check` on a schedule in the background and sends desktop +notifications on status change (via `terminal-notifier` when available). See +[commands/claude.md](../commands/claude.md#watch-daemon) and +[tutorials/49-flow-claude-check.md](../tutorials/49-flow-claude-check.md) for the daemon's state +files, PID handling, and full worked examples. ### `--fix` Behavior @@ -3167,7 +3182,7 @@ flow claude check --fix | Code | Meaning | |------|---------| | 0 | All checks pass | -| 1 | Any ERROR (C2) | +| 1 | Any ERROR (C2, C10) | | 2 | Any WARN, no ERRORs | ### Source of Truth @@ -3176,8 +3191,9 @@ flow claude check --fix ### Dependencies -- `jq` — required for C1/C6 JSON parsing; degrades gracefully if absent +- `jq` — required for C1/C6/C10 JSON parsing; degrades gracefully if absent - `shellcheck` — optional for C2; skips lint sub-check if absent +- `terminal-notifier` — optional for `flow claude watch`; daemon runs, desktop notifications silently skipped if absent **Reference:** [commands/claude.md](../commands/claude.md) diff --git a/docs/reference/REFCARD-DOCTOR.md b/docs/reference/REFCARD-DOCTOR.md index 4071c9095..a80bbc2bc 100644 --- a/docs/reference/REFCARD-DOCTOR.md +++ b/docs/reference/REFCARD-DOCTOR.md @@ -96,11 +96,20 @@ After each run, teach doctor writes `.flow/doctor-status.json`. The health dot s - `zsh` - Shell - `git` - Version control -### 2. Required Tools +### 2. Installation (Homebrew distribution health) + +- Homebrew opt/Cellar link integrity (installed-but-unlinked detection) +- Shell-loaded version vs. installed Cellar keg version drift +- flow-cli's own man pages resolving cleanly (vs. losing a case-insensitive + name collision to another formula) + +Skips silently for non-Homebrew installs (git-clone, plugin manager). + +### 3. Required Tools - `fzf` - Fuzzy finder -### 3. Recommended Tools +### 4. Recommended Tools - `eza` - Enhanced ls - `bat` - Enhanced cat @@ -108,7 +117,7 @@ After each run, teach doctor writes `.flow/doctor-status.json`. The health dot s - `fd` - Enhanced find - `rg` (ripgrep) - Enhanced grep -### 4. Optional Tools +### 5. Optional Tools - `dust` - Disk usage - `duf` - Disk free @@ -117,12 +126,12 @@ After each run, teach doctor writes `.flow/doctor-status.json`. The health dot s - `gh` - GitHub CLI - `jq` - JSON processor -### 5. Integrations +### 6. Integrations - `atlas` - State management - `radian` - R console (if R exists) -### 6. Email (conditional — when `em` loaded) +### 7. Email (conditional — when `em` loaded) - `himalaya` - Email CLI backend (required, version >= 1.0.0) - `w3m`/`lynx`/`pandoc` - HTML rendering (any-of, recommended) @@ -132,33 +141,33 @@ After each run, teach doctor writes `.flow/doctor-status.json`. The health dot s - `claude`/`gemini` - AI backend (conditional on `$FLOW_EMAIL_AI`) - Config summary: AI backend, timeout, page size, folder, config file -### 7. ZSH Plugin Manager +### 8. ZSH Plugin Manager Checks: - antidote/zinit/oh-my-zsh installed - Plugin bundle file -### 8. ZSH Plugins +### 9. ZSH Plugins - powerlevel10k - zsh-autosuggestions - zsh-syntax-highlighting - zsh-completions -### 9. flow-cli Status +### 10. flow-cli Status - Plugin loaded - Version - Atlas connection -### 10. GitHub Token +### 11. GitHub Token - Token configured - Token validity - Token expiration - Token-dependent services (gh CLI, Claude MCP) -### 11. Aliases +### 12. Aliases - Total alias count - Shadow detection diff --git a/docs/specs/BRAINSTORM-issue-423-stress-test-2026-07-02.md b/docs/specs/BRAINSTORM-issue-423-stress-test-2026-07-02.md new file mode 100644 index 000000000..9e70c7718 --- /dev/null +++ b/docs/specs/BRAINSTORM-issue-423-stress-test-2026-07-02.md @@ -0,0 +1,88 @@ +# BRAINSTORM: Issue #423 Stress Test vs. v7.14.0 — 2026-07-02 + +**Topic:** Stress test issue #423 ("Scholar Config Sync wiring + new teach wrappers") against the +latest release (v7.14.0) and existing flow-cli functions. + +**Method:** Read the issue body, grepped `teach-dispatcher.zsh` / `teach-doctor-impl.zsh` for every +deliverable listed, cross-checked against `git log --grep` for `#423`, then ran a live smoke test +of `teach config show` against the current tree. + +## Headline finding + +**Issue #423 is already fully shipped.** Every deliverable in its scope is implemented, tested, and +documented in the current `dev`/`main` tree. This is a stale/unclosed issue, not a gap. + +| Issue scope item | Status | Evidence | +|---|---|---| +| Auto-inject `--config .flow/teach-config.yml` on Scholar commands | ✅ Shipped | `teach-dispatcher.zsh:1379-1390` | +| Wire `_teach_find_config()` into command assembly | ✅ Shipped | same block, `config_path=$(_teach_find_config ...)` | +| Wire `_flow_config_changed()` stale-config warning | ✅ Shipped | `teach-dispatcher.zsh:1379` | +| Legacy deprecation warning (`.claude/teaching-style.local.md`) | ✅ Shipped | `teach-dispatcher.zsh:1385-1390`, `4144`, `4196` | +| `teach config check/diff/show/scaffold` | ✅ Shipped | `teach-dispatcher.zsh:4552-4558`; commit `89838aeaa` "(#423)" | +| `teach solution` / `teach sync` / `teach validate-r` | ✅ Shipped | `teach-dispatcher.zsh:4516-4524`; commit `5c812e05d` "(#423)" | +| Config sync status in `teach doctor` | ✅ Shipped | `_teach_doctor_config_sync()` in `teach-doctor-impl.zsh:1250` | +| Help output updates | ✅ Shipped | `_teach_doctor_help`, dispatcher help blocks reference all subcommands | +| MASTER-DISPATCHER-GUIDE.md updates | ✅ Shipped | lines 2681-2689 list all 7 new subcommands | +| SCHOLAR-INTEGRATION-GUIDE.md | ✅ Shipped | `docs/guides/SCHOLAR-INTEGRATION-GUIDE.md` exists | + +Three commits explicitly close the loop on this issue: +- `6b7e447e1` — "feat: wire --config injection to Scholar commands (#423)" +- `89838aeaa` — "feat: add teach config check/diff/show/scaffold subcommands (#423)" +- `5c812e05d` — "feat: add teach solution, sync, validate-r wrappers (#423)" +- `27b1b4256` — "fix: address PR review findings — config arg duplication, legacy path, ORCHESTRATE cleanup" + +## What the smoke test actually surfaced + +Ran `teach config show` live in this tree (no `.flow/teach-config.yml` present — this repo isn't a +teaching course project, so this is an expected cold-start path, not a course-configured one): + +``` +⚠️ teach: Config has validation issues +⚠️ teach: No 'scholar:' section in config — Scholar commands will use defaults +⚠️ teach: Config changed since last Scholar run — Run: teach config check +``` + +All three warnings are the *designed* degrade path working correctly — `_flow_config_changed` and +the legacy-config checks fired exactly as scoped in the issue. The wrapper then attempted to invoke +Scholar's `/teaching:config` slash command, which only resolves inside an actual Claude Code +session (not a bare zsh shell) — expected, not a bug: `_teach_scholar_wrapper` is designed to shell +out to the Claude Code CLI, which this raw-shell smoke test doesn't provide. + +## Genuine stale point in the issue text (not a code gap) + +The issue's "Prerequisites" line says *"Scholar plugin v2.2.0+ (installed)"*. Per this session's +memory and `CLAUDE.md`, Scholar has since split (as of Scholar v3.0.0): teaching-only content stays +in `scholar`, research moved to a new `savant` plugin. The `/teaching:*` slash commands this issue +wires against still live in `scholar`, so the integration itself is unaffected — but the +prerequisite line is now imprecise (doesn't mention the split) and could confuse a future reader +auditing this issue. + +## Quick Wins (< 30 min) + +1. **Close issue #423 with a comment linking the 3 implementing commits** — it's done; leaving it + open is a false backlog signal for anyone triaging. +2. **One-line update to the issue body's Prerequisites** (if not closing outright) — note the + Scholar v3.0.0 teaching/research split so the prerequisite doesn't mislead. + +## Medium Effort (1-2 hrs) + +- [ ] **Add an E2E fixture test** that runs `teach config show/check` inside a real Claude Code + session against `tests/fixtures/demo-course/` — the current test suite likely covers the zsh-side + wiring (arg assembly, warnings) but probably not the actual Scholar slash-command round trip, + since that requires the `claude` binary. Confirm coverage before assuming a gap. +- [ ] **Audit the other 4 open issues** (#359, #331, #298, #275) the same way — #298 "Teaching + config consolidation" in particular sounds adjacent to #423's scope and may also be + partially/fully subsumed by work already shipped in `teach-dispatcher.zsh`. + +## Long-term (future sessions) + +- [ ] **Add a lightweight "issue-vs-shipped" drift check** to the release checklist — grep merged + commit messages for `#` and flag open issues whose number appears in `git log` + as merged-but-still-open. Would have caught #423 automatically at v7.14.0 release time. + +## Recommended Next Step + +→ **Close #423** (Quick Win #1) — it's fully shipped, verified via 3 independent commit +cross-references and a live code read of every deliverable. This clears one of the 5 open issues +with zero implementation risk, and the drift-check idea (Long-term) is worth a one-line note in the +next `/craft:release` retro so it doesn't recur. diff --git a/docs/specs/PLAN-docs-gap-2026-07-02.md b/docs/specs/PLAN-docs-gap-2026-07-02.md new file mode 100644 index 000000000..20c1b4c31 --- /dev/null +++ b/docs/specs/PLAN-docs-gap-2026-07-02.md @@ -0,0 +1,55 @@ +# PLAN — flow-cli documentation gap & staleness analysis + +**Date:** 2026-07-02 · **Status:** Implemented — items 1–4 of "Recommended next steps" applied same session (`e9396bfca`). Item 5 (full remaining ~10-spec sweep) intentionally still out of scope, unstarted. +**Trigger:** post-v7.14.0-release audit (the cloud-agent routine that would have done this was created then disabled — see `.STATUS` — this plan supersedes it, done directly instead) + +## Method + +Checked, in order: `mkdocs build --strict`, full test suite reproduction, API-reference coverage for functions/features added in the last ~30 commits, spec-status accuracy (cross-referenced against CHANGELOG evidence of actual shipping), test-count references across docs vs. the real current count, and the CHANGELOG root/docs mirror (already fixed earlier this session). + +## Findings + +### Clean — no action needed + +| Check | Result | +|---|---| +| `mkdocs build --strict` | 0 warnings | +| Full suite reproduction | 74 passed, 0 failed, 0 timeout, 1 skipped — matches CLAUDE.md's stated count | +| API-reference coverage for this session's 4 new functions (`_flow_status_field`, `_flow_resolve_project_path`, `_flow_suggest_project`, `_schedule_atlas_items`) | all documented (Phase 4 of the planning-coordination work) | +| `tok mint` dispatcher-guide coverage | documented (10 references in `MASTER-DISPATCHER-GUIDE.md`) | +| `flow claude` C7–C11 checks documented | 12 references in `docs/commands/claude.md` | +| `SPEC-agenda-schedule-2026-06-13.md` status | correctly `Implemented` (table-format status line — my first grep pattern missed it, false alarm on my end, not a real gap) | +| CHANGELOG root/docs mirror | identical (fixed earlier this session) | + +### Real gaps found + +**1. `docs/guides/TESTING.md` is significantly stale.** +Line 411: `**Test Count:** 219 test files, 12000+ assertions, 67/67 suites passing` — actual current state is **74/74 suites passing** (per `run-all.sh`'s own count) on **230 raw `.zsh` files** under `tests/`. This number has been stale across at least 2 releases (the last update I can find bumped 217→219, well before the 74-suite count existed). + +**2. Test-file count itself needs a defined methodology, not just a bump.** +CLAUDE.md currently states **245** test files (set in this session's own Phase 4 commit), but a raw `find tests -name "*.zsh" -type f` count is **230**. `run-all.sh` registers **75** `run_test` calls (74 pass + 1 skip). Three different numbers for "how many tests" (230 files / 75 registered suites / 245 claimed) — the 245 figure looks like an overcount introduced this session, not verified against a `find` at the time. **Recommend:** pick one canonical definition (I'd recommend "registered suites" = the `run_test` count, since that's what `run-all.sh`'s own summary line reports and what a reader actually experiences), state it explicitly in both CLAUDE.md and TESTING.md, and correct both to match. Do not just bump the number again without fixing the counting method, or this recurs at the next release. + +**3. At least 5 specs in `docs/specs/` are marked `Status: draft` despite their features having clearly shipped** (confirmed via CHANGELOG hits, not assumption): +- `SPEC-teach-doctor-v2-2026-02-07.md` — draft; CHANGELOG has 6 "teach doctor" hits +- `SPEC-teach-deploy-v2-2026-02-03.md` — draft; CHANGELOG has 8 "teach deploy" hits +- `SPEC-teach-plan-v2-2026-01-29.md` — draft; CHANGELOG has 1+ "teach plan" hits (worth a closer look — lower confidence than the other four) +- `SPEC-em-v2-2026-02-26.md` — draft; CHANGELOG has 8 "em v2" hits +- `SPEC-dot-rename-split-2026-02-14.md` — draft; CHANGELOG has the "Dispatcher split" entry (`dot` → `dots`/`sec`/`tok`, v7.1.0) + +**Not yet cross-checked** (lower-confidence candidates, same pattern, worth the same treatment): `SPEC-teach-map-2026-02-08.md`, `SPEC-himalaya-editor-plugin-2026-02-11.md` (already partially annotated as "partially-implemented" — may just need the annotation refreshed), `SPEC-latex-macros-2026-01-28.md`, `SPEC-testing-framework-2026-02-16.md` (no CHANGELOG hits found — could be genuinely still-draft, not stale; needs a feature-existence check, not a CHANGELOG grep, before concluding either way). + +**Out of scope for this pass:** the ~10 remaining "draft"/"proposal" specs not mentioned above were not individually checked — this plan prioritized specs with strong positive CHANGELOG evidence over an exhaustive sweep of all ~40 spec files. + +## Recommended next steps (not yet executed) + +1. Fix `docs/guides/TESTING.md`'s stale count (219/67 → current numbers, once #2 below is settled). +2. Decide the canonical test-count methodology, then correct CLAUDE.md + TESTING.md to match it consistently. +3. Mark the 5 confirmed-stale specs `Implemented` (with a one-line pointer to the shipping version/PR, matching the pattern already used in `SPEC-agenda-schedule-2026-06-13.md` and `SPEC-obs-dispatcher-shadowing-2026-06-04.md`). +4. Do the same check for the "not yet cross-checked" list (§ above) before touching them — don't mark `SPEC-testing-framework-2026-02-16.md` implemented without confirming a real feature exists, since it had zero CHANGELOG evidence either way. +5. Full remaining spec sweep (the ~10 out-of-scope ones) is a separate, larger pass — size it before starting; don't fold it silently into item 3. + +## Verification (once fixes are applied) + +- `mkdocs build --strict` — must stay 0 warnings. +- `./tests/run-all.sh` — must stay green; re-run count-derivation commands (`find tests -name "*.zsh" | wc -l`, `grep -c "^run_test " tests/run-all.sh`) to confirm the new stated numbers are actually correct, not just different. +- Re-grep spec statuses after the mark-implemented pass to confirm no accidental over-claiming (a spec marked Implemented should have a real, checkable shipped feature — CHANGELOG entry or passing test — not just "looks old"). diff --git a/docs/specs/SPEC-dot-rename-split-2026-02-14.md b/docs/specs/SPEC-dot-rename-split-2026-02-14.md index 884f74b60..c965c18bc 100644 --- a/docs/specs/SPEC-dot-rename-split-2026-02-14.md +++ b/docs/specs/SPEC-dot-rename-split-2026-02-14.md @@ -1,6 +1,6 @@ # SPEC: Rename `dot` → `dots` + Split into 3 Dispatchers -**Status:** draft +**Status:** Implemented — shipped exactly as targeted in v7.1.0 (`README.md`: "Dispatcher split — `dot` → `dots` (dotfiles) + `sec` (secrets) + `tok` (tokens)") (verified 2026-07-02 via docs-gap audit, `docs/specs/PLAN-docs-gap-2026-07-02.md`) **Created:** 2026-02-14 **Version Target:** v7.1.0 **From Brainstorm:** BRAINSTORM-dot-rename-2026-02-14.md diff --git a/docs/specs/SPEC-em-v2-2026-02-26.md b/docs/specs/SPEC-em-v2-2026-02-26.md index 220456e39..a9d505338 100644 --- a/docs/specs/SPEC-em-v2-2026-02-26.md +++ b/docs/specs/SPEC-em-v2-2026-02-26.md @@ -1,6 +1,6 @@ # SPEC: em Dispatcher v2.0 -**Status:** draft +**Status:** Implemented — em v2.0 shipped (v7.5.0 per `README.md` What's New: "em v2.0 safety gate, ICS calendar, IMAP watch, folder CRUD") (verified 2026-07-02 via docs-gap audit, `docs/specs/PLAN-docs-gap-2026-07-02.md`) **Created:** 2026-02-26 **From Brainstorm:** BRAINSTORM-em-v2-2026-02-26.md **Target Release:** flow-cli v7.5.0 diff --git a/docs/specs/SPEC-latex-macros-2026-01-28.md b/docs/specs/SPEC-latex-macros-2026-01-28.md index b4b2ebaea..d4c3bacbc 100644 --- a/docs/specs/SPEC-latex-macros-2026-01-28.md +++ b/docs/specs/SPEC-latex-macros-2026-01-28.md @@ -1,6 +1,6 @@ # SPEC: LaTeX Macro Configuration Support -**Status:** draft +**Status:** Implemented — `lib/macro-parser.zsh` + `tests/test-macro-parser.zsh` exist and pass (verified 2026-07-02 via docs-gap audit, `docs/specs/PLAN-docs-gap-2026-07-02.md`) **Created:** 2026-01-28 **Issue:** #305 **From Brainstorm:** BRAINSTORM-latex-macros-2026-01-28.md (inline, not saved separately) diff --git a/docs/specs/SPEC-teach-deploy-v2-2026-02-03.md b/docs/specs/SPEC-teach-deploy-v2-2026-02-03.md index 264a32b7e..869ab1e42 100644 --- a/docs/specs/SPEC-teach-deploy-v2-2026-02-03.md +++ b/docs/specs/SPEC-teach-deploy-v2-2026-02-03.md @@ -1,6 +1,6 @@ # SPEC: teach deploy v2 — STAT-545 Port + New Features -**Status:** draft +**Status:** Implemented — `teach deploy` v2 shipped; see `docs/guides/TEACH-DEPLOY-GUIDE.md` and `CHANGELOG.md` (verified 2026-07-02 via docs-gap audit, `docs/specs/PLAN-docs-gap-2026-07-02.md`) **Created:** 2026-02-03 **From Brainstorm:** BRAINSTORM-teach-deploy-v2-2026-02-03.md **Target Version:** v6.4.0 diff --git a/docs/specs/SPEC-teach-doctor-v2-2026-02-07.md b/docs/specs/SPEC-teach-doctor-v2-2026-02-07.md index e2a02e30a..1a78261e6 100644 --- a/docs/specs/SPEC-teach-doctor-v2-2026-02-07.md +++ b/docs/specs/SPEC-teach-doctor-v2-2026-02-07.md @@ -1,6 +1,6 @@ # SPEC: teach doctor v2 — Fast Default, Full Opt-in, renv-Aware -**Status:** draft +**Status:** Implemented — `teach doctor` fast-default/full-opt-in/renv-aware behavior shipped; see `CHANGELOG.md` and `docs/reference/REFCARD-DOCTOR.md` (verified 2026-07-02 via docs-gap audit, `docs/specs/PLAN-docs-gap-2026-07-02.md`) **Created:** 2026-02-07 **From Brainstorm:** BRAINSTORM-teach-doctor-improvements-2026-02-07.md **Target Version:** v6.5.0 diff --git a/docs/specs/SPEC-teach-map-2026-02-08.md b/docs/specs/SPEC-teach-map-2026-02-08.md index 85960ef74..0b2916053 100644 --- a/docs/specs/SPEC-teach-map-2026-02-08.md +++ b/docs/specs/SPEC-teach-map-2026-02-08.md @@ -1,6 +1,6 @@ # SPEC: `teach map` -- Unified Ecosystem Discovery -**Status:** draft +**Status:** Implemented — shipped v6.6.0 (`CHANGELOG.md`: "`teach map` — unified ecosystem discovery command"); documented in `docs/reference/MASTER-DISPATCHER-GUIDE.md` (verified 2026-07-02 via docs-gap audit, `docs/specs/PLAN-docs-gap-2026-07-02.md`) **Created:** 2026-02-08 **Issue:** #358 **From Brainstorm:** BRAINSTORM-teach-map-2026-02-08.md diff --git a/docs/specs/SPEC-teach-plan-v2-2026-01-29.md b/docs/specs/SPEC-teach-plan-v2-2026-01-29.md index da7956015..22a592979 100644 --- a/docs/specs/SPEC-teach-plan-v2-2026-01-29.md +++ b/docs/specs/SPEC-teach-plan-v2-2026-01-29.md @@ -1,6 +1,6 @@ # Implementation Spec: teach plan Command (v2 - Revised for Centralized Format) -**Status:** draft +**Status:** Implemented — `teach plan` centralized-format command shipped, `test-teach-plan.zsh` + `test-teach-plan-security.zsh` passing (verified 2026-07-02 via docs-gap audit, `docs/specs/PLAN-docs-gap-2026-07-02.md`) **Created:** 2026-01-29 **Supersedes:** SPEC-teach-plan-create-2026-01-27.md (outdated per-file format) **From Issue:** #278 diff --git a/docs/specs/SPEC-testing-framework-2026-02-16.md b/docs/specs/SPEC-testing-framework-2026-02-16.md index fda0a350c..df877dd5a 100644 --- a/docs/specs/SPEC-testing-framework-2026-02-16.md +++ b/docs/specs/SPEC-testing-framework-2026-02-16.md @@ -1,7 +1,7 @@ # SPEC: Comprehensive Testing Framework for Zsh/Bash Projects **Date:** 2026-02-16 -**Status:** Draft +**Status:** Implemented — "Enhanced Native" framework realized as specced: `tests/test-framework.zsh` (assertion/mock helpers), `tests/dogfood-test-quality.zsh` (anti-pattern scanner), CI full-suite gate blocking broken commits (`docs/guides/TESTING.md`) (verified 2026-07-02 via docs-gap audit, `docs/specs/PLAN-docs-gap-2026-07-02.md`) **Branch:** feature/testing-overhaul **Scope:** flow-cli (primary), extensible to all dev-tools projects diff --git a/docs/specs/SPEC-code-workspace-2026-02-13.md b/docs/specs/_archive/SPEC-code-workspace-2026-02-13.md similarity index 98% rename from docs/specs/SPEC-code-workspace-2026-02-13.md rename to docs/specs/_archive/SPEC-code-workspace-2026-02-13.md index 3b25ea2c3..5fdd2226a 100644 --- a/docs/specs/SPEC-code-workspace-2026-02-13.md +++ b/docs/specs/_archive/SPEC-code-workspace-2026-02-13.md @@ -2,7 +2,7 @@ | Field | Value | |-------|-------| -| **Status** | draft | +| **Status** | retired — 2026-07-02, never implemented, no demand signal in 4.5mo, `code` binary overload risk not worth it without validated need | | **Created** | 2026-02-13 | | **From Brainstorm** | ~/BRAINSTORM-code-workspace-2026-02-13.md | | **Component** | `lib/code-workspace.zsh` | diff --git a/flow.plugin.zsh b/flow.plugin.zsh index 513e28af6..98ef09c2f 100644 --- a/flow.plugin.zsh +++ b/flow.plugin.zsh @@ -186,7 +186,7 @@ _flow_plugin_init # Export loaded marker export FLOW_PLUGIN_LOADED=1 -export FLOW_VERSION="7.14.0" +export FLOW_VERSION="7.15.0" # Register exit hook for plugin cleanup add-zsh-hook zshexit _flow_plugin_cleanup diff --git a/man/man1/agenda.1 b/man/man1/agenda.1 index f0aad69e8..620da406e 100644 --- a/man/man1/agenda.1 +++ b/man/man1/agenda.1 @@ -1,6 +1,6 @@ .\" Man page for the agenda command (forward-looking schedule view) .\" Updated: June 2026 -.TH AGENDA 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH AGENDA 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME agenda \- forward-looking schedule across all projects .SH SYNOPSIS diff --git a/man/man1/at.1 b/man/man1/at.1 index 1d74b9bc4..baaad2669 100644 --- a/man/man1/at.1 +++ b/man/man1/at.1 @@ -1,6 +1,6 @@ .\" Man page for at dispatcher (Atlas bridge) .\" Generated: June 2026 -.TH AT 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH AT 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME at \- Atlas project intelligence bridge (optional integration) .SH SYNOPSIS diff --git a/man/man1/cc.1 b/man/man1/cc.1 index 969305ea9..a08a305ae 100644 --- a/man/man1/cc.1 +++ b/man/man1/cc.1 @@ -1,6 +1,6 @@ .\" Man page for cc dispatcher (Claude Code launcher) .\" Generated: June 2026 -.TH CC 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH CC 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME cc \- Claude Code launcher and dispatcher .SH SYNOPSIS diff --git a/man/man1/dash.1 b/man/man1/dash.1 index dda4625b3..4e8d1ab09 100644 --- a/man/man1/dash.1 +++ b/man/man1/dash.1 @@ -1,6 +1,6 @@ .\" Man page for the dash command (project dashboard) .\" Updated: June 2026 -.TH DASH 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH DASH 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME dash \- ADHD-friendly project dashboard .SH SYNOPSIS diff --git a/man/man1/dots.1 b/man/man1/dots.1 index 3a436ce33..469089460 100644 --- a/man/man1/dots.1 +++ b/man/man1/dots.1 @@ -1,6 +1,6 @@ .\" Man page for dots dispatcher (Dotfile Management) .\" Generated: June 2026 -.TH DOTS 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH DOTS 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME dots \- Dotfile management dispatcher (chezmoi wrapper) .SH SYNOPSIS diff --git a/man/man1/em.1 b/man/man1/em.1 index 2256b05b5..6ccc874f2 100644 --- a/man/man1/em.1 +++ b/man/man1/em.1 @@ -1,6 +1,6 @@ .\" Man page for em dispatcher (Email / himalaya) .\" Generated: June 2026 -.TH EM 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH EM 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME em \- Email dispatcher (himalaya wrapper) .SH SYNOPSIS diff --git a/man/man1/flow-claude.1 b/man/man1/flow-claude.1 index b5aaf6e2a..5036d7da1 100644 --- a/man/man1/flow-claude.1 +++ b/man/man1/flow-claude.1 @@ -1,4 +1,4 @@ -.TH FLOW-CLAUDE 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH FLOW-CLAUDE 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME flow-claude \- Claude Code environment health checker .SH SYNOPSIS diff --git a/man/man1/flow.1 b/man/man1/flow.1 index dda7484cc..93bbf7220 100644 --- a/man/man1/flow.1 +++ b/man/man1/flow.1 @@ -1,6 +1,6 @@ .\" Man page for flow command .\" Updated: June 2026 -.TH FLOW 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH FLOW 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME flow \- ADHD-friendly workflow CLI for developers .SH SYNOPSIS diff --git a/man/man1/g.1 b/man/man1/g.1 index 599bd8c6c..0b6963e7f 100644 --- a/man/man1/g.1 +++ b/man/man1/g.1 @@ -1,6 +1,6 @@ .\" Man page for g dispatcher (Git workflows) .\" Updated: June 2026 -.TH G 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH G 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME g \- Git commands dispatcher .SH SYNOPSIS diff --git a/man/man1/mcp.1 b/man/man1/mcp.1 index 41dc33c54..9b1acb2c0 100644 --- a/man/man1/mcp.1 +++ b/man/man1/mcp.1 @@ -1,6 +1,6 @@ .\" Man page for mcp dispatcher (MCP server management) .\" Updated: June 2026 -.TH MCP 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH MCP 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME mcp \- MCP server management dispatcher .SH SYNOPSIS diff --git a/man/man1/morning.1 b/man/man1/morning.1 index ddfd02c26..3b167d7f9 100644 --- a/man/man1/morning.1 +++ b/man/man1/morning.1 @@ -1,6 +1,6 @@ .\" Man page for the morning command (daily startup routine) .\" Updated: June 2026 -.TH MORNING 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH MORNING 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME morning \- ADHD-friendly daily startup routine .SH SYNOPSIS diff --git a/man/man1/prompt.1 b/man/man1/prompt.1 index df810a746..a168d48b0 100644 --- a/man/man1/prompt.1 +++ b/man/man1/prompt.1 @@ -1,6 +1,6 @@ .\" Man page for prompt dispatcher (Prompt Engine Switcher) .\" Generated: June 2026 -.TH PROMPT 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH PROMPT 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME prompt \- Prompt engine switcher .SH SYNOPSIS diff --git a/man/man1/qu.1 b/man/man1/qu.1 index 4d86294fd..f285a9525 100644 --- a/man/man1/qu.1 +++ b/man/man1/qu.1 @@ -1,6 +1,6 @@ .\" Man page for qu dispatcher (Quarto publishing) .\" Updated: June 2026 -.TH QU 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH QU 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME qu \- Quarto publishing dispatcher .SH SYNOPSIS diff --git a/man/man1/r.1 b/man/man1/r.1 index 1e7639834..ca7c38ce3 100644 --- a/man/man1/r.1 +++ b/man/man1/r.1 @@ -1,6 +1,6 @@ .\" Man page for r dispatcher (R package development) .\" Updated: June 2026 -.TH R 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH R 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME r \- R package development dispatcher .SH SYNOPSIS diff --git a/man/man1/sec.1 b/man/man1/sec.1 index 481a61606..d53e6e564 100644 --- a/man/man1/sec.1 +++ b/man/man1/sec.1 @@ -1,6 +1,6 @@ .\" Man page for sec dispatcher (Secret Management) .\" Generated: June 2026 -.TH SEC 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH SEC 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME sec \- Secret management dispatcher (Keychain and Bitwarden) .SH SYNOPSIS diff --git a/man/man1/teach.1 b/man/man1/teach.1 index 9858d7631..0dea962e3 100644 --- a/man/man1/teach.1 +++ b/man/man1/teach.1 @@ -1,6 +1,6 @@ .\" Man page for teach dispatcher (Teaching Workflow) .\" Generated: June 2026 -.TH TEACH 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH TEACH 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME teach \- Teaching workflow dispatcher (Scholar integration) .SH SYNOPSIS diff --git a/man/man1/tm.1 b/man/man1/tm.1 index 5fbf7c6bc..4a7f90e23 100644 --- a/man/man1/tm.1 +++ b/man/man1/tm.1 @@ -1,6 +1,6 @@ .\" Man page for tm dispatcher (Terminal Manager) .\" Generated: June 2026 -.TH TM 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH TM 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME tm \- Terminal manager dispatcher .SH SYNOPSIS diff --git a/man/man1/today.1 b/man/man1/today.1 index 034a4575b..ac0370ec7 100644 --- a/man/man1/today.1 +++ b/man/man1/today.1 @@ -1,6 +1,6 @@ .\" Man page for the today command (quick daily status) .\" Updated: June 2026 -.TH TODAY 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH TODAY 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME today \- quick daily status .SH SYNOPSIS diff --git a/man/man1/tok.1 b/man/man1/tok.1 index 7200ae05e..d1472e788 100644 --- a/man/man1/tok.1 +++ b/man/man1/tok.1 @@ -1,6 +1,6 @@ .\" Man page for tok dispatcher (Token Management) .\" Generated: June 2026 -.TH TOK 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH TOK 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME tok \- Token lifecycle management dispatcher .SH SYNOPSIS diff --git a/man/man1/v.1 b/man/man1/v.1 index 60edd4077..f3eb2f8ab 100644 --- a/man/man1/v.1 +++ b/man/man1/v.1 @@ -1,6 +1,6 @@ .\" Man page for v dispatcher (Vibe / Workflow Automation) .\" Generated: June 2026 -.TH V 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH V 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME v \- Workflow automation dispatcher (vibe coding mode) .SH SYNOPSIS diff --git a/man/man1/week.1 b/man/man1/week.1 index 0295c8631..9c4ade17f 100644 --- a/man/man1/week.1 +++ b/man/man1/week.1 @@ -1,6 +1,6 @@ .\" Man page for the week command (weekly review helper) .\" Updated: June 2026 -.TH WEEK 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH WEEK 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME week \- weekly review helper .SH SYNOPSIS diff --git a/man/man1/wt.1 b/man/man1/wt.1 index 4024c0664..47c2f038f 100644 --- a/man/man1/wt.1 +++ b/man/man1/wt.1 @@ -1,6 +1,6 @@ .\" Man page for wt dispatcher (Git Worktree Management) .\" Generated: June 2026 -.TH WT 1 "June 2026" "flow-cli 7.14.0" "User Commands" +.TH WT 1 "June 2026" "flow-cli 7.15.0" "User Commands" .SH NAME wt \- Git worktree management dispatcher .SH SYNOPSIS diff --git a/mkdocs.yml b/mkdocs.yml index 7c3668163..26a003c92 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -244,6 +244,7 @@ nav: - guides/index.md - Start Here: guides/00-START-HERE.md - Quick Wins: guides/WORKFLOWS-QUICK-WINS.md + - 📖 Workflow Cookbook (Daily/Weekly): guides/WORKFLOW-COOKBOOK.md - Git & Branching: - Git Dispatcher (g): reference/REFCARD-GIT-DISPATCHER.md - Git Feature Flow: tutorials/08-git-feature-workflow.md @@ -309,6 +310,9 @@ nav: - at (Atlas bridge): commands/at.md - claude (env check): commands/claude.md - dashboard: commands/dashboard.md + - ref: commands/ref.md + - setup: commands/setup.md + - tutorial: commands/tutorial.md - Quick Reference Cards: - 🌳 Worktree (wt): reference/REFCARD-WORKTREE-DISPATCHER.md - 📁 Dotfiles (dots): reference/REFCARD-DOTFILE-DISPATCHER.md diff --git a/package-lock.json b/package-lock.json index dbebfce20..2d44b49d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "flow-cli", - "version": "7.13.0", + "version": "7.15.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "flow-cli", - "version": "7.13.0", + "version": "7.15.0", "license": "MIT", "devDependencies": { "husky": "^9.1.7", diff --git a/package.json b/package.json index b4c9ea900..cefb85f1f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flow-cli", - "version": "7.14.0", + "version": "7.15.0", "description": "ADHD-optimized ZSH workflow plugin", "private": true, "scripts": { diff --git a/tests/e2e-doctor-install.zsh b/tests/e2e-doctor-install.zsh new file mode 100755 index 000000000..1aa97fec8 --- /dev/null +++ b/tests/e2e-doctor-install.zsh @@ -0,0 +1,288 @@ +#!/usr/bin/env zsh +# e2e-doctor-install.zsh - End-to-end tests for `doctor`'s INSTALLATION section +# +# Targets the exact failure class fixed in homebrew-tap PR #135: a Homebrew +# formula install that "succeeds" (brew reports installed, brew upgrade says +# "already installed") but never actually links — man-page name collisions +# on case-insensitive filesystems, stale Cellar kegs after a formula fix, +# and shell/Cellar version drift after an upgrade. All of these leave the +# user silently running broken or stale code with no error message. +# +# Drives the real `_doctor_check_installation` function against a mocked +# `brew` covering: no Homebrew, not brew-installed, healthy link, broken +# link (installed-but-unlinked), version drift, and man-page collisions +# across two formulae's Cellar kegs. +# +# Usage: zsh tests/e2e-doctor-install.zsh + +SCRIPT_DIR="${0:A:h}" +PROJECT_ROOT="${SCRIPT_DIR:h}" + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +CYAN='\033[0;36m' +DIM='\033[2m' +RESET='\033[0m' + +TESTS_RUN=0 +TESTS_PASSED=0 +TESTS_FAILED=0 + +run_test() { + local test_name="$1" + local test_func="$2" + + TESTS_RUN=$((TESTS_RUN + 1)) + echo -n " ${CYAN}[$TESTS_RUN] $test_name...${RESET} " + + local output + output=$(eval "$test_func" 2>&1) + local rc=$? + + if [[ $rc -eq 0 ]]; then + echo "${GREEN}PASS${RESET}" + TESTS_PASSED=$((TESTS_PASSED + 1)) + else + echo "${RED}FAIL${RESET}" + [[ -n "$output" ]] && echo " ${DIM}${output:0:300}${RESET}" + TESTS_FAILED=$((TESTS_FAILED + 1)) + fi +} + +echo "" +echo "${CYAN}══════════════════════════════════════════════════════════════${RESET}" +echo "${CYAN} E2E: doctor INSTALLATION checks (Homebrew distribution health)${RESET}" +echo "${CYAN}══════════════════════════════════════════════════════════════${RESET}" +echo "" + +FLOW_QUIET=1 +FLOW_ATLAS_ENABLED=no +FLOW_PLUGIN_DIR="$PROJECT_ROOT" +source "$PROJECT_ROOT/flow.plugin.zsh" 2>/dev/null || { + echo "${RED}Failed to load plugin${RESET}" + exit 1 +} + +exec < /dev/null + +TEST_TMP=$(mktemp -d) +trap 'rm -rf "$TEST_TMP"' EXIT + +# Builds a fake Cellar under a given root (each scenario gets its own root +# so man-page fixtures never leak across scenarios): $1=cellar_root +# $2=formula $3=version $4... =man1 basenames to ship +_fake_keg() { + local cellar_root="$1" formula="$2" version="$3" + shift 3 + local mandir="$cellar_root/$formula/$version/share/man/man1" + mkdir -p "$mandir" + for name in "$@"; do + touch "$mandir/$name" + done +} + +# ───────────────────────────────────────────────────────────────── +# Scenario 1: brew not present at all — must skip silently, no error +# ───────────────────────────────────────────────────────────────── +test_no_brew() { + unfunction brew 2>/dev/null + local orig_path="$PATH" + PATH="/nonexistent_bin_dir_for_test" + local out + out=$(_doctor_check_installation 2>&1) + PATH="$orig_path" + assert_output_contains "$out" "not present" +} + +# ───────────────────────────────────────────────────────────────── +# Scenario 2: brew present, flow-cli not installed via it — skip +# ───────────────────────────────────────────────────────────────── +test_not_brew_installed() { + brew() { + case "$1 $2" in + "list --formula") echo "some-other-formula" ;; + esac + } + local out + out=$(_doctor_check_installation 2>&1) + unfunction brew + assert_output_contains "$out" "not installed via Homebrew" +} + +# ───────────────────────────────────────────────────────────────── +# Scenario 3: healthy install — linked, version matches, no collisions +# ───────────────────────────────────────────────────────────────── +test_healthy_install() { + local cellar="$TEST_TMP/cellar-healthy" + local optdir="$TEST_TMP/prefix-healthy/opt/flow-cli" + mkdir -p "$cellar/flow-cli/${FLOW_VERSION}" + mkdir -p "$TEST_TMP/prefix-healthy/opt" + ln -sfn "$cellar/flow-cli/${FLOW_VERSION}" "$optdir" + + brew() { + if [[ "$1 $2" == "list --formula" ]]; then echo "flow-cli" + elif [[ "$1 $2" == "list --versions" && "$3" == "flow-cli" ]]; then echo "flow-cli ${FLOW_VERSION}" + elif [[ "$1" == "--prefix" ]]; then echo "$TEST_TMP/prefix-healthy" + elif [[ "$1" == "--cellar" ]]; then echo "$cellar" + fi + } + + local out + out=$(_doctor_check_installation 2>&1) + unfunction brew + + assert_output_contains "$out" "Homebrew link" && + assert_output_not_contains "$out" "not linked" && + assert_output_not_contains "$out" "drift" && + assert_output_not_contains "$out" "Shell has" +} + +# ───────────────────────────────────────────────────────────────── +# Scenario 4: installed but NOT linked (the PR #135 symptom before the fix) +# ───────────────────────────────────────────────────────────────── +test_installed_not_linked() { + local cellar="$TEST_TMP/cellar-broken" + mkdir -p "$cellar/flow-cli/${FLOW_VERSION}" + mkdir -p "$TEST_TMP/prefix-broken/opt" + # deliberately do NOT create the opt symlink + + brew() { + if [[ "$1 $2" == "list --formula" ]]; then echo "flow-cli" + elif [[ "$1 $2" == "list --versions" && "$3" == "flow-cli" ]]; then echo "flow-cli ${FLOW_VERSION}" + elif [[ "$1" == "--prefix" ]]; then echo "$TEST_TMP/prefix-broken" + elif [[ "$1" == "--cellar" ]]; then echo "$cellar" + fi + } + + local out + out=$(_doctor_check_installation 2>&1) + unfunction brew + + assert_output_contains "$out" "not linked" +} + +# ───────────────────────────────────────────────────────────────── +# Scenario 5: version drift — shell's loaded version != installed keg +# ───────────────────────────────────────────────────────────────── +test_version_drift() { + local cellar="$TEST_TMP/cellar-drift" + local optdir="$TEST_TMP/prefix-drift/opt/flow-cli" + mkdir -p "$cellar/flow-cli/99.99.99" + mkdir -p "$TEST_TMP/prefix-drift/opt" + ln -sfn "$cellar/flow-cli/99.99.99" "$optdir" + + brew() { + if [[ "$1 $2" == "list --formula" ]]; then echo "flow-cli" + elif [[ "$1 $2" == "list --versions" && "$3" == "flow-cli" ]]; then echo "flow-cli 99.99.99" + elif [[ "$1" == "--prefix" ]]; then echo "$TEST_TMP/prefix-drift" + elif [[ "$1" == "--cellar" ]]; then echo "$cellar" + fi + } + + local out + out=$(_doctor_check_installation 2>&1) + unfunction brew + + assert_output_contains "$out" "99.99.99" && + assert_output_contains "$out" "restart your shell" +} + +# ───────────────────────────────────────────────────────────────── +# Scenario 6: flow-cli's own man page lost a collision — its r.1 was never +# linked into the shared man1 dir because the `r` formula's R.1 took the +# case-insensitive slot instead (the exact PR #135 symptom, pre-fix). +# ───────────────────────────────────────────────────────────────── +test_manpage_collision_detected() { + local cellar="$TEST_TMP/cellar-collide" + local prefix="$TEST_TMP/prefix-collide" + local optdir="$prefix/opt/flow-cli" + mkdir -p "$prefix/opt" + _fake_keg "$cellar" "flow-cli" "${FLOW_VERSION}" "agenda.1" "r.1" + _fake_keg "$cellar" "r" "4.5.0" "R.1" + ln -sfn "$cellar/flow-cli/${FLOW_VERSION}" "$optdir" + + # Simulate the shared man1 dir after a lost collision: agenda.1 links to + # flow-cli as expected, but the r.1 slot resolved to the `r` formula's + # keg instead of flow-cli's. + mkdir -p "$prefix/share/man/man1" + ln -sfn "$cellar/flow-cli/${FLOW_VERSION}/share/man/man1/agenda.1" "$prefix/share/man/man1/agenda.1" + ln -sfn "$cellar/r/4.5.0/share/man/man1/R.1" "$prefix/share/man/man1/r.1" + + brew() { + if [[ "$1 $2" == "list --formula" ]]; then echo "flow-cli" + elif [[ "$1 $2" == "list --versions" && "$3" == "flow-cli" ]]; then echo "flow-cli ${FLOW_VERSION}" + elif [[ "$1" == "--prefix" ]]; then echo "$prefix" + elif [[ "$1" == "--cellar" ]]; then echo "$cellar" + fi + } + + local out + out=$(_doctor_check_installation 2>&1) + unfunction brew + + assert_output_contains "$out" "not linked (collision" && + assert_output_contains "$out" "r.1" +} + +# ───────────────────────────────────────────────────────────────── +# Scenario 7: all of flow-cli's own man pages link cleanly — including +# alongside an unrelated formula (jq) that ships its own, non-colliding page. +# ───────────────────────────────────────────────────────────────── +test_no_manpage_collision() { + local cellar="$TEST_TMP/cellar-clean" + local prefix="$TEST_TMP/prefix-clean" + local optdir="$prefix/opt/flow-cli" + mkdir -p "$prefix/opt" + _fake_keg "$cellar" "flow-cli" "${FLOW_VERSION}" "agenda.1" "dash.1" + _fake_keg "$cellar" "jq" "1.7" "jq.1" + ln -sfn "$cellar/flow-cli/${FLOW_VERSION}" "$optdir" + + mkdir -p "$prefix/share/man/man1" + ln -sfn "$cellar/flow-cli/${FLOW_VERSION}/share/man/man1/agenda.1" "$prefix/share/man/man1/agenda.1" + ln -sfn "$cellar/flow-cli/${FLOW_VERSION}/share/man/man1/dash.1" "$prefix/share/man/man1/dash.1" + ln -sfn "$cellar/jq/1.7/share/man/man1/jq.1" "$prefix/share/man/man1/jq.1" + + brew() { + if [[ "$1 $2" == "list --formula" ]]; then echo "flow-cli" + elif [[ "$1 $2" == "list --versions" && "$3" == "flow-cli" ]]; then echo "flow-cli ${FLOW_VERSION}" + elif [[ "$1" == "--prefix" ]]; then echo "$prefix" + elif [[ "$1" == "--cellar" ]]; then echo "$cellar" + fi + } + + local out + out=$(_doctor_check_installation 2>&1) + unfunction brew + + assert_output_contains "$out" "All flow-cli man pages linked cleanly" +} + +# ───────────────────────────────────────────────────────────────── +# Assertion helpers (self-contained, mirrors test-framework.zsh's contract) +# ───────────────────────────────────────────────────────────────── +assert_output_contains() { + local haystack="$1" needle="$2" + [[ "$haystack" == *"$needle"* ]] || { echo "expected to contain: $needle"; return 1; } +} + +assert_output_not_contains() { + local haystack="$1" needle="$2" + [[ "$haystack" != *"$needle"* ]] || { echo "expected NOT to contain: $needle"; return 1; } +} + +run_test "no brew on PATH → skip" test_no_brew +run_test "brew present, flow-cli not installed via it → skip" test_not_brew_installed +run_test "healthy install → linked, version matches, no collisions" test_healthy_install +run_test "installed but not linked → flagged" test_installed_not_linked +run_test "version drift (shell vs Cellar) → flagged" test_version_drift +run_test "man-page collision across formulae → detected" test_manpage_collision_detected +run_test "no man-page collision → clean" test_no_manpage_collision + +echo "" +echo "${CYAN}──────────────────────────────────────────────────────────────${RESET}" +echo " Results: ${GREEN}${TESTS_PASSED} passed${RESET}, ${RED}${TESTS_FAILED} failed${RESET} (${TESTS_RUN} total)" +echo "${CYAN}──────────────────────────────────────────────────────────────${RESET}" +echo "" + +[[ $TESTS_FAILED -eq 0 ]] diff --git a/tests/run-all.sh b/tests/run-all.sh index 6c0bbaa8e..03ad8341d 100755 --- a/tests/run-all.sh +++ b/tests/run-all.sh @@ -164,6 +164,7 @@ run_test ./tests/e2e-scholar-config-sync.zsh run_test ./tests/e2e-tok-sync.zsh run_test ./tests/e2e-agenda.zsh run_test ./tests/e2e-agenda-atlas.zsh +run_test ./tests/e2e-doctor-install.zsh echo "" echo "Atlas contract tests:"