atk-cli 0.2.0__tar.gz → 0.3.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 (144) hide show
  1. {atk_cli-0.2.0 → atk_cli-0.3.0}/.gitignore +7 -1
  2. atk_cli-0.3.0/CONTRIBUTING.md +90 -0
  3. atk_cli-0.3.0/Makefile +49 -0
  4. {atk_cli-0.2.0 → atk_cli-0.3.0}/PKG-INFO +1 -1
  5. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/ROADMAP.md +5 -0
  6. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/backlog.md +2 -3
  7. atk_cli-0.3.0/docs/phases/phase-11-git-sync.md +88 -0
  8. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/specs/commands-spec.md +37 -0
  9. atk_cli-0.3.0/docs/specs/git-sync-spec.md +156 -0
  10. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/specs/home-spec.md +3 -0
  11. {atk_cli-0.2.0 → atk_cli-0.3.0}/skills/create-atk-plugin/SKILL.md +16 -0
  12. atk_cli-0.3.0/skills/release/SKILL.md +289 -0
  13. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/add.py +25 -7
  14. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/cli.py +80 -4
  15. atk_cli-0.3.0/src/atk/commands/doctor.py +75 -0
  16. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/commands/status.py +55 -0
  17. atk_cli-0.3.0/src/atk/git.py +661 -0
  18. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/init.py +19 -8
  19. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/manifest_schema.py +4 -0
  20. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/remove.py +5 -2
  21. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/upgrade.py +3 -1
  22. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_add.py +64 -10
  23. atk_cli-0.3.0/tests/test_doctor.py +81 -0
  24. atk_cli-0.3.0/tests/test_git.py +860 -0
  25. atk_cli-0.3.0/tests/test_git_proxy.py +72 -0
  26. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_init.py +5 -0
  27. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_manifest_schema.py +19 -0
  28. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_mcp.py +2 -2
  29. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_plug.py +0 -2
  30. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_remove.py +52 -4
  31. atk_cli-0.3.0/tests/test_repo_status.py +109 -0
  32. atk_cli-0.2.0/CONTRIBUTING.md +0 -51
  33. atk_cli-0.2.0/Makefile +0 -29
  34. atk_cli-0.2.0/src/atk/git.py +0 -349
  35. atk_cli-0.2.0/tests/test_git.py +0 -440
  36. {atk_cli-0.2.0 → atk_cli-0.3.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  37. {atk_cli-0.2.0 → atk_cli-0.3.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  38. {atk_cli-0.2.0 → atk_cli-0.3.0}/.github/pull_request_template.md +0 -0
  39. {atk_cli-0.2.0 → atk_cli-0.3.0}/.github/workflows/ci.yml +0 -0
  40. {atk_cli-0.2.0 → atk_cli-0.3.0}/.github/workflows/publish.yml +0 -0
  41. {atk_cli-0.2.0 → atk_cli-0.3.0}/CODE_OF_CONDUCT.md +0 -0
  42. {atk_cli-0.2.0 → atk_cli-0.3.0}/LICENSE +0 -0
  43. {atk_cli-0.2.0 → atk_cli-0.3.0}/README.md +0 -0
  44. {atk_cli-0.2.0 → atk_cli-0.3.0}/SECURITY.md +0 -0
  45. {atk_cli-0.2.0 → atk_cli-0.3.0}/assets/demo-hero.gif +0 -0
  46. {atk_cli-0.2.0 → atk_cli-0.3.0}/assets/demo-search.gif +0 -0
  47. {atk_cli-0.2.0 → atk_cli-0.3.0}/assets/demo-status.gif +0 -0
  48. {atk_cli-0.2.0 → atk_cli-0.3.0}/assets/logo.png +0 -0
  49. {atk_cli-0.2.0 → atk_cli-0.3.0}/assets/tapes/demo-hero.tape +0 -0
  50. {atk_cli-0.2.0 → atk_cli-0.3.0}/assets/tapes/demo-search.tape +0 -0
  51. {atk_cli-0.2.0 → atk_cli-0.3.0}/assets/tapes/demo-status.tape +0 -0
  52. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/README.md +0 -0
  53. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/legacy/backup-feature-spec.md +0 -0
  54. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/legacy/cli-architecture.md +0 -0
  55. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/legacy/service-yaml-spec.md +0 -0
  56. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/phases/phase-1-core-cli.md +0 -0
  57. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/phases/phase-2-lifecycle.md +0 -0
  58. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/phases/phase-3-configuration.md +0 -0
  59. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/phases/phase-4-plugin-sources.md +0 -0
  60. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/specs/atk-spec.md +0 -0
  61. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/specs/mcp-agent-configure-spec.md +0 -0
  62. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/specs/plugin-schema.md +0 -0
  63. {atk_cli-0.2.0 → atk_cli-0.3.0}/docs/specs/registry-spec.md +0 -0
  64. {atk_cli-0.2.0 → atk_cli-0.3.0}/pyproject.toml +0 -0
  65. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/__init__.py +0 -0
  66. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/agents/__init__.py +0 -0
  67. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/agents/auggie_skill.py +0 -0
  68. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/agents/claude_skill.py +0 -0
  69. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/agents/codex_skill.py +0 -0
  70. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/agents/gemini_skill.py +0 -0
  71. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/agents/managed_section.py +0 -0
  72. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/agents/opencode_skill.py +0 -0
  73. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/agents/symlink_skill.py +0 -0
  74. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/banner.py +0 -0
  75. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/bootstrap.py +0 -0
  76. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/cli_logger.py +0 -0
  77. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/commands/__init__.py +0 -0
  78. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/commands/lifecycle.py +0 -0
  79. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/commands/mcp.py +0 -0
  80. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/commands/plug.py +0 -0
  81. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/commands/preconditions.py +0 -0
  82. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/commands/run.py +0 -0
  83. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/commands/search.py +0 -0
  84. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/commands/upgrade.py +0 -0
  85. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/env.py +0 -0
  86. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/errors.py +0 -0
  87. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/exit_codes.py +0 -0
  88. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/fetch.py +0 -0
  89. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/git_source.py +0 -0
  90. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/home.py +0 -0
  91. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/lifecycle.py +0 -0
  92. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/mcp.py +0 -0
  93. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/mcp_agents.py +0 -0
  94. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/mcp_configure.py +0 -0
  95. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/plugin.py +0 -0
  96. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/plugin_schema.py +0 -0
  97. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/registry.py +0 -0
  98. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/registry_schema.py +0 -0
  99. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/sanitize.py +0 -0
  100. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/setup.py +0 -0
  101. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/source.py +0 -0
  102. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/update_check.py +0 -0
  103. {atk_cli-0.2.0 → atk_cli-0.3.0}/src/atk/validation.py +0 -0
  104. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/__init__.py +0 -0
  105. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/agents/__init__.py +0 -0
  106. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/agents/test_auggie_skill.py +0 -0
  107. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/agents/test_claude_skill.py +0 -0
  108. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/agents/test_codex_skill.py +0 -0
  109. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/agents/test_gemini_skill.py +0 -0
  110. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/agents/test_opencode_skill.py +0 -0
  111. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/agents/test_symlink_skill.py +0 -0
  112. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/commands/__init__.py +0 -0
  113. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/commands/test_cli.py +0 -0
  114. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/commands/test_search.py +0 -0
  115. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/commands/test_status.py +0 -0
  116. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/conftest.py +0 -0
  117. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/fixtures/plugins/full-plugin/README.md +0 -0
  118. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/fixtures/plugins/full-plugin/SKILL.md +0 -0
  119. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/fixtures/plugins/full-plugin/install.sh +0 -0
  120. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/fixtures/plugins/full-plugin/mcp-server.sh +0 -0
  121. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/fixtures/plugins/full-plugin/plugin.yaml +0 -0
  122. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/fixtures/plugins/full-plugin/start.sh +0 -0
  123. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/fixtures/plugins/full-plugin/status.sh +0 -0
  124. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/fixtures/plugins/full-plugin/stop.sh +0 -0
  125. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/fixtures/plugins/invalid-plugin/plugin.yaml +0 -0
  126. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/fixtures/plugins/minimal-plugin/plugin.yaml +0 -0
  127. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/fixtures/plugins/skill-only-plugin/SKILL.md +0 -0
  128. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/fixtures/plugins/skill-only-plugin/plugin.yaml +0 -0
  129. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_env.py +0 -0
  130. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_errors.py +0 -0
  131. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_git_source.py +0 -0
  132. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_home.py +0 -0
  133. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_lifecycle.py +0 -0
  134. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_plugin.py +0 -0
  135. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_plugin_schema.py +0 -0
  136. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_registry.py +0 -0
  137. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_run.py +0 -0
  138. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_sanitize.py +0 -0
  139. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_setup.py +0 -0
  140. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_source.py +0 -0
  141. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_update_check.py +0 -0
  142. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_upgrade.py +0 -0
  143. {atk_cli-0.2.0 → atk_cli-0.3.0}/tests/test_version.py +0 -0
  144. {atk_cli-0.2.0 → atk_cli-0.3.0}/uv.lock +0 -0
@@ -207,4 +207,10 @@ marimo/_lsp/
207
207
  __marimo__/
208
208
 
209
209
  .idea
210
- img
210
+ img
211
+
212
+ # Derived skill copies (source of truth: skills/)
213
+ .claude/skills/
214
+
215
+ # Codanna index
216
+ .codanna/
@@ -0,0 +1,90 @@
1
+ # Contributing to ATK
2
+
3
+ Thanks for your interest. ATK is an early-stage tool — contributions are welcome.
4
+
5
+ ## Getting started
6
+
7
+ ```bash
8
+ git clone https://github.com/Svtoo/atk
9
+ cd atk
10
+ uv sync --dev
11
+ make install-hooks # Install pre-commit hook
12
+ make sync-skills # Copy skills to agent directories
13
+ ```
14
+
15
+ ## Development workflow
16
+
17
+ ### Pre-commit hook
18
+
19
+ `make install-hooks` installs a git pre-commit hook that:
20
+
21
+ 1. Runs `make check` (ruff lint, mypy type-check, pytest) — commit is blocked if any fail
22
+ 2. Runs `make sync-skills` — copies skills to agent-specific directories
23
+
24
+ The hook is local (`.git/hooks/pre-commit`) and not tracked in git. Run `make install-hooks` after cloning.
25
+
26
+ ### Skills
27
+
28
+ ATK includes skills (structured prompts) for AI coding agents. The source of truth is `skills/<name>/SKILL.md` at the project root. Skills are agent-agnostic — they work with any agent that supports structured prompts.
29
+
30
+ `make sync-skills` copies skills to agent-specific directories where they are discoverable:
31
+
32
+ | Agent | Target directory | Discovery |
33
+ |-------|-----------------|-----------|
34
+ | Claude Code | `.claude/skills/<name>/SKILL.md` | Auto-discovered as `/name` slash commands |
35
+
36
+ The agent directories (`.claude/skills/`) are gitignored — they contain derived copies, not source files. Always edit `skills/<name>/SKILL.md`, never the copies.
37
+
38
+ To add a new skill: create `skills/<your-skill>/SKILL.md` and run `make sync-skills`.
39
+
40
+ ## Making changes
41
+
42
+ - Open an issue first for non-trivial changes.
43
+ - Keep PRs focused — one concern per PR.
44
+ - Match existing code style (ruff + mypy strict).
45
+
46
+ ## Tests
47
+
48
+ All code changes must include automated tests.
49
+
50
+ ```bash
51
+ # Run the full test suite
52
+ uv run pytest
53
+
54
+ # Lint and type-check
55
+ uv run ruff check src tests
56
+ uv run mypy src
57
+
58
+ # All of the above in one command
59
+ make check
60
+ ```
61
+
62
+ If you're adding a command or changing CLI behaviour, also test it manually:
63
+
64
+ ```bash
65
+ uv run atk <your command>
66
+ ```
67
+
68
+ The CI must pass before a PR is merged.
69
+
70
+ ## Releases
71
+
72
+ Releases are managed via the `/release` skill (or `make release` for manual local builds). See `skills/release/SKILL.md` for the full process.
73
+
74
+ Key points:
75
+ - Versioning uses **hatch-vcs** — version is derived from git tags (`vX.Y.Z`), not hardcoded
76
+ - CI runs on push to `main`; publish to PyPI triggers on tag push matching `v*.*.*`
77
+ - PyPI does not allow re-uploads — once a version is published, it is permanent
78
+
79
+ ## Submitting a PR
80
+
81
+ 1. Fork and create a branch from `main`.
82
+ 2. Write or update tests for your change.
83
+ 3. Run `make check` — all must pass.
84
+ 4. Open a PR with a clear description of what changed and why.
85
+
86
+ ## Adding a registry plugin
87
+
88
+ Submit a PR to [atk-registry](https://github.com/Svtoo/atk-registry), not this repo.
89
+ See the registry README for schema requirements.
90
+
atk_cli-0.3.0/Makefile ADDED
@@ -0,0 +1,49 @@
1
+ .PHONY: test check release install-local install-pypi uninstall sync-skills install-hooks
2
+
3
+ # TDD cycle - run often
4
+ test:
5
+ uv run pytest
6
+
7
+ # Pre-commit validation - lint, type check, tests
8
+ check:
9
+ uv run ruff check src tests
10
+ uv run mypy src
11
+ uv run pytest
12
+
13
+ # Sync skills from skills/ to agent-specific directories
14
+ # Source of truth: skills/<name>/SKILL.md
15
+ # Currently supported agents: Claude Code (.claude/skills/)
16
+ sync-skills:
17
+ @mkdir -p .claude/skills
18
+ @for dir in skills/*/; do \
19
+ name=$$(basename "$$dir"); \
20
+ mkdir -p ".claude/skills/$$name"; \
21
+ cp "$$dir"SKILL.md ".claude/skills/$$name/SKILL.md" 2>/dev/null || true; \
22
+ done
23
+ @echo "Skills synced to .claude/skills/"
24
+
25
+ # Install git pre-commit hook that runs check + sync-skills
26
+ install-hooks:
27
+ @echo '#!/bin/sh' > .git/hooks/pre-commit
28
+ @echo 'make check || exit 1' >> .git/hooks/pre-commit
29
+ @echo 'make sync-skills' >> .git/hooks/pre-commit
30
+ @chmod +x .git/hooks/pre-commit
31
+ @echo "Pre-commit hook installed."
32
+
33
+ # Build and publish to PyPI
34
+ release:
35
+ uv build
36
+ uv publish
37
+
38
+ # Install from local source — editable, so changes are live without reinstalling
39
+ install-local:
40
+ uv tool install --editable . --reinstall
41
+
42
+ # Uninstall (works after either install-local or install-pypi)
43
+ uninstall:
44
+ uv tool uninstall atk-cli
45
+
46
+ # Install stable release from PyPI
47
+ install-pypi:
48
+ uv tool install atk-cli --reinstall
49
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atk-cli
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: AI Toolkit - Manage AI development tools through a git-backed, declarative manifest
5
5
  Project-URL: Homepage, https://github.com/Svtoo/atk
6
6
  Project-URL: Repository, https://github.com/Svtoo/atk
@@ -25,6 +25,7 @@
25
25
  | 8 | MCP Management | ✅ | Auto-install to Claude Code, Codex, Gemini, etc. |
26
26
  | 9 | Plug/Unplug | ✅ | `atk plug`/`unplug` — unified agent wiring |
27
27
  | 10 | Data Backup | ⏳ | Backup/restore plugin data |
28
+ | 11 | Git Sync | 🔄 | Remote sync, auto-push, repo status |
28
29
 
29
30
  ## Phase Summaries
30
31
 
@@ -83,6 +84,10 @@ Deprecates `atk mcp add`/`atk mcp remove`. `atk mcp <plugin>` reverts to its ori
83
84
 
84
85
  Backup and restore plugin data (databases, state files).
85
86
 
87
+ ### Phase 11: Git Sync 🔄
88
+
89
+ `atk git` proxy command for managing the .atk repository without navigating to it. `auto_push` config parameter for automatic push after mutations. Enhanced `atk status` with repository section showing branch, remote, sync state, and working directory status.
90
+
86
91
  ---
87
92
 
88
93
  ## Navigation
@@ -8,10 +8,9 @@ This document collects ideas, deferred features, and future enhancements. Items
8
8
  For the master plan, see `ROADMAP.md`.
9
9
  ---
10
10
 
11
- ## Git push
11
+ ## ~~Git push~~ -> Promoted to Phase 11
12
12
 
13
- For .atk registries with remote repositories, enable a config parameter alongside with auto_commit and auto_push to automatically push changes to the remote.
14
- also add command to pull changes from the remote. just a proxy for git, but useful so that the user does not need to navigate to the .atk directory to pull/push changes.
13
+ Addressed by Phase 11: Git Sync. `atk git` proxy command replaces dedicated push/pull commands. `auto_push` config parameter enables automatic push after mutations. `atk status` shows repository state. See `ROADMAP.md` Phase 11 and `specs/git-sync-spec.md`.
15
14
  ---
16
15
  ## ~~Manage Agents.md and other prompts through atk~~ → Promoted to Phase 9
17
16
 
@@ -0,0 +1,88 @@
1
+ # Phase 11: Git Sync
2
+
3
+ > **Status**: In Progress
4
+ > **Last Updated**: 2026-04-14
5
+
6
+ Remote synchronization for ATK Home. Users can add a git remote, auto-push after mutations, and see repository state in `atk status`.
7
+
8
+ ## Goals
9
+
10
+ 1. Users can manage the .atk git repo without navigating to the directory
11
+ 2. Mutations can automatically push to a remote after committing
12
+ 3. `atk status` shows the git repository state alongside plugin status
13
+
14
+ ---
15
+
16
+ ## Scenarios
17
+
18
+ ### Scenario 1: Git Proxy
19
+
20
+ **User story:** I want to manage my .atk repo's git remote without `cd ~/.atk`.
21
+
22
+ **Flow:**
23
+ 1. `atk git remote add origin git@github.com:user/dotfiles-atk.git`
24
+ 2. ATK runs `git remote add origin ...` in ATK_HOME
25
+ 3. Git output passed through to terminal
26
+
27
+ **Edge cases:**
28
+ - ATK Home not initialized -> exit 3
29
+ - Git not available -> exit 7
30
+ - Invalid git arguments -> git's own error, git's exit code
31
+
32
+ ### Scenario 2: Auto-Push After Mutation
33
+
34
+ **User story:** I want my plugin changes to automatically sync to my remote.
35
+
36
+ **Flow:**
37
+ 1. Edit `manifest.yaml` to set `auto_push: true`
38
+ 2. `atk add openmemory`
39
+ 3. ATK adds plugin, commits (auto_commit), pushes (auto_push)
40
+ 4. Remote now has the latest state
41
+
42
+ **Edge cases:**
43
+ - No remote configured -> warn, don't error
44
+ - Push fails (auth, network) -> warn, don't error; commit already succeeded
45
+ - `auto_commit: false` with `auto_push: true` -> no push (push requires commit)
46
+
47
+ ### Scenario 3: Repository Status
48
+
49
+ **User story:** I want to see if my .atk repo is in sync with the remote.
50
+
51
+ **Flow:**
52
+ 1. `atk status`
53
+ 2. ATK shows plugin table (existing behavior)
54
+ 3. ATK shows Repository section: branch, remote, ahead/behind, last commit, working dir
55
+
56
+ **Edge cases:**
57
+ - No remote -> show `(none)` for remote, omit sync line
58
+ - No tracking branch -> show `(no tracking branch)` for sync
59
+ - Empty repo (no commits) -> gracefully degrade, show what's available
60
+ - Git queries fail -> skip failing fields, show what's available
61
+
62
+ ---
63
+
64
+ ## Tasks
65
+
66
+ - [ ] Write git-sync-spec.md
67
+ - [ ] Update ROADMAP.md with Phase 11
68
+ - [ ] Update commands-spec.md with `atk git` command
69
+ - [ ] Update home-spec.md with `auto_push` in manifest schema
70
+ - [ ] Update backlog.md — promote "Git push" item
71
+ - [ ] Add git helper functions to `git.py` (push, branch, remote info, ahead/behind, working dir status)
72
+ - [ ] Add `auto_push` field to `ConfigSection` in `manifest_schema.py`
73
+ - [ ] Add `atk git` proxy command to `cli.py`
74
+ - [ ] Add repository section to `atk status` output
75
+ - [ ] Wire auto-push into `add.py`, `remove.py`, `upgrade.py`
76
+ - [ ] Update initial manifest in `init.py` with `auto_push: false`
77
+ - [ ] Tests for all new functions and behaviors
78
+
79
+ ## Acceptance Criteria
80
+
81
+ - `atk git remote add origin <url>` successfully adds a remote to .atk
82
+ - `atk git push` pushes .atk commits to the remote
83
+ - `atk git log --oneline` shows .atk commit history
84
+ - Setting `auto_push: true` in manifest causes mutations to push after commit
85
+ - Auto-push failure warns but does not fail the mutation
86
+ - `atk status` shows Repository section with branch, remote, sync, last commit, working dir
87
+ - `atk status` with no remote shows `(none)` gracefully
88
+ - `make check` passes (ruff + mypy + pytest)
@@ -62,6 +62,7 @@ flowchart TB
62
62
  plug[atk plug]
63
63
  mcp[atk mcp]
64
64
  help[atk help]
65
+ git[atk git]
65
66
  end
66
67
 
67
68
  init --> add
@@ -711,6 +712,42 @@ Continue? [y/N]:
711
712
 
712
713
  ---
713
714
 
715
+ ## `atk git [args...]`
716
+
717
+ Run git commands in ATK Home. Thin proxy — passes all arguments to `git` executed in ATK_HOME.
718
+
719
+ **Arguments:**
720
+ - `[args...]`: Any git arguments (passed through verbatim)
721
+
722
+ **Usage:**
723
+ ```bash
724
+ atk git remote add origin git@github.com:user/dotfiles-atk.git
725
+ atk git remote show origin
726
+ atk git push
727
+ atk git pull
728
+ atk git log --oneline -5
729
+ atk git status
730
+ atk git diff
731
+ ```
732
+
733
+ **Behavior:**
734
+ 1. Validate ATK Home is initialized (exit 3 if not)
735
+ 2. Require git available (exit 7 if not)
736
+ 3. Execute `git <args>` in ATK_HOME with stdin/stdout/stderr passed through
737
+ 4. Return git's exit code
738
+
739
+ **Notes:**
740
+ - No argument validation — git handles its own errors
741
+ - Interactive commands work (stdin is passed through)
742
+ - Destructive commands are the user's responsibility
743
+
744
+ **Exit Codes:**
745
+ - 3: ATK Home not initialized
746
+ - 7: Git not available
747
+ - (other): Git's own exit code passed through
748
+
749
+ ---
750
+
714
751
  # Deferred to Future
715
752
 
716
753
  The following commands and features are documented in `atk-future.md`:
@@ -0,0 +1,156 @@
1
+ # Git Sync Specification
2
+
3
+ > **Status**: Approved
4
+ > **Last Updated**: 2026-04-14
5
+
6
+ ## Overview
7
+
8
+ ATK Home is a git-backed repository. Phase 1 introduced `auto_commit` — every mutation creates a local commit. Git Sync extends this with remote synchronization: users can add a remote, auto-push after mutations, and see the repository state in `atk status`.
9
+
10
+ ## Design Principles
11
+
12
+ 1. **Proxy, don't reinvent.** `atk git` passes arguments straight to `git` in ATK_HOME. Users already know git.
13
+ 2. **Push is best-effort.** Auto-push failures warn but never fail the mutation. The commit already succeeded locally.
14
+ 3. **Sensible defaults.** `auto_push` defaults to `false`. Users opt in after adding a remote.
15
+
16
+ ## `atk git [args...]`
17
+
18
+ Thin proxy that runs `git <args>` in ATK_HOME.
19
+
20
+ ### Behavior
21
+
22
+ 1. Resolve ATK_HOME (env var or `~/.atk/`)
23
+ 2. Validate ATK Home is initialized (exit 3 if not)
24
+ 3. Require git available (exit 7 if not)
25
+ 4. Execute `git <args>` in ATK_HOME with stdin/stdout/stderr passed through (no capture)
26
+ 5. Return git's exit code
27
+
28
+ ### Examples
29
+
30
+ ```bash
31
+ atk git remote add origin git@github.com:user/dotfiles-atk.git
32
+ atk git remote show origin
33
+ atk git push
34
+ atk git pull
35
+ atk git log --oneline -5
36
+ atk git status
37
+ atk git diff
38
+ ```
39
+
40
+ ### Edge Cases
41
+
42
+ - No arguments (`atk git`) — passes no args to git, which prints git help. Acceptable.
43
+ - Interactive commands (`atk git rebase -i`) — works because stdin/stdout are passed through.
44
+ - Destructive commands (`atk git reset --hard`) — user's responsibility. ATK does not guard against this.
45
+
46
+ ## `auto_push` Configuration
47
+
48
+ New field in the manifest `config` section.
49
+
50
+ ### Manifest Schema
51
+
52
+ ```yaml
53
+ config:
54
+ auto_commit: true # Existing (default: true)
55
+ auto_push: false # New (default: false)
56
+ ```
57
+
58
+ ### Rules
59
+
60
+ | `auto_commit` | `auto_push` | Remote exists | Behavior |
61
+ |---------------|-------------|---------------|----------|
62
+ | true | true | yes | Commit + push |
63
+ | true | true | no | Commit only, warn "no remote configured" |
64
+ | true | false | any | Commit only (current behavior) |
65
+ | false | true | any | Neither — `auto_push` requires `auto_commit` |
66
+ | false | false | any | Neither (current behavior) |
67
+
68
+ ### Push Semantics
69
+
70
+ - Pushes the current branch to its upstream tracking branch
71
+ - Command: `git push` (no force, no explicit remote/branch — uses git defaults)
72
+ - On failure: print warning to stderr, do not exit with error
73
+ - On success: silent (consistent with auto_commit behavior)
74
+
75
+ ## Enhanced `atk status` — Repository Section
76
+
77
+ After the plugin status table, `atk status` displays a repository section.
78
+
79
+ ### Output Format
80
+
81
+ **With remote:**
82
+ ```
83
+ Repository:
84
+ Branch: main
85
+ Remote: origin -> git@github.com:user/dotfiles-atk.git
86
+ Sync: 2 ahead, 0 behind
87
+ Last commit: Add plugin 'sasha-rules' (2m ago)
88
+ Working dir: clean
89
+ ```
90
+
91
+ **Without remote:**
92
+ ```
93
+ Repository:
94
+ Branch: main
95
+ Remote: (none)
96
+ Last commit: Add plugin 'sasha-rules' (2m ago)
97
+ Working dir: clean
98
+ ```
99
+
100
+ **With dirty working directory:**
101
+ ```
102
+ Repository:
103
+ Branch: main
104
+ Remote: origin -> git@github.com:user/dotfiles-atk.git
105
+ Sync: 0 ahead, 0 behind
106
+ Last commit: Initialize ATK Home (3d ago)
107
+ Working dir: 1 modified, 2 untracked
108
+ ```
109
+
110
+ **No remote tracking branch:**
111
+ ```
112
+ Repository:
113
+ Branch: main
114
+ Remote: origin -> git@github.com:user/dotfiles-atk.git
115
+ Sync: (no tracking branch)
116
+ Last commit: Add plugin 'openmemory' (1h ago)
117
+ Working dir: clean
118
+ ```
119
+
120
+ ### Fields
121
+
122
+ | Field | Source | Notes |
123
+ |-------|--------|-------|
124
+ | Branch | `git branch --show-current` | Current branch name |
125
+ | Remote | `git remote get-url origin` | First remote name + URL. `(none)` if no remotes |
126
+ | Sync | `git rev-list --left-right --count HEAD...@{upstream}` | Ahead/behind upstream. Omitted if no remote. `(no tracking branch)` if remote exists but no tracking |
127
+ | Last commit | `git log -1 --format='%s (%cr)'` | Subject + relative time |
128
+ | Working dir | `git status --porcelain` | `clean` if empty, otherwise count by category |
129
+
130
+ ### Error Handling
131
+
132
+ If any git query fails (e.g., empty repo with no commits), the Repository section gracefully degrades — show what's available, skip what's not.
133
+
134
+ ## Auto-Push Wiring
135
+
136
+ Mutations that auto-commit (`add`, `remove`, `upgrade`) gain auto-push:
137
+
138
+ ```
139
+ mutation happens
140
+ -> if auto_commit:
141
+ git add -A
142
+ git commit -m "..."
143
+ -> if auto_push:
144
+ git push (best-effort, warn on failure)
145
+ ```
146
+
147
+ ### Warning Messages
148
+
149
+ - No remote: `Warning: auto_push enabled but no remote configured. Run: atk git remote add origin <url>`
150
+ - Push failed: `Warning: auto-push failed: <git error message>`
151
+
152
+ ## Exit Codes
153
+
154
+ `atk git` uses git's own exit codes (passed through). No new ATK exit codes needed.
155
+
156
+ For auto-push failures within mutations, the mutation still exits 0 (the commit succeeded).
@@ -96,6 +96,7 @@ schema_version: "2026-01-22"
96
96
 
97
97
  config:
98
98
  auto_commit: true # Commit after mutations (default: true)
99
+ auto_push: false # Push after auto-commit (default: false)
99
100
 
100
101
  plugins:
101
102
  - name: "OpenMemory" # Display name (user-friendly)
@@ -165,6 +166,8 @@ Display names (`name` field) have no restrictions—they are for human readabili
165
166
 
166
167
  If `auto_commit: false`, user must manually commit changes.
167
168
 
169
+ If `auto_push: true` and `auto_commit: true` and a remote is configured, ATK pushes after each auto-commit. Push failures warn but do not fail the mutation. If no remote is configured, auto-push silently no-ops with a warning.
170
+
168
171
  ## User Customizations
169
172
 
170
173
  Users customize plugins via the `custom/` directory inside each plugin.
@@ -248,6 +248,22 @@ mcp:
248
248
  **Idempotency rule**: Always build from scratch. Always `rm -rf` and fresh clone/install — no conditional
249
249
  "if exists, pull; else clone" logic.
250
250
 
251
+ **External package managers silently skip when already installed — you MUST force re-install.** Bare
252
+ `uv tool install pkg@latest`, `npm install -g pkg@latest`, and `pip install pkg` are no-ops once the
253
+ package is present, even if upstream has shipped a newer version. The user runs `atk install <plugin>`
254
+ expecting an upgrade and gets nothing. Required flags per manager:
255
+
256
+ | Manager | Wrong (silently skips) | Right (always pulls latest) |
257
+ |---|---|---|
258
+ | uv tool | `uv tool install pkg@latest` | `uv tool install pkg@latest --reinstall` |
259
+ | Homebrew | `brew install pkg` | `brew upgrade pkg \|\| brew install pkg` |
260
+ | npm global | `npm install -g pkg@latest` | `npm install -g pkg@latest --force` |
261
+ | pipx | `pipx install pkg` | `pipx install pkg --force` |
262
+ | cargo | `cargo install pkg` | `cargo install pkg --force` |
263
+
264
+ If your install relies on a `curl ... \| sh` install script (codanna-style), that's usually fine —
265
+ those scripts typically replace the binary unconditionally. But verify before shipping.
266
+
251
267
  Use `set -e` in `install.sh`: fail fast on errors.
252
268
 
253
269
  ### start