@data-matters.io/agent-harness 0.1.1 → 0.1.2

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 CHANGED
@@ -18,7 +18,7 @@ minimumReleaseAgeExclude:
18
18
 
19
19
  ```sh
20
20
  pnpm add -D -E @data-matters.io/agent-harness
21
- pnpm exec harness init --new --stack nextjs # or nestjs; --existing for a codebase without tests
21
+ pnpm exec harness init --new --stack nextjs # or nestjs, vite; --existing for a codebase without tests
22
22
  ```
23
23
 
24
24
  ```json
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-matters.io/agent-harness",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Spec-Driven Development with Claude Code: gates, task loop and standards installed into a product repository",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -8,6 +8,7 @@ standards, and differ only in the framework.
8
8
  | -------- | -------------------------------- | -------------------------------------- | ------------------------ |
9
9
  | `nextjs` | `data-matters-io/nextjs-new-app` | Web applications (UI + route handlers) | `stacks/nextjs/stack.md` |
10
10
  | `nestjs` | `data-matters-io/nestjs-new-app` | Backend services (HTTP APIs) | `stacks/nestjs/stack.md` |
11
+ | `vite` | none (ADR 0023) | Static Vite + TypeScript sites, no DB | `stacks/vite/stack.md` |
11
12
 
12
13
  In a product repo, the chosen stack's files are in `.harness/standards/stack/`.
13
14
 
@@ -40,3 +41,4 @@ workflow (`gates.yml`) validated against each template:
40
41
  | -------- | ---------------------------- |
41
42
  | `nextjs` | see `stacks/nextjs/stack.md` |
42
43
  | `nestjs` | see `stacks/nestjs/stack.md` |
44
+ | `vite` | see `stacks/vite/stack.md` |
@@ -0,0 +1,10 @@
1
+ # Architecture: Vite static sites
2
+
3
+ A static site: everything runs in the browser and `vite build` emits `dist/`.
4
+ Deviations need an ADR in the product repo.
5
+
6
+ - Source in `src/`, entry from `index.html`; tests beside the code.
7
+ - No server, no database, no secrets: nothing in `src/` or `dist/` may hold one.
8
+ - Keep pure logic (data, rules) in modules apart from DOM code, so it is
9
+ testable without a browser.
10
+ - Dependencies are added only when the spec declares them (ADR 0015).
@@ -0,0 +1,13 @@
1
+ # Conventions: Vite static sites
2
+
3
+ Extends the shared `conventions.md`.
4
+
5
+ - Type-only imports inline: `import { type Foo } from '…'`.
6
+ - Import order is auto-fixed by lint (`@data-matters.io/eslint-config`).
7
+ - Files are kebab-case `.ts`; tests are `<file>.test.ts` beside the code.
8
+ - Env vars exposed to the client use the `VITE_` prefix and are never secret.
9
+
10
+ ## Local workflow
11
+
12
+ `pnpm dev`, `pnpm build`, `pnpm test`, `pnpm lint`, `pnpm typecheck` and
13
+ `pnpm gates` (all gates).
@@ -0,0 +1,27 @@
1
+ # Stack: Vite static sites
2
+
3
+ No app template: the preset is derived from `data-matters-io/play-around-world`
4
+ (ADR 0023), with `@data-matters.io/eslint-config` 4.0.0.
5
+
6
+ | Area | Choice | Version |
7
+ | ------------ | ----------------------------------------- | ------- |
8
+ | Runtime | Node.js (build and tooling only) | 24.x |
9
+ | Bundler | Vite, static output in `dist/` | 8.x |
10
+ | Language | TypeScript, `strict: true` | 5.9.x |
11
+ | Testing | Vitest + jsdom, coverage with istanbul | 5.x |
12
+ | Lint preset | `typescript` | 4.x |
13
+ | Backend / DB | None: no server, no Prisma, no PostgreSQL | — |
14
+
15
+ ## Gates (`templates/stacks/vite/gates.conf`)
16
+
17
+ | Gate | Command |
18
+ | --------- | ------------------------------------------------------------------------------ |
19
+ | setup | none |
20
+ | test | `vitest run` with istanbul (floor: 85% lines, statements, branches, functions) |
21
+ | lint | `eslint . --max-warnings 0` |
22
+ | typecheck | `tsc --noEmit` |
23
+ | build | `vite build` |
24
+ | db | none (no database) |
25
+
26
+ The coverage floor lives in `gates.conf`, not in `vite.config.ts`, so an agent
27
+ cannot lower it.
@@ -0,0 +1,25 @@
1
+ # Testing: Vite static sites
2
+
3
+ Extends the shared `testing.md`.
4
+
5
+ Tooling: Vitest 5 with jsdom, coverage provider istanbul
6
+ (`@vitest/coverage-istanbul`).
7
+
8
+ ## Tiers
9
+
10
+ | Tier | Pattern | Status |
11
+ | ----------- | ------------------------------ | ------------------- |
12
+ | Unit | `src/**/*.test.ts` beside code | in use; `test` gate |
13
+ | Integration | none: there is no backend | not applicable |
14
+ | E2E | none yet | not a harness gate |
15
+
16
+ ## Rules
17
+
18
+ - Unit tests do not touch the network.
19
+ - DOM code is tested through jsdom with accessible queries, not implementation
20
+ details.
21
+
22
+ ## Coverage floor
23
+
24
+ 85% on lines, statements, branches and functions, over every file matching
25
+ `src/**/*.ts` (set in `gates.conf`).
@@ -0,0 +1,31 @@
1
+ # Gate commands for a static Vite + TypeScript site (no database, no server).
2
+ # Sourced by .harness/gates.sh from the repo root. Validated against
3
+ # data-matters-io/play-around-world: vite 8.3.5, typescript 5.9.3, vitest 5.0.5,
4
+ # @vitest/coverage-istanbul 5.0.5, jsdom 30.1.3, @data-matters.io/eslint-config 4.0.0.
5
+
6
+ # Gates call node_modules/.bin directly instead of `pnpm exec`: a gate must never
7
+ # install or mutate anything (same rule as the other stack presets). Dependencies
8
+ # are installed beforehand (`pnpm install --frozen-lockfile`).
9
+ bin="node_modules/.bin"
10
+
11
+ # No setup step: nothing to generate before the gates run.
12
+ GATE_SETUP=""
13
+
14
+ # Coverage floor 85% on every metric, statement-based (istanbul), measured over
15
+ # every source file (standards/testing.md). Kept here, not in vite.config.ts, so
16
+ # an agent cannot lower it. Raise it as coverage grows; never lower it.
17
+ GATE_TEST="$bin/vitest run --coverage.enabled --coverage.provider=istanbul --coverage.include='src/**/*.ts' --coverage.thresholds.lines=85 --coverage.thresholds.statements=85 --coverage.thresholds.branches=85 --coverage.thresholds.functions=85"
18
+ # Read-only and zero warnings (@data-matters.io/eslint-config, typescript preset).
19
+ GATE_LINT="$bin/eslint . --max-warnings 0"
20
+ GATE_TYPECHECK="$bin/tsc --noEmit"
21
+ GATE_BUILD="$bin/vite build"
22
+
23
+ # Formats openspec/ after an archive (the archive output is not formatted).
24
+ FORMAT_SPECS="$bin/prettier --write openspec"
25
+
26
+ # Stop hook runs the fast gates; build runs in the loop and CI.
27
+ STOP_GATES=(lint typecheck test)
28
+
29
+ GATE_EXTRA=(
30
+ # "security:pnpm audit --audit-level high"
31
+ )
@@ -0,0 +1,50 @@
1
+ name: gates
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+
8
+ jobs:
9
+ gates:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ # fetch-depth 2: HEAD is the PR merge commit and HEAD^1 its base, enough
13
+ # to list the files the pull request changes.
14
+ - uses: actions/checkout@v4
15
+ with:
16
+ fetch-depth: 2
17
+
18
+ # Reads the exact pnpm version from package.json#packageManager (ADR 0014).
19
+ # pnpm 12 needs v6.1.0+; the floating @v6 tag is older.
20
+ - uses: pnpm/action-setup@v6.1.0
21
+
22
+ - uses: actions/setup-node@v4
23
+ with:
24
+ node-version: 24
25
+ cache: pnpm
26
+
27
+ - name: Install dependencies
28
+ run: pnpm install --frozen-lockfile
29
+
30
+ # A harness installed from the package (ADR 0021) is generated by the
31
+ # install's "prepare"; a missing or stale one fails here.
32
+ - name: Check the harness
33
+ run: if [[ -x node_modules/.bin/harness ]]; then node_modules/.bin/harness check; fi
34
+
35
+ # After the install: with the package, .harness/ is generated by it.
36
+ # Spec-only PRs (ADR 0011, 0013) validate the specs instead of running the
37
+ # DoD gates; pr-scope.sh also fails a spec/<id> PR that changes anything
38
+ # outside openspec/changes/<id>/. Pushes to main always run the gates.
39
+ - name: Classify pull request
40
+ id: scope
41
+ run: .harness/pr-scope.sh >>"$GITHUB_OUTPUT"
42
+
43
+ # OpenSpec is a pinned devDependency (.harness/openspec.sh).
44
+ - name: Validate OpenSpec changes and specs
45
+ if: steps.scope.outputs.spec_only == 'true'
46
+ run: .harness/openspec.sh validate --all --strict --no-interactive
47
+
48
+ - name: Run DoD gates
49
+ if: steps.scope.outputs.spec_only != 'true'
50
+ run: .harness/gates.sh