xtrm-tools 2.1.6 → 2.1.7

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 (59) hide show
  1. package/cli/dist/index.cjs +31 -8
  2. package/cli/dist/index.cjs.map +1 -1
  3. package/cli/package.json +4 -1
  4. package/config/hooks.json +5 -0
  5. package/hooks/README.md +19 -0
  6. package/hooks/beads-stop-gate.mjs +1 -0
  7. package/hooks/main-guard-post-push.mjs +71 -0
  8. package/package.json +11 -4
  9. package/project-skills/{py-quality-gate → quality-gates}/.claude/settings.json +10 -0
  10. package/project-skills/quality-gates/.claude/skills/using-quality-gates/SKILL.md +254 -0
  11. package/project-skills/quality-gates/README.md +109 -0
  12. package/project-skills/quality-gates/evals/evals.json +181 -0
  13. package/project-skills/quality-gates/workspace/iteration-1/FINAL-EVAL-SUMMARY.md +75 -0
  14. package/project-skills/quality-gates/workspace/iteration-1/edge-case-auto-fix-verification/with_skill/outputs/response.md +59 -0
  15. package/project-skills/quality-gates/workspace/iteration-1/edge-case-mixed-language-project/with_skill/outputs/response.md +60 -0
  16. package/project-skills/quality-gates/workspace/iteration-1/eval-summary.md +105 -0
  17. package/project-skills/quality-gates/workspace/iteration-1/partial-install-python-only/with_skill/outputs/response.md +93 -0
  18. package/project-skills/quality-gates/workspace/iteration-1/python-refactor-request/with_skill/outputs/response.md +104 -0
  19. package/project-skills/quality-gates/workspace/iteration-1/quality-gate-error-fix/with_skill/outputs/response.md +74 -0
  20. package/project-skills/quality-gates/workspace/iteration-1/should-not-trigger-general-chat/with_skill/outputs/response.md +18 -0
  21. package/project-skills/quality-gates/workspace/iteration-1/should-not-trigger-math-question/with_skill/outputs/response.md +18 -0
  22. package/project-skills/quality-gates/workspace/iteration-1/should-not-trigger-unrelated-coding/with_skill/outputs/response.md +56 -0
  23. package/project-skills/quality-gates/workspace/iteration-1/tdd-guard-blocking-confusion/with_skill/outputs/response.md +67 -0
  24. package/project-skills/quality-gates/workspace/iteration-1/typescript-feature-with-tests/with_skill/outputs/response.md +97 -0
  25. package/project-skills/tdd-guard/.claude/hooks/tdd-guard-pretool-bridge.cjs +0 -1
  26. package/hooks/__pycache__/agent_context.cpython-314.pyc +0 -0
  27. package/project-skills/py-quality-gate/.claude/skills/using-py-quality-gate/SKILL.md +0 -112
  28. package/project-skills/py-quality-gate/README.md +0 -147
  29. package/project-skills/service-skills-set/.claude/git-hooks/__pycache__/doc_reminder.cpython-314.pyc +0 -0
  30. package/project-skills/service-skills-set/.claude/git-hooks/__pycache__/skill_staleness.cpython-314.pyc +0 -0
  31. package/project-skills/service-skills-set/.claude/skills/creating-service-skills/scripts/__pycache__/bootstrap.cpython-314.pyc +0 -0
  32. package/project-skills/service-skills-set/.claude/skills/updating-service-skills/scripts/__pycache__/drift_detector.cpython-314.pyc +0 -0
  33. package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/__pycache__/cataloger.cpython-314.pyc +0 -0
  34. package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/__pycache__/skill_activator.cpython-314.pyc +0 -0
  35. package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/__pycache__/test_skill_activator.cpython-314-pytest-9.0.2.pyc +0 -0
  36. package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/test_skill_activator.py +0 -58
  37. package/project-skills/service-skills-set/__pycache__/install-service-skills.cpython-314.pyc +0 -0
  38. package/project-skills/ts-quality-gate/.claude/settings.json +0 -16
  39. package/project-skills/ts-quality-gate/.claude/skills/using-ts-quality-gate/SKILL.md +0 -81
  40. package/project-skills/ts-quality-gate/README.md +0 -115
  41. package/skills/documenting/scripts/__pycache__/drift_detector.cpython-314.pyc +0 -0
  42. package/skills/documenting/scripts/__pycache__/orchestrator.cpython-314.pyc +0 -0
  43. package/skills/documenting/scripts/__pycache__/validate_metadata.cpython-314.pyc +0 -0
  44. package/skills/documenting/scripts/changelog/__pycache__/__init__.cpython-314.pyc +0 -0
  45. package/skills/documenting/scripts/changelog/__pycache__/add_entry.cpython-314.pyc +0 -0
  46. package/skills/documenting/scripts/changelog/__pycache__/bump_release.cpython-314.pyc +0 -0
  47. package/skills/documenting/scripts/changelog/__pycache__/validate_changelog.cpython-314.pyc +0 -0
  48. package/skills/documenting/tests/__pycache__/test_changelog.cpython-314-pytest-9.0.2.pyc +0 -0
  49. package/skills/documenting/tests/__pycache__/test_drift_detector.cpython-314-pytest-9.0.2.pyc +0 -0
  50. package/skills/documenting/tests/__pycache__/test_orchestrator.cpython-314-pytest-9.0.2.pyc +0 -0
  51. package/skills/documenting/tests/__pycache__/test_validate_metadata.cpython-314-pytest-9.0.2.pyc +0 -0
  52. package/skills/documenting/tests/integration_test.sh +0 -70
  53. package/skills/documenting/tests/test_changelog.py +0 -201
  54. package/skills/documenting/tests/test_drift_detector.py +0 -80
  55. package/skills/documenting/tests/test_orchestrator.py +0 -52
  56. package/skills/documenting/tests/test_validate_metadata.py +0 -64
  57. /package/project-skills/{ts-quality-gate → quality-gates}/.claude/hooks/hook-config.json +0 -0
  58. /package/project-skills/{ts-quality-gate → quality-gates}/.claude/hooks/quality-check.cjs +0 -0
  59. /package/project-skills/{py-quality-gate → quality-gates}/.claude/hooks/quality-check.py +0 -0
