wade-cli 0.0.1__tar.gz → 0.0.2__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 (199) hide show
  1. wade_cli-0.0.2/.claude/settings.local.json +37 -0
  2. wade_cli-0.0.2/.github/workflows/ci.yml +89 -0
  3. wade_cli-0.0.2/.github/workflows/publish.yml +17 -0
  4. wade_cli-0.0.2/.github/workflows/release.yml +33 -0
  5. wade_cli-0.0.2/.gitignore +42 -0
  6. wade_cli-0.0.2/.pre-commit-config.yaml +34 -0
  7. wade_cli-0.0.2/AGENTS.md +183 -0
  8. wade_cli-0.0.2/CHANGELOG.md +9 -0
  9. wade_cli-0.0.2/CLAUDE.md +1 -0
  10. wade_cli-0.0.2/CONTRIBUTING.md +98 -0
  11. wade_cli-0.0.2/Dockerfile +37 -0
  12. wade_cli-0.0.2/PKG-INFO +218 -0
  13. wade_cli-0.0.2/README.md +183 -0
  14. wade_cli-0.0.2/assets/wade.png +0 -0
  15. wade_cli-0.0.2/docker-compose.yml +42 -0
  16. wade_cli-0.0.2/docs/dev/architecture.md +303 -0
  17. wade_cli-0.0.2/docs/dev/documentation-policies.md +64 -0
  18. wade_cli-0.0.2/docs/dev/extending.md +64 -0
  19. wade_cli-0.0.2/docs/dev/skills-system.md +116 -0
  20. wade_cli-0.0.2/docs/dev/testing.md +121 -0
  21. wade_cli-0.0.2/install.sh +50 -0
  22. wade_cli-0.0.2/pyproject.toml +99 -0
  23. wade_cli-0.0.2/scripts/auto_version.py +159 -0
  24. wade_cli-0.0.2/scripts/changelog.py +195 -0
  25. wade_cli-0.0.2/scripts/check-all.sh +6 -0
  26. wade_cli-0.0.2/scripts/check.sh +33 -0
  27. wade_cli-0.0.2/scripts/e2e_smoke.sh +216 -0
  28. wade_cli-0.0.2/scripts/fmt.sh +4 -0
  29. wade_cli-0.0.2/scripts/hooks/pre-push +103 -0
  30. wade_cli-0.0.2/scripts/install-hooks.sh +54 -0
  31. wade_cli-0.0.2/scripts/probe_models.py +344 -0
  32. wade_cli-0.0.2/scripts/probe_models.sh +3 -0
  33. wade_cli-0.0.2/scripts/setup-release.sh +187 -0
  34. wade_cli-0.0.2/scripts/test.sh +7 -0
  35. wade_cli-0.0.2/src/wade/__init__.py +3 -0
  36. wade_cli-0.0.2/src/wade/__main__.py +5 -0
  37. wade_cli-0.0.2/src/wade/ai_tools/__init__.py +16 -0
  38. wade_cli-0.0.2/src/wade/ai_tools/antigravity.py +54 -0
  39. wade_cli-0.0.2/src/wade/ai_tools/base.py +280 -0
  40. wade_cli-0.0.2/src/wade/ai_tools/claude.py +77 -0
  41. wade_cli-0.0.2/src/wade/ai_tools/codex.py +53 -0
  42. wade_cli-0.0.2/src/wade/ai_tools/copilot.py +58 -0
  43. wade_cli-0.0.2/src/wade/ai_tools/gemini.py +45 -0
  44. wade_cli-0.0.2/src/wade/ai_tools/model_utils.py +49 -0
  45. wade_cli-0.0.2/src/wade/ai_tools/opencode.py +70 -0
  46. wade_cli-0.0.2/src/wade/ai_tools/transcript.py +714 -0
  47. wade_cli-0.0.2/src/wade/ai_tools/vscode.py +53 -0
  48. wade_cli-0.0.2/src/wade/cli/__init__.py +1 -0
  49. wade_cli-0.0.2/src/wade/cli/admin.py +134 -0
  50. wade_cli-0.0.2/src/wade/cli/autocomplete.py +35 -0
  51. wade_cli-0.0.2/src/wade/cli/main.py +224 -0
  52. wade_cli-0.0.2/src/wade/cli/task.py +236 -0
  53. wade_cli-0.0.2/src/wade/cli/work.py +244 -0
  54. wade_cli-0.0.2/src/wade/config/__init__.py +5 -0
  55. wade_cli-0.0.2/src/wade/config/claude_allowlist.py +70 -0
  56. wade_cli-0.0.2/src/wade/config/defaults.py +54 -0
  57. wade_cli-0.0.2/src/wade/config/loader.py +165 -0
  58. wade_cli-0.0.2/src/wade/config/migrations.py +62 -0
  59. wade_cli-0.0.2/src/wade/config/schema.py +31 -0
  60. wade_cli-0.0.2/src/wade/data/__init__.py +18 -0
  61. wade_cli-0.0.2/src/wade/data/models.json +128 -0
  62. wade_cli-0.0.2/src/wade/db/__init__.py +27 -0
  63. wade_cli-0.0.2/src/wade/db/engine.py +85 -0
  64. wade_cli-0.0.2/src/wade/db/repositories.py +261 -0
  65. wade_cli-0.0.2/src/wade/db/tables.py +131 -0
  66. wade_cli-0.0.2/src/wade/git/__init__.py +67 -0
  67. wade_cli-0.0.2/src/wade/git/branch.py +140 -0
  68. wade_cli-0.0.2/src/wade/git/pr.py +273 -0
  69. wade_cli-0.0.2/src/wade/git/repo.py +430 -0
  70. wade_cli-0.0.2/src/wade/git/sync.py +130 -0
  71. wade_cli-0.0.2/src/wade/git/worktree.py +160 -0
  72. wade_cli-0.0.2/src/wade/logging/__init__.py +1 -0
  73. wade_cli-0.0.2/src/wade/logging/context.py +18 -0
  74. wade_cli-0.0.2/src/wade/logging/setup.py +41 -0
  75. wade_cli-0.0.2/src/wade/models/__init__.py +58 -0
  76. wade_cli-0.0.2/src/wade/models/ai.py +89 -0
  77. wade_cli-0.0.2/src/wade/models/config.py +144 -0
  78. wade_cli-0.0.2/src/wade/models/deps.py +152 -0
  79. wade_cli-0.0.2/src/wade/models/events.py +45 -0
  80. wade_cli-0.0.2/src/wade/models/task.py +188 -0
  81. wade_cli-0.0.2/src/wade/models/work.py +76 -0
  82. wade_cli-0.0.2/src/wade/providers/__init__.py +6 -0
  83. wade_cli-0.0.2/src/wade/providers/base.py +146 -0
  84. wade_cli-0.0.2/src/wade/providers/github.py +511 -0
  85. wade_cli-0.0.2/src/wade/providers/registry.py +24 -0
  86. wade_cli-0.0.2/src/wade/services/__init__.py +1 -0
  87. wade_cli-0.0.2/src/wade/services/ai_resolution.py +93 -0
  88. wade_cli-0.0.2/src/wade/services/check_service.py +427 -0
  89. wade_cli-0.0.2/src/wade/services/deps_service.py +530 -0
  90. wade_cli-0.0.2/src/wade/services/init_service.py +1317 -0
  91. wade_cli-0.0.2/src/wade/services/plan_service.py +743 -0
  92. wade_cli-0.0.2/src/wade/services/prompt_delivery.py +37 -0
  93. wade_cli-0.0.2/src/wade/services/task_service.py +712 -0
  94. wade_cli-0.0.2/src/wade/services/work_service.py +2284 -0
  95. wade_cli-0.0.2/src/wade/skills/__init__.py +1 -0
  96. wade_cli-0.0.2/src/wade/skills/installer.py +234 -0
  97. wade_cli-0.0.2/src/wade/skills/pointer.py +195 -0
  98. wade_cli-0.0.2/src/wade/ui/__init__.py +5 -0
  99. wade_cli-0.0.2/src/wade/ui/console.py +363 -0
  100. wade_cli-0.0.2/src/wade/ui/prompts.py +192 -0
  101. wade_cli-0.0.2/src/wade/utils/__init__.py +1 -0
  102. wade_cli-0.0.2/src/wade/utils/clipboard.py +43 -0
  103. wade_cli-0.0.2/src/wade/utils/install.py +105 -0
  104. wade_cli-0.0.2/src/wade/utils/markdown.py +166 -0
  105. wade_cli-0.0.2/src/wade/utils/process.py +130 -0
  106. wade_cli-0.0.2/src/wade/utils/slug.py +35 -0
  107. wade_cli-0.0.2/src/wade/utils/terminal.py +281 -0
  108. wade_cli-0.0.2/src/wade/utils/update_check.py +141 -0
  109. wade_cli-0.0.2/templates/agents-pointer.md +11 -0
  110. wade_cli-0.0.2/templates/prompts/deps-analysis.md +16 -0
  111. wade_cli-0.0.2/templates/prompts/deps-interactive.md +2 -0
  112. wade_cli-0.0.2/templates/prompts/plan-session.md +42 -0
  113. wade_cli-0.0.2/templates/prompts/work-context.md +9 -0
  114. wade_cli-0.0.2/templates/skills/deps/SKILL.md +92 -0
  115. wade_cli-0.0.2/templates/skills/plan-session/SKILL.md +106 -0
  116. wade_cli-0.0.2/templates/skills/task/SKILL.md +227 -0
  117. wade_cli-0.0.2/templates/skills/task/examples.md +132 -0
  118. wade_cli-0.0.2/templates/skills/task/plan-format.md +81 -0
  119. wade_cli-0.0.2/templates/skills/work-session/SKILL.md +184 -0
  120. wade_cli-0.0.2/templates/statusline-command.sh +126 -0
  121. wade_cli-0.0.2/tests/__init__.py +1 -0
  122. wade_cli-0.0.2/tests/conftest.py +104 -0
  123. wade_cli-0.0.2/tests/e2e/__init__.py +1 -0
  124. wade_cli-0.0.2/tests/e2e/test_live_workflow.py +161 -0
  125. wade_cli-0.0.2/tests/e2e/test_workflow_chain.py +572 -0
  126. wade_cli-0.0.2/tests/fixtures/transcripts/claude_session.txt +57 -0
  127. wade_cli-0.0.2/tests/fixtures/transcripts/codex_session.txt +4 -0
  128. wade_cli-0.0.2/tests/fixtures/transcripts/copilot_session.txt +48 -0
  129. wade_cli-0.0.2/tests/fixtures/transcripts/gemini_session.txt +30 -0
  130. wade_cli-0.0.2/tests/fixtures/transcripts/generic_session.txt +10 -0
  131. wade_cli-0.0.2/tests/integration/__init__.py +1 -0
  132. wade_cli-0.0.2/tests/integration/test_check.py +45 -0
  133. wade_cli-0.0.2/tests/integration/test_git.py +460 -0
  134. wade_cli-0.0.2/tests/integration/test_init.py +49 -0
  135. wade_cli-0.0.2/tests/integration/test_skill_install.py +60 -0
  136. wade_cli-0.0.2/tests/integration/test_work_lifecycle.py +268 -0
  137. wade_cli-0.0.2/tests/live/__init__.py +1 -0
  138. wade_cli-0.0.2/tests/live/test_gh_integration.py +60 -0
  139. wade_cli-0.0.2/tests/test_cli_basics.py +112 -0
  140. wade_cli-0.0.2/tests/unit/__init__.py +1 -0
  141. wade_cli-0.0.2/tests/unit/test_ai_tools/__init__.py +1 -0
  142. wade_cli-0.0.2/tests/unit/test_ai_tools/test_base_registry.py +243 -0
  143. wade_cli-0.0.2/tests/unit/test_ai_tools/test_model_registry.py +58 -0
  144. wade_cli-0.0.2/tests/unit/test_cli/__init__.py +1 -0
  145. wade_cli-0.0.2/tests/unit/test_cli/test_shell_init.py +72 -0
  146. wade_cli-0.0.2/tests/unit/test_cli/test_work_ai_flags.py +39 -0
  147. wade_cli-0.0.2/tests/unit/test_config/__init__.py +1 -0
  148. wade_cli-0.0.2/tests/unit/test_config/test_claude_allowlist.py +227 -0
  149. wade_cli-0.0.2/tests/unit/test_config/test_loader.py +172 -0
  150. wade_cli-0.0.2/tests/unit/test_config/test_migrations.py +104 -0
  151. wade_cli-0.0.2/tests/unit/test_config/test_migrations_atomic.py +119 -0
  152. wade_cli-0.0.2/tests/unit/test_db/__init__.py +0 -0
  153. wade_cli-0.0.2/tests/unit/test_db/test_repository_transactions.py +114 -0
  154. wade_cli-0.0.2/tests/unit/test_git/__init__.py +0 -0
  155. wade_cli-0.0.2/tests/unit/test_git/test_branch_slugify.py +76 -0
  156. wade_cli-0.0.2/tests/unit/test_git/test_repo.py +87 -0
  157. wade_cli-0.0.2/tests/unit/test_git/test_scaffold_commit.py +89 -0
  158. wade_cli-0.0.2/tests/unit/test_git/test_sync_conflicted_files.py +107 -0
  159. wade_cli-0.0.2/tests/unit/test_git/test_worktree_remove.py +63 -0
  160. wade_cli-0.0.2/tests/unit/test_models/__init__.py +1 -0
  161. wade_cli-0.0.2/tests/unit/test_models/test_ai_tools.py +289 -0
  162. wade_cli-0.0.2/tests/unit/test_models/test_config_models.py +71 -0
  163. wade_cli-0.0.2/tests/unit/test_models/test_db.py +200 -0
  164. wade_cli-0.0.2/tests/unit/test_models/test_deps_models.py +85 -0
  165. wade_cli-0.0.2/tests/unit/test_models/test_deps_partition.py +58 -0
  166. wade_cli-0.0.2/tests/unit/test_models/test_task_models.py +122 -0
  167. wade_cli-0.0.2/tests/unit/test_providers/__init__.py +0 -0
  168. wade_cli-0.0.2/tests/unit/test_providers/test_github.py +592 -0
  169. wade_cli-0.0.2/tests/unit/test_providers/test_github_pr.py +58 -0
  170. wade_cli-0.0.2/tests/unit/test_services/__init__.py +1 -0
  171. wade_cli-0.0.2/tests/unit/test_services/test_bootstrap_hook_timeout.py +123 -0
  172. wade_cli-0.0.2/tests/unit/test_services/test_check.py +215 -0
  173. wade_cli-0.0.2/tests/unit/test_services/test_deps_service.py +368 -0
  174. wade_cli-0.0.2/tests/unit/test_services/test_done_plan_flag.py +151 -0
  175. wade_cli-0.0.2/tests/unit/test_services/test_done_via_direct_cleanup.py +259 -0
  176. wade_cli-0.0.2/tests/unit/test_services/test_init.py +821 -0
  177. wade_cli-0.0.2/tests/unit/test_services/test_init_shell_integration.py +244 -0
  178. wade_cli-0.0.2/tests/unit/test_services/test_plan_service.py +472 -0
  179. wade_cli-0.0.2/tests/unit/test_services/test_post_work_lifecycle.py +408 -0
  180. wade_cli-0.0.2/tests/unit/test_services/test_pr_summary_path.py +108 -0
  181. wade_cli-0.0.2/tests/unit/test_services/test_prompt_delivery.py +51 -0
  182. wade_cli-0.0.2/tests/unit/test_services/test_task_service.py +373 -0
  183. wade_cli-0.0.2/tests/unit/test_services/test_work_done_sync.py +873 -0
  184. wade_cli-0.0.2/tests/unit/test_services/test_work_service.py +759 -0
  185. wade_cli-0.0.2/tests/unit/test_transcript/__init__.py +1 -0
  186. wade_cli-0.0.2/tests/unit/test_transcript/test_parser.py +632 -0
  187. wade_cli-0.0.2/tests/unit/test_utils/__init__.py +1 -0
  188. wade_cli-0.0.2/tests/unit/test_utils/test_install.py +245 -0
  189. wade_cli-0.0.2/tests/unit/test_utils/test_markdown.py +206 -0
  190. wade_cli-0.0.2/tests/unit/test_utils/test_process.py +143 -0
  191. wade_cli-0.0.2/tests/unit/test_utils/test_prompts.py +48 -0
  192. wade_cli-0.0.2/tests/unit/test_utils/test_slug.py +42 -0
  193. wade_cli-0.0.2/tests/unit/test_utils/test_terminal.py +37 -0
  194. wade_cli-0.0.2/tests/unit/test_utils/test_terminal_launch.py +273 -0
  195. wade_cli-0.0.2/tests/unit/test_utils/test_update_check.py +268 -0
  196. wade_cli-0.0.1/PKG-INFO +0 -27
  197. wade_cli-0.0.1/README.md +0 -7
  198. wade_cli-0.0.1/pyproject.toml +0 -32
  199. wade_cli-0.0.1/src/wade_cli/__init__.py +0 -3
