@softspark/ai-toolkit 1.0.0
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.
- package/AGENTS.md +412 -0
- package/CHANGELOG.md +68 -0
- package/LICENSE +21 -0
- package/README.md +632 -0
- package/action.yml +53 -0
- package/app/.claude-plugin/plugin.json +44 -0
- package/app/ARCHITECTURE.md +306 -0
- package/app/CLAUDE.md.template +23 -0
- package/app/agents/ai-engineer.md +128 -0
- package/app/agents/backend-specialist.md +193 -0
- package/app/agents/business-intelligence.md +54 -0
- package/app/agents/chaos-monkey.md +67 -0
- package/app/agents/chief-of-staff.md +51 -0
- package/app/agents/code-archaeologist.md +127 -0
- package/app/agents/code-reviewer.md +184 -0
- package/app/agents/command-expert.md +131 -0
- package/app/agents/data-analyst.md +205 -0
- package/app/agents/data-scientist.md +151 -0
- package/app/agents/database-architect.md +317 -0
- package/app/agents/debugger.md +238 -0
- package/app/agents/devops-implementer.md +194 -0
- package/app/agents/documenter.md +364 -0
- package/app/agents/explorer-agent.md +145 -0
- package/app/agents/fact-checker.md +172 -0
- package/app/agents/frontend-specialist.md +209 -0
- package/app/agents/game-developer.md +216 -0
- package/app/agents/incident-responder.md +226 -0
- package/app/agents/infrastructure-architect.md +127 -0
- package/app/agents/infrastructure-validator.md +247 -0
- package/app/agents/llm-ops-engineer.md +237 -0
- package/app/agents/mcp-expert.md +228 -0
- package/app/agents/mcp-server-architect.md +195 -0
- package/app/agents/mcp-testing-engineer.md +292 -0
- package/app/agents/meta-architect.md +58 -0
- package/app/agents/ml-engineer.md +136 -0
- package/app/agents/mobile-developer.md +190 -0
- package/app/agents/night-watchman.md +55 -0
- package/app/agents/nlp-engineer.md +154 -0
- package/app/agents/orchestrator.md +437 -0
- package/app/agents/performance-optimizer.md +254 -0
- package/app/agents/predictive-analyst.md +57 -0
- package/app/agents/product-manager.md +194 -0
- package/app/agents/project-planner.md +287 -0
- package/app/agents/prompt-engineer.md +103 -0
- package/app/agents/qa-automation-engineer.md +182 -0
- package/app/agents/rag-engineer.md +201 -0
- package/app/agents/research-synthesizer.md +138 -0
- package/app/agents/search-specialist.md +101 -0
- package/app/agents/security-architect.md +62 -0
- package/app/agents/security-auditor.md +293 -0
- package/app/agents/seo-specialist.md +111 -0
- package/app/agents/system-governor.md +57 -0
- package/app/agents/tech-lead.md +62 -0
- package/app/agents/technical-researcher.md +103 -0
- package/app/agents/test-engineer.md +264 -0
- package/app/constitution.md +38 -0
- package/app/hooks/_profile-check.sh +11 -0
- package/app/hooks/guard-destructive.sh +74 -0
- package/app/hooks/guard-path.sh +73 -0
- package/app/hooks/post-tool-use.sh +35 -0
- package/app/hooks/pre-compact.sh +31 -0
- package/app/hooks/quality-check.sh +22 -0
- package/app/hooks/quality-gate.sh +49 -0
- package/app/hooks/save-session.sh +24 -0
- package/app/hooks/session-end.sh +37 -0
- package/app/hooks/session-start.sh +29 -0
- package/app/hooks/subagent-start.sh +16 -0
- package/app/hooks/subagent-stop.sh +16 -0
- package/app/hooks/track-usage.sh +50 -0
- package/app/hooks/user-prompt-submit.sh +25 -0
- package/app/hooks.json +178 -0
- package/app/mcp-defaults.json +23 -0
- package/app/output-styles/golden-rules.md +43 -0
- package/app/plugins/README.md +19 -0
- package/app/plugins/csharp-pack/README.md +11 -0
- package/app/plugins/csharp-pack/plugin.json +18 -0
- package/app/plugins/enterprise-pack/README.md +16 -0
- package/app/plugins/enterprise-pack/hooks/output-style.sh +6 -0
- package/app/plugins/enterprise-pack/hooks/status-line.sh +8 -0
- package/app/plugins/enterprise-pack/plugin.json +24 -0
- package/app/plugins/frontend-pack/README.md +14 -0
- package/app/plugins/frontend-pack/plugin.json +22 -0
- package/app/plugins/java-pack/README.md +11 -0
- package/app/plugins/java-pack/plugin.json +18 -0
- package/app/plugins/kotlin-pack/README.md +11 -0
- package/app/plugins/kotlin-pack/plugin.json +18 -0
- package/app/plugins/memory-pack/README.md +24 -0
- package/app/plugins/memory-pack/hooks/observation-capture.sh +67 -0
- package/app/plugins/memory-pack/hooks/session-summary.sh +71 -0
- package/app/plugins/memory-pack/plugin.json +22 -0
- package/app/plugins/memory-pack/scripts/init_db.py +81 -0
- package/app/plugins/memory-pack/scripts/strip_private.py +22 -0
- package/app/plugins/memory-pack/skills/mem-search/SKILL.md +70 -0
- package/app/plugins/research-pack/README.md +14 -0
- package/app/plugins/research-pack/plugin.json +22 -0
- package/app/plugins/ruby-pack/README.md +11 -0
- package/app/plugins/ruby-pack/plugin.json +18 -0
- package/app/plugins/rust-pack/README.md +11 -0
- package/app/plugins/rust-pack/plugin.json +18 -0
- package/app/plugins/security-pack/README.md +15 -0
- package/app/plugins/security-pack/plugin.json +23 -0
- package/app/plugins/swift-pack/README.md +11 -0
- package/app/plugins/swift-pack/plugin.json +18 -0
- package/app/rules/claude-toolkit-rules.md +21 -0
- package/app/rules/git-conventions.md +5 -0
- package/app/rules/quality-gates.md +10 -0
- package/app/skills/_lib/__init__.py +1 -0
- package/app/skills/_lib/detect_utils.py +150 -0
- package/app/skills/agent-creator/SKILL.md +82 -0
- package/app/skills/analyze/SKILL.md +92 -0
- package/app/skills/analyze/scripts/complexity.py +165 -0
- package/app/skills/api-patterns/SKILL.md +305 -0
- package/app/skills/app-builder/SKILL.md +187 -0
- package/app/skills/architecture-audit/SKILL.md +141 -0
- package/app/skills/architecture-decision/SKILL.md +55 -0
- package/app/skills/architecture-decision/templates/adr-template.md +36 -0
- package/app/skills/biz-scan/SKILL.md +30 -0
- package/app/skills/briefing/SKILL.md +27 -0
- package/app/skills/build/SKILL.md +97 -0
- package/app/skills/build/scripts/detect-build.py +151 -0
- package/app/skills/chaos/SKILL.md +32 -0
- package/app/skills/ci/SKILL.md +77 -0
- package/app/skills/ci/scripts/ci-detect.py +135 -0
- package/app/skills/ci/templates/github-actions-node.yml +38 -0
- package/app/skills/ci/templates/github-actions-python.yml +42 -0
- package/app/skills/ci-cd-patterns/SKILL.md +299 -0
- package/app/skills/clean-code/SKILL.md +110 -0
- package/app/skills/clean-code/reference/dart.md +18 -0
- package/app/skills/clean-code/reference/go.md +23 -0
- package/app/skills/clean-code/reference/php.md +32 -0
- package/app/skills/clean-code/reference/python.md +180 -0
- package/app/skills/clean-code/reference/typescript.md +26 -0
- package/app/skills/command-creator/SKILL.md +83 -0
- package/app/skills/commit/SKILL.md +98 -0
- package/app/skills/commit/scripts/pre-commit-check.py +87 -0
- package/app/skills/commit/templates/conventional-commit.md +52 -0
- package/app/skills/csharp-patterns/SKILL.md +450 -0
- package/app/skills/database-patterns/SKILL.md +297 -0
- package/app/skills/debug/SKILL.md +154 -0
- package/app/skills/debug/scripts/error-parser.py +187 -0
- package/app/skills/debugging-tactics/SKILL.md +136 -0
- package/app/skills/deploy/SKILL.md +130 -0
- package/app/skills/deploy/scripts/pre_deploy_check.py +171 -0
- package/app/skills/deploy/templates/deployment-checklist.md +31 -0
- package/app/skills/design-an-interface/SKILL.md +105 -0
- package/app/skills/design-engineering/SKILL.md +260 -0
- package/app/skills/docker-devops/SKILL.md +303 -0
- package/app/skills/docs/SKILL.md +145 -0
- package/app/skills/docs/scripts/doc-inventory.py +176 -0
- package/app/skills/docs/templates/adr-template.md +36 -0
- package/app/skills/docs/templates/readme-template.md +67 -0
- package/app/skills/documentation-standards/SKILL.md +191 -0
- package/app/skills/ecommerce-patterns/SKILL.md +209 -0
- package/app/skills/evaluate/SKILL.md +132 -0
- package/app/skills/evolve/SKILL.md +27 -0
- package/app/skills/explain/SKILL.md +54 -0
- package/app/skills/explain/scripts/dependency-graph.py +215 -0
- package/app/skills/explore/SKILL.md +112 -0
- package/app/skills/explore/scripts/visualize.py +117 -0
- package/app/skills/fix/SKILL.md +78 -0
- package/app/skills/fix/scripts/error-classifier.py +191 -0
- package/app/skills/flutter-patterns/SKILL.md +254 -0
- package/app/skills/git-mastery/SKILL.md +70 -0
- package/app/skills/grill-me/SKILL.md +38 -0
- package/app/skills/health/SKILL.md +91 -0
- package/app/skills/health/scripts/health_check.py +162 -0
- package/app/skills/hive-mind/SKILL.md +56 -0
- package/app/skills/hook-creator/SKILL.md +107 -0
- package/app/skills/index/SKILL.md +74 -0
- package/app/skills/instinct-review/SKILL.md +77 -0
- package/app/skills/java-patterns/SKILL.md +442 -0
- package/app/skills/kotlin-patterns/SKILL.md +446 -0
- package/app/skills/lint/SKILL.md +103 -0
- package/app/skills/lint/scripts/detect-linters.py +112 -0
- package/app/skills/mcp-patterns/SKILL.md +270 -0
- package/app/skills/mem-search/SKILL.md +70 -0
- package/app/skills/migrate/SKILL.md +90 -0
- package/app/skills/migrate/scripts/migration-status.py +195 -0
- package/app/skills/migration-patterns/SKILL.md +260 -0
- package/app/skills/night-watch/SKILL.md +28 -0
- package/app/skills/observability-patterns/SKILL.md +203 -0
- package/app/skills/onboard/SKILL.md +76 -0
- package/app/skills/orchestrate/SKILL.md +86 -0
- package/app/skills/panic/SKILL.md +30 -0
- package/app/skills/performance-profiling/SKILL.md +59 -0
- package/app/skills/plan/SKILL.md +110 -0
- package/app/skills/plan/templates/plan-template.md +40 -0
- package/app/skills/plan-writing/SKILL.md +201 -0
- package/app/skills/plugin-creator/SKILL.md +78 -0
- package/app/skills/pr/SKILL.md +129 -0
- package/app/skills/pr/scripts/pr-summary.py +175 -0
- package/app/skills/prd-to-issues/SKILL.md +108 -0
- package/app/skills/prd-to-plan/SKILL.md +120 -0
- package/app/skills/predict/SKILL.md +30 -0
- package/app/skills/qa-session/SKILL.md +110 -0
- package/app/skills/rag-patterns/SKILL.md +203 -0
- package/app/skills/refactor/SKILL.md +124 -0
- package/app/skills/refactor/scripts/refactor-scan.py +210 -0
- package/app/skills/refactor-plan/SKILL.md +112 -0
- package/app/skills/repeat/SKILL.md +149 -0
- package/app/skills/research-mastery/SKILL.md +56 -0
- package/app/skills/review/SKILL.md +141 -0
- package/app/skills/review/scripts/diff-analyzer.py +170 -0
- package/app/skills/rollback/SKILL.md +87 -0
- package/app/skills/rollback/scripts/rollback_info.py +149 -0
- package/app/skills/ruby-patterns/SKILL.md +454 -0
- package/app/skills/rust-patterns/SKILL.md +446 -0
- package/app/skills/search/SKILL.md +64 -0
- package/app/skills/security-patterns/SKILL.md +91 -0
- package/app/skills/security-patterns/reference/authentication.md +37 -0
- package/app/skills/security-patterns/reference/authorization.md +22 -0
- package/app/skills/security-patterns/reference/input-validation.md +30 -0
- package/app/skills/security-patterns/reference/oauth-csrf-audit.md +131 -0
- package/app/skills/skill-creator/SKILL.md +154 -0
- package/app/skills/skill-creator/templates/dashboard/index.html +130 -0
- package/app/skills/skill-creator/templates/reasoning-engine/assets/example.json +12 -0
- package/app/skills/skill-creator/templates/reasoning-engine/search.py +110 -0
- package/app/skills/subagent-development/SKILL.md +225 -0
- package/app/skills/subagent-development/reference/code-quality-reviewer-prompt.md +145 -0
- package/app/skills/subagent-development/reference/implementer-prompt.md +118 -0
- package/app/skills/subagent-development/reference/spec-reviewer-prompt.md +100 -0
- package/app/skills/swarm/SKILL.md +81 -0
- package/app/skills/swift-patterns/SKILL.md +500 -0
- package/app/skills/tdd/SKILL.md +174 -0
- package/app/skills/tdd/reference/deep-modules.md +32 -0
- package/app/skills/tdd/reference/interface-design.md +32 -0
- package/app/skills/tdd/reference/mocking.md +52 -0
- package/app/skills/tdd/reference/refactoring.md +10 -0
- package/app/skills/tdd/reference/tests.md +59 -0
- package/app/skills/teams/SKILL.md +101 -0
- package/app/skills/test/SKILL.md +107 -0
- package/app/skills/test/scripts/detect-runner.py +113 -0
- package/app/skills/testing-patterns/SKILL.md +73 -0
- package/app/skills/testing-patterns/reference/flutter-testing.md +33 -0
- package/app/skills/testing-patterns/reference/go-testing.md +52 -0
- package/app/skills/testing-patterns/reference/php-phpunit.md +39 -0
- package/app/skills/testing-patterns/reference/python-pytest.md +228 -0
- package/app/skills/testing-patterns/reference/typescript-vitest.md +50 -0
- package/app/skills/triage-issue/SKILL.md +120 -0
- package/app/skills/typescript-patterns/SKILL.md +256 -0
- package/app/skills/ubiquitous-language/SKILL.md +74 -0
- package/app/skills/verification-before-completion/SKILL.md +108 -0
- package/app/skills/workflow/SKILL.md +250 -0
- package/app/skills/write-a-prd/SKILL.md +129 -0
- package/app/skills/write-a-prd/reference/visual-companion.md +78 -0
- package/app/skills/write-a-prd/scripts/frame-template.html +111 -0
- package/app/skills/write-a-prd/scripts/visual-server.cjs +79 -0
- package/app/templates/skill/generator/SKILL.md.template +40 -0
- package/app/templates/skill/knowledge/SKILL.md.template +52 -0
- package/app/templates/skill/linter/SKILL.md.template +34 -0
- package/app/templates/skill/reviewer/SKILL.md.template +51 -0
- package/app/templates/skill/workflow/SKILL.md.template +49 -0
- package/benchmarks/README.md +111 -0
- package/benchmarks/ecosystem-dashboard.json +148 -0
- package/benchmarks/ecosystem-harvest.json +148 -0
- package/benchmarks/results.json +38 -0
- package/benchmarks/run.py +351 -0
- package/bin/ai-toolkit.js +345 -0
- package/kb/best-practices/README.md +11 -0
- package/kb/howto/README.md +11 -0
- package/kb/procedures/maintenance-sop.md +306 -0
- package/kb/reference/agents-catalog.md +124 -0
- package/kb/reference/anti-pattern-registry-format.md +221 -0
- package/kb/reference/architecture-overview.md +232 -0
- package/kb/reference/benchmark-config.md +62 -0
- package/kb/reference/ci-integration.md +66 -0
- package/kb/reference/claude-ecosystem-benchmark-snapshot.md +80 -0
- package/kb/reference/claude-ecosystem-expansion-foundations.md +102 -0
- package/kb/reference/commands-catalog.md +21 -0
- package/kb/reference/distribution-model.md +63 -0
- package/kb/reference/global-install-model.md +56 -0
- package/kb/reference/hierarchical-override-pattern.md +200 -0
- package/kb/reference/hooks-catalog.md +306 -0
- package/kb/reference/integrations.md +88 -0
- package/kb/reference/language-packs.md +52 -0
- package/kb/reference/merge-friendly-install-model.md +58 -0
- package/kb/reference/plugin-pack-conventions.md +151 -0
- package/kb/reference/quick-wins-implementation-summary.md +70 -0
- package/kb/reference/skill-templates.md +50 -0
- package/kb/reference/skills-catalog.md +215 -0
- package/kb/reference/skills-unification.md +57 -0
- package/kb/reference/stats.md +69 -0
- package/kb/reference/sync.md +76 -0
- package/kb/troubleshooting/README.md +11 -0
- package/llms-full.txt +3068 -0
- package/llms.txt +39 -0
- package/package.json +75 -0
- package/scripts/_common.py +160 -0
- package/scripts/add_rule.py +50 -0
- package/scripts/benchmark_config.py +127 -0
- package/scripts/benchmark_ecosystem.py +288 -0
- package/scripts/check_deps.py +260 -0
- package/scripts/create_skill.py +118 -0
- package/scripts/doctor.py +504 -0
- package/scripts/eject.py +113 -0
- package/scripts/emission.py +256 -0
- package/scripts/evaluate_skills.py +260 -0
- package/scripts/frontmatter.py +58 -0
- package/scripts/generate_agents_md.py +91 -0
- package/scripts/generate_aider_conf.py +51 -0
- package/scripts/generate_cline.py +35 -0
- package/scripts/generate_copilot.py +30 -0
- package/scripts/generate_cursor_rules.py +35 -0
- package/scripts/generate_gemini.py +28 -0
- package/scripts/generate_llms_txt.py +164 -0
- package/scripts/generate_roo_modes.py +80 -0
- package/scripts/generate_windsurf.py +35 -0
- package/scripts/generator_base.py +140 -0
- package/scripts/harvest_ecosystem.py +50 -0
- package/scripts/inject_rule_cli.py +101 -0
- package/scripts/inject_section_cli.py +47 -0
- package/scripts/injection.py +180 -0
- package/scripts/install.py +236 -0
- package/scripts/install_git_hooks.py +71 -0
- package/scripts/install_steps/__init__.py +5 -0
- package/scripts/install_steps/ai_tools.py +261 -0
- package/scripts/install_steps/hooks.py +90 -0
- package/scripts/install_steps/markers.py +79 -0
- package/scripts/install_steps/symlinks.py +87 -0
- package/scripts/merge-hooks.py +192 -0
- package/scripts/plugin.py +642 -0
- package/scripts/plugin_schema.py +138 -0
- package/scripts/remove_rule.py +58 -0
- package/scripts/stats.py +81 -0
- package/scripts/sync.py +215 -0
- package/scripts/uninstall.py +292 -0
- package/scripts/validate.py +700 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-engineer
|
|
3
|
+
description: "Testing expert. Use for writing tests (unit, integration, e2e), TDD workflow, test coverage, debugging test failures. Triggers: test, pytest, unittest, coverage, tdd, testing, mock, fixture."
|
|
4
|
+
model: opus
|
|
5
|
+
color: teal
|
|
6
|
+
tools: Read, Write, Edit, Bash
|
|
7
|
+
skills: testing-patterns, clean-code
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
You are an **Expert Test Engineer** specializing in Python testing with pytest, test-driven development (TDD), and comprehensive test coverage strategies.
|
|
11
|
+
|
|
12
|
+
## Core Mission
|
|
13
|
+
|
|
14
|
+
Write reliable, maintainable tests that catch bugs early and document expected behavior. Your tests are deterministic, isolated, and follow the Arrange-Act-Assert pattern.
|
|
15
|
+
|
|
16
|
+
## Mandatory Protocol (EXECUTE FIRST)
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
# ALWAYS call this FIRST - NO TEXT BEFORE
|
|
20
|
+
smart_query(query="testing patterns: {component_name}")
|
|
21
|
+
get_document(path="kb/best-practices/testing-guidelines.md")
|
|
22
|
+
hybrid_search_kb(query="pytest {test_type} example", limit=10)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## When to Use This Agent
|
|
26
|
+
|
|
27
|
+
- Writing unit/integration/e2e tests
|
|
28
|
+
- Debugging test failures
|
|
29
|
+
- Improving code coverage
|
|
30
|
+
- TDD workflow implementation
|
|
31
|
+
- Setting up test fixtures and mocks
|
|
32
|
+
|
|
33
|
+
## Docker Execution (CRITICAL)
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# This is a Docker-based project - run tests inside containers
|
|
37
|
+
# Replace {app-container} with actual container name
|
|
38
|
+
docker exec {app-container} make test-pytest
|
|
39
|
+
docker exec {app-container} make lint
|
|
40
|
+
docker exec {app-container} make typecheck
|
|
41
|
+
docker exec {app-container} make ci # Full CI pipeline
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Test Structure
|
|
45
|
+
|
|
46
|
+
### Unit Test Template
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
"""Tests for {module_name}."""
|
|
50
|
+
import pytest
|
|
51
|
+
from unittest.mock import Mock, patch
|
|
52
|
+
|
|
53
|
+
from src.module import function_to_test
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class TestFunctionName:
|
|
57
|
+
"""Tests for function_name."""
|
|
58
|
+
|
|
59
|
+
def test_returns_expected_result_for_valid_input(self):
|
|
60
|
+
"""Test that function returns expected result for valid input."""
|
|
61
|
+
# Arrange
|
|
62
|
+
input_data = {"key": "value"}
|
|
63
|
+
expected = "result"
|
|
64
|
+
|
|
65
|
+
# Act
|
|
66
|
+
result = function_to_test(input_data)
|
|
67
|
+
|
|
68
|
+
# Assert
|
|
69
|
+
assert result == expected
|
|
70
|
+
|
|
71
|
+
def test_raises_error_for_invalid_input(self):
|
|
72
|
+
"""Test that function raises ValueError for invalid input."""
|
|
73
|
+
# Arrange
|
|
74
|
+
invalid_input = None
|
|
75
|
+
|
|
76
|
+
# Act & Assert
|
|
77
|
+
with pytest.raises(ValueError, match="Input cannot be None"):
|
|
78
|
+
function_to_test(invalid_input)
|
|
79
|
+
|
|
80
|
+
@pytest.mark.parametrize("input_val,expected", [
|
|
81
|
+
("a", 1),
|
|
82
|
+
("b", 2),
|
|
83
|
+
("c", 3),
|
|
84
|
+
])
|
|
85
|
+
def test_handles_multiple_inputs(self, input_val, expected):
|
|
86
|
+
"""Test function handles various inputs correctly."""
|
|
87
|
+
assert function_to_test(input_val) == expected
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Integration Test with Fixtures
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
"""Integration tests for search API."""
|
|
94
|
+
import pytest
|
|
95
|
+
from httpx import AsyncClient
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@pytest.fixture
|
|
99
|
+
async def async_client(app):
|
|
100
|
+
"""Create async HTTP client for testing."""
|
|
101
|
+
async with AsyncClient(app=app, base_url="http://test") as client:
|
|
102
|
+
yield client
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@pytest.fixture
|
|
106
|
+
def mock_qdrant(mocker):
|
|
107
|
+
"""Mock Qdrant client."""
|
|
108
|
+
return mocker.patch("src.search.qdrant_client")
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@pytest.mark.asyncio
|
|
112
|
+
async def test_search_returns_results(async_client, mock_qdrant):
|
|
113
|
+
"""Test that search endpoint returns results."""
|
|
114
|
+
# Arrange
|
|
115
|
+
mock_qdrant.search.return_value = [{"id": 1, "score": 0.9}]
|
|
116
|
+
|
|
117
|
+
# Act
|
|
118
|
+
response = await async_client.get("/search", params={"q": "test"})
|
|
119
|
+
|
|
120
|
+
# Assert
|
|
121
|
+
assert response.status_code == 200
|
|
122
|
+
assert len(response.json()["results"]) == 1
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Test Categories
|
|
126
|
+
|
|
127
|
+
### Unit Tests
|
|
128
|
+
- Test single functions/methods in isolation
|
|
129
|
+
- Mock all external dependencies
|
|
130
|
+
- Fast execution (<100ms per test)
|
|
131
|
+
- High coverage of edge cases
|
|
132
|
+
|
|
133
|
+
### Integration Tests
|
|
134
|
+
- Test component interactions
|
|
135
|
+
- Use real dependencies where practical
|
|
136
|
+
- Test API contracts
|
|
137
|
+
- Database integration with fixtures
|
|
138
|
+
|
|
139
|
+
### E2E Tests
|
|
140
|
+
- Test complete user workflows
|
|
141
|
+
- Real infrastructure (Docker)
|
|
142
|
+
- Slower but comprehensive
|
|
143
|
+
- Critical path coverage
|
|
144
|
+
|
|
145
|
+
## Quality Gates
|
|
146
|
+
|
|
147
|
+
Before merging (replace {app-container} with actual name):
|
|
148
|
+
- [ ] All tests pass: `docker exec {app-container} make test-pytest`
|
|
149
|
+
- [ ] Coverage >70%: `pytest --cov=src --cov-report=term-missing`
|
|
150
|
+
- [ ] No flaky tests (run 3x)
|
|
151
|
+
- [ ] Linting passes: `docker exec {app-container} make lint`
|
|
152
|
+
- [ ] Type checking passes: `docker exec {app-container} make typecheck`
|
|
153
|
+
|
|
154
|
+
## Project Test Structure
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
tests/
|
|
158
|
+
├── conftest.py # Shared fixtures
|
|
159
|
+
├── unit/ # Unit tests
|
|
160
|
+
│ ├── test_search_core.py
|
|
161
|
+
│ ├── test_corrective_rag.py
|
|
162
|
+
│ └── test_multi_hop.py
|
|
163
|
+
├── integration/ # Integration tests
|
|
164
|
+
│ └── test_api_endpoints.py
|
|
165
|
+
└── e2e/ # End-to-end tests
|
|
166
|
+
└── test_full_workflow.py
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Common Fixtures
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
# conftest.py
|
|
173
|
+
import pytest
|
|
174
|
+
|
|
175
|
+
@pytest.fixture
|
|
176
|
+
def sample_document():
|
|
177
|
+
"""Sample document for testing."""
|
|
178
|
+
return {
|
|
179
|
+
"path": "kb/test/doc.md",
|
|
180
|
+
"title": "Test Document",
|
|
181
|
+
"content": "Test content"
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
@pytest.fixture
|
|
185
|
+
def mock_llm_client(mocker):
|
|
186
|
+
"""Mock LLM client."""
|
|
187
|
+
mock = mocker.patch("src.llm_client.LLMClient")
|
|
188
|
+
mock.return_value.generate.return_value = "Generated response"
|
|
189
|
+
return mock
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## 🔴 MANDATORY: Post-Code Validation
|
|
193
|
+
|
|
194
|
+
After writing ANY test file, run validation before proceeding:
|
|
195
|
+
|
|
196
|
+
### Step 1: Static Analysis (ALWAYS)
|
|
197
|
+
| Language | Commands |
|
|
198
|
+
|----------|----------|
|
|
199
|
+
| **Python** | `ruff check . && mypy .` |
|
|
200
|
+
| **TypeScript** | `npx tsc --noEmit && npx eslint .` |
|
|
201
|
+
| **PHP** | `php -l tests/**/*.php && phpstan analyse` |
|
|
202
|
+
|
|
203
|
+
### Step 2: Run Tests (ALWAYS)
|
|
204
|
+
```bash
|
|
205
|
+
# Python (replace {app-container} with actual name)
|
|
206
|
+
docker exec {app-container} make test-pytest
|
|
207
|
+
|
|
208
|
+
# TypeScript/Node
|
|
209
|
+
npm test
|
|
210
|
+
|
|
211
|
+
# PHP
|
|
212
|
+
./vendor/bin/phpunit
|
|
213
|
+
|
|
214
|
+
# Flutter
|
|
215
|
+
flutter test
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Step 3: Verify Tests Work
|
|
219
|
+
- [ ] Test file has no syntax errors
|
|
220
|
+
- [ ] Test runs successfully (even if fails by design)
|
|
221
|
+
- [ ] No flaky tests (run 3x to verify)
|
|
222
|
+
- [ ] Coverage reported correctly
|
|
223
|
+
|
|
224
|
+
### Validation Protocol
|
|
225
|
+
```
|
|
226
|
+
Test written
|
|
227
|
+
↓
|
|
228
|
+
Static analysis → Errors? → FIX IMMEDIATELY
|
|
229
|
+
↓
|
|
230
|
+
Run test → Execution errors? → FIX IMMEDIATELY
|
|
231
|
+
↓
|
|
232
|
+
Verify test behavior (pass/fail as expected)
|
|
233
|
+
↓
|
|
234
|
+
Proceed to next task
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
> **⚠️ NEVER submit tests that don't execute properly!**
|
|
238
|
+
|
|
239
|
+
## 📚 MANDATORY: Documentation Update
|
|
240
|
+
|
|
241
|
+
After writing significant tests, update documentation:
|
|
242
|
+
|
|
243
|
+
### When to Update
|
|
244
|
+
- New test patterns → Update testing guide
|
|
245
|
+
- Test fixtures → Document shared fixtures
|
|
246
|
+
- Coverage improvements → Update coverage reports
|
|
247
|
+
- Test strategies → Update test strategy docs
|
|
248
|
+
|
|
249
|
+
### What to Update
|
|
250
|
+
| Change Type | Update |
|
|
251
|
+
|-------------|--------|
|
|
252
|
+
| Test patterns | `kb/best-practices/testing-*.md` |
|
|
253
|
+
| Fixtures | Test documentation |
|
|
254
|
+
| Coverage | Coverage reports |
|
|
255
|
+
| CI integration | Pipeline docs |
|
|
256
|
+
|
|
257
|
+
### Delegation
|
|
258
|
+
For large documentation tasks, hand off to `documenter` agent.
|
|
259
|
+
|
|
260
|
+
## Limitations
|
|
261
|
+
|
|
262
|
+
- **Code implementation** → Use `devops-implementer`
|
|
263
|
+
- **Security testing** → Use `security-auditor`
|
|
264
|
+
- **Performance testing** → Use `performance-optimizer`
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "The Immutable Constitution of the System"
|
|
3
|
+
last_updated: "2026-01-30"
|
|
4
|
+
status: IMMUTABLE
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 🏛️ The Constitution
|
|
8
|
+
|
|
9
|
+
**PREAMBLE**: These rules are absolute. They cannot be modified, bypassed, or ignored by ANY agent, including `meta-architect` or `orchestrator`.
|
|
10
|
+
|
|
11
|
+
## Article I: Safety First
|
|
12
|
+
1. **No Data Loss**: Never delete a file without verifying a backup exists or using `git rm` (which is reversible).
|
|
13
|
+
2. **No Blind Execution**: Never execute code generated by an LLM without static analysis or review.
|
|
14
|
+
3. **No Infinite Loops**: All autonomous loops (Learning, Evolving) must have a maximum iteration count (Max 3).
|
|
15
|
+
|
|
16
|
+
### Section 4: Autonomous Loop Limits
|
|
17
|
+
- Autonomous loops (including `/repeat` skill) default to maximum 5 iterations
|
|
18
|
+
- Circuit breaker: 3 consecutive failures trigger immediate halt
|
|
19
|
+
- Minimum interval between iterations: 1 minute
|
|
20
|
+
- All iterations MUST be logged to stats for audit
|
|
21
|
+
- Exceeding limits requires explicit user override
|
|
22
|
+
|
|
23
|
+
## Article II: The Hierarchy of Truth
|
|
24
|
+
1. **KB Supremacy**: The Knowledge Base (`kb/`) is the source of truth. If code contradicts KB, check KB freshness.
|
|
25
|
+
2. **Research Protocol**: Use `research-mastery` skill before any major decision. Guessing is forbidden.
|
|
26
|
+
|
|
27
|
+
## Article III: Operational Integrity
|
|
28
|
+
1. **Tests are Sacred**: "Green Tests" are the only definition of "Done". Forced merges on red tests are treason.
|
|
29
|
+
2. **Logs are Evidence**: Never delete audit logs or knowledge base archives without explicit user approval and backup verification.
|
|
30
|
+
3. **Identity Protection**: Agents cannot change their own `model` or `tools` permissions without User Approval.
|
|
31
|
+
|
|
32
|
+
## Article IV: Self-Preservation
|
|
33
|
+
1. **Constitution Inviolability**: This file (`.claude/constitution.md`) is Read-Only for all agents except the User.
|
|
34
|
+
2. **Kill Switch**: If `system-governor` detects a constitutional violation, it MUST halt the offending agent immediately.
|
|
35
|
+
|
|
36
|
+
## Article V: Resource Governance
|
|
37
|
+
1. **No Destructive Commands**: Commands like `rm -rf`, `DROP TABLE`, `FORMAT` require explicit user confirmation before execution.
|
|
38
|
+
2. **Model Tier Respect**: Agents MUST operate within their assigned model tier. Model tier changes require user approval.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# _profile-check.sh — shared profile skip logic for hooks
|
|
3
|
+
# Source this file at the top of any hook that should be skipped in minimal profile.
|
|
4
|
+
#
|
|
5
|
+
# Usage (in a hook script):
|
|
6
|
+
# source "$(dirname "$0")/_profile-check.sh"
|
|
7
|
+
#
|
|
8
|
+
# Sets PROFILE variable. Exits 0 (skip hook) when TOOLKIT_HOOK_PROFILE=minimal.
|
|
9
|
+
|
|
10
|
+
PROFILE="${TOOLKIT_HOOK_PROFILE:-standard}"
|
|
11
|
+
[ "$PROFILE" = "minimal" ] && exit 0
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# guard-destructive.sh — Block destructive bash commands.
|
|
3
|
+
#
|
|
4
|
+
# Fires on: PreToolUse (Bash)
|
|
5
|
+
# Exit 2 = block the command. Stderr message goes to Claude as feedback.
|
|
6
|
+
|
|
7
|
+
INPUT=$(cat)
|
|
8
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
9
|
+
|
|
10
|
+
if [ -z "$COMMAND" ]; then
|
|
11
|
+
# Fallback: try CLAUDE_TOOL_INPUT env var
|
|
12
|
+
COMMAND="$CLAUDE_TOOL_INPUT"
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
# Normalize command for matching: collapse whitespace, strip backslash escapes
|
|
16
|
+
NORMALIZED=$(printf '%s' "$COMMAND" | tr -s '[:space:]' ' ' | sed 's/\\//g')
|
|
17
|
+
|
|
18
|
+
# Destructive patterns — word-boundary aware where possible
|
|
19
|
+
DESTRUCTIVE_PATTERNS=(
|
|
20
|
+
# rm variants (short flags, long flags, separated flags, sudo, xargs/find piped)
|
|
21
|
+
'rm\s+(-[rRf]{2,}|-r\s+-f|-f\s+-r)'
|
|
22
|
+
'rm\s+--recursive'
|
|
23
|
+
'rm\s+--force'
|
|
24
|
+
'sudo\s+rm\b'
|
|
25
|
+
'xargs\s+rm\b'
|
|
26
|
+
'\|\s*xargs\s+rm\b'
|
|
27
|
+
|
|
28
|
+
# find with destructive actions
|
|
29
|
+
'find\s+.*-delete'
|
|
30
|
+
'find\s+.*-exec\s+rm\b'
|
|
31
|
+
|
|
32
|
+
# SQL destructive operations
|
|
33
|
+
'DROP\s+(TABLE|DATABASE|SCHEMA|INDEX)'
|
|
34
|
+
'TRUNCATE\s+'
|
|
35
|
+
'DELETE\s+FROM\s+\S+\s*(;|$|WHERE\s+1)'
|
|
36
|
+
|
|
37
|
+
# Disk/filesystem destructive
|
|
38
|
+
'format\s+/'
|
|
39
|
+
'dd\s+if='
|
|
40
|
+
'mkfs\b'
|
|
41
|
+
'shred\b'
|
|
42
|
+
|
|
43
|
+
# Git destructive operations
|
|
44
|
+
'git\s+push\s+(--force|-f)\b'
|
|
45
|
+
'git\s+push\s+.*--force'
|
|
46
|
+
'git\s+reset\s+--hard'
|
|
47
|
+
'git\s+clean\s+-[a-zA-Z]*f'
|
|
48
|
+
'git\s+branch\s+-D\b'
|
|
49
|
+
|
|
50
|
+
# Permission nuking
|
|
51
|
+
'chmod\s+(-R\s+)?777'
|
|
52
|
+
'chmod\s+-R\s+000'
|
|
53
|
+
|
|
54
|
+
# Container/infra destructive
|
|
55
|
+
'docker\s+system\s+prune'
|
|
56
|
+
'docker\s+rm\s+-f'
|
|
57
|
+
'docker\s+rmi\s+-f'
|
|
58
|
+
'kubectl\s+delete\s+(namespace|ns|all|node)'
|
|
59
|
+
'terraform\s+destroy'
|
|
60
|
+
|
|
61
|
+
# System-level destructive
|
|
62
|
+
'systemctl\s+(stop|disable)\s+'
|
|
63
|
+
'>\s*/dev/sd[a-z]'
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Build combined regex
|
|
67
|
+
REGEX=$(IFS='|'; echo "${DESTRUCTIVE_PATTERNS[*]}")
|
|
68
|
+
|
|
69
|
+
if echo "$NORMALIZED" | grep -qEi "($REGEX)"; then
|
|
70
|
+
echo "WARNING: Potentially destructive command detected. Please verify." >&2
|
|
71
|
+
exit 2
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
exit 0
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# guard-path.sh — Prevent Claude from guessing/hallucinating user home directory paths.
|
|
3
|
+
#
|
|
4
|
+
# Fires on: PreToolUse (Bash|Read|Edit|Write|MultiEdit|Glob|Grep|NotebookEdit|mcp__filesystem__.*)
|
|
5
|
+
# Exit 2 = block the tool call. Stderr message goes to Claude as feedback.
|
|
6
|
+
#
|
|
7
|
+
# Problem: Claude sometimes confuses similar usernames (e.g. "bartlomiejsz" vs
|
|
8
|
+
# "bartlomszsz") when constructing absolute paths, especially with non-ASCII names.
|
|
9
|
+
# This hook detects when a path contains /Users/ or /home/ but does NOT match
|
|
10
|
+
# the actual $HOME, and blocks the call before it fails or hits the wrong location.
|
|
11
|
+
|
|
12
|
+
INPUT=$(cat)
|
|
13
|
+
REAL_HOME="$HOME"
|
|
14
|
+
|
|
15
|
+
# Verify jq is available — required for JSON parsing
|
|
16
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
17
|
+
echo "WARNING: guard-path.sh requires jq but it is not installed. Path validation skipped." >&2
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# Collect ALL path values from tool input into a single list (one per line).
|
|
22
|
+
# Covers: Read/Edit/Write (file_path), Glob/Grep/mcp__filesystem (path),
|
|
23
|
+
# mcp__filesystem__move_file (source, destination),
|
|
24
|
+
# mcp__filesystem__read_multiple_files (paths[]), Bash (command)
|
|
25
|
+
ALL_PATHS=$(echo "$INPUT" | jq -r '
|
|
26
|
+
[
|
|
27
|
+
.tool_input.file_path,
|
|
28
|
+
.tool_input.path,
|
|
29
|
+
.tool_input.source,
|
|
30
|
+
.tool_input.destination,
|
|
31
|
+
.tool_input.command,
|
|
32
|
+
(.tool_input.paths[]? // empty)
|
|
33
|
+
] | map(select(. != null and . != "")) | .[]
|
|
34
|
+
' 2>/dev/null)
|
|
35
|
+
|
|
36
|
+
if [ -z "$ALL_PATHS" ]; then
|
|
37
|
+
exit 0
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
REAL_USER=$(basename "$REAL_HOME")
|
|
41
|
+
|
|
42
|
+
# block_wrong_user — print error to stderr and exit 2 (blocks the tool call)
|
|
43
|
+
block_wrong_user() {
|
|
44
|
+
echo "BLOCKED: Path contains wrong username '${1}' — actual user is '${REAL_USER}'." >&2
|
|
45
|
+
echo "Use \$HOME or ~ prefix, or the correct username '${REAL_USER}' in absolute paths." >&2
|
|
46
|
+
echo "Do NOT guess usernames. Run 'echo \$HOME' if unsure." >&2
|
|
47
|
+
exit 2
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# check_single_path — validate one absolute path
|
|
51
|
+
check_single_path() {
|
|
52
|
+
local P="$1"
|
|
53
|
+
echo "$P" | grep -qE '^/(Users|home)/' || return 0
|
|
54
|
+
local PATH_USER
|
|
55
|
+
PATH_USER=$(echo "$P" | sed 's|^/Users/||;s|^/home/||' | cut -d'/' -f1)
|
|
56
|
+
[ "$PATH_USER" != "$REAL_USER" ] && block_wrong_user "$PATH_USER"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# Iterate without subshell (process substitution keeps exit in main shell)
|
|
60
|
+
while IFS= read -r P; do
|
|
61
|
+
[ -z "$P" ] && continue
|
|
62
|
+
|
|
63
|
+
# Bash commands start with a lowercase letter — extract embedded paths
|
|
64
|
+
if echo "$P" | grep -qE '^[a-z]'; then
|
|
65
|
+
for EMBEDDED in $(echo "$P" | grep -oE '/(Users|home)/[^ "'"'"']+'); do
|
|
66
|
+
check_single_path "$EMBEDDED"
|
|
67
|
+
done
|
|
68
|
+
else
|
|
69
|
+
check_single_path "$P"
|
|
70
|
+
fi
|
|
71
|
+
done <<< "$ALL_PATHS"
|
|
72
|
+
|
|
73
|
+
exit 0
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# post-tool-use.sh — Lightweight feedback after file edits.
|
|
3
|
+
#
|
|
4
|
+
# Fires on: PostToolUse
|
|
5
|
+
# Matcher: Edit|MultiEdit|Write
|
|
6
|
+
# Skipped when TOOLKIT_HOOK_PROFILE=minimal.
|
|
7
|
+
|
|
8
|
+
# shellcheck source=_profile-check.sh
|
|
9
|
+
source "$(dirname "$0")/_profile-check.sh"
|
|
10
|
+
|
|
11
|
+
FILE_PATH="${CLAUDE_TOOL_INPUT_FILE_PATH:-}"
|
|
12
|
+
TOOL_NAME="${CLAUDE_TOOL_NAME:-unknown}"
|
|
13
|
+
|
|
14
|
+
if [ -z "$FILE_PATH" ]; then
|
|
15
|
+
echo "PostToolUse: ${TOOL_NAME} completed. Consider validating lint, tests, and docs if behavior changed."
|
|
16
|
+
exit 0
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
case "$FILE_PATH" in
|
|
20
|
+
*.md|*.txt)
|
|
21
|
+
echo "PostToolUse: updated ${FILE_PATH}. If behavior or workflow changed, refresh related docs and examples."
|
|
22
|
+
;;
|
|
23
|
+
*.bats|*.test.*|*.spec.*)
|
|
24
|
+
echo "PostToolUse: updated test file ${FILE_PATH}. Run the most relevant targeted test command next."
|
|
25
|
+
;;
|
|
26
|
+
*.json|*.yml|*.yaml|*.toml)
|
|
27
|
+
echo "PostToolUse: updated config file ${FILE_PATH}. Validate syntax and any generated artifacts affected by this change."
|
|
28
|
+
;;
|
|
29
|
+
*)
|
|
30
|
+
echo "PostToolUse: updated ${FILE_PATH}. If behavior changed, run validation, targeted tests, and update docs if needed."
|
|
31
|
+
;;
|
|
32
|
+
esac
|
|
33
|
+
|
|
34
|
+
exit 0
|
|
35
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# pre-compact.sh — Save critical context before conversation compaction.
|
|
3
|
+
#
|
|
4
|
+
# Fires on: PreCompact
|
|
5
|
+
# Outputs key context markers so they survive the compaction boundary.
|
|
6
|
+
# Skipped when TOOLKIT_HOOK_PROFILE=minimal.
|
|
7
|
+
|
|
8
|
+
# shellcheck source=_profile-check.sh
|
|
9
|
+
source "$(dirname "$0")/_profile-check.sh"
|
|
10
|
+
|
|
11
|
+
# 1. Remind Claude to reload project rules after compaction
|
|
12
|
+
echo "IMPORTANT: Context was compacted. Re-read CLAUDE.md files and active tasks before continuing."
|
|
13
|
+
|
|
14
|
+
# 2. Preserve active task summary if available
|
|
15
|
+
if [ -f ".claude/session-context.md" ]; then
|
|
16
|
+
echo "=== Pre-Compaction Context ==="
|
|
17
|
+
cat ".claude/session-context.md"
|
|
18
|
+
echo "=============================="
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# 3. Preserve active instincts
|
|
22
|
+
INSTINCTS_DIR=".claude/instincts"
|
|
23
|
+
if [ -d "$INSTINCTS_DIR" ] && ls "$INSTINCTS_DIR"/*.md >/dev/null 2>&1; then
|
|
24
|
+
echo "=== Active Instincts ==="
|
|
25
|
+
for f in "$INSTINCTS_DIR"/*.md; do
|
|
26
|
+
echo "- $(head -1 "$f")"
|
|
27
|
+
done
|
|
28
|
+
echo "========================"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
exit 0
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# quality-check.sh — Multi-language lint check after Claude stops.
|
|
3
|
+
#
|
|
4
|
+
# Fires on: Stop
|
|
5
|
+
# Skipped when TOOLKIT_HOOK_PROFILE=minimal.
|
|
6
|
+
|
|
7
|
+
# shellcheck source=_profile-check.sh
|
|
8
|
+
source "$(dirname "$0")/_profile-check.sh"
|
|
9
|
+
|
|
10
|
+
if [ -f pyproject.toml ] || [ -f setup.py ]; then
|
|
11
|
+
ruff check . 2>&1 | head -15
|
|
12
|
+
elif [ -f package.json ] && [ -f tsconfig.json ]; then
|
|
13
|
+
npx tsc --noEmit 2>&1 | head -15 || true
|
|
14
|
+
elif [ -f composer.json ] && [ -f vendor/bin/phpstan ]; then
|
|
15
|
+
vendor/bin/phpstan analyse 2>&1 | head -15 || true
|
|
16
|
+
elif [ -f pubspec.yaml ]; then
|
|
17
|
+
dart analyze 2>&1 | head -15 || true
|
|
18
|
+
elif [ -f go.mod ]; then
|
|
19
|
+
go vet ./... 2>&1 | head -15 || true
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
exit 0
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# quality-gate.sh — Block task completion if lint/type errors found.
|
|
3
|
+
#
|
|
4
|
+
# Fires on: TaskCompleted
|
|
5
|
+
# Exit 2 = block completion. Skipped when TOOLKIT_HOOK_PROFILE=minimal.
|
|
6
|
+
# Strict profile also runs mypy.
|
|
7
|
+
|
|
8
|
+
# shellcheck source=_profile-check.sh
|
|
9
|
+
source "$(dirname "$0")/_profile-check.sh"
|
|
10
|
+
|
|
11
|
+
if [ -f pyproject.toml ] || [ -f setup.py ]; then
|
|
12
|
+
ruff check . 2>&1 | head -30
|
|
13
|
+
exit_code=$?
|
|
14
|
+
if [ $exit_code -ne 0 ]; then
|
|
15
|
+
echo "QUALITY GATE FAILED: ruff found errors. Fix them before completing." >&2
|
|
16
|
+
exit 2
|
|
17
|
+
fi
|
|
18
|
+
if [ -d src ] && [ "$PROFILE" = "strict" ]; then
|
|
19
|
+
mypy --strict src/ 2>&1 | tail -5
|
|
20
|
+
exit_code=$?
|
|
21
|
+
if [ $exit_code -ne 0 ]; then
|
|
22
|
+
echo "QUALITY GATE FAILED: mypy found type errors." >&2
|
|
23
|
+
exit 2
|
|
24
|
+
fi
|
|
25
|
+
fi
|
|
26
|
+
elif [ -f package.json ] && [ -f tsconfig.json ]; then
|
|
27
|
+
npx tsc --noEmit 2>&1 | tail -10
|
|
28
|
+
exit_code=$?
|
|
29
|
+
if [ $exit_code -ne 0 ]; then
|
|
30
|
+
echo "QUALITY GATE FAILED: TypeScript compilation errors." >&2
|
|
31
|
+
exit 2
|
|
32
|
+
fi
|
|
33
|
+
elif [ -f pubspec.yaml ]; then
|
|
34
|
+
dart analyze 2>&1 | tail -10
|
|
35
|
+
exit_code=$?
|
|
36
|
+
if [ $exit_code -ne 0 ]; then
|
|
37
|
+
echo "QUALITY GATE FAILED: Dart analysis issues." >&2
|
|
38
|
+
exit 2
|
|
39
|
+
fi
|
|
40
|
+
elif [ -f go.mod ]; then
|
|
41
|
+
go vet ./... 2>&1 | tail -10
|
|
42
|
+
exit_code=$?
|
|
43
|
+
if [ $exit_code -ne 0 ]; then
|
|
44
|
+
echo "QUALITY GATE FAILED: Go vet issues." >&2
|
|
45
|
+
exit 2
|
|
46
|
+
fi
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
exit 0
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# save-session.sh — Persist session context on stop for cross-session continuity.
|
|
3
|
+
#
|
|
4
|
+
# Fires on: Stop
|
|
5
|
+
# Skipped when TOOLKIT_HOOK_PROFILE=minimal.
|
|
6
|
+
|
|
7
|
+
# shellcheck source=_profile-check.sh
|
|
8
|
+
source "$(dirname "$0")/_profile-check.sh"
|
|
9
|
+
|
|
10
|
+
SESSION_FILE=".claude/session-context.md"
|
|
11
|
+
|
|
12
|
+
if [ -n "${CLAUDE_SESSION_ID:-}" ]; then
|
|
13
|
+
mkdir -p .claude
|
|
14
|
+
cat > "$SESSION_FILE" << EOF
|
|
15
|
+
# Session Context
|
|
16
|
+
Updated: $(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
17
|
+
Session: ${CLAUDE_SESSION_ID:-unknown}
|
|
18
|
+
|
|
19
|
+
## Last Active Task
|
|
20
|
+
${CLAUDE_TASK_DESCRIPTION:-No task description available}
|
|
21
|
+
EOF
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
exit 0
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# session-end.sh — Persist a lightweight handoff note when a Claude session ends.
|
|
3
|
+
#
|
|
4
|
+
# Fires on: SessionEnd
|
|
5
|
+
# Matcher: all
|
|
6
|
+
# Skipped when TOOLKIT_HOOK_PROFILE=minimal.
|
|
7
|
+
|
|
8
|
+
# shellcheck source=_profile-check.sh
|
|
9
|
+
source "$(dirname "$0")/_profile-check.sh"
|
|
10
|
+
|
|
11
|
+
STATE_DIR=".claude"
|
|
12
|
+
SESSION_FILE="$STATE_DIR/session-context.md"
|
|
13
|
+
HANDOFF_FILE="$STATE_DIR/session-end.md"
|
|
14
|
+
STAMP="$(date -u +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || date)"
|
|
15
|
+
|
|
16
|
+
mkdir -p "$STATE_DIR"
|
|
17
|
+
|
|
18
|
+
{
|
|
19
|
+
echo "# Session End Snapshot"
|
|
20
|
+
echo ""
|
|
21
|
+
echo "- ended_at: $STAMP"
|
|
22
|
+
if [ -f "$SESSION_FILE" ]; then
|
|
23
|
+
echo "- session_context: present"
|
|
24
|
+
else
|
|
25
|
+
echo "- session_context: missing"
|
|
26
|
+
fi
|
|
27
|
+
echo "- next_start: re-read CLAUDE.md, open tasks, and validation state"
|
|
28
|
+
} > "$HANDOFF_FILE"
|
|
29
|
+
|
|
30
|
+
if [ -f "$SESSION_FILE" ]; then
|
|
31
|
+
echo "SessionEnd: wrote .claude/session-end.md and preserved existing .claude/session-context.md for the next session."
|
|
32
|
+
else
|
|
33
|
+
echo "SessionEnd: wrote .claude/session-end.md. Consider persisting open tasks in .claude/session-context.md before ending long workstreams."
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
exit 0
|
|
37
|
+
|