Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .dependency-cruiser.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Owners and constraints for this repository's actual runtime roots.
module.exports = {
forbidden: [
{
name: 'no-runtime-cycles',
severity: 'error',
from: {},
to: {
circular: true,
dependencyTypesNot: ['type-only'],
},
},
{
name: 'no-unresolved-dependencies',
severity: 'error',
from: {},
to: {
couldNotResolve: true,
},
},
{
name: 'no-runtime-test-dependencies',
severity: 'error',
from: {
path: '^(?:src)/',
pathNot: '(?:__tests__|test|tests)/|\\.(?:test|spec)\\.',
},
to: {
path: '(?:^|/)(?:__tests__|tests|test)/|(?:^|node_modules/)(?:jest|vitest|ts-jest)',
},
},
],
options: {
doNotFollow: {
path: 'node_modules',
},
tsConfig: {
fileName: 'tsconfig.quality.json',
},
tsPreCompilationDeps: true,
enhancedResolveOptions: {
exportsFields: ['exports'],
conditionNames: ['types', 'require', 'node', 'default'],
extensions: ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.tsx', '.mts', '.cts', '.json'],
},
exclude: '(?:^|/)node_modules/',
},
};
72 changes: 72 additions & 0 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Quality
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
concurrency:
group: quality-${{ github.ref }}
cancel-in-progress: true
jobs:
checks:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: '24.19.0'
- run: npm ci
- run: npm --prefix tools/quality ci
- run: npm run test:preset
- run: npm run quality:guards
- run: npm run format:check
- run: npm run lint:static
- run: npm run lint:typed
- run: npm run typecheck
- run: npm run lint:arch
- run: npm run lint:unused:production
- run: npm run lint:unused:full
- run: npm run lint:duplicates
- run: npm run lint:duplicates:full
- run: npm run lint:complexity
- run: npm run test:quality
- run: npm test
- run: npm run build
- run: npm run test:pack
- uses: actions/upload-artifact@v4
if: always()
with:
name: quality-reports
path: quality/reports/
if-no-files-found: error
package-consumer:
runs-on: ubuntu-24.04
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
node: ['18', '20', '22', '24']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '24.19.0'
- run: npm ci --ignore-scripts
- run: npm run build
- name: Pack the actual distributable
run: mkdir -p "$RUNNER_TEMP/packed" && npm pack --ignore-scripts --pack-destination "$RUNNER_TEMP/packed"
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: bash scripts/consumer-smoke.sh "$RUNNER_TEMP"/packed/*.tgz '@1msg/cli'
quality-required:
if: always()
needs: [checks, package-consumer]
runs-on: ubuntu-24.04
steps:
- env:
RESULTS: ${{ toJSON(needs) }}
run: node -e 'const jobs=JSON.parse(process.env.RESULTS); if(!Object.values(jobs).every(job=>job.result==="success")) process.exit(1)'
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,10 @@ coverage/
.env.*
!.env.example
npm-debug.log*

quality/reports/

.husky/_/

# Local shared-tool dependency links are never repository content.
tools/quality/node_modules
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node tools/quality/node_modules/lint-staged/bin/lint-staged.js
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24.19.0
9 changes: 9 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
node_modules
dist
tools/quality
quality/reports


# Byte-pinned producer inputs; integrity is checked by the contract tests.
quality/contracts/openapi.yaml
quality/contracts/CLI.md
5 changes: 5 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100
}
15 changes: 15 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Quality and ownership

Profile A, Node 24.19.0. SDK/tooling maintainers own this repository. The public package entrypoints are defined in package.json; framework registration and executable consumers must remain intact. Imports must be acyclic at runtime, production cannot import tests, and dependency boundaries are enforced in `.dependency-cruiser.cjs`. `quality.config.mjs` is the source inventory and exact generated-path declaration.

Configuration belongs in the existing config/bootstrap adapters; pure conversion/validation helpers must not gain transport or environment reads. SDK and HTTP calls belong in the existing transport/client adapters. Keep complete scenarios readable at their application entrypoints; avoid pass-through facade layers. Comments on new/changed functions describe purpose, inputs/results, invariants and relevant failure/resource ownership. Check comments against behavior rather than repeating the function name.

Install with the frozen lockfile, then `npm --prefix tools/quality ci`. Run `npm run hooks:install` for local Husky/lint-staged feedback. Run all commands listed in `.github/workflows/quality.yml` before review: formatter, static and typed ESLint, strict production/test typecheck, dependency-cruiser, both Knip graphs, jscpd runtime gate and full report, complexity, guard negative fixtures, tests, build and packed-entrypoint smoke. No CI skip variable disables typed lint.

Historical debt is recorded per finding in `quality/baselines`, with adoption SHA, evidence, owner, issue and expiry. Initial allowances are replayed against the default branch; new findings and increases are forbidden. Remove entries when fixed. Generated paths have producer provenance; authored tooling is always checked.

The `quality-required` job fails on failed/skipped/cancelled prerequisites. Configure branch protection to require it; YAML alone does not change server protection. Tests use isolated/local inputs; never point them at production services.

Standalone contract tests use the byte-pinned public API and CLI RFC in `quality/contracts`. Their provenance records the producer commit and checksums. Missing or edited inputs fail; they never skip based on checkout layout. Update the input snapshots deliberately from a reviewed producer commit, retaining full operation coverage and help assertions. These checks compare the pinned contract, not the latest remote API.

Knip classifies `src/__tests__` as a test graph input and retains it in the full graph. The obsolete production allowance for the test-only `helpers.ts` was removed; runtime modules used only by a test remain production findings, as the real Knip fixture verifies.
Loading
Loading