gitstow 0.3.0__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. {gitstow-0.3.0 → gitstow-0.5.0}/AGENTS.md +48 -43
  2. gitstow-0.5.0/BACKLOG.md +43 -0
  3. {gitstow-0.3.0 → gitstow-0.5.0}/CHANGELOG.md +30 -0
  4. {gitstow-0.3.0 → gitstow-0.5.0}/CLAUDE.md +4 -0
  5. {gitstow-0.3.0 → gitstow-0.5.0}/PKG-INFO +1 -1
  6. gitstow-0.5.0/docs/building/plans/2026-07-12-ui-wave-a-make-it-real.md +831 -0
  7. gitstow-0.5.0/docs/building/plans/2026-07-12-ui-wave-b-polish.md +455 -0
  8. gitstow-0.5.0/docs/building/plans/2026-07-16-move-repo-between-workspaces.md +95 -0
  9. gitstow-0.5.0/docs/building/ui-audit-2026-07-12.md +57 -0
  10. {gitstow-0.3.0 → gitstow-0.5.0}/docs/user/commands.md +1 -1
  11. {gitstow-0.3.0 → gitstow-0.5.0}/pyproject.toml +1 -1
  12. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/__init__.py +1 -1
  13. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/export_cmd.py +3 -89
  14. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/manage.py +31 -0
  15. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/pull.py +6 -0
  16. gitstow-0.5.0/src/gitstow/core/collection_io.py +98 -0
  17. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/core/git.py +11 -0
  18. gitstow-0.5.0/src/gitstow/core/operations.py +349 -0
  19. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/core/status_model.py +8 -1
  20. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/routes/collection.py +14 -73
  21. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/routes/dashboard.py +45 -10
  22. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/routes/pages.py +76 -8
  23. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/routes/repos.py +30 -3
  24. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/server.py +2 -2
  25. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/static/app.css +105 -9
  26. gitstow-0.5.0/src/gitstow/web/static/dashboard.js +97 -0
  27. gitstow-0.5.0/src/gitstow/web/static/fonts/bricolage-grotesque-latin-ext-var.woff2 +0 -0
  28. gitstow-0.5.0/src/gitstow/web/static/fonts/bricolage-grotesque-latin-var.woff2 +0 -0
  29. gitstow-0.5.0/src/gitstow/web/static/fonts/fonts.css +81 -0
  30. gitstow-0.5.0/src/gitstow/web/static/fonts/jetbrains-mono-latin-ext-var.woff2 +0 -0
  31. gitstow-0.5.0/src/gitstow/web/static/fonts/jetbrains-mono-latin-var.woff2 +0 -0
  32. gitstow-0.5.0/src/gitstow/web/static/vendor/VENDORED.md +39 -0
  33. gitstow-0.5.0/src/gitstow/web/static/vendor/htmx.min.js +1 -0
  34. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/templates/_repo_drawer.html +26 -3
  35. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/templates/add_repo.html +20 -2
  36. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/templates/base.html +73 -1
  37. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/templates/dashboard.html +19 -12
  38. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/templates/partials/pull_summary.html +1 -1
  39. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/templates/partials/repo_row.html +6 -6
  40. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/templates/settings.html +46 -13
  41. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/templates/workspaces.html +4 -2
  42. {gitstow-0.3.0 → gitstow-0.5.0}/tests/test_cli.py +70 -2
  43. gitstow-0.5.0/tests/test_collection_io.py +33 -0
  44. gitstow-0.5.0/tests/test_move.py +600 -0
  45. {gitstow-0.3.0 → gitstow-0.5.0}/tests/test_serve.py +426 -0
  46. {gitstow-0.3.0 → gitstow-0.5.0}/tests/test_status_model.py +6 -2
  47. gitstow-0.3.0/BACKLOG.md +0 -18
  48. gitstow-0.3.0/src/gitstow/core/operations.py +0 -98
  49. {gitstow-0.3.0 → gitstow-0.5.0}/.claude/settings.json +0 -0
  50. {gitstow-0.3.0 → gitstow-0.5.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  51. {gitstow-0.3.0 → gitstow-0.5.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  52. {gitstow-0.3.0 → gitstow-0.5.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  53. {gitstow-0.3.0 → gitstow-0.5.0}/.github/workflows/ci.yml +0 -0
  54. {gitstow-0.3.0 → gitstow-0.5.0}/.github/workflows/publish.yml +0 -0
  55. {gitstow-0.3.0 → gitstow-0.5.0}/.gitignore +0 -0
  56. {gitstow-0.3.0 → gitstow-0.5.0}/CODE_OF_CONDUCT.md +0 -0
  57. {gitstow-0.3.0 → gitstow-0.5.0}/CONTRIBUTING.md +0 -0
  58. {gitstow-0.3.0 → gitstow-0.5.0}/LICENSE +0 -0
  59. {gitstow-0.3.0 → gitstow-0.5.0}/README.md +0 -0
  60. {gitstow-0.3.0 → gitstow-0.5.0}/SECURITY.md +0 -0
  61. {gitstow-0.3.0 → gitstow-0.5.0}/demo.gif +0 -0
  62. {gitstow-0.3.0 → gitstow-0.5.0}/demo.tape +0 -0
  63. {gitstow-0.3.0 → gitstow-0.5.0}/docs/building/audit-2026-07-06.md +0 -0
  64. {gitstow-0.3.0 → gitstow-0.5.0}/docs/building/implementation-plan.md +0 -0
  65. {gitstow-0.3.0 → gitstow-0.5.0}/docs/building/plans/2026-07-06-wave-1-correctness-safety.md +0 -0
  66. {gitstow-0.3.0 → gitstow-0.5.0}/docs/building/plans/2026-07-06-wave-2-status-model.md +0 -0
  67. {gitstow-0.3.0 → gitstow-0.5.0}/docs/building/plans/2026-07-06-wave-3-structure-polish.md +0 -0
  68. {gitstow-0.3.0 → gitstow-0.5.0}/docs/user/concepts.md +0 -0
  69. {gitstow-0.3.0 → gitstow-0.5.0}/docs/user/configuration.md +0 -0
  70. {gitstow-0.3.0 → gitstow-0.5.0}/docs/user/getting-started.md +0 -0
  71. {gitstow-0.3.0 → gitstow-0.5.0}/scripts/release.sh +0 -0
  72. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/__main__.py +0 -0
  73. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/__init__.py +0 -0
  74. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/add.py +0 -0
  75. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/config_cmd.py +0 -0
  76. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/doctor.py +0 -0
  77. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/exec_cmd.py +0 -0
  78. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/fetch.py +0 -0
  79. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/helpers.py +0 -0
  80. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/list_cmd.py +0 -0
  81. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/main.py +0 -0
  82. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/migrate.py +0 -0
  83. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/onboard.py +0 -0
  84. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/open_cmd.py +0 -0
  85. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/remove.py +0 -0
  86. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/search.py +0 -0
  87. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/serve.py +0 -0
  88. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/setup_ai.py +0 -0
  89. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/shell.py +0 -0
  90. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/skill_cmd.py +0 -0
  91. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/stats.py +0 -0
  92. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/status.py +0 -0
  93. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/update.py +0 -0
  94. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/cli/workspace_cmd.py +0 -0
  95. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/core/__init__.py +0 -0
  96. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/core/config.py +0 -0
  97. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/core/discovery.py +0 -0
  98. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/core/locking.py +0 -0
  99. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/core/parallel.py +0 -0
  100. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/core/paths.py +0 -0
  101. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/core/repo.py +0 -0
  102. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/core/url_parser.py +0 -0
  103. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/mcp/__init__.py +0 -0
  104. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/mcp/server.py +0 -0
  105. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/skill/SKILL.md +0 -0
  106. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/__init__.py +0 -0
  107. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/routes/__init__.py +0 -0
  108. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/routes/system.py +0 -0
  109. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/routes/workspaces.py +0 -0
  110. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/templates/partials/dashboard_rows.html +0 -0
  111. {gitstow-0.3.0 → gitstow-0.5.0}/src/gitstow/web/templates/partials/fetch_summary.html +0 -0
  112. {gitstow-0.3.0 → gitstow-0.5.0}/tests/__init__.py +0 -0
  113. {gitstow-0.3.0 → gitstow-0.5.0}/tests/conftest.py +0 -0
  114. {gitstow-0.3.0 → gitstow-0.5.0}/tests/test_config.py +0 -0
  115. {gitstow-0.3.0 → gitstow-0.5.0}/tests/test_git.py +0 -0
  116. {gitstow-0.3.0 → gitstow-0.5.0}/tests/test_locking.py +0 -0
  117. {gitstow-0.3.0 → gitstow-0.5.0}/tests/test_mcp.py +0 -0
  118. {gitstow-0.3.0 → gitstow-0.5.0}/tests/test_onboard.py +0 -0
  119. {gitstow-0.3.0 → gitstow-0.5.0}/tests/test_operations.py +0 -0
  120. {gitstow-0.3.0 → gitstow-0.5.0}/tests/test_repo.py +0 -0
  121. {gitstow-0.3.0 → gitstow-0.5.0}/tests/test_setup_ai.py +0 -0
  122. {gitstow-0.3.0 → gitstow-0.5.0}/tests/test_url_parser.py +0 -0
@@ -1,8 +1,8 @@
1
- # gitstow - AI Developer Guide
1
+ # gitstow — AI Developer Guide
2
2
 
3
3
  ## What is this?
4
4
 
5
- A CLI tool that manages collections of git repositories across multiple workspaces. Think "package manager for repos" - whether they're open-source projects you learn from or active projects you work on.
5
+ A CLI tool that manages collections of git repositories across multiple workspaces. Think "package manager for repos" — whether they're open-source projects you learn from or active projects you work on.
6
6
 
7
7
  ## Operating Contract
8
8
 
@@ -14,14 +14,15 @@ A CLI tool that manages collections of git repositories across multiple workspac
14
14
 
15
15
  ## Product Standards
16
16
 
17
- - Keep CLI, TUI, web dashboard, JSON output, docs, and tests semantically aligned when changing user-facing status behavior.
17
+ - Keep CLI, web dashboard, JSON output, docs, and tests semantically aligned when changing user-facing status behavior.
18
18
  - For repo state presentation, avoid using "dirty" as a broad user-facing bucket for every local change. Present it as local/uncommitted changes with the composition visible: modified, staged, and untracked counts.
19
19
  - Keep local working-tree state separate from remote relationship state. For example: local changes, clean, ahead, behind, diverged, frozen, missing.
20
20
  - When improving the web dashboard, implement the actual missing dashboard feature and shared classification/model behavior instead of copying a CLI-only assumption into the template.
21
+ - For `web/` changes, HTTP-level tests (TestClient, curl) are necessary but not sufficient — they pass on bugs below the HTTP layer. Before calling a `web/` change done, verify form structure against the parsed DOM (browsers silently drop nested `<form>` tags) and verify layout/geometry in a real browser (`overflow-x: auto` clips absolutely-positioned children even without horizontal overflow).
21
22
 
22
23
  ## Key Concept: Workspaces
23
24
 
24
- Repos are organized into **workspaces** - directories with a label and layout mode:
25
+ Repos are organized into **workspaces** — directories with a label and layout mode:
25
26
  - **structured** layout: `workspace/owner/repo/` (open-source collections)
26
27
  - **flat** layout: `workspace/repo/` (active projects, no owner subdirectory)
27
28
 
@@ -40,60 +41,62 @@ src/gitstow/
40
41
  │ ├── exec_cmd.py, search.py, open_cmd.py, stats.py # Power commands
41
42
  │ ├── export_cmd.py # export/import collection
42
43
  │ ├── shell.py # Shell integration (fzf, aliases)
43
- │ ├── tui.py # TUI launcher
44
44
  │ ├── serve.py # Web dashboard launcher
45
45
  │ ├── migrate.py, config_cmd.py, onboard.py, doctor.py, skill_cmd.py
46
46
  │ └── __init__.py
47
47
  ├── core/ # Business logic (git ops, URL parsing, state)
48
- │ ├── paths.py # Path constants, central repos.yaml resolution
49
- │ ├── config.py # Workspace + Settings dataclasses, load/save
50
- │ ├── repo.py # Repo dataclass + RepoStore (nested YAML CRUD)
51
- │ ├── url_parser.py # URL → (host, owner, repo) extraction
52
- │ ├── git.py # All git subprocess calls
53
- │ ├── discovery.py # Walk directory tree (structured + flat), reconcile
54
- │ ├── parallel.py # Async execution with semaphore
55
- │ └── __init__.py
56
- ├── tui/ # Textual interactive dashboard
57
- │ ├── app.py # Main TUI application
48
+ │ ├── paths.py # Path constants, central repos.yaml resolution
49
+ │ ├── config.py # Workspace + Settings dataclasses, load/save
50
+ │ ├── repo.py # Repo dataclass + RepoStore (nested YAML CRUD)
51
+ │ ├── url_parser.py # URL → (host, owner, repo) extraction
52
+ │ ├── git.py # All git subprocess calls
53
+ │ ├── discovery.py # Walk directory tree (structured + flat), reconcile
54
+ │ ├── parallel.py # Async execution with semaphore
55
+ │ ├── status_model.py # Shared repo-state classifier — local composition vs remote relationship
56
+ │ ├── operations.py # Shared filter + bulk-runner layer (pull/fetch/MCP)
57
+ │ ├── locking.py # Cross-process file lock guarding repos.yaml writes
58
58
  │ └── __init__.py
59
59
  ├── web/ # FastAPI browser dashboard (gitstow ui)
60
60
  │ ├── server.py # FastAPI app, uvicorn runner, app.state.server stash
61
61
  │ ├── static/app.css # Dark theme, Bricolage Grotesque + JetBrains Mono
62
62
  │ ├── templates/ # Jinja2 — base.html + page templates + partials/
63
63
  │ └── routes/ # dashboard.py, repos.py, workspaces.py, collection.py, pages.py, system.py
64
- └── skill/ # Codex skill (SKILL.md)
64
+ └── skill/ # Claude Code skill (SKILL.md)
65
65
  └── SKILL.md
66
66
  ```
67
67
 
68
68
  **Key rules:**
69
- 1. CLI never touches git directly - it calls `core/git.py`
69
+ 1. CLI never touches git directly — it calls `core/git.py`
70
70
  2. `core/repo.py` (RepoStore) is the only module that reads/writes `repos.yaml`
71
- 3. `core/config.py` defines Workspace dataclass - all workspace logic flows from here
71
+ 3. `core/config.py` defines Workspace dataclass — all workspace logic flows from here
72
72
  4. `cli/helpers.py` provides `resolve_workspaces()`, `resolve_repo()`, `iter_repos_with_workspace()`
73
73
 
74
74
  ## Key Files
75
75
 
76
- - `core/config.py` - Workspace + Settings dataclasses. `get_workspaces()` with legacy migration shim.
77
- - `core/repo.py` - Repo with workspace field, RepoStore with nested YAML format, legacy auto-migration.
78
- - `core/discovery.py` - `discover_repos(root, layout)` supports structured and flat layouts.
79
- - `core/url_parser.py` - URL parsing (the hardest part). Test changes here thoroughly.
80
- - `core/git.py` - All git subprocess calls. Uses `git status --porcelain=v2 --branch` for single-call efficiency.
81
- - `core/parallel.py` - Async execution with semaphore (max 6 concurrent).
82
- - `cli/helpers.py` - Shared workspace resolution used by all CLI commands.
83
- - `cli/workspace_cmd.py` - workspace list/add/remove/scan subcommands.
84
- - `cli/main.py` - Typer app, global `-w/--workspace` option, command registration.
85
- - `tui/app.py` - Textual dashboard with DataTable, filter, pull, freeze toggle.
76
+ - `core/config.py` — Workspace + Settings dataclasses. `get_workspaces()` with legacy migration shim.
77
+ - `core/repo.py` — Repo with workspace field, RepoStore with nested YAML format, legacy auto-migration.
78
+ - `core/discovery.py` — `discover_repos(root, layout)` supports structured and flat layouts.
79
+ - `core/url_parser.py` — URL parsing (the hardest part). Test changes here thoroughly.
80
+ - `core/git.py` — All git subprocess calls. Uses `git status --porcelain=v2 --branch` for single-call efficiency.
81
+ - `core/parallel.py` — Async execution with semaphore (max 6 concurrent).
82
+ - `core/status_model.py` — `RepoState` — the single source of truth for local (modified/staged/untracked) vs remote (in-sync/ahead/behind/diverged) classification, consumed by CLI, web, and JSON.
83
+ - `core/operations.py` — Shared `filter_repo_pairs()` + bulk-runner used by `pull`, `fetch`, and the MCP server so surfaces can't drift.
84
+ - `core/locking.py` — `file_lock()` cross-process advisory lock guarding `repos.yaml` against concurrent CLI/web writes.
85
+ - `cli/helpers.py` — Shared workspace resolution used by all CLI commands.
86
+ - `cli/workspace_cmd.py` — workspace list/add/remove/scan subcommands.
87
+ - `cli/main.py` — Typer app, global `-w/--workspace` option, command registration.
86
88
 
87
89
  ## Data Files
88
90
 
89
- - `~/.gitstow/config.yaml` - Settings (workspaces list, default host, SSH pref).
90
- - `~/.gitstow/repos.yaml` - Repo metadata nested by workspace label. Central location.
91
+ - `~/.gitstow/config.yaml` — Settings (workspaces list, default host, SSH pref).
92
+ - `~/.gitstow/repos.yaml` — Repo metadata nested by workspace label. Central location.
93
+ - `~/.gitstow/repos.lock` — Cross-process advisory lock file (`core/locking.py`) held during `repos.yaml` writes. Not user-facing data; safe to ignore/delete if orphaned.
91
94
 
92
95
  ### repos.yaml format
93
96
  ```yaml
94
97
  oss:
95
- anthropic/Codex:
96
- remote_url: https://github.com/anthropic/Codex.git
98
+ anthropic/claude-code:
99
+ remote_url: https://github.com/anthropic/claude-code.git
97
100
  tags: [ai]
98
101
  active:
99
102
  gitstow:
@@ -101,14 +104,14 @@ active:
101
104
  tags: [active]
102
105
  ```
103
106
 
104
- ## All Commands (32)
107
+ ## All Commands (37)
105
108
 
106
109
  **Core:** `add`, `pull`, `fetch`, `list`, `status`, `remove`, `migrate`
107
110
  **Workspace:** `workspace list`, `workspace add`, `workspace remove`, `workspace scan`
108
111
  **Repo management:** `repo freeze`, `repo unfreeze`, `repo tag`, `repo untag`, `repo tags`, `repo info`
109
112
  **Power:** `exec`, `search`, `open`, `stats`
110
113
  **Sharing:** `collection export`, `collection import`
111
- **Shell:** `shell pick`, `shell init`, `shell completions`, `shell setup`, `tui`, `ui`
114
+ **Shell:** `shell pick`, `shell init`, `shell completions`, `shell setup`, `ui`
112
115
  **Setup:** `onboard`, `config show/set/path/migrate-root`, `doctor`, `install-skill`, `setup-ai`, `update`
113
116
 
114
117
  ## Development
@@ -116,11 +119,13 @@ active:
116
119
  ```bash
117
120
  cd ~/labs/projects/gitstow
118
121
  pip install -e ".[dev]"
119
- pytest # 44 tests
122
+ pytest # full suite — keep green
120
123
  ruff check src/
121
- pip install -e ".[tui]" # For TUI development
122
124
  ```
123
125
 
126
+ - **Worktree gotcha:** tests run from a git worktree silently exercise the main checkout (the editable install points at the primary clone). From a worktree, run `PYTHONPATH=<worktree>/src .venv/bin/python -m pytest -q`.
127
+ - **Releasing publishes to PyPI.** `scripts/release.sh X.Y.Z` tags and pushes; the tag triggers a public PyPI publish. Require the user's explicit in-session instruction to release — plan approval or a "let's go" on implementation does not cover it.
128
+
124
129
  ## Patterns
125
130
 
126
131
  - `--json -j` and `--quiet -q` on all main commands
@@ -132,19 +137,19 @@ pip install -e ".[tui]" # For TUI development
132
137
  - asyncio with semaphore for parallel git ops
133
138
  - `git status --porcelain=v2 --branch` for single-call status (vs gita's 4-5 calls)
134
139
  - Repo.global_key (`workspace:key`) for unique identification across workspaces
135
- - Legacy format auto-migration (flat repos.yaml -> nested, root_path -> workspaces)
140
+ - Legacy format auto-migration (flat repos.yaml → nested, root_path → workspaces)
136
141
 
137
142
  ## AI Integration
138
143
 
139
- **Primary: Codex skill** (`src/gitstow/skill/SKILL.md`)
140
- - Installed to `~/.Codex/skills/gitstow/` via `gitstow install-skill` or `gitstow onboard`
144
+ **Primary: Claude Code skill** (`src/gitstow/skill/SKILL.md`)
145
+ - Installed to `~/.claude/skills/gitstow/` via `gitstow install-skill` or `gitstow onboard`
141
146
  - Auto-updates on version bumps (checks `.version` marker on every CLI invocation)
142
- - Zero context cost when inactive - only loaded when task matches the skill description
143
- - Codex runs gitstow CLI commands via Bash - full access to all commands
147
+ - Zero context cost when inactive — only loaded when task matches the skill description
148
+ - Claude runs gitstow CLI commands via Bash — full access to all commands
144
149
 
145
150
  **Optional: MCP server** (`src/gitstow/mcp/server.py`)
146
- - For non-Codex AI tools (Codex Desktop, Cursor, Windsurf)
151
+ - For non-Claude-Code AI tools (Claude Desktop, Cursor, Windsurf)
147
152
  - Install: `pip install gitstow[mcp]`, entry point: `gitstow-mcp`
148
- - 13 tools + 3 resources, wraps same `core/` modules as CLI
153
+ - 14 tools + 3 resources, wraps same `core/` modules as CLI
149
154
  - **Tradeoff:** MCP tools are always loaded into context (costs tokens even when idle).
150
155
  The skill has no such cost. Only use MCP for dedicated repo-management setups.
@@ -0,0 +1,43 @@
1
+ # Backlog
2
+
3
+ Post-v0.1.0 improvements tracked here. See [GitHub Issues](https://github.com/rishmadaan/gitstow/issues) for discussion.
4
+
5
+ ## Enhancements
6
+
7
+ - [x] **TUI: expand beyond read-only dashboard** (#1) — Added pull selected (P), workspace cycling (w), tag cycling (t)
8
+ - [x] **Shell completion for repo names** (#2) — `gitstow shell completions` for bash/zsh/fish; `--quiet` on list/tags/workspace list
9
+ - [x] **Network retry/resume for batch operations** (#3) — `--retry N` flag on add and pull; cleans up partial clones before retry
10
+ - [x] **Export format versioning and checksums** (#4) — Added `version: 1` to YAML/JSON exports; validates on import; backward-compatible with unversioned files
11
+ - [x] **Progress indication during long clones** (#5) — `git clone --progress`; pull shows live counter `[5/47]`
12
+ - [x] **Publish to PyPI** (#6) — Release workflow created (`.github/workflows/publish.yml`); publish on GitHub release
13
+ - [x] **Web dashboard (`gitstow ui`)** — Dark local browser UI wrapping core/ for daily repo management. FastAPI + Jinja2 + HTMX, dark + ember accent aesthetic. See [CHANGELOG.md](CHANGELOG.md) v0.2.0.
14
+ - [x] **Fix TUI breakage** — Resolved by retirement: the Textual TUI was removed in v0.3.0; `gitstow ui` (web dashboard) is the visual surface going forward.
15
+
16
+ ## Documentation
17
+
18
+ - [x] **Record demo GIF for README** (#7) — Recorded with VHS, embedded in README
19
+
20
+ ## Post-0.3.0 follow-ups
21
+
22
+ Triaged non-blocking items from the 2026-07 audit remediation (see
23
+ [docs/building/audit-2026-07-06.md](docs/building/audit-2026-07-06.md) for the full effort).
24
+
25
+ - [ ] **URL parser: schemeless multi-dot hosts** — `dev.azure.com/org/project/_git/repo` without
26
+ `https://` parses as owner/repo shorthand and builds a garbage clone URL (`_LOOKS_LIKE_HOST`
27
+ regex can't match a multi-dot first segment). Pre-existing; 0.3.1 candidate.
28
+ - [ ] **Route search subprocesses through a hardened runner** — `git grep`/`rg` in `cli/search.py`
29
+ and `mcp/server.py` shell raw `subprocess.run` without the `GIT_TERMINAL_PROMPT=0`/`LC_ALL=C`
30
+ env applied to all other git calls. Local-only operations, negligible risk — consistency cleanup.
31
+ - [ ] **Test strengthening batch** — frozen-collapse MCP test needs two frozen same-named repos;
32
+ `run_bulk` missing-status retry + `on_attempt` callback untested; locking mutual-exclusion test
33
+ passes without a lock (use an event-based barrier); status JSON legacy-key test covers 3/13 keys.
34
+ - [ ] **Small edges** — `add` on an on-disk repo with no remote falls through to a doomed clone;
35
+ whitespace-only `$EDITOR` raises IndexError; fully-untracked workspaces never get the untracked
36
+ hint (early return; `doctor` covers); dashboard vs single-row-refresh number sources diverge for
37
+ orphaned-workspace repos.
38
+ - [ ] **Product call: `pull --force` escape hatch** — CLI explicit args follow the bulk skip rule
39
+ while a web single-row Pull click pulls unconditionally; a `--force` flag would reconcile the
40
+ "explicit intent" asymmetry.
41
+ - [ ] **Product call: frozen + diverged + `--include-frozen`** — surfaces as an ff-only error row
42
+ instead of a clean "diverged" skip (check `remote_state` directly in the worker if the messaging
43
+ matters).
@@ -4,6 +4,36 @@ All notable changes to gitstow will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [0.5.0] - 2026-07-16
8
+
9
+ ### Added
10
+
11
+ - **Move repos between workspaces.** From the dashboard's repo detail page (new Workspace section: pick a target, confirm, done) or the new `gitstow repo move <repo> <workspace>` command. The folder physically relocates on disk following the target workspace's layout (structured `owner/repo` vs flat), the catalog updates in the same locked operation, existing tags are kept and the target's auto-tags merge in, and repos that own linked git worktrees get `git worktree repair` run automatically after the move.
12
+ - **Move safety net.** Collisions are refused before anything is touched (catalog, disk, even dangling symlinks); sources that can't move safely are refused with actionable errors (symlinked repos, linked-worktree gitfiles, relative `.git` symlinks, non-repo directories squatting on a tracked path); catalog keys can never escape their workspace on disk; and if anything fails mid-move, the rollback restores the folder without ever deleting data it can't prove is its own.
13
+
14
+ ## [0.4.0] - 2026-07-12
15
+
16
+ ### Added
17
+
18
+ - **Dashboard filters that actually filter.** The search box, workspace dropdown, and Hide-frozen toggle now work — instant client-side filtering that survives auto-refresh and pull updates.
19
+ - **Settings save.** The Settings page persists changes for real (and gains Parallel limit + Clone timeout fields).
20
+ - **`local` badge.** Repos without an upstream remote show a `local` Remote Δ badge; bulk pulls skip them with a clear reason instead of failing every run.
21
+ - **Responsive dashboard.** Works down to half-monitor width — columns collapse by priority, the table scrolls within its own container, and row menus flip upward when space runs out.
22
+ - **Last-fetched visibility.** The repo detail page shows when each repo was last pulled AND last fetched (hover for exact times); Remote Δ tooltips state which fetch the counts reflect.
23
+
24
+ ### Changed
25
+
26
+ - **Fully offline dashboard.** htmx and both fonts are now bundled — no CDN, no network needed for the UI itself.
27
+ - **Styled confirmations.** Native browser confirm/alert dialogs replaced with an in-app dialog (also makes the dashboard automatable).
28
+ - **Web collection import honors recorded workspaces**, sharing one implementation with the CLI.
29
+ - **Honest metrics chips.** Diverged and missing repos get their own hero chips instead of hiding inside 'conflict'; the pull summary reads 'N attempted' with exclusions stated.
30
+ - **Cleaner micro-interactions.** Styled file picker, a LIVE dot that actually goes red when the server is unreachable, keyboard-visible focus rings, Escape closes menus, add-repo shows a Cloning… state.
31
+
32
+ ### Fixed
33
+
34
+ - **Pull all / Fetch all spinners stop when the operation completes** (htmx indicator/disable double-count).
35
+ - **Repo detail timestamps** no longer render raw machine format.
36
+
7
37
  ## [0.3.0] - 2026-07-12
8
38
 
9
39
  ### Added
@@ -107,6 +107,9 @@ pytest # full suite — keep green
107
107
  ruff check src/
108
108
  ```
109
109
 
110
+ - **Worktree gotcha:** tests run from a git worktree silently exercise the main checkout (the editable install points at the primary clone). From a worktree, run `PYTHONPATH=<worktree>/src .venv/bin/python -m pytest -q`.
111
+ - **Releasing publishes to PyPI.** `scripts/release.sh X.Y.Z` tags and pushes; the tag triggers a public PyPI publish. Require the user's explicit in-session instruction to release — plan approval or a "let's go" on implementation does not cover it.
112
+
110
113
  ## Patterns
111
114
 
112
115
  - `--json -j` and `--quiet -q` on all main commands
@@ -128,6 +131,7 @@ ruff check src/
128
131
  - For repo state presentation, avoid using "dirty" as a broad user-facing bucket for every local change. Present it as local/uncommitted changes with the composition visible: modified, staged, and untracked counts.
129
132
  - Keep local working-tree state separate from remote relationship state. For example: local changes, clean, ahead, behind, diverged, frozen, missing.
130
133
  - When improving the web dashboard, implement the actual missing dashboard feature and shared classification/model behavior instead of copying a CLI-only assumption into the template.
134
+ - For `web/` changes, HTTP-level tests (pytest TestClient, curl) are necessary but not sufficient — they pass on bugs that live below the HTTP layer. Before calling a UI change done, verify form structure against the parsed DOM (browsers silently drop nested `<form>` tags) and verify layout/geometry in a real browser (e.g. `overflow-x: auto` clips absolutely-positioned children even without horizontal overflow).
131
135
 
132
136
  ## AI Integration
133
137
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitstow
3
- Version: 0.3.0
3
+ Version: 0.5.0
4
4
  Summary: A git repository library manager — clone, organize, and maintain collections of repos you learn from
5
5
  Project-URL: Homepage, https://github.com/rishmadaan/gitstow
6
6
  Project-URL: Repository, https://github.com/rishmadaan/gitstow