kagan 0.1.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 (120) hide show
  1. kagan-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +46 -0
  2. kagan-0.1.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
  3. kagan-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +31 -0
  4. kagan-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +66 -0
  5. kagan-0.1.0/.github/copilot-instructions.md +13 -0
  6. kagan-0.1.0/.github/dependabot.yml +15 -0
  7. kagan-0.1.0/.github/workflows/cd.yaml +132 -0
  8. kagan-0.1.0/.github/workflows/ci.yml +25 -0
  9. kagan-0.1.0/.gitignore +170 -0
  10. kagan-0.1.0/.pre-commit-config.yaml +55 -0
  11. kagan-0.1.0/AGENTS.md +184 -0
  12. kagan-0.1.0/CHANGELOG.md +37 -0
  13. kagan-0.1.0/CLAUDE.md +1 -0
  14. kagan-0.1.0/CNAME +1 -0
  15. kagan-0.1.0/CONTRIBUTING.md +232 -0
  16. kagan-0.1.0/LICENSE +21 -0
  17. kagan-0.1.0/PKG-INFO +114 -0
  18. kagan-0.1.0/README.md +78 -0
  19. kagan-0.1.0/docs/config.md +121 -0
  20. kagan-0.1.0/docs/contributing.md +7 -0
  21. kagan-0.1.0/docs/index.md +76 -0
  22. kagan-0.1.0/docs/styles/kagan.css +316 -0
  23. kagan-0.1.0/docs/user-guide.md +149 -0
  24. kagan-0.1.0/mkdocs.yml +23 -0
  25. kagan-0.1.0/pyproject.toml +167 -0
  26. kagan-0.1.0/src/kagan/__init__.py +13 -0
  27. kagan-0.1.0/src/kagan/__main__.py +145 -0
  28. kagan-0.1.0/src/kagan/acp/__init__.py +1 -0
  29. kagan-0.1.0/src/kagan/acp/agent.py +364 -0
  30. kagan-0.1.0/src/kagan/acp/api.py +52 -0
  31. kagan-0.1.0/src/kagan/acp/buffers.py +44 -0
  32. kagan-0.1.0/src/kagan/acp/messages.py +169 -0
  33. kagan-0.1.0/src/kagan/acp/protocol.py +341 -0
  34. kagan-0.1.0/src/kagan/acp/rpc.py +244 -0
  35. kagan-0.1.0/src/kagan/acp/terminal.py +220 -0
  36. kagan-0.1.0/src/kagan/acp/terminals.py +113 -0
  37. kagan-0.1.0/src/kagan/agents/__init__.py +22 -0
  38. kagan-0.1.0/src/kagan/agents/config_resolver.py +58 -0
  39. kagan-0.1.0/src/kagan/agents/planner.py +132 -0
  40. kagan-0.1.0/src/kagan/agents/prompt.py +59 -0
  41. kagan-0.1.0/src/kagan/agents/prompt_loader.py +124 -0
  42. kagan-0.1.0/src/kagan/agents/scheduler.py +367 -0
  43. kagan-0.1.0/src/kagan/agents/signals.py +54 -0
  44. kagan-0.1.0/src/kagan/agents/worktree.py +392 -0
  45. kagan-0.1.0/src/kagan/app.py +222 -0
  46. kagan-0.1.0/src/kagan/config.py +106 -0
  47. kagan-0.1.0/src/kagan/constants.py +126 -0
  48. kagan-0.1.0/src/kagan/data/__init__.py +11 -0
  49. kagan-0.1.0/src/kagan/data/builtin_agents.py +82 -0
  50. kagan-0.1.0/src/kagan/database/__init__.py +6 -0
  51. kagan-0.1.0/src/kagan/database/manager.py +207 -0
  52. kagan-0.1.0/src/kagan/database/models.py +132 -0
  53. kagan-0.1.0/src/kagan/database/queries.py +191 -0
  54. kagan-0.1.0/src/kagan/database/schema.sql +45 -0
  55. kagan-0.1.0/src/kagan/git_utils.py +136 -0
  56. kagan-0.1.0/src/kagan/jsonrpc.py +595 -0
  57. kagan-0.1.0/src/kagan/limits.py +13 -0
  58. kagan-0.1.0/src/kagan/lock.py +124 -0
  59. kagan-0.1.0/src/kagan/mcp/__init__.py +8 -0
  60. kagan-0.1.0/src/kagan/mcp/server.py +74 -0
  61. kagan-0.1.0/src/kagan/mcp/tools.py +99 -0
  62. kagan-0.1.0/src/kagan/sessions/__init__.py +7 -0
  63. kagan-0.1.0/src/kagan/sessions/manager.py +240 -0
  64. kagan-0.1.0/src/kagan/sessions/tmux.py +23 -0
  65. kagan-0.1.0/src/kagan/styles/kagan.tcss +1544 -0
  66. kagan-0.1.0/src/kagan/theme.py +40 -0
  67. kagan-0.1.0/src/kagan/ui/__init__.py +1 -0
  68. kagan-0.1.0/src/kagan/ui/modals/__init__.py +23 -0
  69. kagan-0.1.0/src/kagan/ui/modals/actions.py +5 -0
  70. kagan-0.1.0/src/kagan/ui/modals/agent_output.py +164 -0
  71. kagan-0.1.0/src/kagan/ui/modals/confirm.py +42 -0
  72. kagan-0.1.0/src/kagan/ui/modals/description_editor.py +80 -0
  73. kagan-0.1.0/src/kagan/ui/modals/diff.py +40 -0
  74. kagan-0.1.0/src/kagan/ui/modals/rejection_input.py +67 -0
  75. kagan-0.1.0/src/kagan/ui/modals/review.py +205 -0
  76. kagan-0.1.0/src/kagan/ui/modals/settings.py +184 -0
  77. kagan-0.1.0/src/kagan/ui/modals/ticket_details/__init__.py +5 -0
  78. kagan-0.1.0/src/kagan/ui/modals/ticket_details/form.py +173 -0
  79. kagan-0.1.0/src/kagan/ui/modals/ticket_details/modal.py +304 -0
  80. kagan-0.1.0/src/kagan/ui/screens/__init__.py +17 -0
  81. kagan-0.1.0/src/kagan/ui/screens/approval.py +138 -0
  82. kagan-0.1.0/src/kagan/ui/screens/base.py +19 -0
  83. kagan-0.1.0/src/kagan/ui/screens/kanban/__init__.py +5 -0
  84. kagan-0.1.0/src/kagan/ui/screens/kanban/actions.py +84 -0
  85. kagan-0.1.0/src/kagan/ui/screens/kanban/focus.py +74 -0
  86. kagan-0.1.0/src/kagan/ui/screens/kanban/screen.py +773 -0
  87. kagan-0.1.0/src/kagan/ui/screens/planner.py +314 -0
  88. kagan-0.1.0/src/kagan/ui/screens/ticket_editor.py +137 -0
  89. kagan-0.1.0/src/kagan/ui/screens/troubleshooting.py +471 -0
  90. kagan-0.1.0/src/kagan/ui/screens/welcome.py +222 -0
  91. kagan-0.1.0/src/kagan/ui/widgets/__init__.py +19 -0
  92. kagan-0.1.0/src/kagan/ui/widgets/card.py +219 -0
  93. kagan-0.1.0/src/kagan/ui/widgets/column.py +161 -0
  94. kagan-0.1.0/src/kagan/ui/widgets/empty_state.py +56 -0
  95. kagan-0.1.0/src/kagan/ui/widgets/header.py +96 -0
  96. kagan-0.1.0/src/kagan/ui/widgets/search_bar.py +74 -0
  97. kagan-0.1.0/src/kagan/ui/widgets/status_bar.py +70 -0
  98. kagan-0.1.0/src/kagan/ui/widgets/streaming_output.py +133 -0
  99. kagan-0.1.0/tests/__init__.py +1 -0
  100. kagan-0.1.0/tests/__snapshots__/test_snapshots/TestCardSnapshots.test_card_long_title_wrapping.raw +123 -0
  101. kagan-0.1.0/tests/__snapshots__/test_snapshots/TestCardSnapshots.test_card_review_status.raw +163 -0
  102. kagan-0.1.0/tests/__snapshots__/test_snapshots/TestCardSnapshots.test_card_session_states.raw +139 -0
  103. kagan-0.1.0/tests/__snapshots__/test_snapshots/TestCardSnapshots.test_card_types_and_priorities.raw +139 -0
  104. kagan-0.1.0/tests/conftest.py +344 -0
  105. kagan-0.1.0/tests/helpers/__init__.py +1 -0
  106. kagan-0.1.0/tests/helpers/pages.py +125 -0
  107. kagan-0.1.0/tests/test_database.py +457 -0
  108. kagan-0.1.0/tests/test_e2e_smoke.py +203 -0
  109. kagan-0.1.0/tests/test_interactions.py +442 -0
  110. kagan-0.1.0/tests/test_lock.py +206 -0
  111. kagan-0.1.0/tests/test_mcp_tools.py +219 -0
  112. kagan-0.1.0/tests/test_models.py +144 -0
  113. kagan-0.1.0/tests/test_planner.py +440 -0
  114. kagan-0.1.0/tests/test_prompt_loader.py +60 -0
  115. kagan-0.1.0/tests/test_scheduler.py +600 -0
  116. kagan-0.1.0/tests/test_sessions.py +282 -0
  117. kagan-0.1.0/tests/test_signals.py +75 -0
  118. kagan-0.1.0/tests/test_snapshots.py +304 -0
  119. kagan-0.1.0/tests/test_troubleshooting.py +598 -0
  120. kagan-0.1.0/tests/test_worktree.py +372 -0
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: "🐛 Bug Report"
3
+ about: Report a reproducible bug or unexpected behavior
4
+ title: ""
5
+ labels: bug
6
+ assignees: ""
7
+ ---
8
+
9
+ ## Bug Description
10
+
11
+ <!-- A clear and concise description of the bug -->
12
+
13
+ ## Environment
14
+
15
+ - **Kagan Version**: <!-- e.g., 0.1.0 -->
16
+ - **Python Version**: <!-- e.g., 3.12.1 -->
17
+ - **OS**: <!-- e.g., macOS 14.0, Ubuntu 22.04 -->
18
+ - **Terminal**: <!-- e.g., iTerm2, Alacritty, Terminal.app -->
19
+
20
+ <!-- Optional: Include output of `uv --version` and `python --version` -->
21
+
22
+ ## Steps to Reproduce
23
+
24
+ 1.
25
+ 2.
26
+ 3.
27
+
28
+ ## Expected Behavior
29
+
30
+ <!-- What should happen? -->
31
+
32
+ ## Actual Behavior
33
+
34
+ <!-- What actually happens? -->
35
+
36
+ ## Screenshots/Logs
37
+
38
+ <!-- If applicable, add screenshots or terminal output to help explain the problem -->
39
+
40
+ ## Additional Context
41
+
42
+ <!-- Any other context about the problem, such as:
43
+ - Does this happen consistently or intermittently?
44
+ - Any recent changes to your setup?
45
+ - Relevant configuration from your environment?
46
+ -->
@@ -0,0 +1,8 @@
1
+ blank_issues_enabled: true
2
+ contact_links:
3
+ - name: 💬 Discussions
4
+ url: https://github.com/aorumbayev/kagan/discussions
5
+ about: Ask questions and discuss ideas with the community
6
+ - name: 📖 Documentation
7
+ url: https://aorumbayev.github.io/kagan
8
+ about: Browse the documentation
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: "✨ Feature Request"
3
+ about: Suggest a new feature or enhancement for Kagan
4
+ title: ""
5
+ labels: enhancement
6
+ assignees: ""
7
+ ---
8
+
9
+ ## Problem
10
+
11
+ <!-- What problem are you trying to solve? What's missing or could be improved? -->
12
+
13
+ ## Proposed Solution
14
+
15
+ <!-- Describe your ideal solution in detail -->
16
+
17
+ ## Alternative Solutions
18
+
19
+ <!-- Have you considered any alternative approaches? -->
20
+
21
+ ## Use Case
22
+
23
+ <!-- Describe how this feature would be used. Who would benefit from it? -->
24
+
25
+ ## Implementation Ideas
26
+
27
+ <!-- Optional: Any thoughts on how this could be implemented? -->
28
+
29
+ ## Additional Context
30
+
31
+ <!-- Any other context, screenshots, or examples that help explain the feature request -->
@@ -0,0 +1,66 @@
1
+ ## Description
2
+
3
+ <!-- Describe your changes in detail -->
4
+
5
+ ## Type of Change
6
+
7
+ <!-- Put an `x` in the boxes that apply -->
8
+
9
+ - [ ] 🐛 Bug fix (non-breaking change which fixes an issue)
10
+ - [ ] ✨ New feature (non-breaking change which adds functionality)
11
+ - [ ] 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
12
+ - [ ] 📝 Documentation update
13
+ - [ ] 🎨 Style/UI update (no functional changes)
14
+ - [ ] ♻️ Code refactoring (no functional changes)
15
+ - [ ] ⚡ Performance improvement
16
+ - [ ] ✅ Test update
17
+ - [ ] 🔧 Configuration/build update
18
+
19
+ ## Related Issues
20
+
21
+ <!-- Link related issues here using #issue-number -->
22
+
23
+ Fixes #
24
+ Relates to #
25
+
26
+ ## Changes Made
27
+
28
+ <!-- List the specific changes made in this PR -->
29
+
30
+ -
31
+ -
32
+ -
33
+
34
+ ## Testing
35
+
36
+ <!-- Describe how you tested your changes -->
37
+
38
+ - [ ] All existing tests pass (`uv run poe check`)
39
+ - [ ] Added new tests for new functionality
40
+ - [ ] Tested manually in the TUI
41
+
42
+ ### Manual Testing Steps
43
+
44
+ 1.
45
+ 2.
46
+ 3.
47
+
48
+ ## Screenshots/Demo
49
+
50
+ <!-- If applicable, add screenshots or a demo of the changes -->
51
+
52
+ ## Checklist
53
+
54
+ - [ ] My code follows the project's style guidelines
55
+ - [ ] I have run `uv run poe fix` to format my code
56
+ - [ ] I have performed a self-review of my code
57
+ - [ ] I have commented my code, particularly in hard-to-understand areas
58
+ - [ ] I have made corresponding changes to the documentation
59
+ - [ ] My changes generate no new warnings
60
+ - [ ] I have added tests that prove my fix is effective or that my feature works
61
+ - [ ] New and existing unit tests pass locally with my changes
62
+ - [ ] Any dependent changes have been merged and published
63
+
64
+ ## Additional Notes
65
+
66
+ <!-- Any additional information that reviewers should know -->
@@ -0,0 +1,13 @@
1
+ # GitHub Copilot Instructions
2
+
3
+ Read and strictly follow all guidelines defined in the [AGENTS.md](../AGENTS.md) file at the repository root.
4
+
5
+ This file contains comprehensive instructions for:
6
+
7
+ - Build and development commands
8
+ - Project structure
9
+ - Code style and conventions
10
+ - Testing patterns
11
+ - Git commit rules
12
+
13
+ All rules in AGENTS.md are mandatory and must be followed without exception.
@@ -0,0 +1,15 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ commit-message:
8
+ prefix: "chore(deps)"
9
+ groups:
10
+ all:
11
+ patterns:
12
+ - "*"
13
+ update-types:
14
+ - "minor"
15
+ - "patch"
@@ -0,0 +1,132 @@
1
+ name: Continuous Delivery
2
+
3
+ run-name: ${{ inputs.docs_only && 'Docs Only' || (inputs.production_release && 'Production Release' || 'Beta Release') }}
4
+
5
+ on:
6
+ push:
7
+ branches:
8
+ - main
9
+ paths-ignore:
10
+ - "docs/**"
11
+ - "*.md"
12
+ workflow_dispatch:
13
+ inputs:
14
+ production_release:
15
+ description: "Production release?"
16
+ type: boolean
17
+ required: true
18
+ default: false
19
+ docs_only:
20
+ description: "Publish docs only (skip release and PyPI)?"
21
+ type: boolean
22
+ required: true
23
+ default: false
24
+
25
+ concurrency: release
26
+
27
+ permissions:
28
+ contents: write
29
+ packages: read
30
+
31
+ jobs:
32
+ release:
33
+ name: Semantic Release
34
+ # Skip release job when docs_only flag is set
35
+ if: ${{ !inputs.docs_only }}
36
+ runs-on: ubuntu-latest
37
+ permissions:
38
+ # IMPORTANT: mandatory for trusted publishing and GitHub releases
39
+ id-token: write
40
+ contents: write
41
+ packages: read
42
+ steps:
43
+ - uses: actions/create-github-app-token@v1
44
+ id: app-token
45
+ with:
46
+ app-id: ${{ secrets.BOT_ID }}
47
+ private-key: ${{ secrets.BOT_SK }}
48
+
49
+ - uses: actions/checkout@v4
50
+ with:
51
+ # Fetch entire repository history so we can determine version number from it
52
+ fetch-depth: 0
53
+ token: ${{ steps.app-token.outputs.token }}
54
+
55
+ - name: Setup uv
56
+ uses: astral-sh/setup-uv@v7
57
+ with:
58
+ enable-cache: true
59
+
60
+ - name: Install dependencies
61
+ run: uv sync --dev
62
+
63
+ - name: Run tests and quality checks
64
+ run: |
65
+ set -o pipefail
66
+ uv run poe check
67
+
68
+ - name: Get branch name
69
+ shell: bash
70
+ run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
71
+ id: get_branch
72
+
73
+ - name: Python Semantic Release - Beta (non-prod)
74
+ id: release-beta
75
+ if: steps.get_branch.outputs.branch == 'main' && !inputs.production_release
76
+ uses: python-semantic-release/python-semantic-release@v10.3.1
77
+ with:
78
+ github_token: ${{ steps.app-token.outputs.token }}
79
+ prerelease: true
80
+
81
+ - name: Python Semantic Release - Production
82
+ id: release-prod
83
+ if: steps.get_branch.outputs.branch == 'main' && inputs.production_release
84
+ uses: python-semantic-release/python-semantic-release@v10.3.1
85
+ with:
86
+ github_token: ${{ steps.app-token.outputs.token }}
87
+
88
+ - name: Publish to PyPI
89
+ if: (steps.release-beta.outputs.released == 'true') || (steps.release-prod.outputs.released == 'true')
90
+ uses: pypa/gh-action-pypi-publish@release/v1
91
+ with:
92
+ verbose: true
93
+
94
+ publish-docs:
95
+ name: Publish Documentation
96
+ # Conditionally depend on release job (only when not docs_only mode)
97
+ needs: release
98
+ # Run docs publishing in two scenarios:
99
+ # 1. After a successful production release on main branch
100
+ # 2. When docs_only flag is set (on main branch only)
101
+ # Note: docs_only takes precedence if both flags are set
102
+ if: always() && !cancelled() && github.ref == 'refs/heads/main' && (needs.release.result == 'success' || needs.release.result == 'skipped') && (inputs.production_release || inputs.docs_only)
103
+ runs-on: ubuntu-latest
104
+ permissions:
105
+ contents: read
106
+ pages: write
107
+ id-token: write
108
+ steps:
109
+ - uses: actions/checkout@v4
110
+
111
+ - name: Setup uv
112
+ uses: astral-sh/setup-uv@v7
113
+ with:
114
+ enable-cache: true
115
+
116
+ - name: Install dependencies
117
+ run: uv sync --dev
118
+
119
+ - name: Build documentation
120
+ run: uv run mkdocs build
121
+
122
+ - name: Setup Pages
123
+ uses: actions/configure-pages@v5
124
+
125
+ - name: Upload artifact
126
+ uses: actions/upload-pages-artifact@v3
127
+ with:
128
+ path: site
129
+
130
+ - name: Deploy to GitHub Pages
131
+ id: deployment
132
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,25 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+ paths:
8
+ - "**.py"
9
+ - "pyproject.toml"
10
+ - "uv.lock"
11
+ - ".github/workflows/ci.yml"
12
+
13
+ jobs:
14
+ check:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - uses: astral-sh/setup-uv@v7
20
+ with:
21
+ enable-cache: true
22
+
23
+ - run: uv sync --dev
24
+
25
+ - run: uv run poe check
kagan-0.1.0/.gitignore ADDED
@@ -0,0 +1,170 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ *.manifest
31
+ *.spec
32
+
33
+ # Installer logs
34
+ pip-log.txt
35
+ pip-delete-this-directory.txt
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .nox/
41
+ .coverage
42
+ .coverage.*
43
+ .cache
44
+ nosetests.xml
45
+ coverage.xml
46
+ *.cover
47
+ *.py,cover
48
+ .hypothesis/
49
+ .pytest_cache/
50
+
51
+ # Translations
52
+ *.mo
53
+ *.pot
54
+
55
+ # Django stuff:
56
+ *.log
57
+ local_settings.py
58
+ db.sqlite3
59
+ db.sqlite3-journal
60
+
61
+ # Flask stuff:
62
+ instance/
63
+ .webassets-cache
64
+
65
+ # Scrapy stuff:
66
+ .scrapy
67
+
68
+ # Sphinx documentation
69
+ docs/_build/
70
+
71
+ # PyBuilder
72
+ .pybuilder/
73
+ target/
74
+
75
+ # Jupyter Notebook
76
+ .ipynb_checkpoints
77
+
78
+ # IPython
79
+ profile_default/
80
+ ipython_config.py
81
+
82
+ # pyenv
83
+ .python-version
84
+
85
+ # pipenv
86
+ Pipfile.lock
87
+
88
+ # poetry
89
+ poetry.lock
90
+
91
+ # pdm
92
+ .pdm.toml
93
+ .pdm-python
94
+ .pdm-build/
95
+
96
+ # PEP 582
97
+ __pypackages__/
98
+
99
+ # Celery stuff
100
+ celerybeat-schedule
101
+ celerybeat.pid
102
+
103
+ # SageMath parsed files
104
+ *.sage.py
105
+
106
+ # Environments
107
+ .env
108
+ .venv
109
+ env/
110
+ venv/
111
+ ENV/
112
+ env.bak/
113
+ venv.bak/
114
+
115
+ # Spyder project settings
116
+ .spyderproject
117
+ .spyproject
118
+
119
+ # Rope project settings
120
+ .ropeproject
121
+
122
+ # mkdocs documentation
123
+ /site
124
+
125
+ # mypy
126
+ .mypy_cache/
127
+ .dmypy.json
128
+ dmypy.json
129
+
130
+ # Pyre type checker
131
+ .pyre/
132
+
133
+ # pytype static type analyzer
134
+ .pytype/
135
+
136
+ # Cython debug symbols
137
+ cython_debug/
138
+
139
+ # UV specific
140
+ .uv/
141
+ uv.lock
142
+
143
+ # Ruff
144
+ .ruff_cache/
145
+
146
+ # IDE
147
+ .idea/
148
+ .vscode/
149
+ *.swp
150
+ *.swo
151
+ *~
152
+
153
+ # OS
154
+ .DS_Store
155
+ .DS_Store?
156
+ ._*
157
+ .Spotlight-V100
158
+ .Trashes
159
+ ehthumbs.db
160
+ Thumbs.db
161
+
162
+ # Project specific
163
+ .kagan/
164
+
165
+ references/
166
+
167
+ snapshot_report.html
168
+
169
+ # Kagan MCP config (auto-generated)
170
+ .mcp.json
@@ -0,0 +1,55 @@
1
+ repos:
2
+ # Pre-commit default hooks
3
+ - repo: https://github.com/pre-commit/pre-commit-hooks
4
+ rev: v6.0.0
5
+ hooks:
6
+ - id: end-of-file-fixer
7
+ exclude: ^(tests/__snapshots__/|CNAME$)
8
+ - id: trailing-whitespace
9
+ exclude: ^tests/__snapshots__/
10
+ - id: check-yaml
11
+ - id: check-added-large-files
12
+ - id: check-merge-conflict
13
+ - id: mixed-line-ending
14
+ args: [--fix=lf]
15
+ exclude: ^tests/__snapshots__/
16
+
17
+ # Markdown formatter
18
+ - repo: https://github.com/hukkin/mdformat
19
+ rev: 1.0.0
20
+ hooks:
21
+ - id: mdformat
22
+ exclude: ^(\.github/|README\.md$|CNAME$|CHANGELOG\.md$)
23
+ additional_dependencies:
24
+ - mdformat-gfm
25
+ - mdformat-ruff
26
+
27
+ # UV lock file sync
28
+ - repo: https://github.com/astral-sh/uv-pre-commit
29
+ rev: 0.9.26
30
+ hooks:
31
+ - id: uv-lock
32
+
33
+ # Local hooks using uv and poe tasks
34
+ - repo: local
35
+ hooks:
36
+ - id: lint
37
+ name: ruff lint
38
+ entry: uv run poe lint
39
+ language: system
40
+ types: [python]
41
+ pass_filenames: false
42
+
43
+ - id: format
44
+ name: ruff format
45
+ entry: uv run poe format
46
+ language: system
47
+ types: [python]
48
+ pass_filenames: false
49
+
50
+ - id: typecheck
51
+ name: pyrefly typecheck
52
+ entry: uv run poe typecheck
53
+ language: system
54
+ types: [python]
55
+ pass_filenames: false