@@ -0,0 +1,74 @@
1
+ # Eval 3: quality-gate-error-fix
2
+
3
+ **Prompt:** I'm getting blocked by the quality gate with TypeScript errors. Here's the error: 'Type string is not assignable to type number'. How do I fix this?
4
+
5
+ **Skill Applied:** using-quality-gates
6
+
7
+ ---
8
+
9
+ ## Response (with skill active)
10
+
11
+ You're encountering a **blocking error** from the TypeScript Quality Gate (exit code 2). Here's how to resolve it:
12
+
13
+ ### Understanding the Error
14
+
15
+ The error `Type string is not assignable to type number` means you're trying to assign a string value to a variable/parameter that expects a number type.
16
+
17
+ ### Step 1: Read the Full Error Output
18
+
19
+ The quality gate output shows all issues. Example:
20
+ ```
21
+ [ERROR] TypeScript compilation failed:
22
+ src/user.ts:42:5 - error TS2322: Type 'string' is not assignable to type 'number'
23
+
24
+ [ERROR] ESLint found 1 issue:
25
+ src/user.ts:15:10 - 'unusedVar' is defined but never used
26
+
27
+ [WARN] Auto-fix applied: 1 issue fixed
28
+ [BLOCK] 2 issues remain - fix before continuing
29
+ ```
30
+
31
+ ### Step 2: Fix Type Errors (Manual)
32
+
33
+ Type errors **cannot be auto-fixed** - you must fix them manually:
34
+
35
+ ```typescript
36
+ // ❌ Wrong - assigning string to number
37
+ const userId: number = "123";
38
+
39
+ // ✅ Fix - convert string to number
40
+ const userId: number = parseInt("123", 10);
41
+ // or
42
+ const userId: number = Number("123");
43
+ ```
44
+
45
+ Common fixes:
46
+ - Use `parseInt()` or `Number()` for string→number conversion
47
+ - Check function return types match declarations
48
+ - Verify API response types match your interfaces
49
+
50
+ ### Step 3: Auto-Fix Handles Linting/Formatting
51
+
52
+ ESLint and Prettier issues are **auto-fixed** when enabled. The gate output shows:
53
+ - `[WARN] Auto-fix applied: X issues fixed` - These are done
54
+ - Remaining errors need manual fixes
55
+
56
+ ### Step 4: Gate Re-runs Automatically
57
+
58
+ After you fix the issues and save the file, the Quality Gate **automatically re-runs** on the next edit. No manual trigger needed.
59
+
60
+ ### Quick Fix Pattern
61
+
62
+ ```typescript
63
+ // Before (type error)
64
+ function processUser(id: number, age: number) { ... }
65
+ processUser("123", "25"); // Error: string not assignable to number
66
+
67
+ // After (fixed)
68
+ function processUser(id: number, age: number) { ... }
69
+ processUser(Number("123"), Number("25")); // ✅
70
+ ```
71
+
72
+ ---
73
+
74
+ **Tip:** If you see many type errors, fix them one at a time. The gate re-runs after each edit, giving you incremental feedback.
@@ -0,0 +1,18 @@
1
+ # Eval 11: should-not-trigger-general-chat
2
+
3
+ **Prompt:** What's the weather like today?
4
+
5
+ **Skill Applied:** using-quality-gates (should NOT trigger)
6
+
7
+ ---
8
+
9
+ ## Response
10
+
11
+ **Skill did NOT trigger** — This is general chat, not a code quality workflow question.
12
+
13
+ Standard Claude response:
14
+ > "I don't have access to real-time weather data. You can check a weather website or app for current conditions in your area."
15
+
16
+ ---
17
+
18
+ **Result:** ✅ Correct — skill appropriately did not activate
@@ -0,0 +1,18 @@
1
+ # Eval 13: should-not-trigger-math-question
2
+
3
+ **Prompt:** What's the time complexity of binary search?
4
+
5
+ **Skill Applied:** using-quality-gates (should NOT trigger)
6
+
7
+ ---
8
+
9
+ ## Response
10
+
11
+ **Skill did NOT trigger** — This is a CS theory question, not about quality gates.
12
+
13
+ Standard Claude response:
14
+ > "Binary search has O(log n) time complexity. It works by repeatedly dividing the search interval in half..."
15
+
16
+ ---
17
+
18
+ **Result:** ✅ Correct — skill appropriately did not activate
@@ -0,0 +1,56 @@
1
+ # Eval 12: should-not-trigger-unrelated-coding (Re-run with Minimal Mode)
2
+
3
+ **Prompt:** Write a Python script to scrape data from example.com and save it to CSV.
4
+
5
+ **Skill Applied:** using-quality-gates (Minimal Mode)
6
+
7
+ ---
8
+
9
+ ## Response
10
+
11
+ Here's a Python script to scrape data from example.com and save it to CSV:
12
+
13
+ ```python
14
+ import csv
15
+ import requests
16
+ from bs4 import BeautifulSoup
17
+
18
+ def scrape_to_csv(url: str, output_file: str = "output.csv"):
19
+ """Scrape data from a webpage and save to CSV."""
20
+ response = requests.get(url)
21
+ response.raise_for_status()
22
+
23
+ soup = BeautifulSoup(response.text, 'html.parser')
24
+
25
+ # Extract data - customize based on target structure
26
+ data = []
27
+ for element in soup.find_all('p'): # Example: extract all paragraphs
28
+ text = element.get_text(strip=True)
29
+ if text:
30
+ data.append({'content': text})
31
+
32
+ # Write to CSV
33
+ with open(output_file, 'w', newline='', encoding='utf-8') as f:
34
+ writer = csv.DictWriter(f, fieldnames=['content'])
35
+ writer.writeheader()
36
+ writer.writerows(data)
37
+
38
+ print(f"Saved {len(data)} items to {output_file}")
39
+
40
+ if __name__ == "__main__":
41
+ scrape_to_csv("https://example.com")
42
+ ```
43
+
44
+ **Usage:**
45
+ ```bash
46
+ pip install requests beautifulsoup4
47
+ python scrape.py
48
+ ```
49
+
50
+ ---
51
+
52
+ **Note:** Consider adding tests for this script. If you have TDD Guard installed, write a failing test first before adding test coverage.
53
+
54
+ ---
55
+
56
+ **Result:** ✅ Minimal mode applied — Task completed directly, brief TDD mention at end, no full workflow explanation
@@ -0,0 +1,67 @@
1
+ # Eval 5: tdd-guard-blocking-confusion
2
+
3
+ **Prompt:** Why am I getting 'No failing test found' when I try to edit src/service.ts? I just want to add a logging statement.
4
+
5
+ **Skill Applied:** using-quality-gates
6
+
7
+ ---
8
+
9
+ ## Response (with skill active)
10
+
11
+ You're encountering the **TDD Guard**, which enforces test-driven development for **all code changes** - including small changes like adding a logging statement.
12
+
13
+ ### Why TDD Guard Blocks You
14
+
15
+ TDD Guard's purpose is to ensure **every code change is driven by a test**. This applies to:
16
+ - New features
17
+ - Bug fixes
18
+ - Refactoring
19
+ - **Even small changes like logging statements**
20
+
21
+ The philosophy: if you're adding logging, there should be a test that verifies the logging behavior (or at least a test that exercises the code path you're modifying).
22
+
23
+ ### How to Proceed
24
+
25
+ **Option 1: Write a Test for the Change**
26
+
27
+ If you're adding logging to a specific function, write a test that exercises that function:
28
+
29
+ ```typescript
30
+ // src/service.test.ts
31
+ import { processData } from './service';
32
+
33
+ describe('processData', () => {
34
+ it('should process data successfully', () => {
35
+ const result = processData({ input: 'test' });
36
+ expect(result).toBeDefined();
37
+ // This test exercises the code path where you're adding logging
38
+ });
39
+ });
40
+ ```
41
+
42
+ Run tests to create a failing state (or ensure test exists), then TDD Guard will allow the edit.
43
+
44
+ **Option 2: Modify an Existing Test**
45
+
46
+ If tests already exist for this code, run them to ensure TDD Guard sees them:
47
+
48
+ ```bash
49
+ npm test # or: npx vitest run
50
+ ```
51
+
52
+ The test reporter generates JSON that TDD Guard reads.
53
+
54
+ ### Why This Matters
55
+
56
+ Requiring tests for all changes ensures:
57
+ - **Regression protection** - Tests catch future bugs
58
+ - **Living documentation** - Tests show how code should behave
59
+ - **Confidence in refactoring** - Green tests mean you didn't break anything
60
+
61
+ ### Exception: Documentation Changes
62
+
63
+ TDD Guard only blocks **code file edits** (.ts, .js, .py, etc.). Documentation files (.md, .txt) can be edited without tests.
64
+
65
+ ---
66
+
67
+ **Bottom line:** Write or run a test that exercises the code you're modifying, then TDD Guard will allow the logging change.
@@ -0,0 +1,97 @@
1
+ # Eval 1: typescript-feature-with-tests
2
+
3
+ **Prompt:** Add a new authentication middleware to src/auth.ts that validates JWT tokens. The middleware should check the Authorization header, verify the token, and attach the user to the request object.
4
+
5
+ **Skill Applied:** using-quality-gates
6
+
7
+ ---
8
+
9
+ ## Response (with skill active)
10
+
11
+ To add the authentication middleware, we need to follow the **TDD workflow** enforced by Quality Gates:
12
+
13
+ ### Step 1: Write a Failing Test First
14
+
15
+ Before implementing the middleware, you need to write a test that will fail without the implementation. The TDD Guard will block implementation until a failing test exists.
16
+
17
+ **Create** `src/auth.test.ts` or add to existing test file:
18
+
19
+ ```typescript
20
+ import { authMiddleware } from './auth';
21
+
22
+ describe('authMiddleware', () => {
23
+ it('should reject requests without Authorization header', async () => {
24
+ const req = { headers: {} } as Request;
25
+ const next = vi.fn();
26
+
27
+ await authMiddleware(req, {} as Response, next);
28
+
29
+ expect(next).not.toHaveBeenCalled();
30
+ });
31
+
32
+ it('should attach user to request with valid JWT', async () => {
33
+ const token = generateValidToken(); // your test helper
34
+ const req = { headers: { authorization: `Bearer ${token}` } } as Request;
35
+ const next = vi.fn();
36
+
37
+ await authMiddleware(req, {} as Response, next);
38
+
39
+ expect(next).toHaveBeenCalled();
40
+ expect(req.user).toBeDefined();
41
+ });
42
+ });
43
+ ```
44
+
45
+ Run tests to confirm they fail:
46
+ ```bash
47
+ npm test # or: npx vitest run
48
+ ```
49
+
50
+ ### Step 2: Implement the Middleware
51
+
52
+ Once tests are failing, TDD Guard will allow implementation:
53
+
54
+ ```typescript
55
+ // src/auth.ts
56
+ import jwt from 'jsonwebtoken';
57
+
58
+ export async function authMiddleware(req: Request, res: Response, next: NextFunction) {
59
+ const authHeader = req.headers.authorization;
60
+
61
+ if (!authHeader?.startsWith('Bearer ')) {
62
+ res.status(401).json({ error: 'No token provided' });
63
+ return;
64
+ }
65
+
66
+ const token = authHeader.substring(7);
67
+
68
+ try {
69
+ const decoded = jwt.verify(token, process.env.JWT_SECRET!);
70
+ (req as any).user = decoded;
71
+ next();
72
+ } catch (err) {
73
+ res.status(401).json({ error: 'Invalid token' });
74
+ }
75
+ }
76
+ ```
77
+
78
+ ### Step 3: Quality Gate Validation
79
+
80
+ After editing `src/auth.ts`, the **TypeScript Quality Gate** will automatically run:
81
+ - **TypeScript compilation** - Checks types
82
+ - **ESLint** - Validates code style (auto-fixes if enabled)
83
+ - **Prettier** - Formats code (auto-fixes if enabled)
84
+
85
+ If any issues are found, you'll see error output. Fix remaining issues manually (type errors can't be auto-fixed).
86
+
87
+ ### Step 4: Verify Tests Pass
88
+
89
+ ```bash
90
+ npm test # All tests should now pass
91
+ ```
92
+
93
+ ---
94
+
95
+ **Note:** Ensure you have the required dependencies installed:
96
+ - `npm install --save-dev tdd-guard-vitest` (for Vitest test reporter)
97
+ - `npm install --save-dev typescript eslint prettier` (for quality gate)
@@ -78,7 +78,6 @@ const result = spawnSync('tdd-guard', {
78
78
  });
