comp-gate 0.1.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/README.md +353 -0
- package/dist/agents/agents-md.d.ts +2 -0
- package/dist/agents/agents-md.d.ts.map +1 -0
- package/dist/agents/agents-md.js +25 -0
- package/dist/agents/agents-md.js.map +1 -0
- package/dist/agents/claude.d.ts +2 -0
- package/dist/agents/claude.d.ts.map +1 -0
- package/dist/agents/claude.js +45 -0
- package/dist/agents/claude.js.map +1 -0
- package/dist/agents/cursor.d.ts +2 -0
- package/dist/agents/cursor.d.ts.map +1 -0
- package/dist/agents/cursor.js +28 -0
- package/dist/agents/cursor.js.map +1 -0
- package/dist/agents/detect.d.ts +4 -0
- package/dist/agents/detect.d.ts.map +1 -0
- package/dist/agents/detect.js +96 -0
- package/dist/agents/detect.js.map +1 -0
- package/dist/agents/shared.d.ts +9 -0
- package/dist/agents/shared.d.ts.map +1 -0
- package/dist/agents/shared.js +83 -0
- package/dist/agents/shared.js.map +1 -0
- package/dist/agents/types.d.ts +14 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +8 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/agents/windsurf.d.ts +2 -0
- package/dist/agents/windsurf.d.ts.map +1 -0
- package/dist/agents/windsurf.js +27 -0
- package/dist/agents/windsurf.js.map +1 -0
- package/dist/bootstrap-summary.d.ts +2 -0
- package/dist/bootstrap-summary.d.ts.map +1 -0
- package/dist/bootstrap-summary.js +262 -0
- package/dist/bootstrap-summary.js.map +1 -0
- package/dist/categories.d.ts +13 -0
- package/dist/categories.d.ts.map +1 -0
- package/dist/categories.js +382 -0
- package/dist/categories.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +361 -0
- package/dist/cli.js.map +1 -0
- package/dist/config-init.d.ts +16 -0
- package/dist/config-init.d.ts.map +1 -0
- package/dist/config-init.js +53 -0
- package/dist/config-init.js.map +1 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +127 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +2 -0
- package/dist/constants.js.map +1 -0
- package/dist/detect.d.ts +4 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +244 -0
- package/dist/detect.js.map +1 -0
- package/dist/diff.d.ts +11 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +198 -0
- package/dist/diff.js.map +1 -0
- package/dist/generate.d.ts +7 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +71 -0
- package/dist/generate.js.map +1 -0
- package/dist/gitignore.d.ts +12 -0
- package/dist/gitignore.d.ts.map +1 -0
- package/dist/gitignore.js +106 -0
- package/dist/gitignore.js.map +1 -0
- package/dist/hooks.d.ts +22 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +199 -0
- package/dist/hooks.js.map +1 -0
- package/dist/init.d.ts +24 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +218 -0
- package/dist/init.js.map +1 -0
- package/dist/paths.d.ts +13 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +18 -0
- package/dist/paths.js.map +1 -0
- package/dist/prompts.d.ts +9 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +88 -0
- package/dist/prompts.js.map +1 -0
- package/dist/repo-stats.d.ts +10 -0
- package/dist/repo-stats.d.ts.map +1 -0
- package/dist/repo-stats.js +117 -0
- package/dist/repo-stats.js.map +1 -0
- package/dist/setup-wizard.d.ts +34 -0
- package/dist/setup-wizard.d.ts.map +1 -0
- package/dist/setup-wizard.js +251 -0
- package/dist/setup-wizard.js.map +1 -0
- package/dist/testing.d.ts +6 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +24 -0
- package/dist/testing.js.map +1 -0
- package/dist/types.d.ts +156 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +31 -0
- package/dist/types.js.map +1 -0
- package/dist/verify.d.ts +38 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +254 -0
- package/dist/verify.js.map +1 -0
- package/package.json +52 -0
- package/src/templates/PROMPTS.md +6 -0
- package/src/templates/SKILL.md +253 -0
- package/src/templates/SUMMARY.md +29 -0
- package/src/templates/agents/agents-md/section.md +11 -0
- package/src/templates/agents/claude/SKILL.md +8 -0
- package/src/templates/agents/claude/settings.fragment.json +16 -0
- package/src/templates/agents/claude/testing-SKILL.md +9 -0
- package/src/templates/agents/cursor/SKILL.md +9 -0
- package/src/templates/agents/cursor/hooks.json +23 -0
- package/src/templates/agents/cursor/testing-SKILL.md +9 -0
- package/src/templates/agents/windsurf/SKILL.md +8 -0
- package/src/templates/agents/windsurf/hooks.json +10 -0
- package/src/templates/agents/windsurf/testing-SKILL.md +9 -0
- package/src/templates/hooks/after-push.sh +17 -0
- package/src/templates/hooks/block-commit.sh +29 -0
- package/src/templates/hooks/block-push.sh +29 -0
- package/src/templates/hooks/claude-pre-tool.sh +59 -0
- package/src/templates/hooks/git-pre-commit.sh +35 -0
- package/src/templates/hooks/git-pre-push.sh +53 -0
- package/src/templates/hooks/statusline.sh +3 -0
- package/src/templates/hooks/windsurf-pre-run.sh +39 -0
- package/src/templates/hooks.json +23 -0
- package/src/templates/testing-SKILL.md +33 -0
- package/src/templates/testme.config.json +32 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testme
|
|
3
|
+
description: Generate and verify codebase comprehension tests before committing or pushing. Use when the user runs /testme, asks to commit or push, or when a hook blocks git commit/push.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# testme
|
|
8
|
+
|
|
9
|
+
> **Gate off?** Run `npx comp-gate testing status`. If the gate is disabled, do not run this workflow — tell the user to run `/testing` to re-enable.
|
|
10
|
+
|
|
11
|
+
Gate `git commit` (when `gateCommits` is enabled) and `git push` to protected branches behind a comprehension check. The agent generates reference answers, quizzes you in chat, then grades your replies by **conceptual alignment** — not keyword matching.
|
|
12
|
+
|
|
13
|
+
## When to use
|
|
14
|
+
|
|
15
|
+
- User runs `/testme`
|
|
16
|
+
- User asks to commit or push to a protected branch
|
|
17
|
+
- Hook blocks a commit or push and asks for verification
|
|
18
|
+
|
|
19
|
+
## Workflow
|
|
20
|
+
|
|
21
|
+
**Use conversational Q&A in chat.** Do not ask the user to manually edit `.testme/` JSON files.
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Task Progress:
|
|
25
|
+
- [ ] Step 1: Update PROMPTS.md with session changes
|
|
26
|
+
- [ ] Step 2: Run npx comp-gate generate
|
|
27
|
+
- [ ] Step 3: Read referenced files; write .testme/references.json
|
|
28
|
+
- [ ] Step 4: Ask each question in chat; collect answers from user replies
|
|
29
|
+
- [ ] Step 5: Grade semantically; write .testme/judgments.json; run npx comp-gate verify
|
|
30
|
+
- [ ] Step 6: Commit and push only after PASS
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Step 1: Update PROMPTS.md
|
|
34
|
+
|
|
35
|
+
Before generating questions, ensure `PROMPTS.md` documents what changed:
|
|
36
|
+
|
|
37
|
+
```markdown
|
|
38
|
+
# Session Changes
|
|
39
|
+
|
|
40
|
+
## src/auth.ts
|
|
41
|
+
- Added validateToken middleware; checks JWT expiry before route handlers
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Write bullets as you work. If empty, update from `git diff --stat` first.
|
|
45
|
+
|
|
46
|
+
### Step 2: Generate questions
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx comp-gate generate
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Reads `SUMMARY.md`, `PROMPTS.md`, and git diff. Writes `.testme/session.json`.
|
|
53
|
+
|
|
54
|
+
Announce how many questions were generated and list their ids/categories.
|
|
55
|
+
|
|
56
|
+
### Step 3: Generate reference answers
|
|
57
|
+
|
|
58
|
+
Read `.testme/session.json`. For each question, read **only** files in `files[]`.
|
|
59
|
+
|
|
60
|
+
Write `.testme/references.json`:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"diffHash": "<same as session.json>",
|
|
65
|
+
"generatedAt": "<ISO timestamp>",
|
|
66
|
+
"references": {
|
|
67
|
+
"q1": "A complete reference answer explaining what changed and why, based on the code and PROMPTS.md.",
|
|
68
|
+
"q2": "A reference answer describing how the change fits the project architecture."
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Reference answers are the **gold standard** you will compare user replies against. Write them from your understanding of the code — not by copying PROMPTS.md bullets verbatim.
|
|
74
|
+
|
|
75
|
+
### Step 4: Conversational Q&A (in chat)
|
|
76
|
+
|
|
77
|
+
Ask questions **one at a time**. Wait for the user's reply before asking the next.
|
|
78
|
+
|
|
79
|
+
**Format each question:**
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
**Question 1 of N** · `q1` · changeRationale
|
|
83
|
+
|
|
84
|
+
What changed in src/auth.ts and why?
|
|
85
|
+
|
|
86
|
+
_Files: src/auth.ts_
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Rules:
|
|
90
|
+
- Show progress, question id, category, prompt verbatim, and referenced files
|
|
91
|
+
- Do **not** show reference answers or rubric terms to the user
|
|
92
|
+
- Nudge once if an answer is too vague: "Can you explain what changed and why?"
|
|
93
|
+
- Store each answer keyed by question id (`q1`, `q2`, …)
|
|
94
|
+
|
|
95
|
+
### Step 5: Semantic grading and verify
|
|
96
|
+
|
|
97
|
+
For each question, compare the user's answer to the reference in `.testme/references.json`:
|
|
98
|
+
|
|
99
|
+
1. **Summarize** the user's answer in 1–2 sentences (`userSummary`)
|
|
100
|
+
2. **Score accuracy** from 0–100 (`accuracy`) — how well they understand what changed vs the reference
|
|
101
|
+
3. **Judge alignment**: `high` (core concepts correct), `medium` (mostly right, minor gaps), `low` (wrong or too vague)
|
|
102
|
+
4. **Pass** a question if `passed: true`, `accuracy >= passThreshold` (default 70 from config), and alignment is `high` or `medium`
|
|
103
|
+
5. Do **not** fail answers for missing specific keywords — judge meaning, not wording
|
|
104
|
+
|
|
105
|
+
Write `.testme/answers.json` and `.testme/judgments.json`:
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{
|
|
109
|
+
"diffHash": "<same as session.json>",
|
|
110
|
+
"gradedAt": "<ISO timestamp>",
|
|
111
|
+
"judgments": {
|
|
112
|
+
"q1": {
|
|
113
|
+
"passed": true,
|
|
114
|
+
"accuracy": 88,
|
|
115
|
+
"userSummary": "User explained the README now documents setup and the chat-based workflow.",
|
|
116
|
+
"alignment": "high",
|
|
117
|
+
"feedback": "Strong understanding of the documentation changes; minor detail on troubleshooting missing."
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Share grading feedback in chat for each question:
|
|
124
|
+
- accuracy score (0–100)
|
|
125
|
+
- alignment (`low` / `medium` / `high`)
|
|
126
|
+
- brief summary of what they got right or wrong
|
|
127
|
+
|
|
128
|
+
Then run:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx comp-gate verify
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**On PASS:** commit and push to protected branches are allowed.
|
|
135
|
+
|
|
136
|
+
**On FAIL:** re-ask only failed questions in chat, update answers + judgments, run `verify` again. Do not re-run `generate`.
|
|
137
|
+
|
|
138
|
+
### Step 6: Commit and push
|
|
139
|
+
|
|
140
|
+
Only after verify passes:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
git commit -m "your message"
|
|
144
|
+
git push origin <protected-branch>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Gate configuration
|
|
148
|
+
|
|
149
|
+
In `testme.config.json`:
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"protectedBranches": ["main"],
|
|
154
|
+
"gateCommits": true,
|
|
155
|
+
"autoProtectCurrentBranch": true
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
- `gateCommits: true` blocks `git commit` until `/testme` passes
|
|
160
|
+
- `autoProtectCurrentBranch: true` (default) also protects your current branch — no config edits when switching branches
|
|
161
|
+
- Pushes to protected branches are blocked with: `You must run the /testme skill before pushing to '<branch>'.`
|
|
162
|
+
- `npx comp-gate init` also installs **git** `pre-commit` / `pre-push` hooks (blocks the Cursor terminal and any other terminal)
|
|
163
|
+
|
|
164
|
+
## Token efficiency rules
|
|
165
|
+
|
|
166
|
+
- Never scan the full repo for this workflow
|
|
167
|
+
- Read only files referenced in session questions
|
|
168
|
+
- Re-run verify after any last-minute edits (pass invalidates on diff change)
|
|
169
|
+
|
|
170
|
+
## Grading mode
|
|
171
|
+
|
|
172
|
+
Default is **semantic** (`grading: "semantic"` in `testme.config.json`). Set `passThreshold` (default `70`) for minimum accuracy % per question. Legacy keyword mode: `"grading": "keywords"`.
|
|
173
|
+
|
|
174
|
+
## SUMMARY.md
|
|
175
|
+
|
|
176
|
+
Update only when architecture, stack, or major conventions change — not every commit.
|
|
177
|
+
|
|
178
|
+
Add a `## Domain` section to steer auto-detection:
|
|
179
|
+
|
|
180
|
+
```markdown
|
|
181
|
+
## Domain
|
|
182
|
+
|
|
183
|
+
- Primary: machine learning
|
|
184
|
+
- Focus areas: model training, evaluation metrics, inference API
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Configure categories
|
|
188
|
+
|
|
189
|
+
Question count and knowledge areas are configured in `testme.config.json` (team defaults) with optional local overrides in `.testme/config.json`.
|
|
190
|
+
|
|
191
|
+
### Checkbox-style categories
|
|
192
|
+
|
|
193
|
+
Set booleans in `categories` — `true` enables, `false` disables:
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"questions": { "min": 2, "max": 5 },
|
|
198
|
+
"categories": {
|
|
199
|
+
"changeRationale": true,
|
|
200
|
+
"symbols": true,
|
|
201
|
+
"architecture": true,
|
|
202
|
+
"runtime": false,
|
|
203
|
+
"dataStructures": false,
|
|
204
|
+
"testing": true,
|
|
205
|
+
"machineLearning": false,
|
|
206
|
+
"cybersecurity": false
|
|
207
|
+
},
|
|
208
|
+
"autoDetect": true
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Core categories
|
|
213
|
+
|
|
214
|
+
`changeRationale`, `symbols`, `architecture`, `runtime`, `dataStructures`, `dependencies`, `testing`, `errorHandling`, `apiContracts`, `security`, `performance`, `database`
|
|
215
|
+
|
|
216
|
+
### Domain categories (auto-suggested)
|
|
217
|
+
|
|
218
|
+
`machineLearning`, `cybersecurity`, `frontend`, `backend`, `devops`, `mobile`, `dataEngineering`
|
|
219
|
+
|
|
220
|
+
Run detection before editing config:
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
npx comp-gate detect
|
|
224
|
+
npx comp-gate config init
|
|
225
|
+
npx comp-gate config show
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### One-off overrides
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
npx comp-gate generate --max-questions 3 --category changeRationale,runtime,testing
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Examples
|
|
235
|
+
|
|
236
|
+
**Machine learning project** — enable `machineLearning`, `dataStructures`; disable `cybersecurity`.
|
|
237
|
+
|
|
238
|
+
**Security tooling project** — enable `cybersecurity`, `security`; disable `machineLearning`.
|
|
239
|
+
|
|
240
|
+
Ask the user which categories matter if unclear, then update `testme.config.json`.
|
|
241
|
+
|
|
242
|
+
## Troubleshooting
|
|
243
|
+
|
|
244
|
+
| Issue | Fix |
|
|
245
|
+
|-------|-----|
|
|
246
|
+
| Session stale | Re-run `npx comp-gate generate` |
|
|
247
|
+
| Missing terms | Add clearer bullets to `PROMPTS.md` |
|
|
248
|
+
| Commit blocked | `gateCommits` is on — run `/testme` before committing |
|
|
249
|
+
| Push blocked | Run `/testme` or `npx comp-gate generate` → answer → `verify` |
|
|
250
|
+
| Pass invalid | `npx comp-gate status` — verify then commit/push |
|
|
251
|
+
| Reset session | `npx comp-gate reset` |
|
|
252
|
+
| Verify failed | Re-ask failed questions; re-grade and update judgments.json |
|
|
253
|
+
| Missing judgments | Agent must grade semantically before running verify |
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Project Summary
|
|
2
|
+
|
|
3
|
+
Keep this file updated when architecture, stack, or major conventions change — not on every commit.
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
|
|
7
|
+
- Language:
|
|
8
|
+
- Framework:
|
|
9
|
+
- Runtime:
|
|
10
|
+
|
|
11
|
+
## Architecture
|
|
12
|
+
|
|
13
|
+
- `src/` — application source
|
|
14
|
+
- `tests/` — test suites
|
|
15
|
+
|
|
16
|
+
## Conventions
|
|
17
|
+
|
|
18
|
+
- Follow existing naming and import patterns in each directory.
|
|
19
|
+
- Prefer small, focused modules over large catch-all files.
|
|
20
|
+
|
|
21
|
+
## Runtime Notes
|
|
22
|
+
|
|
23
|
+
- How to run locally:
|
|
24
|
+
- How to run tests:
|
|
25
|
+
|
|
26
|
+
## Domain
|
|
27
|
+
|
|
28
|
+
- Primary:
|
|
29
|
+
- Focus areas:
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## testme comprehension gate
|
|
2
|
+
|
|
3
|
+
Before committing or pushing to a protected branch, run the testme workflow:
|
|
4
|
+
|
|
5
|
+
1. Update `PROMPTS.md` with session change bullets per file.
|
|
6
|
+
2. Run `npx comp-gate generate` to create questions in `.testme/session.json`.
|
|
7
|
+
3. Answer each question in chat; the agent writes `.testme/answers.json` and `.testme/judgments.json`.
|
|
8
|
+
4. Run `npx comp-gate verify` — on PASS, `.testme/pass.json` is written and git operations are allowed.
|
|
9
|
+
5. After a successful push, `PROMPTS.md` resets automatically via hook.
|
|
10
|
+
|
|
11
|
+
Do not commit or push until `npx comp-gate verify` passes.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testme
|
|
3
|
+
description: Generate and verify codebase comprehension tests before committing or pushing. Use when the user asks to commit or push, or when a hook blocks git commit/push.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# testme
|
|
7
|
+
|
|
8
|
+
Use the shared workflow: update PROMPTS.md, run `npx comp-gate generate`, quiz the user in chat, grade semantically, then `npx comp-gate verify` before commit/push.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testing
|
|
3
|
+
description: Toggle the testme comprehension gate on or off. Use when the user runs /testing or asks to enable/disable testme gating.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# testing
|
|
8
|
+
|
|
9
|
+
Run `npx comp-gate testing` (toggle), `on`, `off`, or `status`. Show the CLI banner output verbatim in chat.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testme
|
|
3
|
+
description: Generate and verify codebase comprehension tests before committing or pushing. Use when the user runs /testme, asks to commit or push, or when a hook blocks git commit/push.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# testme
|
|
8
|
+
|
|
9
|
+
Use the shared workflow in the project `SKILL.md` template. Run `npx comp-gate generate`, quiz the user in chat, grade semantically, then `npx comp-gate verify` before commit/push.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"hooks": {
|
|
4
|
+
"beforeShellExecution": [
|
|
5
|
+
{
|
|
6
|
+
"command": ".testme/hooks/block-commit.sh",
|
|
7
|
+
"matcher": "git\\s+commit",
|
|
8
|
+
"failClosed": true
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"command": ".testme/hooks/block-push.sh",
|
|
12
|
+
"matcher": "git\\s+push",
|
|
13
|
+
"failClosed": true
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"afterShellExecution": [
|
|
17
|
+
{
|
|
18
|
+
"command": ".testme/hooks/after-push.sh",
|
|
19
|
+
"matcher": "git\\s+push"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testing
|
|
3
|
+
description: Toggle the testme comprehension gate on or off. Use when the user runs /testing or asks to enable/disable testme gating.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# testing
|
|
8
|
+
|
|
9
|
+
Run `npx comp-gate testing` (toggle), `on`, `off`, or `status`. Show the CLI banner output verbatim in chat.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testme
|
|
3
|
+
description: Generate and verify codebase comprehension tests before committing or pushing. Use when the user asks to commit or push, or when a hook blocks git commit/push.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# testme
|
|
7
|
+
|
|
8
|
+
Use the shared workflow: update PROMPTS.md, run `npx comp-gate generate`, quiz the user in chat, grade semantically, then `npx comp-gate verify` before commit/push.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testing
|
|
3
|
+
description: Toggle the testme comprehension gate on or off. Use when the user runs /testing or asks to enable/disable testme gating.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# testing
|
|
8
|
+
|
|
9
|
+
Run `npx comp-gate testing` (toggle), `on`, `off`, or `status`. Show the CLI banner output verbatim in chat.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
input=$(cat)
|
|
5
|
+
command=$(node -e 'const i=JSON.parse(process.argv[1]); process.stdout.write(i.command||"")' "$input")
|
|
6
|
+
exit_code=$(node -e 'const i=JSON.parse(process.argv[1]); process.stdout.write(String(i.exit_code ?? i.exitCode ?? 1))' "$input")
|
|
7
|
+
|
|
8
|
+
if [ "$exit_code" != "0" ]; then
|
|
9
|
+
exit 0
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
if ! echo "$command" | grep -qE '^git[[:space:]]+push'; then
|
|
13
|
+
exit 0
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
npx --yes comp-gate hook after-push --command "$command" 2>/dev/null || true
|
|
17
|
+
exit 0
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
input=$(cat)
|
|
5
|
+
command=$(node -e 'const i=JSON.parse(process.argv[1]); process.stdout.write(i.command||"")' "$input")
|
|
6
|
+
|
|
7
|
+
if ! echo "$command" | grep -qE '^git[[:space:]]+commit'; then
|
|
8
|
+
echo '{"permission":"allow"}'
|
|
9
|
+
exit 0
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
response=$(npx --yes comp-gate hook before-commit --command "$command" --json 2>/dev/null || true)
|
|
13
|
+
|
|
14
|
+
if [ -n "$response" ]; then
|
|
15
|
+
echo "$response"
|
|
16
|
+
if echo "$response" | grep -q '"permission"[[:space:]]*:[[:space:]]*"deny"'; then
|
|
17
|
+
exit 2
|
|
18
|
+
fi
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
cat <<'EOF'
|
|
23
|
+
{
|
|
24
|
+
"permission": "deny",
|
|
25
|
+
"user_message": "You must run the /testme skill before committing.",
|
|
26
|
+
"agent_message": "You must run the /testme skill before committing."
|
|
27
|
+
}
|
|
28
|
+
EOF
|
|
29
|
+
exit 2
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
input=$(cat)
|
|
5
|
+
command=$(node -e 'const i=JSON.parse(process.argv[1]); process.stdout.write(i.command||"")' "$input")
|
|
6
|
+
|
|
7
|
+
if ! echo "$command" | grep -qE '^git[[:space:]]+push'; then
|
|
8
|
+
echo '{"permission":"allow"}'
|
|
9
|
+
exit 0
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
response=$(npx --yes comp-gate hook before-push --command "$command" --json 2>/dev/null || true)
|
|
13
|
+
|
|
14
|
+
if [ -n "$response" ]; then
|
|
15
|
+
echo "$response"
|
|
16
|
+
if echo "$response" | grep -q '"permission"[[:space:]]*:[[:space:]]*"deny"'; then
|
|
17
|
+
exit 2
|
|
18
|
+
fi
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
cat <<'EOF'
|
|
23
|
+
{
|
|
24
|
+
"permission": "deny",
|
|
25
|
+
"user_message": "You must run the /testme skill before pushing.",
|
|
26
|
+
"agent_message": "You must run the /testme skill before pushing."
|
|
27
|
+
}
|
|
28
|
+
EOF
|
|
29
|
+
exit 2
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
input=$(cat)
|
|
5
|
+
command=$(node -e '
|
|
6
|
+
const data = JSON.parse(process.argv[1]);
|
|
7
|
+
const tool = data.tool_name || "";
|
|
8
|
+
const toolInput = data.tool_input || {};
|
|
9
|
+
const cmd = toolInput.command || toolInput.cmd || "";
|
|
10
|
+
process.stdout.write(cmd);
|
|
11
|
+
' "$input")
|
|
12
|
+
|
|
13
|
+
if [ -z "$command" ]; then
|
|
14
|
+
exit 0
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
hook_kind=""
|
|
18
|
+
if echo "$command" | grep -qE '^git[[:space:]]+commit'; then
|
|
19
|
+
hook_kind="before-commit"
|
|
20
|
+
elif echo "$command" | grep -qE '^git[[:space:]]+push'; then
|
|
21
|
+
hook_kind="before-push"
|
|
22
|
+
else
|
|
23
|
+
exit 0
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
response=$(npx --yes comp-gate hook "$hook_kind" --command "$command" --json 2>/dev/null || true)
|
|
27
|
+
|
|
28
|
+
if [ -n "$response" ] && echo "$response" | grep -q '"permission"[[:space:]]*:[[:space:]]*"deny"'; then
|
|
29
|
+
message=$(echo "$response" | node -e '
|
|
30
|
+
const data = JSON.parse(require("fs").readFileSync(0, "utf8"));
|
|
31
|
+
process.stdout.write(data.agent_message || data.user_message || "Blocked by testme.");
|
|
32
|
+
')
|
|
33
|
+
node -e "
|
|
34
|
+
const reason = process.argv[1];
|
|
35
|
+
process.stdout.write(JSON.stringify({
|
|
36
|
+
hookSpecificOutput: {
|
|
37
|
+
hookEventName: 'PreToolUse',
|
|
38
|
+
permissionDecision: 'deny',
|
|
39
|
+
permissionDecisionReason: reason
|
|
40
|
+
}
|
|
41
|
+
}));
|
|
42
|
+
" "$message"
|
|
43
|
+
exit 0
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
if [ -n "$response" ]; then
|
|
47
|
+
exit 0
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
node -e '
|
|
51
|
+
process.stdout.write(JSON.stringify({
|
|
52
|
+
hookSpecificOutput: {
|
|
53
|
+
hookEventName: "PreToolUse",
|
|
54
|
+
permissionDecision: "deny",
|
|
55
|
+
permissionDecisionReason: "You must run the testme workflow before committing or pushing."
|
|
56
|
+
}
|
|
57
|
+
}));
|
|
58
|
+
'
|
|
59
|
+
exit 0
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
root="$(git rev-parse --show-toplevel)"
|
|
5
|
+
cd "$root"
|
|
6
|
+
|
|
7
|
+
run_comp_gate() {
|
|
8
|
+
if [ -x "$root/node_modules/.bin/comp-gate" ]; then
|
|
9
|
+
"$root/node_modules/.bin/comp-gate" "$@"
|
|
10
|
+
elif command -v comp-gate >/dev/null 2>&1; then
|
|
11
|
+
comp-gate "$@"
|
|
12
|
+
elif [ -x "$root/node_modules/.bin/testme" ]; then
|
|
13
|
+
"$root/node_modules/.bin/testme" "$@"
|
|
14
|
+
elif command -v testme >/dev/null 2>&1; then
|
|
15
|
+
testme "$@"
|
|
16
|
+
else
|
|
17
|
+
npx --yes comp-gate "$@"
|
|
18
|
+
fi
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
result=$(run_comp_gate hook before-commit --command "git commit" --json 2>/dev/null || true)
|
|
22
|
+
|
|
23
|
+
if [ -n "$result" ]; then
|
|
24
|
+
if echo "$result" | grep -q '"permission"[[:space:]]*:[[:space:]]*"deny"'; then
|
|
25
|
+
echo "$result" | node -e '
|
|
26
|
+
const input = JSON.parse(require("fs").readFileSync(0, "utf8"));
|
|
27
|
+
console.error(input.user_message ?? input.agent_message ?? "Commit blocked by testme.");
|
|
28
|
+
'
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
echo "You must run the /testme skill before committing." >&2
|
|
35
|
+
exit 1
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
root="$(git rev-parse --show-toplevel)"
|
|
5
|
+
cd "$root"
|
|
6
|
+
|
|
7
|
+
run_comp_gate() {
|
|
8
|
+
if [ -x "$root/node_modules/.bin/comp-gate" ]; then
|
|
9
|
+
"$root/node_modules/.bin/comp-gate" "$@"
|
|
10
|
+
elif command -v comp-gate >/dev/null 2>&1; then
|
|
11
|
+
comp-gate "$@"
|
|
12
|
+
elif [ -x "$root/node_modules/.bin/testme" ]; then
|
|
13
|
+
"$root/node_modules/.bin/testme" "$@"
|
|
14
|
+
elif command -v testme >/dev/null 2>&1; then
|
|
15
|
+
testme "$@"
|
|
16
|
+
else
|
|
17
|
+
npx --yes comp-gate "$@"
|
|
18
|
+
fi
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
zero="0000000000000000000000000000000000000000"
|
|
22
|
+
|
|
23
|
+
while read -r local_ref local_sha remote_ref remote_sha; do
|
|
24
|
+
if [ -z "${local_ref:-}" ]; then
|
|
25
|
+
continue
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
if [ "$local_sha" = "$zero" ]; then
|
|
29
|
+
continue
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
case "$remote_ref" in
|
|
33
|
+
refs/heads/*) ;;
|
|
34
|
+
*) continue ;;
|
|
35
|
+
esac
|
|
36
|
+
|
|
37
|
+
result=$(run_comp_gate hook before-push-ref --remote-ref "$remote_ref" --json 2>/dev/null || true)
|
|
38
|
+
|
|
39
|
+
if [ -z "$result" ]; then
|
|
40
|
+
echo "You must run the /testme skill before pushing." >&2
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
if echo "$result" | grep -q '"permission"[[:space:]]*:[[:space:]]*"deny"'; then
|
|
45
|
+
echo "$result" | node -e '
|
|
46
|
+
const input = JSON.parse(require("fs").readFileSync(0, "utf8"));
|
|
47
|
+
console.error(input.user_message ?? input.agent_message ?? "Push blocked by testme.");
|
|
48
|
+
'
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
done
|
|
52
|
+
|
|
53
|
+
exit 0
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
input=$(cat)
|
|
5
|
+
command=$(node -e '
|
|
6
|
+
const data = JSON.parse(process.argv[1]);
|
|
7
|
+
const toolInfo = data.tool_info || {};
|
|
8
|
+
process.stdout.write(toolInfo.command_line || "");
|
|
9
|
+
' "$input")
|
|
10
|
+
|
|
11
|
+
if [ -z "$command" ]; then
|
|
12
|
+
exit 0
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
hook_kind=""
|
|
16
|
+
if echo "$command" | grep -qE '^git[[:space:]]+commit'; then
|
|
17
|
+
hook_kind="before-commit"
|
|
18
|
+
elif echo "$command" | grep -qE '^git[[:space:]]+push'; then
|
|
19
|
+
hook_kind="before-push"
|
|
20
|
+
else
|
|
21
|
+
exit 0
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
response=$(npx --yes comp-gate hook "$hook_kind" --command "$command" --json 2>/dev/null || true)
|
|
25
|
+
|
|
26
|
+
if [ -n "$response" ] && echo "$response" | grep -q '"permission"[[:space:]]*:[[:space:]]*"deny"'; then
|
|
27
|
+
echo "$response" | node -e '
|
|
28
|
+
const data = JSON.parse(require("fs").readFileSync(0, "utf8"));
|
|
29
|
+
console.error(data.user_message || data.agent_message || "Blocked by testme.");
|
|
30
|
+
' >&2
|
|
31
|
+
exit 2
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
if [ -n "$response" ]; then
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
echo "You must run the testme workflow before committing or pushing." >&2
|
|
39
|
+
exit 2
|