diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..9722037 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,65 @@ +name: Bug report +description: Something broke or behaved unexpectedly +labels: [bug] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to report. Most bugs reproduce from a one-line zone snippet — please include one. + + - type: textarea + id: what-happened + attributes: + label: What happened? + description: A clear, concise description of the bug + placeholder: When I import a zone with X, the parser does Y instead of Z. + validations: + required: true + + - type: textarea + id: zone-snippet + attributes: + label: Zone snippet (if applicable) + description: Minimal zone-file lines that reproduce the bug. Strip anything sensitive. + render: text + placeholder: | + $ORIGIN example.com. + $TTL 300 + @ IN SOA ns.example.com. admin.example.com. (1 1H 1H 1W 1H) + ... + validations: + required: false + + - type: textarea + id: expected + attributes: + label: What did you expect? + placeholder: I expected the parser to keep the embedded ; in the TXT value. + validations: + required: true + + - type: input + id: where + attributes: + label: Where did this happen? + description: Editor, propagation check, email-health card, DMARC ramp, export, … + placeholder: Parser / import flow + validations: + required: true + + - type: input + id: browser + attributes: + label: Browser & version + placeholder: Chrome 130 on Windows 11 + validations: + required: false + + - type: textarea + id: console + attributes: + label: Console errors (if any) + description: Open DevTools → Console; paste anything red. + render: text + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..c4b724f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Question or discussion + url: https://github.com/codarn/codabind/discussions + about: For questions, ideas, or open-ended conversations — not bug reports. + - name: Security report + url: https://github.com/codarn/codabind/security/advisories/new + about: Report a security issue privately via GitHub Security Advisories. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..25b13f3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,45 @@ +name: Feature request +description: Suggest a new capability or an improvement +labels: [enhancement] +body: + - type: markdown + attributes: + value: | + Codabind aims to stay narrow: a browser-only zone editor with live propagation and email-deliverability linting. Features that fit that scope land easily; features that pull in a backend, signups, analytics, or telemetry won't. + + - type: textarea + id: problem + attributes: + label: What problem are you trying to solve? + description: Describe the situation that's painful today, not the feature. + placeholder: I publish DKIM keys via three providers and have no quick way to see which selector belongs to which. + validations: + required: true + + - type: textarea + id: proposal + attributes: + label: Proposed solution + description: Sketch what you'd build. Mockups, snippets, anything. + validations: + required: false + + - type: textarea + id: alternatives + attributes: + label: Alternatives you considered + placeholder: Could be solved by … but that has tradeoff … + validations: + required: false + + - type: dropdown + id: scope + attributes: + label: Does this fit the self-operating philosophy? + options: + - Yes — pure-browser, no new outbound traffic + - Yes — adds a DoH-style call to a public, allowlisted endpoint + - I'm not sure + - No — but I think it's worth the trade-off (please explain below) + validations: + required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..920d385 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,21 @@ +## Summary + + + +## Test plan + + +- [ ] `npm test` passes +- [ ] `npm run build` succeeds + +## Screenshots / before & after + + + +## Checklist + +- [ ] Tests added or updated for new logic +- [ ] No new runtime dependencies (or, if added, justified above) +- [ ] No analytics / trackers / external embeds introduced +- [ ] CSP `connect-src` updated explicitly if a new origin is needed +- [ ] Touched files follow existing style (no `as any`, no `@ts-ignore`) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..fb6945d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,57 @@ +# Contributing to Codabind + +Thanks for being interested. Codabind is a small, deliberately self-contained project — short PRs are easier to review and merge. + +## Before you start + +- For **bug fixes**, just open a PR — issues are nice but not required. +- For **new features or larger refactors**, open an issue first so we can confirm fit before you spend time. The project is intentionally narrow (browser-only zone editor with live propagation checks). Adding scope creep — server-side parts, signups, analytics, telemetry — won't land. + +## Dev setup + +```bash +git clone https://github.com/codarn/codabind.git +cd codabind +npm install +npm run dev # http://localhost:5173 +``` + +Other useful scripts are in [the README](./README.md#common-scripts). + +## Workflow + +1. Branch from `main` — `feat/short-name`, `fix/what-broke`, or `chore/cleanup-thing` +2. Make your change, add or update tests +3. Run locally: `npm test && npm run build` +4. Push and open a PR — the CI workflow runs the same commands +5. Squash-merge once green; main is protected and direct pushes are blocked + +## What we expect in a PR + +- **Tests for new logic.** Pure modules in `src/zone/`, `src/dns/`, and `src/email/` have mirrored test files in `tests/`. Components are thin and don't have component tests today; if you add non-trivial UI logic, consider extracting it into a hook or selector that can be tested in isolation. +- **No new runtime dependencies** without a clear reason. The whole runtime today is `react` + `react-dom`. Dev tools are unconstrained. +- **No analytics / trackers / external embeds.** This is a self-operating tool — only DoH resolver calls and one GitHub stars fetch leave the browser. +- **Keep CSP strict.** If you need a new origin, add it to `vite.config.ts`'s `connect-src` allowlist explicitly. No wildcards. + +## Code style + +There is no ESLint config yet (might add one later). Until then: + +- TypeScript `strict: true` and `noUncheckedIndexedAccess: true` are on — respect them, no `as any`, no `// @ts-ignore`. +- Match the surrounding style — 2-space indent, double-quoted strings, trailing commas, named exports. +- Keep components focused. If a file passes ~250 lines, it usually wants splitting. +- Domain logic (parsing, validating, diffing, linting) lives outside React. Components are presentation; hooks bridge them. + +## Commit messages + +Free-form, but explain the **why**, not just the what — the diff already shows what. +Good: `Parser: rescue unquoted TXT from registrar exports` +Less good: `Update parser` + +## Reporting bugs + +Use the [Bug report](https://github.com/codarn/codabind/issues/new?template=bug_report.yml) template. Include the zone snippet that triggered it (with anything sensitive removed) — most parser bugs reproduce from a one-line example. + +## License + +By contributing, you agree your changes are released under the project's [MIT license](./LICENSE).