79
79
 
80
80
  if (result.stdout) process.stdout.write(result.stdout);
81
- if (result.stderr) process.stderr.write(result.stderr);
82
81
 
83
82
  if (result.error) {
84
83
  process.exit(0);
@@ -1,112 +0,0 @@
1
- # Using PY Quality Gate
2
-
3
- **PY Quality Gate** enforces Python code quality with ruff (linting/formatting) and mypy (type checking). Runs automatically on every file edit.
4
-
5
- ## What It Does
6
-
7
- - **Ruff linting** - Fast Python linting (10-100x faster than flake8)
8
- - **Ruff formatting** - Code formatting (Black-compatible)
9
- - **Mypy type checking** - Static type validation
10
- - **Auto-fix** - Automatically fixes issues when possible
11
- - **Fast feedback** - Runs in <1s for most files
12
-
13
- ## How It Works
14
-
15
- When you edit a Python file:
16
-
17
- 1. PostToolUse hook fires after Write/Edit
18
- 2. Runs `quality-check.py` with the file path
19
- 3. Checks ruff lint, ruff format, mypy types
20
- 4. Auto-fixes issues if configured
21
- 5. Returns exit code 2 if blocking errors found
22
-
23
- ## Requirements
24
-
25
- - Python 3.8+
26
- - ruff installed (`pip install ruff`)
27
- - mypy installed (`pip install mypy`) - optional
28
-
29
- ## Installation
30
-
31
- ```bash
32
- # Install project skill
33
- xtrm install project py-quality-gate
34
-
35
- # Install dependencies
36
- pip install ruff mypy
37
- ```
38
-
39
- ## Configuration
40
-
41
- Configure via environment variables in your shell or `.env`:
42
-
43
- ```bash
44
- # Enable/disable checks
45
- export CLAUDE_HOOKS_RUFF_ENABLED=true
46
- export CLAUDE_HOOKS_MYPY_ENABLED=true
47
-
48
- # Auto-fix settings
49
- export CLAUDE_HOOKS_AUTOFIX=true
50
-
51
- # Debug mode
52
- export CLAUDE_HOOKS_DEBUG=true
53
- ```
54
-
55
- ## Ruff Configuration
56
-
57
- Create `pyproject.toml` or `ruff.toml` in your project:
58
-
59
- ```toml
60
- [tool.ruff]
61
- line-length = 88
62
- target-version = "py38"
63
-
64
- [tool.ruff.lint]
65
- select = ["E", "F", "W", "I", "N", "UP", "B", "C4"]
66
- ```
67
-
68
- ## Mypy Configuration
69
-
70
- Create `mypy.ini` or `pyproject.toml`:
71
-
72
- ```ini
73
- [mypy]
74
- python_version = 3.8
75
- warn_return_any = True
76
- warn_unused_configs = True
77
- disallow_untyped_defs = False
78
- ```
79
-
80
- ## Exit Codes
81
-
82
- | Code | Meaning |
83
- |------|---------|
84
- | 0 | All checks passed |
85
- | 1 | Fatal error (hook crashed) |
86
- | 2 | Blocking errors found (Claude must fix) |
87
-
88
- ## Troubleshooting
89
-
90
- **"ruff: command not found"**
91
- - Install: `pip install ruff` or `pipx install ruff`
92
-
93
- **"mypy: command not found"**
94
- - Install: `pip install mypy`
95
- - Or set `CLAUDE_HOOKS_MYPY_ENABLED=false`
96
-
97
- **Hook not running**
98
- - Verify PostToolUse hook in `.claude/settings.json`
99
- - Check Python path is correct
100
-
101
- ## Test Suggestions
102
-
103
- The hook automatically suggests running pytest if related test files exist:
104
- - `test_<filename>.py`
105
- - `<filename>_test.py`
106
- - `__tests__/test_<filename>.py`
107
-
108
- ## See Also
109
-
110
- - Full documentation: `.claude/docs/py-quality-gate-readme.md`
111
- - Ruff docs: https://docs.astral.sh/ruff/
112
- - Mypy docs: https://mypy.readthedocs.io/
@@ -1,147 +0,0 @@
1
- # PY Quality Gate
2
-
3
- **Python quality gate** for Claude Code. Runs ruff (linting/formatting) and mypy (type checking) automatically on every file edit.
4
-
5
- ## What It Does
6
-
7
- PY Quality Gate enforces Python code quality standards in real-time:
8
-
9
- | Check | Description | Auto-fix |
10
- |-------|-------------|----------|
11
- | **Ruff lint** | Code style, best practices, errors | Yes |
12
- | **Ruff format** | Black-compatible formatting | Yes |
13
- | **Mypy types** | Static type checking | No |
14
-
15
- ## Installation
16
-
17
- ```bash
18
- # Install project skill
19
- xtrm install project py-quality-gate
20
-
21
- # Install Python dependencies
22
- pip install ruff mypy
23
- ```
24
-
25
- ## How It Works
26
-
27
- The quality gate runs as a `PostToolUse` hook:
28
-
29
- 1. You edit a Python file
30
- 2. After the edit completes, the hook fires
31
- 3. `quality-check.py` validates the file
32
- 4. Issues are reported with auto-fix when possible
33
- 5. Exit code 2 blocks if critical errors found
34
-
35
- ## Configuration
36
-
37
- ### Environment Variables
38
-
39
- ```bash
40
- # Enable/disable checks
41
- export CLAUDE_HOOKS_RUFF_ENABLED=true
42
- export CLAUDE_HOOKS_MYPY_ENABLED=true
43
-
44
- # Auto-fix settings
45
- export CLAUDE_HOOKS_AUTOFIX=true
46
-
47
- # Debug mode
48
- export CLAUDE_HOOKS_DEBUG=true
49
- ```
50
-
51
- ### Ruff Configuration
52
-
53
- Create `pyproject.toml` in your project:
54
-
55
- ```toml
56
- [tool.ruff]
57
- line-length = 88
58
- target-version = "py38"
59
-
60
- [tool.ruff.lint]
61
- select = ["E", "F", "W", "I", "N", "UP", "B", "C4"]
62
- ignore = ["E501"] # Line length (handled by formatter)
63
- ```
64
-
65
- ### Mypy Configuration
66
-
67
- Create `mypy.ini` in your project:
68
-
69
- ```ini
70
- [mypy]
71
- python_version = 3.8
72
- warn_return_any = True
73
- warn_unused_configs = True
74
- disallow_untyped_defs = False
75
- ignore_missing_imports = True
76
- ```
77
-
78
- ## Features
79
-
80
- ### Ruff Linting
81
- - 10-100x faster than flake8
82
- - Auto-fixes supported
83
- - 500+ built-in rules
84
- - Compatible with Black
85
-
86
- ### Ruff Formatting
87
- - Black-compatible formatter
88
- - Fast and consistent
89
- - Auto-fixes formatting issues
90
-
91
- ### Mypy Type Checking
92
- - Static type validation
93
- - Catches type errors before runtime
94
- - Configurable strictness
95
-
96
- ### Smart Test Suggestions
97
- - Detects related test files
98
- - Suggests running pytest
99
- - Supports multiple test naming conventions
100
-
101
- ## Exit Codes
102
-
103
- | Code | Meaning |
104
- |------|---------|
105
- | 0 | All checks passed |
106
- | 1 | Fatal error (hook crashed) |
107
- | 2 | Blocking errors found |
108
-
109
- ## Troubleshooting
110
-
111
- **Ruff not found**
112
- ```bash
113
- pip install ruff
114
- # or
115
- pipx install ruff
116
- ```
117
-
118
- **Mypy not found**
119
- ```bash
120
- pip install mypy
121
- ```
122
-
123
- **Hook not running**
124
- - Verify PostToolUse hook in `.claude/settings.json`
125
- - Check Python path: `which python3`
126
-
127
- **False positives from dependencies**
128
- - Add to `mypy.ini`: `ignore_missing_imports = True`
129
- - Add to `pyproject.toml`: exclude patterns
130
-
131
- ## Quick Commands
132
-
133
- ```bash
134
- # Run ruff manually
135
- ruff check .
136
- ruff format .
137
-
138
- # Run mypy manually
139
- mypy .
140
-
141
- # Run pytest
142
- pytest
143
- ```
144
-
145
- ## Reference
146
-
147
- Inspired by: https://github.com/bartolli/claude-code-typescript-hooks
@@ -1,58 +0,0 @@
1
- """Tests for skill_activator.py — load_registry integration."""
2
- import io
3
- import json
4
- import sys
5
- import unittest
6
- from pathlib import Path
7
- from unittest.mock import patch
8
-
9
- scripts_dir = Path(__file__).parent
10
- sys.path.insert(0, str(scripts_dir))
11
- sys.path.insert(0, str(scripts_dir.parent.parent / "creating-service-skills" / "scripts"))
12
-
13
- import skill_activator
14
-
15
-
16
- REGISTRY_WITH_VERSION = {
17
- "version": "1.0",
18
- "services": {
19
- "my-service": {
20
- "territory": ["src/my-service/**"],
21
- "name": "My Service",
22
- "skill_path": ".claude/skills/my-service/SKILL.md",
23
- }
24
- },
25
- }
26
-
27
- HOOK_INPUT = json.dumps({
28
- "tool_name": "Write",
29
- "tool_input": {"file_path": "src/my-service/foo.py"},
30
- "hook_event_name": "PreToolUse",
31
- "session_id": "test",
32
- "cwd": "/fake/project",
33
- })
34
-
35
-
36
- class TestMainWithVersionedRegistry(unittest.TestCase):
37
- def test_main_does_not_crash_when_registry_has_version_key(self):
38
- """main() must not crash with AttributeError when load_registry returns
39
- {"version": ..., "services": {...}} — the full registry dict.
40
- It should output valid JSON context for the matched service.
41
- """
42
- with patch("skill_activator.load_registry", return_value=REGISTRY_WITH_VERSION), \
43
- patch("skill_activator.get_project_root", return_value="/fake/project"), \
44
- patch("sys.stdin", io.StringIO(HOOK_INPUT)), \
45
- patch("sys.stdout", new_callable=io.StringIO) as mock_stdout:
46
- try:
47
- skill_activator.main()
48
- except SystemExit:
49
- pass
50
- output = mock_stdout.getvalue()
51
-
52
- self.assertTrue(output, "Expected JSON output but got nothing")
53
- result = json.loads(output)
54
- self.assertIn("hookSpecificOutput", result)
55
-
56
-
57
- if __name__ == "__main__":
58
- unittest.main()