create-agent-room 1.2.1
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/README.md +229 -0
- package/bin/cli.js +186 -0
- package/examples/python-project/.agent-room.json +14 -0
- package/examples/python-project/AGENTS.md +32 -0
- package/examples/rust-project/.agent-room.json +12 -0
- package/examples/rust-project/AGENTS.md +32 -0
- package/lib/color.js +31 -0
- package/lib/fsutil.js +218 -0
- package/lib/init.js +660 -0
- package/lib/lint-sessions.js +278 -0
- package/lib/metrics.js +190 -0
- package/lib/pr.js +176 -0
- package/lib/prompt.js +20 -0
- package/lib/session-utils.js +213 -0
- package/lib/sync.js +138 -0
- package/lib/validate.js +179 -0
- package/package.json +48 -0
- package/templates/.agent-room/anti-patterns.md +22 -0
- package/templates/.agent-room/coordination/handoff-protocol.md +60 -0
- package/templates/.agent-room/coordination/scope-boundaries.md +57 -0
- package/templates/.agent-room/coordination/session-log-format.md +62 -0
- package/templates/.agent-room/decisions.md +17 -0
- package/templates/.agent-room/guardrails.json +23 -0
- package/templates/.agent-room/guardrails.md +56 -0
- package/templates/.agent-room/principles.md +306 -0
- package/templates/.agent-room/sessions/.gitkeep +4 -0
- package/templates/.agent-room/skills/brainstorming.md +64 -0
- package/templates/.agent-room/skills/closing-the-loop.md +67 -0
- package/templates/.agent-room/skills/systematic-debugging.md +85 -0
- package/templates/.agent-room/skills/test-driven-development.md +100 -0
- package/templates/.agent-room/skills/verification-before-completion.md +56 -0
- package/templates/.agent-room/skills/writing-plans.md +87 -0
- package/templates/.agent-room/workflow-classifier.md +127 -0
- package/templates/AGENTS.md.tmpl +85 -0
- package/templates/adapters/CLAUDE.md.tmpl +38 -0
- package/templates/adapters/claude-hooks/close-the-loop-check.js +96 -0
- package/templates/adapters/clinerules.tmpl +14 -0
- package/templates/adapters/codexrules.tmpl +45 -0
- package/templates/adapters/cursorrules.tmpl +14 -0
- package/templates/adapters/git-hooks/guardrails-check.js +140 -0
- package/templates/adapters/git-hooks/pre-commit.tmpl +43 -0
- package/templates/adapters/windsurfrules.tmpl +14 -0
- package/templates/docs/plans/.gitkeep +0 -0
- package/templates/skill-packs/api-design/api-design.md +152 -0
- package/templates/skill-packs/code-review/code-review.md +113 -0
- package/templates/skill-packs/database/database-migrations.md +123 -0
- package/templates/skill-packs/documentation/documentation.md +155 -0
- package/templates/skill-packs/observability/observability.md +128 -0
- package/templates/skill-packs/performance/performance-optimization.md +150 -0
- package/templates/skill-packs/release/release-management.md +145 -0
- package/templates/skill-packs/security/security-principles.md +127 -0
- package/templates/skill-packs/testing/integration-testing.md +127 -0
- package/templates/stacks/python/.agent-room/skills/python-testing.md +59 -0
- package/templates/stacks/python/AGENTS.md.tmpl +35 -0
- package/templates/stacks/react/.agent-room/skills/react-component-testing.md +76 -0
- package/templates/stacks/react/AGENTS.md.tmpl +37 -0
- package/templates/stacks/typescript/.agent-room/skills/typescript-testing.md +63 -0
- package/templates/stacks/typescript/AGENTS.md.tmpl +36 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-principles
|
|
3
|
+
description: "Use when dealing with database operations, authentication, user input parsing, secrets management, API security, or any code that handles untrusted data."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Security Principles
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Secure coding is not an afterthought — it's a default. Agents must write
|
|
11
|
+
secure code from the first line. A security bug that ships is orders of
|
|
12
|
+
magnitude more expensive than one caught during development.
|
|
13
|
+
|
|
14
|
+
## The iron law
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
ALL CLIENT DATA IS UNTRUSTED UNTIL VALIDATED ON THE SERVER
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
This applies to query parameters, request bodies, headers, cookies, file
|
|
21
|
+
uploads, and URL paths. No exceptions. "The frontend validates it" is not
|
|
22
|
+
a security control — it's a convenience for the user.
|
|
23
|
+
|
|
24
|
+
## The threat model
|
|
25
|
+
|
|
26
|
+
### 1. Injection attacks
|
|
27
|
+
|
|
28
|
+
**Rule:** Never construct queries, commands, or markup by concatenating
|
|
29
|
+
user input.
|
|
30
|
+
|
|
31
|
+
- **SQL:** Always use parameterized queries or ORMs. Never build query
|
|
32
|
+
strings with template literals or concatenation.
|
|
33
|
+
```
|
|
34
|
+
BAD: db.query(`SELECT * FROM users WHERE id = ${req.params.id}`)
|
|
35
|
+
GOOD: db.query('SELECT * FROM users WHERE id = $1', [req.params.id])
|
|
36
|
+
```
|
|
37
|
+
- **NoSQL:** Same rule applies. MongoDB's `$gt`, `$ne` operators in
|
|
38
|
+
user input can bypass authentication. Validate input types explicitly.
|
|
39
|
+
- **OS commands:** Never pass user input to `exec()` or `system()`. Use
|
|
40
|
+
`execFile()` with an argument array. If shell execution is unavoidable,
|
|
41
|
+
use an allowlist of permitted values.
|
|
42
|
+
- **HTML/XSS:** Sanitize all user-generated content before rendering.
|
|
43
|
+
Use the framework's built-in escaping (React's JSX, Django's template
|
|
44
|
+
engine). If inserting raw HTML, use a sanitization library with an
|
|
45
|
+
allowlist, not a denylist.
|
|
46
|
+
|
|
47
|
+
### 2. Secret exposure
|
|
48
|
+
|
|
49
|
+
**Rule:** Never check in API keys, passwords, tokens, or credentials.
|
|
50
|
+
|
|
51
|
+
- Store secrets in environment variables. Reference them via
|
|
52
|
+
`process.env`, `os.environ`, or equivalent.
|
|
53
|
+
- Add files containing secrets to `.gitignore` immediately.
|
|
54
|
+
- Use `.env.example` with placeholder values, never `.env` with real
|
|
55
|
+
values committed to the repo.
|
|
56
|
+
- **If a secret is committed by accident:**
|
|
57
|
+
1. Rotate the secret immediately — assume it's compromised.
|
|
58
|
+
2. Remove from git history using `git filter-branch` or BFG Repo Cleaner.
|
|
59
|
+
3. Append to `.agent-room/anti-patterns.md`: what happened, how it
|
|
60
|
+
slipped through, what rule prevents recurrence.
|
|
61
|
+
4. Force-push the cleaned history (coordinate with the team).
|
|
62
|
+
|
|
63
|
+
### 3. Authentication and authorization
|
|
64
|
+
|
|
65
|
+
**Rule:** Validate the user session and permissions on the server side
|
|
66
|
+
for every request, not just in the UI.
|
|
67
|
+
|
|
68
|
+
- **Token lifecycle:** Access tokens should be short-lived (15-60
|
|
69
|
+
minutes). Use refresh tokens for re-authentication. Implement token
|
|
70
|
+
revocation for logout and password changes.
|
|
71
|
+
- **Password storage:** Use bcrypt, scrypt, or Argon2 with appropriate
|
|
72
|
+
work factors. Never use MD5, SHA-1, or SHA-256 alone for password
|
|
73
|
+
hashing — they're too fast.
|
|
74
|
+
- **Session management:** Regenerate session IDs after login. Set
|
|
75
|
+
cookies with `HttpOnly`, `Secure`, and `SameSite=Strict` flags.
|
|
76
|
+
- **Authorization checks:** Check permissions at the data layer, not
|
|
77
|
+
just the route layer. A user should not be able to access another
|
|
78
|
+
user's data by guessing the resource ID (IDOR vulnerability).
|
|
79
|
+
|
|
80
|
+
### 4. Input validation and sanitization
|
|
81
|
+
|
|
82
|
+
**Rule:** Parse and validate schemas explicitly. Reject what you don't
|
|
83
|
+
expect rather than trying to clean what you don't understand.
|
|
84
|
+
|
|
85
|
+
- Define expected input shapes using validation libraries (Joi, Zod,
|
|
86
|
+
Pydantic, serde). Reject requests that don't match the schema.
|
|
87
|
+
- Validate types, lengths, ranges, and formats. A "name" field that
|
|
88
|
+
accepts 10MB of text is a denial-of-service vector.
|
|
89
|
+
- File uploads: validate MIME type (by content, not just extension),
|
|
90
|
+
enforce size limits, store outside the web root, generate random
|
|
91
|
+
filenames.
|
|
92
|
+
|
|
93
|
+
### 5. Dependency security
|
|
94
|
+
|
|
95
|
+
**Rule:** Audit dependencies regularly. A vulnerability in a dependency
|
|
96
|
+
is a vulnerability in your application.
|
|
97
|
+
|
|
98
|
+
- Run `npm audit`, `pip audit`, `cargo audit`, or equivalent as part of
|
|
99
|
+
CI. Fail the build on high/critical severity findings.
|
|
100
|
+
- Review new dependencies before adding them: maintenance status, known
|
|
101
|
+
vulnerabilities, transitive dependency count, license compatibility.
|
|
102
|
+
- Pin dependency versions in production. Use lockfiles (`package-lock.json`,
|
|
103
|
+
`Pipfile.lock`, `Cargo.lock`) and commit them.
|
|
104
|
+
- **When an audit finds a vulnerability:**
|
|
105
|
+
1. Check if the vulnerable code path is actually reachable in your app.
|
|
106
|
+
2. If yes, update immediately. If no, document and schedule.
|
|
107
|
+
3. Don't suppress audit warnings without documenting why.
|
|
108
|
+
|
|
109
|
+
### 6. Transport and configuration security
|
|
110
|
+
|
|
111
|
+
**Rule:** Enforce HTTPS. Configure security headers. Don't trust defaults.
|
|
112
|
+
|
|
113
|
+
- **CORS:** Use an explicit allowlist of permitted origins. Never use
|
|
114
|
+
`Access-Control-Allow-Origin: *` with credentials. Misconfigured CORS
|
|
115
|
+
is one of the most common agent-introduced security bugs.
|
|
116
|
+
- **CSP:** Set `Content-Security-Policy` headers. Start restrictive and
|
|
117
|
+
loosen only as needed, with documentation for each exception.
|
|
118
|
+
- **Rate limiting:** Apply rate limits to authentication endpoints, API
|
|
119
|
+
endpoints, and any resource-intensive operations.
|
|
120
|
+
|
|
121
|
+
## Red flags — stop and review
|
|
122
|
+
|
|
123
|
+
"We'll add security later" · skipping input validation because "it's an
|
|
124
|
+
internal API" · storing secrets in config files committed to git · using
|
|
125
|
+
`eval()` or `Function()` with user input · disabling HTTPS for local
|
|
126
|
+
convenience and forgetting to re-enable · "the frontend prevents this" as
|
|
127
|
+
a security justification.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: integration-testing
|
|
3
|
+
description: "Use when implementing integration, API, or database-driven tests, or when deciding the right test type for a cross-boundary behavior."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Integration Testing
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Integration tests verify that components work together correctly across
|
|
11
|
+
real boundaries — HTTP, databases, message queues, file systems. They
|
|
12
|
+
answer: "do these pieces actually connect?" Unit tests can't answer that
|
|
13
|
+
question because they mock the boundaries away.
|
|
14
|
+
|
|
15
|
+
## The iron law
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
NO CROSS-BOUNDARY BEHAVIOR SHIPS WITHOUT AN INTEGRATION TEST
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
If two components talk to each other and you only have unit tests,
|
|
22
|
+
you've tested that each component works alone — not that they work
|
|
23
|
+
together. That's where production bugs live.
|
|
24
|
+
|
|
25
|
+
## The test pyramid — when to use what
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
/ E2E \ Few, slow, expensive, high confidence
|
|
29
|
+
/----------\
|
|
30
|
+
/ Integration \ Moderate count, real boundaries, focused
|
|
31
|
+
/----------------\
|
|
32
|
+
/ Unit Tests \ Many, fast, isolated, one behavior each
|
|
33
|
+
/--------------------\
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- **Unit tests:** One function, one behavior, no I/O. Fast. Write many.
|
|
37
|
+
- **Integration tests:** Real database, real HTTP, real file system. Test
|
|
38
|
+
the boundary, not the business logic behind it. Write enough to cover
|
|
39
|
+
every boundary.
|
|
40
|
+
- **E2E tests:** Full user flow through the running application. Write
|
|
41
|
+
sparingly — they're slow and brittle.
|
|
42
|
+
|
|
43
|
+
**Default rule:** if the behavior crosses a process, network, or storage
|
|
44
|
+
boundary, it needs an integration test. If it doesn't, a unit test is
|
|
45
|
+
sufficient.
|
|
46
|
+
|
|
47
|
+
## Core principles
|
|
48
|
+
|
|
49
|
+
### 1. Isolated state
|
|
50
|
+
|
|
51
|
+
Each test runs against a clean state. Techniques:
|
|
52
|
+
|
|
53
|
+
- **Database:** Use transactions that roll back after each test, or
|
|
54
|
+
truncate tables in `beforeEach`. Never rely on insertion order from
|
|
55
|
+
a previous test.
|
|
56
|
+
- **File system:** Use a temporary directory created in `beforeEach`,
|
|
57
|
+
removed in `afterEach`.
|
|
58
|
+
- **External services:** Use dedicated test instances or containers,
|
|
59
|
+
never shared staging environments.
|
|
60
|
+
|
|
61
|
+
### 2. Real over mocks
|
|
62
|
+
|
|
63
|
+
Use actual databases (Docker containers, SQLite in-memory, test
|
|
64
|
+
instances) and real file systems where possible. Mock only what you
|
|
65
|
+
cannot control:
|
|
66
|
+
|
|
67
|
+
- **Mock:** Third-party APIs with rate limits, payment gateways, email
|
|
68
|
+
services.
|
|
69
|
+
- **Don't mock:** Your own database, your own file system, your own
|
|
70
|
+
message queue. If you mock your own infrastructure, you're testing
|
|
71
|
+
your assumptions about it, not the infrastructure itself.
|
|
72
|
+
|
|
73
|
+
### 3. No flakiness
|
|
74
|
+
|
|
75
|
+
Flaky tests are worse than no tests — they train the team to ignore
|
|
76
|
+
failures.
|
|
77
|
+
|
|
78
|
+
- **Never use** `sleep(N)` or arbitrary timeouts. Use wait-for-condition,
|
|
79
|
+
polling with backoff, or event listeners.
|
|
80
|
+
- **Network tests:** Use retry with assertion (poll until the expected
|
|
81
|
+
state appears, with a hard timeout that fails explicitly).
|
|
82
|
+
- **Ordering:** Tests must not depend on execution order. If test B
|
|
83
|
+
fails only when test A runs first, the tests share state — fix the
|
|
84
|
+
isolation.
|
|
85
|
+
|
|
86
|
+
### Investigating flaky tests
|
|
87
|
+
|
|
88
|
+
When a test flakes:
|
|
89
|
+
|
|
90
|
+
1. **Don't "just retry."** Retrying masks the problem.
|
|
91
|
+
2. **Reproduce locally** — run the test 50 times in a loop. If it passes
|
|
92
|
+
every time locally, the flakiness is environmental (timing, resources,
|
|
93
|
+
network).
|
|
94
|
+
3. **Check for shared state** — is another test leaving data behind?
|
|
95
|
+
4. **Check for timing assumptions** — is the test assuming an operation
|
|
96
|
+
completes within a specific time?
|
|
97
|
+
5. **If genuinely non-deterministic** (rare), add deterministic assertions
|
|
98
|
+
with explicit timeouts and document why in a comment.
|
|
99
|
+
|
|
100
|
+
## Contract testing for API boundaries
|
|
101
|
+
|
|
102
|
+
When your service calls another service (or is called by one), unit tests
|
|
103
|
+
and integration tests aren't enough. Contract tests verify that the
|
|
104
|
+
**interface** between services stays compatible:
|
|
105
|
+
|
|
106
|
+
- **Consumer-driven contracts:** The consumer defines what it expects
|
|
107
|
+
(request shape, response shape). The provider runs the contract as a
|
|
108
|
+
test. If the provider changes break the contract, the test fails before
|
|
109
|
+
deployment.
|
|
110
|
+
- **Use when:** You own both sides of an API, or when a third-party API
|
|
111
|
+
has a versioning scheme you need to track.
|
|
112
|
+
|
|
113
|
+
## Coverage guidance
|
|
114
|
+
|
|
115
|
+
- **Don't chase 100% integration test coverage.** Integration tests are
|
|
116
|
+
expensive to run. Cover every boundary, every error path at the
|
|
117
|
+
boundary (timeouts, connection failures, malformed responses), and the
|
|
118
|
+
critical happy path.
|
|
119
|
+
- **Meaningful coverage:** "Every database query is exercised against a
|
|
120
|
+
real database" is a better target than "95% line coverage."
|
|
121
|
+
- **Unmockable code is a smell:** If you can't test a component without
|
|
122
|
+
mocking 6 dependencies, the component has too many responsibilities.
|
|
123
|
+
Refactor before adding more tests.
|
|
124
|
+
|
|
125
|
+
## Commands
|
|
126
|
+
|
|
127
|
+
* Run integration tests: `{{TEST_COMMAND}}`
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: python-testing
|
|
3
|
+
description: "Python testing best practices: pytest patterns, fixtures, mocking, and TDD workflows"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Python Testing Best Practices
|
|
7
|
+
|
|
8
|
+
## Test discovery and structure
|
|
9
|
+
|
|
10
|
+
- Store tests in `tests/` or adjacent to source files as `*_test.py` or `test_*.py`
|
|
11
|
+
- Use pytest fixtures for setup/teardown
|
|
12
|
+
- Group related tests in test classes with a `Test` prefix
|
|
13
|
+
|
|
14
|
+
## Pytest essentials
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
import pytest
|
|
18
|
+
|
|
19
|
+
@pytest.fixture
|
|
20
|
+
def example_resource():
|
|
21
|
+
resource = setup()
|
|
22
|
+
yield resource
|
|
23
|
+
teardown(resource)
|
|
24
|
+
|
|
25
|
+
def test_with_fixture(example_resource):
|
|
26
|
+
result = example_resource.do_work()
|
|
27
|
+
assert result == expected
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Mocking and isolation
|
|
31
|
+
|
|
32
|
+
Use `unittest.mock` or `pytest-mock`:
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from unittest.mock import Mock, patch
|
|
36
|
+
|
|
37
|
+
def test_with_mock(mocker):
|
|
38
|
+
mock_service = mocker.patch('module.Service')
|
|
39
|
+
mock_service.return_value = Mock(status='ok')
|
|
40
|
+
assert your_code_using_service()
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Red-Green-Refactor cycle
|
|
44
|
+
|
|
45
|
+
1. **Red:** Write a failing test; ensure it fails for the right reason
|
|
46
|
+
2. **Green:** Implement the minimal code to pass the test
|
|
47
|
+
3. **Refactor:** Improve code quality without changing behavior
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pytest tests/ --tb=short
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Coverage
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pytest --cov=src tests/
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Aim for >80% coverage, but prioritize testing critical paths.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Agent Instructions — {{PROJECT_NAME}} (Python)
|
|
2
|
+
|
|
3
|
+
This file supplements the base AGENTS.md with Python-specific guidance.
|
|
4
|
+
|
|
5
|
+
## Python-specific workflow
|
|
6
|
+
|
|
7
|
+
1. **Virtual Environment:** Always operate within a virtual environment (venv, poetry, pipenv, or similar).
|
|
8
|
+
2. **Type Hints:** Use type hints for function signatures (not required but encouraged for clarity).
|
|
9
|
+
3. **Testing:** Use pytest for unit tests; write tests first (TDD), then implement.
|
|
10
|
+
4. **Linting:** Run flake8 or ruff; fix all linting errors before committing.
|
|
11
|
+
5. **Dependencies:** Pin versions in requirements.txt or pyproject.toml; review security advisories.
|
|
12
|
+
|
|
13
|
+
## Language-specific principles
|
|
14
|
+
|
|
15
|
+
- **PEP 8 compliance:** Follow Python's style guide (4-space indentation, line length ≤ 79 for code).
|
|
16
|
+
- **Readability > Cleverness:** Prefer explicit over implicit; write code for the next human.
|
|
17
|
+
- **Avoid Dynamic Features:** Minimize use of `__getattr__`, `eval()`, `exec()` unless absolutely necessary.
|
|
18
|
+
- **Async/Await:** If using asyncio, be consistent; don't mix sync and async without clear boundaries.
|
|
19
|
+
|
|
20
|
+
## Common pitfalls
|
|
21
|
+
|
|
22
|
+
- ❌ Mixing dependency managers (e.g., pip and poetry)
|
|
23
|
+
- ❌ Hardcoding paths; use `pathlib.Path` instead
|
|
24
|
+
- ❌ Catching bare `Exception`; catch specific exceptions
|
|
25
|
+
- ❌ Importing * (`from module import *`)
|
|
26
|
+
- ✅ Always use context managers (`with` statements) for file/resource handling
|
|
27
|
+
|
|
28
|
+
## Stack detection
|
|
29
|
+
|
|
30
|
+
This room was scaffolded for Python. Detected configuration:
|
|
31
|
+
- **Package Manager:** {{PACKAGE_MANAGER}}
|
|
32
|
+
- **Test Command:** {{TEST_COMMAND}}
|
|
33
|
+
- **Lint Command:** {{LINT_COMMAND}}
|
|
34
|
+
|
|
35
|
+
See `.agent-room/principles.md` and `workflow-classifier.md` for the full playbook.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: react-component-testing
|
|
3
|
+
description: "React component testing with React Testing Library: user-centric tests, async, and mocking"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# React Component Testing
|
|
7
|
+
|
|
8
|
+
## Testing user interactions, not implementation
|
|
9
|
+
|
|
10
|
+
```typescript
|
|
11
|
+
import { render, screen } from '@testing-library/react';
|
|
12
|
+
import userEvent from '@testing-library/user-event';
|
|
13
|
+
|
|
14
|
+
test('submits form when user clicks button', async () => {
|
|
15
|
+
const user = userEvent.setup();
|
|
16
|
+
const handleSubmit = jest.fn();
|
|
17
|
+
|
|
18
|
+
render(<MyForm onSubmit={handleSubmit} />);
|
|
19
|
+
|
|
20
|
+
const input = screen.getByLabelText('Name');
|
|
21
|
+
await user.type(input, 'John');
|
|
22
|
+
|
|
23
|
+
const button = screen.getByRole('button', { name: /submit/i });
|
|
24
|
+
await user.click(button);
|
|
25
|
+
|
|
26
|
+
expect(handleSubmit).toHaveBeenCalledWith('John');
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Async patterns
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
test('displays data after loading', async () => {
|
|
34
|
+
render(<DataComponent />);
|
|
35
|
+
|
|
36
|
+
// Component starts with loading state
|
|
37
|
+
expect(screen.getByText(/loading/i)).toBeInTheDocument();
|
|
38
|
+
|
|
39
|
+
// Wait for data to appear
|
|
40
|
+
const element = await screen.findByText('Data loaded');
|
|
41
|
+
expect(element).toBeInTheDocument();
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Mocking hooks and context
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
jest.mock('./hooks', () => ({
|
|
49
|
+
useCustomHook: () => ({ data: 'mocked' })
|
|
50
|
+
}));
|
|
51
|
+
|
|
52
|
+
test('uses mocked hook', () => {
|
|
53
|
+
render(<ComponentUsingHook />);
|
|
54
|
+
expect(screen.getByText('mocked')).toBeInTheDocument();
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Avoid testing implementation details
|
|
59
|
+
|
|
60
|
+
- ❌ Testing internal state directly
|
|
61
|
+
- ❌ Testing component hierarchy
|
|
62
|
+
- ❌ Querying by TestID (except as last resort)
|
|
63
|
+
- ✅ Query by accessible roles, labels, text
|
|
64
|
+
|
|
65
|
+
## Red-Green-Refactor
|
|
66
|
+
|
|
67
|
+
1. Write test that describes user behavior (red)
|
|
68
|
+
2. Implement component to pass test (green)
|
|
69
|
+
3. Refactor component for clarity (refactor)
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm test -- --watch
|
|
73
|
+
npm test -- --coverage
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Target >80% coverage, prioritizing critical user flows.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Agent Instructions — {{PROJECT_NAME}} (React)
|
|
2
|
+
|
|
3
|
+
This file supplements the base AGENTS.md with React-specific guidance.
|
|
4
|
+
|
|
5
|
+
## React-specific workflow
|
|
6
|
+
|
|
7
|
+
1. **Component API:** Start with props and state; avoid lifting state too early.
|
|
8
|
+
2. **Hooks:** Use React hooks (useState, useEffect, useContext); avoid class components.
|
|
9
|
+
3. **Testing:** Test behavior, not implementation; use React Testing Library.
|
|
10
|
+
4. **Styling:** Prefer CSS Modules or Tailwind; avoid inline styles except for dynamic values.
|
|
11
|
+
5. **State Management:** Use Context API for app state; Redux only if complexity warrants.
|
|
12
|
+
|
|
13
|
+
## Component design principles
|
|
14
|
+
|
|
15
|
+
- **Single Responsibility:** One component = one concern
|
|
16
|
+
- **Props Over State:** Push state up only when necessary
|
|
17
|
+
- **Avoid Prop Drilling:** Use Context API to avoid passing props through many levels
|
|
18
|
+
- **Controlled Components:** Form inputs should be controlled by React state
|
|
19
|
+
- **Fragment Use:** Use `<>` for wrapper-less grouping
|
|
20
|
+
|
|
21
|
+
## Common pitfalls
|
|
22
|
+
|
|
23
|
+
- ❌ State mutations (e.g., `array.push()` instead of `[...array, item]`)
|
|
24
|
+
- ❌ Missing dependencies in useEffect
|
|
25
|
+
- ❌ Render functions inside render (creates new function every render)
|
|
26
|
+
- ❌ Inline object literals as props (creates new object every render)
|
|
27
|
+
- ✅ Use React DevTools profiler to find performance issues
|
|
28
|
+
- ✅ Memoize expensive calculations with `useMemo`
|
|
29
|
+
|
|
30
|
+
## Stack detection
|
|
31
|
+
|
|
32
|
+
This room was scaffolded for React. Detected configuration:
|
|
33
|
+
- **Package Manager:** {{PACKAGE_MANAGER}}
|
|
34
|
+
- **Test Command:** {{TEST_COMMAND}}
|
|
35
|
+
- **Lint Command:** {{LINT_COMMAND}}
|
|
36
|
+
|
|
37
|
+
See `.agent-room/principles.md` and `workflow-classifier.md` for the full playbook.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: typescript-testing
|
|
3
|
+
description: "TypeScript testing best practices: Jest/Vitest, mocking, async patterns, and TDD"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# TypeScript Testing Best Practices
|
|
7
|
+
|
|
8
|
+
## Test structure and discovery
|
|
9
|
+
|
|
10
|
+
- Store tests in `tests/` or co-locate as `.test.ts` / `.spec.ts`
|
|
11
|
+
- Use Jest or Vitest; configure in `jest.config.ts` or `vitest.config.ts`
|
|
12
|
+
- Group related tests using `describe()` blocks
|
|
13
|
+
|
|
14
|
+
## Jest/Vitest basics
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
describe('MyFunction', () => {
|
|
18
|
+
it('should return expected value', () => {
|
|
19
|
+
const result = myFunction(input);
|
|
20
|
+
expect(result).toBe(expected);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should handle async work', async () => {
|
|
24
|
+
const result = await asyncFunction();
|
|
25
|
+
expect(result).toEqual({ data: 'value' });
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Mocking in TypeScript
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
jest.mock('./module');
|
|
34
|
+
import { myExport } from './module';
|
|
35
|
+
|
|
36
|
+
const mockFunction = myExport as jest.MockedFunction<typeof myExport>;
|
|
37
|
+
mockFunction.mockReturnValue('mocked');
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Async testing
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
it('should handle promises', () => {
|
|
44
|
+
return expect(asyncFunction()).resolves.toBe(expected);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should handle rejections', () => {
|
|
48
|
+
return expect(asyncFunction()).rejects.toThrow(Error);
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Red-Green-Refactor
|
|
53
|
+
|
|
54
|
+
1. Write a failing test (red)
|
|
55
|
+
2. Implement minimal code to pass (green)
|
|
56
|
+
3. Refactor for quality (refactor)
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm test -- --watch
|
|
60
|
+
npm test -- --coverage
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Target >80% coverage on critical paths.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Agent Instructions — {{PROJECT_NAME}} (TypeScript)
|
|
2
|
+
|
|
3
|
+
This file supplements the base AGENTS.md with TypeScript-specific guidance.
|
|
4
|
+
|
|
5
|
+
## TypeScript-specific workflow
|
|
6
|
+
|
|
7
|
+
1. **Strict Mode:** Always compile with `"strict": true` in tsconfig.json.
|
|
8
|
+
2. **Type Safety:** Write types for public APIs; use `unknown` before `any`.
|
|
9
|
+
3. **Testing:** Use Jest or Vitest; write tests first (TDD), then implement.
|
|
10
|
+
4. **Linting:** Run ESLint with TypeScript plugin; fix all errors before committing.
|
|
11
|
+
5. **Build:** Compile TypeScript before running; catch type errors in CI.
|
|
12
|
+
|
|
13
|
+
## Language-specific principles
|
|
14
|
+
|
|
15
|
+
- **Explicit over implicit:** Declare types, don't rely on inference alone
|
|
16
|
+
- **Interfaces for contracts:** Define interfaces for API boundaries
|
|
17
|
+
- **Discriminated unions:** Use discriminated unions for type-safe variant handling
|
|
18
|
+
- **Avoid `any`:** Use generics or `unknown` instead
|
|
19
|
+
- **Strict null checks:** Enable strictNullChecks to prevent null reference errors
|
|
20
|
+
|
|
21
|
+
## Common pitfalls
|
|
22
|
+
|
|
23
|
+
- ❌ Leaving `any` in production code
|
|
24
|
+
- ❌ Not checking for null/undefined (nullish coalescing is your friend)
|
|
25
|
+
- ❌ Over-using generics; keep types readable
|
|
26
|
+
- ❌ Ignoring TypeScript errors with `@ts-ignore`
|
|
27
|
+
- ✅ Use `.ts` for backend, `.tsx` for React components
|
|
28
|
+
|
|
29
|
+
## Stack detection
|
|
30
|
+
|
|
31
|
+
This room was scaffolded for TypeScript. Detected configuration:
|
|
32
|
+
- **Package Manager:** {{PACKAGE_MANAGER}}
|
|
33
|
+
- **Test Command:** {{TEST_COMMAND}}
|
|
34
|
+
- **Lint Command:** {{LINT_COMMAND}}
|
|
35
|
+
|
|
36
|
+
See `.agent-room/principles.md` and `workflow-classifier.md` for the full playbook.
|