@@ -0,0 +1,37 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(uv run:*)",
5
+ "Bash(git:*)",
6
+ "Bash(chmod +x:*)",
7
+ "Bash(bash:*)",
8
+ "Bash(grep:*)",
9
+ "Bash(ls:*)",
10
+ "Bash(python3:*)",
11
+ "Bash(find:*)",
12
+ "WebSearch",
13
+ "WebFetch(domain:opencode.ai)",
14
+ "WebFetch(domain:github.com)",
15
+ "Bash(python:*)",
16
+ "Bash(uv pip:*)",
17
+ "Bash(codex:*)",
18
+ "Bash(copilot:*)",
19
+ "Bash(gh api:*)",
20
+ "Bash(gh issue:*)",
21
+ "Bash(gh pr:*)",
22
+ "Bash(.venv/bin/pytest:*)",
23
+ "Bash(.venv/bin/mypy:*)",
24
+ "Bash(.venv/bin/ruff:*)",
25
+ "Bash(./scripts/check.sh:*)",
26
+ "Bash(./scripts/test.sh:*)",
27
+ "Bash(./scripts/fmt.sh:*)",
28
+ "Bash(./scripts/check-all.sh:*)",
29
+ "Bash(xargs cat:*)",
30
+ "Bash(uv build:*)",
31
+ "Bash(wade implement-task:*)",
32
+ "Bash(wade work:*)",
33
+ "Bash(wade plan-task:*)",
34
+ "Bash(gh run:*)"
35
+ ]
36
+ }
37
+ }
@@ -0,0 +1,89 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: astral-sh/setup-uv@v3
15
+ with:
16
+ version: "latest"
17
+ - name: Set up Python
18
+ run: uv python install 3.13
19
+ - name: Install dependencies
20
+ run: uv sync --all-extras
21
+ - name: Lint with ruff
22
+ run: uv run ruff check src/ tests/
23
+ - name: Format check with ruff
24
+ run: uv run ruff format --check src/ tests/
25
+
26
+ typecheck:
27
+ runs-on: ubuntu-latest
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+ - uses: astral-sh/setup-uv@v3
31
+ with:
32
+ version: "latest"
33
+ - name: Set up Python
34
+ run: uv python install 3.13
35
+ - name: Install dependencies
36
+ run: uv sync --all-extras
37
+ - name: Type check with mypy
38
+ run: uv run mypy src/ --strict
39
+
40
+ test:
41
+ runs-on: ubuntu-latest
42
+ strategy:
43
+ matrix:
44
+ python-version: ["3.11", "3.12", "3.13"]
45
+ steps:
46
+ - uses: actions/checkout@v4
47
+ - uses: astral-sh/setup-uv@v3
48
+ with:
49
+ version: "latest"
50
+ - name: Set up Python ${{ matrix.python-version }}
51
+ run: uv python install ${{ matrix.python-version }}
52
+ - name: Install dependencies
53
+ run: uv sync --all-extras
54
+ - name: Configure git
55
+ run: |
56
+ git config --global user.email "test@wade.dev"
57
+ git config --global user.name "wade test"
58
+ git config --global init.defaultBranch main
59
+ - name: Run unit tests
60
+ run: uv run pytest tests/unit/ -v --tb=short
61
+ - name: Run integration tests
62
+ run: uv run pytest tests/integration/ -v --tb=short
63
+
64
+ test-live:
65
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
66
+ runs-on: ubuntu-latest
67
+ needs: [test]
68
+ env:
69
+ RUN_LIVE_GH_TESTS: "1"
70
+ GH_TOKEN: ${{ secrets.GH_TOKEN }}
71
+ steps:
72
+ - uses: actions/checkout@v4
73
+ - uses: astral-sh/setup-uv@v3
74
+ with:
75
+ version: "latest"
76
+ - name: Set up Python
77
+ run: uv python install 3.13
78
+ - name: Install dependencies
79
+ run: uv sync --all-extras
80
+ - name: Install gh CLI
81
+ run: |
82
+ type -p curl >/dev/null || (sudo apt update && sudo apt install curl -y)
83
+ curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
84
+ sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
85
+ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
86
+ sudo apt update && sudo apt install gh -y
87
+ - name: Run live tests
88
+ if: env.GH_TOKEN != ''
89
+ run: uv run pytest tests/live/ -v --tb=short
@@ -0,0 +1,17 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ environment: pypi
11
+ permissions:
12
+ id-token: write
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: astral-sh/setup-uv@v4
16
+ - run: uv build
17
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,33 @@
1
+ name: Create Draft Release
2
+
3
+ on:
4
+ push:
5
+ tags: ['v*']
6
+
7
+ jobs:
8
+ draft-release:
9
+ runs-on: ubuntu-latest
10
+ permissions:
11
+ contents: write
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ with:
15
+ fetch-depth: 0
16
+
17
+ - name: Extract changelog section
18
+ id: changelog
19
+ run: |
20
+ VERSION="${GITHUB_REF_NAME}"
21
+ NOTES=$(awk "/^## \[${VERSION}\]/{found=1; next} found && /^## \[/{exit} found{print}" CHANGELOG.md)
22
+ echo "notes<<EOF" >> $GITHUB_OUTPUT
23
+ echo "$NOTES" >> $GITHUB_OUTPUT
24
+ echo "EOF" >> $GITHUB_OUTPUT
25
+
26
+ - name: Create draft release
27
+ env:
28
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29
+ run: |
30
+ gh release create "$GITHUB_REF_NAME" \
31
+ --draft \
32
+ --title "$GITHUB_REF_NAME" \
33
+ --notes "${{ steps.changelog.outputs.notes }}"
@@ -0,0 +1,42 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.egg-info/
6
+ *.egg
7
+ dist/
8
+ build/
9
+ .eggs/
10
+
11
+ # Virtual environments
12
+ .venv/
13
+ venv/
14
+ env/
15
+
16
+ # IDE
17
+ .idea/
18
+ .vscode/
19
+ *.swp
20
+ *.swo
21
+
22
+ # Testing
23
+ .pytest_cache/
24
+ .coverage
25
+ htmlcov/
26
+ .mypy_cache/
27
+
28
+ # wade runtime (per-project, gitignored)
29
+ .wade/
30
+
31
+ # OS
32
+ .DS_Store
33
+ Thumbs.db
34
+
35
+ # uv
36
+ uv.lock
37
+
38
+ # Temporary commit message file (agents use this to avoid rewriting on hook retries)
39
+ .commit-msg
40
+
41
+ # Local archive (pre-reset export)
42
+ archive/
@@ -0,0 +1,34 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.15.2
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+
9
+ - repo: https://github.com/pre-commit/mirrors-mypy
10
+ rev: v1.15.0
11
+ hooks:
12
+ - id: mypy
13
+ args: [--strict]
14
+ additional_dependencies:
15
+ - typer>=0.12
16
+ - pydantic>=2.0
17
+ - pydantic-settings>=2.0
18
+ - sqlmodel>=0.0.16
19
+ - pyyaml>=6.0
20
+ - rich>=13.0
21
+ - structlog>=24.0
22
+ - types-PyYAML>=6.0
23
+ pass_filenames: false
24
+ entry: mypy src/
25
+
26
+ - repo: https://github.com/pre-commit/pre-commit-hooks
27
+ rev: v5.0.0
28
+ hooks:
29
+ - id: trailing-whitespace
30
+ - id: end-of-file-fixer
31
+ - id: check-yaml
32
+ - id: check-added-large-files
33
+ args: [--maxkb=500]
34
+ - id: check-merge-conflict
@@ -0,0 +1,183 @@
1
+ # AGENTS.md
2
+
3
+ This file provides guidance to AI agents working on the WADE codebase.
4
+ For detailed reference on specific topics, see `docs/dev/`.
5
+
6
+ ## Project Overview
7
+
8
+ **WADE** (Workflow for AI-Driven Engineering) is a Python CLI toolkit for AI-agent-driven git workflow management. It wraps `gh` CLI and native git to manage GitHub Issues as tasks, git worktrees for isolated development, branch safety checks, and installable Agent Skill files. CLI entry point: **`wade`**.
9
+
10
+ ## Terminology
11
+
12
+ Two distinct worlds interact in this codebase. Always be clear which one you are working in:
13
+
14
+ | Term | Meaning |
15
+ |------|---------|
16
+ | **the WADE repo** / **this project** | This source repository — `src/wade/`, `templates/`, `tests/`, `scripts/` |
17
+ | **inited project** / **target project** | Any third-party repo that has run `wade init` to adopt the workflow |
18
+ | **skill templates** | Markdown files in `templates/skills/` — the source of truth, part of the WADE repo |
19
+ | **installed skills** | Copies (or symlinks) of skill templates placed in a project's `.claude/skills/` by `wade init` |
20
+ | **AGENTS.md pointer** | A short `## Git Workflow` block that `wade init` injects into an inited project's `AGENTS.md` |
21
+
22
+ **This `AGENTS.md` governs development of WADE itself.** Skills, the pointer, and the progressive disclosure architecture are all *outputs* of WADE — artifacts installed into inited projects, not rules for developing WADE.
23
+
24
+ **WADE uses its own workflow.** This repo is itself an inited project. Follow the `## Git Workflow` pointer at the bottom and the phase-specific skill referenced in your clipboard prompt.
25
+
26
+ ## Commands
27
+
28
+ > **AI agents: always run the scripts below — never improvise raw `uv run pytest` / `mypy` / `ruff` calls.**
29
+
30
+ | Script | Purpose |
31
+ |--------|---------|
32
+ | `./scripts/test.sh` | Run all tests (excludes live) |
33
+ | `./scripts/test.sh tests/unit/` | Unit tests only |
34
+ | `./scripts/check.sh` | Lint + type-check (both) |
35
+ | `./scripts/check.sh --lint` | Lint + format check only |
36
+ | `./scripts/check.sh --types` | Type check (strict mypy) only |
37
+ | `./scripts/fmt.sh` | Auto-format source in-place |
38
+ | `./scripts/check-all.sh` | Full checklist (test + check) |
39
+
40
+ ```bash
41
+ uv pip install -e ".[dev]" # Install for development
42
+ python scripts/auto_version.py patch # Version bump (patch/minor/major)
43
+
44
+ # Version bumps MUST be done with the script above. NEVER bump pyproject.toml
45
+ # manually, as the script generates CHANGELOG.md and git tags automatically.
46
+ ```
47
+
48
+ > Full commands reference: see `docs/dev/architecture.md`
49
+
50
+ ## Architecture
51
+
52
+ ```
53
+ CLI Layer -> can import: services, models, config, logging, ui
54
+ Service Layer -> can import: providers, ai_tools, git, db, models, config, logging
55
+ Provider Layer -> can import: models, config, logging (NO service imports)
56
+ AI Tool Layer -> can import: models, config, logging (NO service imports)
57
+ Git Layer -> can import: models, config, logging (NO service imports)
58
+ DB Layer -> can import: models, logging (NO config imports)
59
+ Models Layer -> can import: nothing (leaf dependency)
60
+ ```
61
+
62
+ No circular dependencies. Models are pure data. Services orchestrate. **Never import a higher layer from a lower layer.**
63
+
64
+ CLI modules are thin dispatch — they parse flags via Typer, then call service methods. Business logic lives in `services/`, not in `cli/`.
65
+
66
+ > Full package structure, command dispatch, config system, and subsystem details: see `docs/dev/architecture.md`
67
+
68
+ ### Key Design Patterns
69
+
70
+ - **AI Tool Self-Registration**: `AbstractAITool.__init_subclass__` auto-registers adapters. Adding a new AI tool = one file, one class.
71
+ - **Provider Abstraction**: `AbstractTaskProvider` ABC with pluggable backends (currently GitHub via `gh` CLI).
72
+ - **Prompts as .md Templates**: All AI prompts live in `templates/prompts/`, not inline strings.
73
+ - **Synchronous Only**: No asyncio. Process-level parallelism via multiple terminals.
74
+ - **Pydantic Everywhere**: All data structures are Pydantic `BaseModel` subclasses, not dicts.
75
+
76
+ ## Design Principles
77
+
78
+ ### Determinism via Services
79
+
80
+ All deterministic operations — git commands, state transitions, file manipulation, API calls — **must live in service/utility code**, never in AI agent reasoning.
81
+
82
+ - **Code decides and executes** — fetch, merge, branch creation, worktree lifecycle, issue state changes. Codified in `services/`, `git/`, `providers/`.
83
+ - **Agents interpret and decide** — reading conflict diffs, choosing resolution strategies, composing commit messages. Guided by skills.
84
+
85
+ **Test**: "Can an AI agent get this wrong by reasoning about it?" If yes, put it in code.
86
+
87
+ ### Two Worlds
88
+
89
+ Everything in this repo exists in one of two worlds:
90
+
91
+ | WADE repo (source) | Inited project (output) |
92
+ |---------------------|------------------------|
93
+ | `src/wade/` | installed `wade` binary |
94
+ | `templates/skills/<name>/SKILL.md` | `.claude/skills/<name>/SKILL.md` |
95
+ | `templates/agents-pointer.md` | `## Git Workflow` block in target `AGENTS.md` |
96
+ | `AGENTS.md` (this file) | target project's own `AGENTS.md` |
97
+
98
+ When developing WADE, **only touch the left column**. Always edit `templates/skills/<name>/SKILL.md` directly — never edit files inside `.claude/skills/` (those are symlinks in this repo, copies in inited projects).
99
+
100
+ > Skills system deep dive (symlinks, pointer markers, installation lifecycle): see `docs/dev/skills-system.md`
101
+
102
+ ## Conventions
103
+
104
+ ### Naming
105
+
106
+ - **Modules**: `snake_case.py` — one module per concern
107
+ - **Classes**: `PascalCase` — Pydantic models, ABCs, adapters
108
+ - **Functions**: `snake_case` — `_` prefix for private helpers
109
+ - **Constants**: `UPPER_SNAKE_CASE`
110
+ - **Enums**: `StrEnum` for string-valued enums
111
+ - **CLI commands**: top-level commands (`wade plan-task`, `wade implement-task`)
112
+
113
+ ### Commits
114
+
115
+ Use [Conventional Commits](https://www.conventionalcommits.org/):
116
+ `feat:` (minor), `fix:` (patch), `docs:` (patch), `refactor:` (patch),
117
+ `test:` (patch), `chore:` (patch). Breaking changes (`feat!:`) -> major.
118
+
119
+ **Before every commit — mandatory sequence (Python changes only):**
120
+
121
+ > Skip this if your commit touches only non-Python files (e.g. `.md`, `.gitignore`, `templates/`).
122
+
123
+ ```bash
124
+ ./scripts/fmt.sh # auto-fix formatting in-place
125
+ ./scripts/check.sh --lint # verify lint passes — fix any remaining errors before proceeding
126
+ ```
127
+
128
+ **Commit using a message file** (handles pre-commit hook retries without rewriting the message):
129
+
130
+ ```bash
131
+ # Write message once
132
+ cat > .commit-msg << 'EOF'
133
+ feat: your message here
134
+ EOF
135
+
136
+ git add <files>
137
+ git commit -F .commit-msg
138
+
139
+ # If hooks auto-modified files, just re-add and retry — same file:
140
+ git add <auto-modified-files>
141
+ git commit -F .commit-msg
142
+ ```
143
+
144
+ `.commit-msg` is gitignored — never committed.
145
+
146
+ ## Change Checklist
147
+
148
+ Before considering any work complete:
149
+
150
+ - [ ] **Code** — `./scripts/test.sh` passes
151
+ - [ ] **Types + Lint** — `./scripts/check.sh` passes (or run both at once: `./scripts/check-all.sh`)
152
+ - [ ] **`AGENTS.md`** — updated if architecture, conventions, or workflow changed
153
+ - [ ] **`README.md`** — updated if user-facing behavior changed
154
+ - [ ] **`templates/skills/`** — updated if agent-facing rules changed (plan-session for planning, work-session for implementation)
155
+ - [ ] **Commit** — uses conventional-commit prefix
156
+
157
+ > Full 10-item checklist, documentation rules, feedback loop, and correction-driven docs: see `docs/dev/documentation-policies.md`
158
+
159
+ ## Detailed Reference
160
+
161
+ Read these on-demand when working in a specific area:
162
+
163
+ | When you are... | Read |
164
+ |-----------------|------|
165
+ | Modifying architecture, config, or commands | `docs/dev/architecture.md` |
166
+ | Adding an AI tool, provider, or subcommand | `docs/dev/extending.md` |
167
+ | Writing or running tests | `docs/dev/testing.md` |
168
+ | Working on skills, pointer system, or `wade init` | `docs/dev/skills-system.md` |
169
+ | Updating documentation policies | `docs/dev/documentation-policies.md` |
170
+
171
+ <!-- wade:pointer:start -->
172
+ ## Git Workflow
173
+
174
+ **First action every session** — read the skill referenced in your clipboard
175
+ prompt for full session rules.
176
+
177
+ Critical rules you must always follow:
178
+
179
+ 1. Never create GitHub Issues via `gh issue create` — use `wade new-task`
180
+ or read @.claude/skills/task/SKILL.md
181
+ 2. Never create PRs manually (`gh pr create`) or push branches directly — use
182
+ `wade work done`
183
+ <!-- wade:pointer:end -->
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ ## v0.0.2 (2026-03-04)
4
+
5
+ Initial public release of WADE — Workflow for AI-Driven Engineering.
6
+
7
+ ## v0.0.1 (2026-03-04)
8
+
9
+ PyPI name reservation.
@@ -0,0 +1 @@
1
+ AGENTS.md
@@ -0,0 +1,98 @@
1
+ # Contributing to WADE
2
+
3
+ ## Development Setup
4
+
5
+ **Prerequisites:** [gh CLI](https://cli.github.com/) must be installed and authenticated — WADE shells out to it for all GitHub operations.
6
+
7
+ ```bash
8
+ gh auth login # first-time setup
9
+ gh auth status # verify it worked
10
+ ```
11
+
12
+ Then clone and install:
13
+
14
+ ```bash
15
+ git clone https://github.com/ivanviragine/wade.git
16
+ cd wade
17
+ uv pip install -e ".[dev]"
18
+ ```
19
+
20
+ ## Running Checks
21
+
22
+ > Always use the scripts — never invoke `pytest`, `mypy`, or `ruff` directly.
23
+
24
+ | Command | What it does |
25
+ |---------|-------------|
26
+ | `./scripts/test.sh` | Run all tests (excludes live) |
27
+ | `./scripts/test.sh tests/unit/` | Unit tests only |
28
+ | `./scripts/check.sh` | Lint + type-check |
29
+ | `./scripts/check.sh --lint` | Lint only |
30
+ | `./scripts/check.sh --types` | mypy strict only |
31
+ | `./scripts/fmt.sh` | Auto-format in-place |
32
+ | `./scripts/check-all.sh` | Full suite (tests + lint + types) |
33
+
34
+ ## Architecture
35
+
36
+ ```
37
+ CLI Layer → services, models, config, logging, ui
38
+ Service Layer → providers, ai_tools, git, db, models, config, logging
39
+ Provider Layer → models, config, logging (no service imports)
40
+ Git Layer → models, config, logging (no service imports)
41
+ Models Layer → nothing (leaf)
42
+ ```
43
+
44
+ CLI modules are thin dispatch — parse flags with Typer, call service methods. Business logic lives in `services/`, not `cli/`.
45
+
46
+ See `docs/dev/architecture.md` for the full reference.
47
+
48
+ ## Commits
49
+
50
+ Use [Conventional Commits](https://www.conventionalcommits.org/):
51
+
52
+ | Prefix | Semver bump |
53
+ |--------|------------|
54
+ | `feat:` | minor |
55
+ | `feat!:` | major (breaking) |
56
+ | `fix:`, `docs:`, `refactor:`, `chore:`, `test:` | patch |
57
+
58
+ ## Releasing
59
+
60
+ ### First release (one-time setup)
61
+
62
+ ```bash
63
+ ./scripts/setup-release.sh
64
+ ```
65
+
66
+ This creates the GitHub `pypi` environment, does the first PyPI upload, and walks you through trusted publishing setup.
67
+
68
+ ### Every release after that
69
+
70
+ ```bash
71
+ python scripts/auto_version.py patch --push # or minor / major
72
+ ```
73
+
74
+ This bumps the version, generates `CHANGELOG.md`, commits, tags, and pushes. CI then:
75
+
76
+ 1. Creates a **draft GitHub Release** with the changelog notes
77
+ 2. You review it on GitHub and click **Publish Release**
78
+ 3. CI publishes the wheel to PyPI automatically
79
+
80
+ ### Version bump types
81
+
82
+ ```bash
83
+ python scripts/auto_version.py patch # bug fixes 0.1.0 → 0.1.1
84
+ python scripts/auto_version.py minor # new features 0.1.0 → 0.2.0
85
+ python scripts/auto_version.py major # breaking 0.1.0 → 1.0.0
86
+ ```
87
+
88
+ Add `--dry-run` to preview without making changes.
89
+
90
+ ## Detailed Reference
91
+
92
+ | Topic | File |
93
+ |-------|------|
94
+ | Architecture, config, commands | `docs/dev/architecture.md` |
95
+ | Adding AI tools, providers, subcommands | `docs/dev/extending.md` |
96
+ | Writing and running tests | `docs/dev/testing.md` |
97
+ | Skills system and `wade init` | `docs/dev/skills-system.md` |
98
+ | Documentation policies | `docs/dev/documentation-policies.md` |
@@ -0,0 +1,37 @@
1
+ ARG PYTHON_VERSION=3.11
2
+ FROM python:${PYTHON_VERSION}-slim
3
+
4
+ # Install git and gh CLI (needed for integration tests)
5
+ RUN apt-get update && apt-get install -y --no-install-recommends \
6
+ git \
7
+ curl \
8
+ && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
9
+ | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
10
+ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
11
+ > /etc/apt/sources.list.d/github-cli.list \
12
+ && apt-get update && apt-get install -y gh \
13
+ && rm -rf /var/lib/apt/lists/*
14
+
15
+ # Install uv
16
+ COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
17
+
18
+ WORKDIR /app
19
+
20
+ # Copy project files
21
+ COPY pyproject.toml .
22
+ COPY src/ src/
23
+ COPY tests/ tests/
24
+ COPY templates/ templates/
25
+
26
+ # Install dependencies
27
+ RUN uv venv /app/.venv && \
28
+ uv pip install --python /app/.venv/bin/python ".[dev]"
29
+
30
+ ENV PATH="/app/.venv/bin:$PATH"
31
+
32
+ # Configure git for tests
33
+ RUN git config --global user.email "test@wade.dev" && \
34
+ git config --global user.name "wade test" && \
35
+ git config --global init.defaultBranch main
36
+
37
+ CMD ["pytest", "tests/", "-v", "--ignore=tests/live"]