Thanks for considering a contribution. snipIT is a single-script PowerShell 7.5+ tool on .NET 9 — the deliverable is SnipIT.ps1. There is no compile step; git clone + pwsh -Sta -File .\SnipIT.ps1 is the install path.
- Functional bugs and feature requests — open a GitHub Issue. Include your Windows + PowerShell + .NET versions and the shortest repro you can produce.
- Security vulnerabilities — do not open a public issue. Use the private channel documented in
SECURITY.md: a GitHub private vulnerability report orak.nitrr13@gmail.comwith[snipIT security]in the subject. Disclosure SLA + scope are listed there.
- Fork and create a topic branch off
main(e.g.feat/window-shadoworfix/dpi-on-mixed-displays). - Make focused, atomic commits in Conventional Commits style (
feat:,fix:,refactor:,chore:,docs:,test:,ci:,perf:). - Sign every commit. Run
scripts/setup-git-signed.shonce per worktree to apply repo-local signing config (SSH / OpenPGP / x509). Branch protection onmainrejects unsigned commits. - Open a PR against
main. Auto-merge fires when CI is green; no human merge button on the happy path.
main is the only protected branch. Direct pushes are blocked; squash-merge is the only allowed merge style; linear history is required.
CI gates every PR on the following — please run them locally before requesting review. Each gate has zero tolerance:
| Gate | Local command | Where it lives |
|---|---|---|
| Headless tests | pwsh -NoProfile -File ./Test-SnipIT.ps1 (84/84 must pass) |
.github/workflows/test.yml |
| Windows AST parse | pwsh -NoProfile -Command "[System.Management.Automation.Language.Parser]::ParseFile((Resolve-Path ./SnipIT.ps1), [ref]\$null, [ref]\$errors)" |
.github/workflows/test.yml |
| PSScriptAnalyzer (PowerShell lint) | pwsh -c "Invoke-ScriptAnalyzer -Path ./SnipIT.ps1 -Severity Error" (0 errors) |
.github/workflows/security.yml |
| Trivy filesystem scan | (CI only) | .github/workflows/security.yml |
Semgrep SAST (p/security-audit, p/owasp-top-ten) |
(CI only) | .github/workflows/security.yml |
| Gitleaks (full git history) | (CI only) | .github/workflows/security.yml |
jscpd duplication < 3% (powershell, --min-tokens 100) |
(CI only) | .github/workflows/security.yml |
| SBOM (SPDX + CycloneDX) | (CI only — surface only) | .github/workflows/security.yml |
The full quality bar — quality gates, code style, branch/commit/PR rules, security tooling, performance targets — is codified in shared/runbooks/engineering-standards.md, the PowerShell variant of the company-canonical runbook. Treat that file as the single source of truth for what is acceptable in this repo. The most load-bearing rules:
- PowerShell 7.5+ only. No PS5.1 fallbacks, no
Add-Typeshims that only compile on Windows PowerShell. - Functions:
Verb-NounPascalCase, approved verbs,[CmdletBinding()]+param()for any function with > 1 parameter. - Pure-logic functions go in the
Coreregion ofSnipIT.ps1so the headless test suite picks them up via-CoreOnly. - Preview-window event handlers are one-line wrappers around named closures captured at window-creation time (e.g.
$beginPan,$pickColor,$handleMouseDown) — keeps the test harness able to drive every code path through the closures via-TestAction. - Tests are zero-dependency (no Pester). Follow the assertion pattern in
Test-SnipIT.ps1. - Single-file deliverable is a headline product feature. Do not propose splitting
SnipIT.ps1into modules without an explicit board reversal.
- Windows 11 + PowerShell 7.5+ for full interactive testing (
Test-SnipIT-Interactive.ps1). - Any pwsh 7.5+ host (Linux / macOS work) for headless tests.
- A signed-commit setup.
scripts/setup-git-signed.shdoes the repo-local config; the script auto-detects ssh / openpgp / x509 from your global git config.
A PR lands when:
- All CI gates above are green (the protection rule on
mainenforces eight required check contexts). - Codex / TechLead review pass shows no HIGH-severity findings.
- The squash commit is signed (GitHub web-flow signing handles this automatically on merge).
For larger changes (new region in SnipIT.ps1, new top-level function group, new workflow file), open a brief proposal as a GitHub Issue first so we can align on shape before you sink hours into the PR.
- Update
CHANGELOG.md[Unreleased]section with an entry under Added / Changed / Fixed / Security as appropriate. - If your PR changes how to build/test/run, conventions, gotchas, or introduces a new dependency, also update
CLAUDE.md. It is the agent / contributor brief read at session start. - Long-form docs go under
docs/.
Thanks again — the project is small, the test suite is fast, and your PR will get a reply quickly.