Skip to content

Commit 9df55f6

Browse files
committed
chore(copilot): first stab at general instructions for the project
1 parent 359bb42 commit 9df55f6

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed

.github/copilot-instructions.md

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
---
2+
applyTo: "**"
3+
---
4+
5+
# form8ion language plugin
6+
7+
A language plugin for the form8ion ecosystem to automate consistent configuration of JavaScript in various projects managed by form8ion.
8+
Follows Test-Driven Development, Clean Architecture, and strict verification workflows.
9+
10+
## Commands
11+
12+
Run `nvm use` before any npm command.
13+
14+
```bash
15+
# ALWAYS run first
16+
nvm use
17+
18+
# Core commands
19+
npm install # Install dependencies (updates package-lock.json)
20+
npm clean-install # Clean node_modules and reinstall based on the existing
21+
npm run test:unit:base # Run unit tests (vitest)
22+
npm run test:integration # Run integration tests (cucumber)
23+
24+
# Validation suite (run before commits)
25+
npm test
26+
```
27+
28+
## Workflow: Outside-In TDD Required
29+
30+
Follow this exact sequence for ALL code changes. Work in small increments — make one change at a time and validate before proceeding.
31+
32+
1. **Research**: Search codebase for existing patterns, commands, utilities. Use Context7 MCP tools for library/API documentation.
33+
2. **Write failing integration test**: Create test describing desired behavior (use Cucumber for integration tests)
34+
3. **Verify failure**: Run `npm run test:integration` — confirm clear failure message
35+
4. **Write failing unit test**: Create test describing desired behavior
36+
5. **Verify failure**: Run `npm run test:unit:base` — confirm clear failure message
37+
6. **Implement minimal code**: Write just enough to pass
38+
7. **Verify pass**: Run `npm run test:unit:base` — confirm pass
39+
8. **Refactor**: Clean up, remove duplication, keep tests green
40+
9. **Check integration test result**: Run `npm run test:integration` — confirm pass. if failure, repeat steps 6-8 until pass
41+
10. **Validate**: `npm test`
42+
43+
Task is NOT complete until all verification passes.
44+
45+
## Tech Stack
46+
47+
- **Language**: JavaScript (ESM)
48+
- **Testing**: Vitest (never Jest), `@travi/any` for test fixtures
49+
- **Linting**: ESLint as configured in `./.eslintrc.yml`
50+
51+
## Code Style
52+
53+
**Rules:**
54+
- Use descriptive names for variables, functions, and modules
55+
- Use full words — avoid abbreviations and acronyms unless widely understood
56+
- Functions must be small and have single responsibility
57+
- Avoid god functions and classes — break into smaller, focused units
58+
- Avoid repetitive code — extract reusable functions
59+
- Extract functions when there are multiple code paths
60+
- Favor immutability and pure functions
61+
- Avoid temporal coupling
62+
- Keep cyclomatic complexity low
63+
- Remove all unused imports and variables
64+
- Run lint and tests after EVERY change
65+
66+
## Testing Standards
67+
68+
Tests are executable documentation. Use Arrange-Act-Assert pattern. Generate test fixtures with `@travi/any`.
69+
70+
```javascript
71+
import any from '@travi/any';
72+
import { describe, it, expect, vi } from 'vitest';
73+
import {when} from 'vitest-when';
74+
75+
import { createConfigLoader } from './config-loader';
76+
77+
// ✅ Good - describes behavior, uses generated fixtures, mocks dependencies
78+
describe('Config Loader', () => {
79+
describe('given a valid config file path', () => {
80+
it('loads and validates the configuration', async () => {
81+
const configPath = any.word() + '.json';
82+
const expectedConfig = {name: any.word(), version: any.integer()};
83+
const loader = createConfigLoader(mockReader);
84+
when(mockReader).calledWith(configPath).thenResolve(JSON.stringify(expectedConfig));
85+
86+
const result = await loader.load(configPath);
87+
88+
expect(result).toEqual(expectedConfig);
89+
});
90+
});
91+
92+
describe('given an empty file path', () => {
93+
it('throws a validation error', async () => {
94+
const mockReader = vi.fn();
95+
const loader = createConfigLoader(mockReader);
96+
97+
await expect(loader.load('')).rejects.toThrow('File path required');
98+
});
99+
});
100+
});
101+
```
102+
103+
**Rules:**
104+
- Tests are executable documentation — describe behavior, not implementation
105+
- Name `describe` blocks for features/scenarios, not function names
106+
- Name `it` blocks as specifications that read as complete sentences
107+
- Use nested `describe` blocks for "given/when" context
108+
- Use `@travi/any` to generate test fixtures — avoid hardcoded test data unless the specific value is what is being tested
109+
- Random values from `@travi/any` must be assigned to a constant and referenced consistently across arrange, act, and assert — the same value must appear at the stub, the call, and the assertion.
110+
The randomness proves the code passes data through correctly without coupling tests to specific values; the test outcome must be the same regardless of what value was generated
111+
- Extract test data to constants — never duplicate values across arrange/act/assert
112+
- Avoid conditional logic in tests unless absolutely necessary
113+
- Ensure all code paths have corresponding tests
114+
- Test happy paths, unhappy paths, and edge cases
115+
- Never modify tests to pass without understanding root cause
116+
117+
## Dependencies
118+
119+
- Use ranges for production dependencies (e.g. `^1.0.0`) but ensure they are updated when implementation depends on a specific version or behavior
120+
- Pin development dependencies to exact versions (no ^ or ~)
121+
- Ensure `package-lock.json` is updated correctly
122+
- Use Renovate to keep dependencies current
123+
124+
## GitHub Actions
125+
126+
- Validation must be automated via GitHub Actions and runnable locally the same way
127+
- Pin all 3rd party Actions to specific version or commit SHA followed by a comment indicating the related semver (e.g. `actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2`)
128+
129+
## Boundaries
130+
131+
**✅ Always do:**
132+
- Run `nvm use` before any npm command
133+
- Write tests before implementation (TDD)
134+
- Run lint and tests after every change
135+
- Run full verification before commits
136+
- Use existing patterns from codebase
137+
- Work in small increments
138+
139+
**⚠️ Ask first:**
140+
- Adding new dependencies
141+
- Changing project structure
142+
- Modifying GitHub Actions workflows
143+
144+
**🚫 Never do:**
145+
- Skip the TDD workflow
146+
- Store secrets in code (use environment variables)
147+
- Use Jest (instead, use Vitest for unit tests and Cucumber for integration tests)
148+
- Modify tests to pass without fixing root cause

0 commit comments

Comments
 (0)