Files
zernie__vigiles/CONTRIBUTING.md
T
zernie 3b81e5042b feat: spec-contract hardening + complete spec/railway docs + subagent-trace eval fix (#42)
Spec: context:fork + gated forked-skill output, agent color/disallowedTools, dir()/glob(), didNotWrite(), scaffold-test, section length-guard, migrate->adopt-spec.
Docs: docs/spec-format.md completed + docs/railway-subagents.md + research/spec-syntax-and-railway-scope.md decisions.
Testing harness: parseSubagents recovers --plugin-dir subagent nested-traces (namespaced subagent_type + the sub's returned result() block).
Evals (real-model): caveman debunk hardened on sonnet (-23%/-20%); the does-our-spec-help A/B validated the spec HELPS (parseable outcome 0%->100%, no quality regression).
2026-06-21 03:09:32 +07:00

4.1 KiB

Contributing to vigiles

Thanks for your interest in contributing! This guide covers everything you need to get started.

Prerequisites

  • Node.js 20+
  • npm 10+
  • For full test coverage, you'll also need these linter CLIs on your PATH:
    • ruff and pylint (Python)
    • rubocop (Ruby)
    • cargo with clippy (Rust)

Setup

git clone https://github.com/zernie/vigiles.git
cd vigiles
npm install
npm run build

Project structure

src/
  types.ts          Type definitions (interfaces, type aliases)
  validate.ts       Core validation engine (parsing, config, linter checks)
  action.ts         GitHub Action wrapper (reads env vars, calls validatePaths)
  cli.ts            CLI entry point (arg parsing, output formatting)
  validate.test.ts  Test suite (node:test)
schemas/            Built-in mdschema YAML presets
skills/             Shipped consumer skills (test-harness, adopt-spec, strengthen, edit-spec, linter-docs)
dev/skills/         Internal dev-only skills, NOT shipped (generate-logo, pr-to-lint-rule, enforce-rules-format, audit-feedback-loop)
dist/               Compiled JavaScript output (git-ignored)

Development workflow

Build

npm run build        # Compile TypeScript → dist/

Test

npm test             # Build + run all tests

Tests use Node.js built-in test runner (node:test) and node:assert/strict. No extra test framework needed.

Format

npm run fmt          # Auto-format with Prettier
npm run fmt:check    # Check formatting (CI uses this)

Type check

npx tsc --noEmit     # Type-check without emitting

Run locally

npx vigiles CLAUDE.md                          # Validate a file
npx vigiles --markers=headings,checkboxes .    # Custom markers
npx vigiles                                    # Auto-discover instruction files

TypeScript conventions

This project uses TypeScript strict mode with these compiler options enabled:

  • strict: true (includes strictNullChecks, noImplicitAny, etc.)
  • noUncheckedIndexedAccess: true
  • noUnusedLocals: true
  • noUnusedParameters: true

Guidelines

  • Explicit types on all exported function signatures (parameters and return types).
  • No any — use unknown and narrow with type guards when the type is truly unknown.
  • Import types with import type { ... } when only used in type positions.
  • Use .js extensions in import paths (required by Node16 module resolution).
  • Keep the single-file core architecture — validate.ts contains all validation logic.

Adding a new validation rule

  1. Add the rule name and default value to RulesConfig in src/types.ts.
  2. Add the default to RULE_PACKS in src/validate.ts.
  3. Implement the check inside the validate() function.
  4. Add tests in src/validate.test.ts.
  5. Document the rule in README.md and CLAUDE.md.

Adding a new linter resolver

  1. Add a Node API resolver to LINTER_RESOLVERS (if the linter has a Node API).
  2. Or add a CLI checker to CLI_RULE_CHECKS and map it in CLI_TOOL_FOR_LINTER.
  3. Optionally add a config-enabled checker to LINTER_CONFIG_CHECKERS.
  4. Add tests covering both existing and nonexistent rules.

Pull requests

  • Keep PRs focused — one feature or fix per PR.
  • All tests must pass (npm test).
  • Code must compile without errors (npx tsc --noEmit).
  • Code must be formatted (npm run fmt:check).
  • Update CLAUDE.md if you change exported APIs or add new rules.
  • Write descriptive commit messages explaining why, not just what.

Architecture decisions

  • Single-file core: All validation logic lives in validate.ts for portability and minimal dependency surface.
  • Zero config by default: vigiles works out of the box. Config exists only for overrides.
  • Two rule packs: "recommended" (permissive defaults) and "strict" (tighter constraints).
  • Linter auto-detection: No need to declare which linters you use — vigiles discovers them.
  • Agent auto-discovery: Detects AI coding tools by their config directories and validates their instruction files exist.