@holdpoint/cli 0.1.0-alpha.2 → 0.1.0-alpha.21
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/dist/chunk-D7ZF5JJH.js +521 -0
- package/dist/chunk-D7ZF5JJH.js.map +1 -0
- package/dist/data/verified-mcp-registry.json +14 -0
- package/dist/index.js +1588 -603
- package/dist/index.js.map +1 -1
- package/dist/init-Y7NZBMU6.js +8 -0
- package/dist/init-Y7NZBMU6.js.map +1 -0
- package/dist/lib/scan.d.ts +20 -0
- package/dist/lib/scan.js +200 -0
- package/dist/lib/scan.js.map +1 -0
- package/dist/prompt-EQ5IFADN.js +23 -0
- package/dist/prompt-EQ5IFADN.js.map +1 -0
- package/dist/templates/HOLDPOINT_PREREQUISITES.md +10 -0
- package/dist/templates/HOLDPOINT_REFERENCE.md +372 -0
- package/dist/templates/MASTER_PROMPT.md +25 -295
- package/dist/templates/default.yaml +274 -0
- package/package.json +16 -14
- package/dist/builder-ui/assets/index-BxfWKnb5.js +0 -437
- package/dist/builder-ui/assets/index-BxfWKnb5.js.map +0 -1
- package/dist/builder-ui/assets/index-DkLHZ-in.css +0 -1
- package/dist/builder-ui/favicon.svg +0 -10
- package/dist/builder-ui/index.html +0 -14
- package/dist/templates/_base.yaml +0 -52
- package/dist/templates/fullstack.yaml +0 -93
- package/dist/templates/go.yaml +0 -60
- package/dist/templates/nextjs.yaml +0 -76
- package/dist/templates/python.yaml +0 -60
- package/dist/templates/typescript.yaml +0 -55
|
@@ -1,309 +1,39 @@
|
|
|
1
1
|
# Holdpoint — Eval Checkpoints
|
|
2
2
|
|
|
3
|
-
This
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
---
|
|
3
|
+
This repo uses [Holdpoint](https://holdpoint.dev) to enforce eval
|
|
4
|
+
checkpoints. Before marking any task done, all checks must pass.
|
|
7
5
|
|
|
8
6
|
## The Rule
|
|
9
7
|
|
|
10
8
|
Before marking **any** task complete:
|
|
11
9
|
|
|
12
|
-
1. Run `
|
|
13
|
-
2. `holdpoint check` also prints every **prompt** check whose `when`
|
|
14
|
-
files you changed. Read and act on each listed
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
`checks.yaml` is not static — it grows alongside the project automatically.
|
|
21
|
-
|
|
22
|
-
**`holdpoint-evolve` is a deterministic check** in `checks.yaml` that fires whenever you change a structural file (`package.json`, `pyproject.toml`, `go.mod`, `Dockerfile`, `tsconfig.json`, `vitest.config.*`, etc.). When it fires, `npx @holdpoint/cli@alpha evolve` runs and **exits 1 if `checks.yaml` is out of sync** — blocking task completion until you apply the proposals.
|
|
23
|
-
|
|
24
|
-
When blocked by `holdpoint-evolve`, run:
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
npx @holdpoint/cli@alpha evolve --apply # scan, apply proposals, regenerate engine files
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Then commit:
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
git add checks.yaml .github/holdpoint/generated/
|
|
34
|
-
git commit -m "chore: evolve holdpoint checks"
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
`holdpoint evolve --apply` is idempotent — safe to re-run at any time. It only adds checks for tools/patterns detected in the project and wraps stale checks (whose `when:` pattern no longer matches any file) with `conditionId: file_exists` so they auto-skip instead of failing.
|
|
38
|
-
|
|
39
|
-
**What triggers evolution:**
|
|
40
|
-
|
|
41
|
-
- New dependency in `package.json` / `pyproject.toml` / `go.mod` / `Cargo.toml`
|
|
42
|
-
- New `Dockerfile`, `docker-compose.yml`, `*.tf`, `openapi.yaml`
|
|
43
|
-
- New test runner config (`vitest.config.*`, `jest.config.*`, `playwright.config.*`)
|
|
44
|
-
- New CI workflow in `.github/workflows/`
|
|
45
|
-
- New TypeScript setup (`tsconfig.json`)
|
|
46
|
-
|
|
47
|
-
**What does NOT trigger it:** `.ts` / `.py` / `.go` source files, docs, styles, tests — minor work proceeds without interruption.
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## checks.yaml — Full Reference
|
|
52
|
-
|
|
53
|
-
`checks.yaml` at the project root is the single source of truth. Edit it to add,
|
|
54
|
-
remove, or change checkpoints.
|
|
55
|
-
|
|
56
|
-
After every edit, regenerate the engine files and commit everything together:
|
|
57
|
-
|
|
58
|
-
```
|
|
59
|
-
npx @holdpoint/cli@alpha update
|
|
60
|
-
git add checks.yaml .github/holdpoint/generated/ .github/hooks/
|
|
61
|
-
git commit -m "chore: update holdpoint checks"
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### Top-level structure
|
|
65
|
-
|
|
66
|
-
```yaml
|
|
67
|
-
version: 1
|
|
68
|
-
|
|
69
|
-
context:
|
|
70
|
-
guides: # project notes shown when `holdpoint check` runs
|
|
71
|
-
setup: >
|
|
72
|
-
Use pnpm, not npm. Node 20+ required.
|
|
73
|
-
|
|
74
|
-
conditions: # gate checks on file/env state
|
|
75
|
-
- id: dist-built
|
|
76
|
-
operator: file_exists
|
|
77
|
-
path: dist/index.js
|
|
78
|
-
|
|
79
|
-
checks: # list of all checks — each has on/when + cmd (task) or prompt
|
|
80
|
-
- ...
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
### Deterministic check
|
|
86
|
-
|
|
87
|
-
```yaml
|
|
88
|
-
- id: lint # unique slug, kebab-case
|
|
89
|
-
label: "ESLint — all packages" # human-readable label shown in output
|
|
90
|
-
# on: before_done # lifecycle hook (default; only value today)
|
|
91
|
-
# when: frontend # file filter — omit to run on every task
|
|
92
|
-
cmd: "pnpm turbo lint" # shell command; must exit 0 to pass
|
|
93
|
-
conditionId: dist-built # optional: skip if condition is not met
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### Prompt check
|
|
97
|
-
|
|
98
|
-
```yaml
|
|
99
|
-
- id: migration-review
|
|
100
|
-
label: "Review DB migration"
|
|
101
|
-
when: "^prisma/migrations/" # only fires when migration files change
|
|
102
|
-
prompt: >
|
|
103
|
-
Open the new migration file. Confirm it is backward-compatible
|
|
104
|
-
and does not drop or truncate data without a fallback.
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
### `on` — lifecycle hooks
|
|
110
|
-
|
|
111
|
-
`on` specifies _when in the agent lifecycle_ a check fires. Omit it to use the default.
|
|
112
|
-
|
|
113
|
-
| Value | Fires |
|
|
114
|
-
| ------------- | ---------------------------------- |
|
|
115
|
-
| `before_done` | Before the agent marks a task done |
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
### `when` — file filters
|
|
120
|
-
|
|
121
|
-
`when` is an optional file filter. If omitted the check runs on every task.
|
|
122
|
-
|
|
123
|
-
| Value | Fires when changed files match |
|
|
124
|
-
| ----------- | -------------------------------------------------------------------------------------------------- |
|
|
125
|
-
| _(absent)_ | Every task — no file filter applied |
|
|
126
|
-
| `frontend` | `**/*.tsx`, `**/*.jsx`, `**/*.css`, `**/*.scss`, `**/tailwind.config.*`, `apps/**` |
|
|
127
|
-
| `backend` | `**/api/**`, `**/server/**`, `**/routes/**`, `**/controllers/**`, `packages/*/src/**` |
|
|
128
|
-
| `socket` | `**/socket/**`, `**/ws/**`, `**/websocket/**` |
|
|
129
|
-
| `visual` | `**/*.stories.{ts,tsx}`, `**/__screenshots__/**`, `**/*.snap` |
|
|
130
|
-
| `python` | `**/*.py`, `**/*.pyi`, `**/requirements*.txt`, `**/pyproject.toml`, `**/setup.py`, `**/pytest.ini` |
|
|
131
|
-
| `go` | `**/*.go`, `**/go.mod`, `**/go.sum` |
|
|
132
|
-
| `rust` | `**/*.rs`, `**/Cargo.toml`, `**/Cargo.lock` |
|
|
133
|
-
| `java` | `**/*.java`, `**/*.kt`, `**/*.gradle`, `**/*.gradle.kts`, `**/pom.xml` |
|
|
134
|
-
| `ruby` | `**/*.rb`, `**/Gemfile`, `**/Gemfile.lock`, `**/Rakefile` |
|
|
135
|
-
| `database` | `**/*.sql`, `**/migrations/**`, `**/db/**`, `**/database/**`, `**/prisma/**`, `**/*.prisma` |
|
|
136
|
-
| `prisma` | `**/prisma/**`, `**/*.prisma` — focused subset of `database` for Prisma-specific checks |
|
|
137
|
-
| `testing` | `**/*.test.*`, `**/*.spec.*`, `**/__tests__/**`, `**/test/**`, `**/tests/**`, `**/spec/**` |
|
|
138
|
-
| `infra` | `**/Dockerfile*`, `**/docker-compose.*`, `**/*.tf`, `**/*.tfvars`, `**/k8s/**`, `**/kubernetes/**` |
|
|
139
|
-
| `ci` | `**/.github/workflows/**`, `**/.circleci/**`, `**/Jenkinsfile`, `**/.gitlab-ci.yml` |
|
|
140
|
-
| `docs` | `**/*.mdx`, `**/*.rst`, `**/docs/**`, `**/documentation/**` |
|
|
141
|
-
| `"^src/.*"` | Any JavaScript regex tested against each changed file path |
|
|
142
|
-
|
|
143
|
-
Regex example — fires only when files under `src/api/` change:
|
|
144
|
-
|
|
145
|
-
```yaml
|
|
146
|
-
when: "^src/api/" # new RegExp(when).test(filePath)
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
> **Note:** Named scopes use glob matching; plain strings are treated as JavaScript regexes.
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
### Conditions
|
|
154
|
-
|
|
155
|
-
Conditions let you skip a check when a prerequisite is not yet met (e.g. a build
|
|
156
|
-
artefact doesn't exist yet).
|
|
157
|
-
|
|
158
|
-
| Operator | What it checks |
|
|
159
|
-
| ----------------- | ------------------------------------------------- |
|
|
160
|
-
| `file_exists` | A file or directory exists at `path` |
|
|
161
|
-
| `file_contains` | The file at `path` contains the substring `value` |
|
|
162
|
-
| `env_var_set` | The environment variable named `value` is set |
|
|
163
|
-
| `shell_returns_0` | The shell command in `cmd` exits with code 0 |
|
|
164
|
-
|
|
165
|
-
```yaml
|
|
166
|
-
conditions:
|
|
167
|
-
- id: packages-built
|
|
168
|
-
operator: file_exists
|
|
169
|
-
path: packages/yaml-core/dist/index.js
|
|
170
|
-
|
|
171
|
-
checks:
|
|
172
|
-
- id: validate-templates
|
|
173
|
-
label: "Templates parse against schema"
|
|
174
|
-
conditionId: packages-built # skipped (◌) when dist is absent
|
|
175
|
-
cmd: "node dist/validate.js templates/"
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
---
|
|
179
|
-
|
|
180
|
-
### Context guides
|
|
181
|
-
|
|
182
|
-
`context.guides` is a freeform key → multiline-string map. Guides are printed
|
|
183
|
-
at the start of `holdpoint check` output as project-level reminders to whoever
|
|
184
|
-
(or whatever) is running the checks.
|
|
185
|
-
|
|
186
|
-
```yaml
|
|
187
|
-
context:
|
|
188
|
-
guides:
|
|
189
|
-
setup: >
|
|
190
|
-
This project requires Node 20 and pnpm 9+.
|
|
191
|
-
Run `pnpm install` from the repo root before any other command.
|
|
192
|
-
architecture: >
|
|
193
|
-
API routes live in src/api/. Models live in src/models/.
|
|
194
|
-
Client code must never import from server modules.
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
## Adding a New Check
|
|
200
|
-
|
|
201
|
-
1. Open `checks.yaml`.
|
|
202
|
-
2. Add your entry under `checks:`.
|
|
203
|
-
3. Run `npx @holdpoint/cli@alpha update`.
|
|
204
|
-
4. Commit `checks.yaml` and the generated files.
|
|
205
|
-
|
|
206
|
-
**Add a task check (runs a shell command automatically):**
|
|
207
|
-
|
|
208
|
-
```yaml
|
|
209
|
-
checks:
|
|
210
|
-
- id: vitest
|
|
211
|
-
label: "Vitest — unit tests"
|
|
212
|
-
cmd: "pnpm vitest run"
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
**Add a scoped task (fires only on matching file changes):**
|
|
216
|
-
|
|
217
|
-
```yaml
|
|
218
|
-
checks:
|
|
219
|
-
- id: openapi-sync
|
|
220
|
-
label: "OpenAPI types are up to date"
|
|
221
|
-
when: "^src/api/"
|
|
222
|
-
cmd: "pnpm generate:types && git diff --exit-code src/generated/"
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
**Add an agent prompt checkpoint:**
|
|
226
|
-
|
|
227
|
-
```yaml
|
|
228
|
-
checks:
|
|
229
|
-
- id: jsdoc
|
|
230
|
-
label: "JSDoc on changed public functions"
|
|
231
|
-
prompt: >
|
|
232
|
-
For every public function or export you modified, ensure there is an
|
|
233
|
-
accurate JSDoc comment: description, @param, and @returns.
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
**Enforce changelog and git commit on every task (recommended):**
|
|
237
|
-
|
|
238
|
-
```yaml
|
|
239
|
-
checks:
|
|
240
|
-
- id: changelog-update
|
|
241
|
-
label: "Add a CHANGELOG.md entry for this session"
|
|
242
|
-
prompt: >
|
|
243
|
-
Before committing, add an entry to CHANGELOG.md describing what was done.
|
|
244
|
-
Use Keep a Changelog format — add under ## [Unreleased] (create the file
|
|
245
|
-
and that section if absent). Group entries as Added, Changed, Fixed, or Removed.
|
|
246
|
-
Be concise but specific. The entry text will serve as the commit message.
|
|
247
|
-
|
|
248
|
-
- id: readme-sync
|
|
249
|
-
label: "Update README.md if user-facing changes were made"
|
|
250
|
-
prompt: >
|
|
251
|
-
If you added, changed, or removed user-facing functionality — CLI commands,
|
|
252
|
-
configuration options, public APIs, or significant new features — update
|
|
253
|
-
README.md to reflect those changes.
|
|
254
|
-
|
|
255
|
-
- id: git-commit
|
|
256
|
-
label: "Commit all changes before finishing"
|
|
257
|
-
cmd: 'git rev-parse --is-inside-work-tree 2>/dev/null || exit 0; [ -z "$(git status --porcelain)" ] && exit 0; git status --short; exit 1'
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
When the `git-commit` check fails (uncommitted changes remain), the agent will also see
|
|
261
|
-
the `changelog-update` and `readme-sync` prompt reminders inline — ensuring it updates
|
|
262
|
-
the changelog, syncs docs, _then_ commits before it can mark the task done.
|
|
263
|
-
|
|
264
|
-
---
|
|
265
|
-
|
|
266
|
-
## `session_context_files`
|
|
267
|
-
|
|
268
|
-
`session_context_files` is an optional list of project files that Holdpoint injects
|
|
269
|
-
as context at the start of every Copilot session. Use it for files the agent should
|
|
270
|
-
always read before starting work.
|
|
271
|
-
|
|
272
|
-
```yaml
|
|
273
|
-
session_context_files:
|
|
274
|
-
- MASTER_PROMPT.md
|
|
275
|
-
- AGENT_CONTEXT.md
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
Files are resolved relative to the repo root and must stay inside it (traversal
|
|
279
|
-
paths like `../../etc/passwd` are rejected). If a file doesn't exist it is silently
|
|
280
|
-
skipped.
|
|
10
|
+
1. Run `holdpoint check` — all checks must exit 0.
|
|
11
|
+
2. `holdpoint check` also prints every **prompt** check whose `when`
|
|
12
|
+
matches the files you changed. Read and act on each listed
|
|
13
|
+
instruction before finishing.
|
|
14
|
+
3. Never bypass via `git commit --no-verify` or by skipping a stop
|
|
15
|
+
hook. If a check is wrong, fix the check in `checks.yaml`, don't
|
|
16
|
+
route around it.
|
|
281
17
|
|
|
282
|
-
|
|
18
|
+
## The Suggest Loop
|
|
283
19
|
|
|
284
|
-
|
|
20
|
+
`checks.yaml` grows with the project. `holdpoint-suggest` is a check
|
|
21
|
+
that fires whenever structural files change (`package.json`,
|
|
22
|
+
`pyproject.toml`, `go.mod`, `Dockerfile`, `tsconfig.json`,
|
|
23
|
+
`vitest.config.*`, etc.). When it fires, `holdpoint suggest` runs and
|
|
24
|
+
**exits 1 if `checks.yaml` is out of sync** — blocking task completion
|
|
25
|
+
until you apply the proposals.
|
|
285
26
|
|
|
286
|
-
|
|
287
|
-
| ---------------------------------- | ------------------------------------------------------- |
|
|
288
|
-
| `npx @holdpoint/cli@alpha check` | Run checks against all files changed vs HEAD |
|
|
289
|
-
| `npx @holdpoint/cli@alpha check --staged` | Run checks against staged files only |
|
|
290
|
-
| `npx @holdpoint/cli@alpha evolve` | Scan project and show proposed additions to checks.yaml |
|
|
291
|
-
| `npx @holdpoint/cli@alpha evolve --apply` | Apply proposals and regenerate engine files |
|
|
292
|
-
| `npx @holdpoint/cli@alpha update` | Regenerate engine files from the current `checks.yaml` |
|
|
293
|
-
| `npx @holdpoint/cli@alpha validate` | Validate `checks.yaml` schema (no commands run) |
|
|
294
|
-
| `npx @holdpoint/cli@alpha builder` | Open the visual builder UI at localhost:4321 |
|
|
27
|
+
When blocked, run:
|
|
295
28
|
|
|
296
|
-
|
|
29
|
+
holdpoint suggest --apply
|
|
297
30
|
|
|
298
|
-
|
|
31
|
+
then commit the changes and continue.
|
|
299
32
|
|
|
300
|
-
|
|
301
|
-
| --------------------------------------------------- | ------- |
|
|
302
|
-
| `.github/holdpoint/generated/checks.immutable.json` | all |
|
|
303
|
-
| `.github/hooks/holdpoint.json` | Copilot |
|
|
304
|
-
| `.github/hooks/holdpoint-check.mjs` | Copilot |
|
|
305
|
-
| `.claude/settings.json` | Claude |
|
|
306
|
-
| `.cursorrules` (Holdpoint section) | Cursor |
|
|
33
|
+
## Going deeper
|
|
307
34
|
|
|
308
|
-
|
|
309
|
-
|
|
35
|
+
For the full reference — every built-in check, every `when:` scope,
|
|
36
|
+
per-engine details, troubleshooting — read
|
|
37
|
+
[`HOLDPOINT_REFERENCE.md`](./HOLDPOINT_REFERENCE.md). The file is on
|
|
38
|
+
disk; you can `cat` it when you need detail. It is intentionally not
|
|
39
|
+
auto-injected because it's reference, not directive.
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
version: 1
|
|
2
|
+
|
|
3
|
+
# Holdpoint default checks — single source of truth across all stacks.
|
|
4
|
+
# Every check below is either universally relevant (e.g. git-commit) or
|
|
5
|
+
# gated by `when:` (path-based scope) AND/OR `conditionId:` (file
|
|
6
|
+
# existence in the repo). Add a new stack by adding a condition that
|
|
7
|
+
# detects its manifest file, then gating stack-specific checks on it —
|
|
8
|
+
# don't fork this file.
|
|
9
|
+
|
|
10
|
+
context:
|
|
11
|
+
guides: {}
|
|
12
|
+
|
|
13
|
+
session_context_files:
|
|
14
|
+
- MASTER_PROMPT.md
|
|
15
|
+
|
|
16
|
+
conditions:
|
|
17
|
+
- id: is-node
|
|
18
|
+
operator: file_exists
|
|
19
|
+
path: package.json
|
|
20
|
+
- id: is-python
|
|
21
|
+
operator: file_exists
|
|
22
|
+
path: pyproject.toml
|
|
23
|
+
- id: is-go
|
|
24
|
+
operator: file_exists
|
|
25
|
+
path: go.mod
|
|
26
|
+
- id: is-rust
|
|
27
|
+
operator: file_exists
|
|
28
|
+
path: Cargo.toml
|
|
29
|
+
- id: has-dockerfile
|
|
30
|
+
operator: file_exists
|
|
31
|
+
path: Dockerfile
|
|
32
|
+
- id: has-openapi
|
|
33
|
+
operator: file_exists
|
|
34
|
+
path: openapi.yaml
|
|
35
|
+
- id: has-playwright
|
|
36
|
+
operator: file_exists
|
|
37
|
+
path: playwright.config.ts
|
|
38
|
+
- id: has-changesets
|
|
39
|
+
operator: file_exists
|
|
40
|
+
path: .changeset/config.json
|
|
41
|
+
- id: has-lint-script
|
|
42
|
+
operator: file_contains
|
|
43
|
+
path: package.json
|
|
44
|
+
contains: '"lint"'
|
|
45
|
+
- id: has-build-script
|
|
46
|
+
operator: file_contains
|
|
47
|
+
path: package.json
|
|
48
|
+
contains: '"build"'
|
|
49
|
+
- id: has-test-script
|
|
50
|
+
operator: file_contains
|
|
51
|
+
path: package.json
|
|
52
|
+
contains: '"test"'
|
|
53
|
+
- id: has-typecheck-script
|
|
54
|
+
operator: file_contains
|
|
55
|
+
path: package.json
|
|
56
|
+
contains: '"typecheck"'
|
|
57
|
+
|
|
58
|
+
patterns:
|
|
59
|
+
changelog-files: "(^|/)CHANGELOG\\.md$"
|
|
60
|
+
|
|
61
|
+
checks:
|
|
62
|
+
# ── Coding practices (universal) ───────────────────────────────────
|
|
63
|
+
- id: karpathy-practices
|
|
64
|
+
label: "Karpathy coding practices"
|
|
65
|
+
on: session_start
|
|
66
|
+
inject:
|
|
67
|
+
text: |
|
|
68
|
+
## Coding practices (enforced by Holdpoint)
|
|
69
|
+
|
|
70
|
+
1. Read all relevant files fully before making any change.
|
|
71
|
+
2. Make the smallest change that satisfies the task. No unsolicited refactors.
|
|
72
|
+
3. Edit existing code surgically. Do not rewrite what you were not asked to rewrite.
|
|
73
|
+
4. Do not add logging, tests, types, or abstractions that were not asked for.
|
|
74
|
+
5. If a test suite exists, it must pass before you stop.
|
|
75
|
+
6. Complete exactly what was asked. Log adjacent issues separately, don't fix them.
|
|
76
|
+
|
|
77
|
+
- id: check-test-suite
|
|
78
|
+
label: "Test suite passes"
|
|
79
|
+
on: before_done
|
|
80
|
+
prompt: "If this project has a test suite (package.json test script, pytest, go test, etc.), confirm it passes. If you did not run it, run it now before finishing."
|
|
81
|
+
|
|
82
|
+
- id: check-minimal-change
|
|
83
|
+
label: "Change is minimal and scoped"
|
|
84
|
+
on: before_done
|
|
85
|
+
prompt: "Review every file you changed. Remove any addition that was not explicitly requested — unused imports, debug logs, reformatted blocks, unrequested refactors. Confirm the diff is surgical."
|
|
86
|
+
|
|
87
|
+
# ── Node / TypeScript / JavaScript ─────────────────────────────────
|
|
88
|
+
- id: node-lint
|
|
89
|
+
label: "Lint (Node) — no warnings"
|
|
90
|
+
conditionId: has-lint-script
|
|
91
|
+
cmd: "pnpm lint --max-warnings 0"
|
|
92
|
+
- id: node-typecheck
|
|
93
|
+
label: "TypeScript type check"
|
|
94
|
+
conditionId: has-typecheck-script
|
|
95
|
+
cmd: "pnpm typecheck"
|
|
96
|
+
- id: node-test
|
|
97
|
+
label: "Unit tests (Node)"
|
|
98
|
+
conditionId: has-test-script
|
|
99
|
+
cmd: "pnpm test --run"
|
|
100
|
+
- id: node-build
|
|
101
|
+
label: "Production build (Node)"
|
|
102
|
+
conditionId: has-build-script
|
|
103
|
+
when: backend
|
|
104
|
+
cmd: "pnpm build"
|
|
105
|
+
- id: jsdoc
|
|
106
|
+
label: "JSDoc on changed public functions"
|
|
107
|
+
conditionId: is-node
|
|
108
|
+
when: backend
|
|
109
|
+
prompt: >
|
|
110
|
+
Ensure all changed public functions, classes, and module exports
|
|
111
|
+
have accurate JSDoc (description + @param + @returns).
|
|
112
|
+
|
|
113
|
+
# ── Python ─────────────────────────────────────────────────────────
|
|
114
|
+
- id: py-lint
|
|
115
|
+
label: "Ruff (Python lint)"
|
|
116
|
+
conditionId: is-python
|
|
117
|
+
when: python
|
|
118
|
+
cmd: "ruff check ."
|
|
119
|
+
- id: py-typecheck
|
|
120
|
+
label: "Mypy (Python type check)"
|
|
121
|
+
conditionId: is-python
|
|
122
|
+
when: python
|
|
123
|
+
cmd: "mypy . --ignore-missing-imports"
|
|
124
|
+
- id: py-test
|
|
125
|
+
label: "pytest"
|
|
126
|
+
conditionId: is-python
|
|
127
|
+
when: python
|
|
128
|
+
cmd: "pytest --tb=short -q"
|
|
129
|
+
- id: py-docstrings
|
|
130
|
+
label: "Docstrings on changed Python functions"
|
|
131
|
+
conditionId: is-python
|
|
132
|
+
when: python
|
|
133
|
+
prompt: >
|
|
134
|
+
Ensure changed public functions and classes have PEP-257 docstrings.
|
|
135
|
+
- id: py-type-hints
|
|
136
|
+
label: "Type hints on new Python functions"
|
|
137
|
+
conditionId: is-python
|
|
138
|
+
when: python
|
|
139
|
+
prompt: >
|
|
140
|
+
Confirm new functions have full type annotations on parameters
|
|
141
|
+
and return values.
|
|
142
|
+
|
|
143
|
+
# ── Go ─────────────────────────────────────────────────────────────
|
|
144
|
+
- id: go-build
|
|
145
|
+
label: "go build — no compilation errors"
|
|
146
|
+
conditionId: is-go
|
|
147
|
+
when: go
|
|
148
|
+
cmd: "go build ./..."
|
|
149
|
+
- id: go-vet
|
|
150
|
+
label: "go vet — no suspicious constructs"
|
|
151
|
+
conditionId: is-go
|
|
152
|
+
when: go
|
|
153
|
+
cmd: "go vet ./..."
|
|
154
|
+
- id: go-test
|
|
155
|
+
label: "go test"
|
|
156
|
+
conditionId: is-go
|
|
157
|
+
when: go
|
|
158
|
+
cmd: "go test ./..."
|
|
159
|
+
- id: godoc
|
|
160
|
+
label: "GoDoc on exported symbols"
|
|
161
|
+
conditionId: is-go
|
|
162
|
+
when: go
|
|
163
|
+
prompt: >
|
|
164
|
+
Exported functions, types, methods, and packages have GoDoc
|
|
165
|
+
starting with the symbol name.
|
|
166
|
+
|
|
167
|
+
# ── Rust ───────────────────────────────────────────────────────────
|
|
168
|
+
- id: rust-build
|
|
169
|
+
label: "cargo build"
|
|
170
|
+
conditionId: is-rust
|
|
171
|
+
when: rust
|
|
172
|
+
cmd: "cargo build"
|
|
173
|
+
- id: rust-clippy
|
|
174
|
+
label: "Clippy — strict"
|
|
175
|
+
conditionId: is-rust
|
|
176
|
+
when: rust
|
|
177
|
+
cmd: "cargo clippy --all-targets -- -D warnings"
|
|
178
|
+
- id: rust-test
|
|
179
|
+
label: "cargo test"
|
|
180
|
+
conditionId: is-rust
|
|
181
|
+
when: rust
|
|
182
|
+
cmd: "cargo test"
|
|
183
|
+
|
|
184
|
+
# ── Frontend ───────────────────────────────────────────────────────
|
|
185
|
+
- id: visual-regression
|
|
186
|
+
label: "Visual regression check"
|
|
187
|
+
conditionId: has-playwright
|
|
188
|
+
when: frontend
|
|
189
|
+
prompt: >
|
|
190
|
+
Run `pnpm playwright test` for UI changes. Review screenshots
|
|
191
|
+
at 1280px, 768px, and 375px breakpoints.
|
|
192
|
+
- id: i18n
|
|
193
|
+
label: "i18n — no hardcoded user-facing strings"
|
|
194
|
+
when: frontend
|
|
195
|
+
prompt: >
|
|
196
|
+
User-visible text is wrapped in the t() translation function
|
|
197
|
+
(or project equivalent) with corresponding locale entries.
|
|
198
|
+
|
|
199
|
+
# ── Backend / API ──────────────────────────────────────────────────
|
|
200
|
+
- id: openapi-updated
|
|
201
|
+
label: "OpenAPI spec updated for API changes"
|
|
202
|
+
conditionId: has-openapi
|
|
203
|
+
when: backend
|
|
204
|
+
prompt: >
|
|
205
|
+
If API routes changed, confirm openapi.yaml has been updated.
|
|
206
|
+
|
|
207
|
+
# ── Database ───────────────────────────────────────────────────────
|
|
208
|
+
- id: db-migrations
|
|
209
|
+
label: "Database migration for schema changes"
|
|
210
|
+
when: database
|
|
211
|
+
prompt: >
|
|
212
|
+
If schema files changed, ensure a migration was generated and
|
|
213
|
+
committed (prisma migrate dev, alembic revision, rails db:migrate).
|
|
214
|
+
|
|
215
|
+
# ── Infra ──────────────────────────────────────────────────────────
|
|
216
|
+
- id: dockerfile-best-practices
|
|
217
|
+
label: "Dockerfile best practices"
|
|
218
|
+
conditionId: has-dockerfile
|
|
219
|
+
when: infra
|
|
220
|
+
prompt: >
|
|
221
|
+
Confirm multi-stage build, non-root USER, pinned base image,
|
|
222
|
+
minimal layers.
|
|
223
|
+
|
|
224
|
+
# ── Documentation (universal) ──────────────────────────────────────
|
|
225
|
+
- id: readme-sync
|
|
226
|
+
label: "Update README.md for user-facing changes"
|
|
227
|
+
prompt: >
|
|
228
|
+
If user-facing functionality changed (CLI commands, config,
|
|
229
|
+
public APIs, features), update README.md.
|
|
230
|
+
- id: changelog-changeset
|
|
231
|
+
label: "Use changesets instead of manual changelog edits"
|
|
232
|
+
conditionId: has-changesets
|
|
233
|
+
when: changelog-files
|
|
234
|
+
prompt: >
|
|
235
|
+
If you changed any CHANGELOG.md file, move the release note into a
|
|
236
|
+
.changeset/*.md entry and let release automation update changelogs.
|
|
237
|
+
Keep manual changelog edits only when explicitly requested or for
|
|
238
|
+
non-release historical notes, and state that reason before finishing.
|
|
239
|
+
- id: git-workflow
|
|
240
|
+
label: "Use the right git workflow"
|
|
241
|
+
prompt: >
|
|
242
|
+
Choose the least-disruptive git workflow: use branch + PR for requested
|
|
243
|
+
feature branches or protected-main work; for small local fixes, commit on
|
|
244
|
+
the current branch without opening a PR unless asked; if already on a
|
|
245
|
+
feature branch, keep committing there instead of creating another branch.
|
|
246
|
+
Push only when a PR, remote review, CI run, or handoff needs it; otherwise
|
|
247
|
+
leave the commit local and report the branch/commit.
|
|
248
|
+
|
|
249
|
+
# ── Code hygiene (universal) ───────────────────────────────────────
|
|
250
|
+
- id: no-todos
|
|
251
|
+
label: "No TODO/FIXME left in changed code"
|
|
252
|
+
cmd: >-
|
|
253
|
+
! grep -rEn "TODO|FIXME|HACK|XXX"
|
|
254
|
+
--include="*.ts" --include="*.tsx"
|
|
255
|
+
--include="*.js" --include="*.jsx"
|
|
256
|
+
--include="*.py" --include="*.go" --include="*.rs"
|
|
257
|
+
--exclude-dir=node_modules --exclude-dir=dist --exclude-dir=.git
|
|
258
|
+
--exclude-dir=.next --exclude-dir=.turbo --exclude-dir=build
|
|
259
|
+
--exclude-dir=.venv --exclude-dir=venv --exclude-dir=__pycache__
|
|
260
|
+
--exclude-dir=target --exclude-dir=vendor
|
|
261
|
+
.
|
|
262
|
+
|
|
263
|
+
# ── Holdpoint-internal ─────────────────────────────────────────────
|
|
264
|
+
- id: holdpoint-suggest
|
|
265
|
+
label: "Suggest checks when project structure changes"
|
|
266
|
+
when: structural
|
|
267
|
+
cmd: "node_modules/.bin/holdpoint suggest"
|
|
268
|
+
- id: changeset
|
|
269
|
+
label: "Changeset for package changes"
|
|
270
|
+
conditionId: has-changesets
|
|
271
|
+
cmd: "node_modules/.bin/holdpoint require-changeset --staged"
|
|
272
|
+
- id: git-commit
|
|
273
|
+
label: "Commit all changes before finishing"
|
|
274
|
+
cmd: 'git rev-parse --is-inside-work-tree >/dev/null 2>&1 || exit 0; [ -z "$(git status --porcelain)" ] && exit 0; git status --short; exit 1'
|
package/package.json
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holdpoint/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.21",
|
|
4
4
|
"publishConfig": {
|
|
5
|
-
"access": "public"
|
|
6
|
-
"tag": "alpha"
|
|
5
|
+
"access": "public"
|
|
7
6
|
},
|
|
8
7
|
"description": "Holdpoint CLI — enforce deterministic eval checkpoints on AI coding agents",
|
|
9
8
|
"homepage": "https://holdpoint.dev",
|
|
@@ -47,20 +46,23 @@
|
|
|
47
46
|
],
|
|
48
47
|
"dependencies": {
|
|
49
48
|
"chalk": "^5.3.0",
|
|
50
|
-
"commander": "^
|
|
51
|
-
"ora": "^
|
|
52
|
-
"@holdpoint/
|
|
53
|
-
"@holdpoint/
|
|
54
|
-
"@holdpoint/engine-
|
|
55
|
-
"@holdpoint/engine-
|
|
56
|
-
"@holdpoint/
|
|
49
|
+
"commander": "^15.0.0",
|
|
50
|
+
"ora": "^9.4.0",
|
|
51
|
+
"@holdpoint/sdk": "0.1.0-alpha.4",
|
|
52
|
+
"@holdpoint/live-daemon": "0.1.0-alpha.6",
|
|
53
|
+
"@holdpoint/engine-claude": "0.1.0-alpha.15",
|
|
54
|
+
"@holdpoint/engine-codex": "0.1.0-alpha.16",
|
|
55
|
+
"@holdpoint/live-protocol": "0.1.0-alpha.4",
|
|
56
|
+
"@holdpoint/engine-copilot": "0.1.0-alpha.16",
|
|
57
|
+
"@holdpoint/engine-cursor": "0.1.0-alpha.14",
|
|
58
|
+
"@holdpoint/types": "0.1.0-alpha.10",
|
|
59
|
+
"@holdpoint/yaml-core": "0.1.0-alpha.11"
|
|
57
60
|
},
|
|
58
61
|
"devDependencies": {
|
|
59
|
-
"@types/node": "^
|
|
62
|
+
"@types/node": "^25.9.1",
|
|
60
63
|
"tsup": "^8.3.5",
|
|
61
|
-
"typescript": "^
|
|
62
|
-
"vitest": "^
|
|
63
|
-
"@holdpoint/builder": "0.1.0"
|
|
64
|
+
"typescript": "^6.0.3",
|
|
65
|
+
"vitest": "^4.1.8"
|
|
64
66
|
},
|
|
65
67
|
"scripts": {
|
|
66
68
|
"build": "tsup",
|