secure-repo 1.0.9 → 1.2.0

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/bin/cli.js CHANGED
@@ -21,6 +21,7 @@ const RECOMMENDED_FILES = [
21
21
  { file: "SECURITY.md", category: "security", severity: "high" },
22
22
  { file: "AUTH.md", category: "security", severity: "high" },
23
23
  { file: "API.md", category: "security", severity: "high" },
24
+ { file: "ACCESSIBILITY.md", category: "accessibility", severity: "medium" },
24
25
  { file: "DATABASE.md", category: "security", severity: "medium" },
25
26
  { file: "DEPLOYMENT.md", category: "operations", severity: "medium" },
26
27
  { file: "INCIDENT_RESPONSE.md", category: "operations", severity: "medium" },
@@ -56,9 +57,10 @@ function printHelp() {
56
57
  --output Output directory (default: current directory)
57
58
 
58
59
  Free templates (always included):
59
- SECURITY.md Secrets management, attack surface, enforced architecture
60
- AUTH.md Token handling, session rules, password policy, roles
61
- API.md Input validation, rate limiting, error handling
60
+ SECURITY.md Secrets management, attack surface, enforced architecture
61
+ AUTH.md Token handling, session rules, password policy, roles
62
+ API.md Input validation, rate limiting, error handling
63
+ ACCESSIBILITY.md WCAG compliance, semantic HTML, keyboard nav, screen readers
62
64
 
63
65
  Pro templates (purchase at https://buy.polar.sh/polar_cl_q7Wa3Gcng42437OoTx4wHVNyMMyYv0WbtobUv145EZH):
64
66
  30 additional files — templates, audit checklist, stack presets, examples
@@ -273,6 +275,88 @@ function installFromZip(zipPath, outputDir, force) {
273
275
  }
274
276
  }
275
277
 
278
+ // ============================================================
279
+ // Agent instruction files — tell AI agents to read policy files
280
+ // ============================================================
281
+ const AGENT_INSTRUCTION = `# Security Policies — MUST READ
282
+
283
+ This project uses ShipSecure security policies. Before writing or modifying code, you MUST read and follow every policy file that exists in this repository.
284
+
285
+ ## Policy Files
286
+
287
+ Read each of these files if they exist before making changes:
288
+
289
+ ### Core
290
+ - SECURITY.md — Secrets management, attack surface, enforced architecture
291
+ - AUTH.md — Token handling, session rules, password policy, roles
292
+ - API.md — Input validation, rate limiting, error handling
293
+ - ACCESSIBILITY.md — WCAG compliance, semantic HTML, keyboard navigation, screen readers
294
+
295
+ ### Extended
296
+ - DATABASE.md — Query safety, access control, migrations
297
+ - ENV_VARIABLES.md — Environment variable handling, secret rotation
298
+ - DEPLOYMENT.md — Deploy pipeline, environment isolation
299
+ - INCIDENT_RESPONSE.md — Breach response, escalation procedures
300
+ - ACCESS_CONTROL.md — Role-based access, permission boundaries
301
+ - DATA_PRIVACY.md — PII handling, data retention, GDPR compliance
302
+ - PAYMENTS.md — Payment processing, PCI compliance
303
+ - FILE_UPLOADS.md — Upload validation, storage security
304
+ - RATE_LIMITING.md — Throttling, abuse prevention
305
+ - THIRD_PARTY.md — Dependency security, vendor risk
306
+ - LOGGING_PII.md — Log sanitization, PII redaction
307
+ - TESTING.md — Security test requirements
308
+ - OBSERVABILITY.md — Monitoring, alerting, audit trails
309
+ - THREAT_MODEL.md — Known threats and mitigations
310
+ - PR_CHECKLIST.md — Pre-merge security checklist
311
+ - CONTRIBUTING_SECURITY.md — Security contribution guidelines
312
+ - VULNERABILITY_REPORTING.md — Responsible disclosure process
313
+ - POLICY_INDEX.md — Index of all policies
314
+ - FULL_AUDIT_CHECKLIST.md — 100+ point security audit checklist
315
+
316
+ ### Stack Presets
317
+ - supabase-preset/ — Supabase-specific security rules (if present)
318
+ - firebase-preset/ — Firebase-specific security rules (if present)
319
+
320
+ ## Rules
321
+
322
+ 1. Always check policy files before writing code — if your task touches auth, APIs, database, payments, file uploads, or any area with a policy file, read that file first.
323
+ 2. Never violate a policy — if a policy says "never do X", do not do X. Flag it if unsure.
324
+ 3. Secrets are never hardcoded — no API keys, tokens, passwords, or credentials in source code.
325
+ 4. Validate all input — every endpoint, every form, every external data source.
326
+ 5. Follow the principle of least privilege — only request the permissions you need.
327
+ `;
328
+
329
+ function writeAgentFiles(outputDir, force) {
330
+ const agentFiles = [
331
+ { path: "CLAUDE.md", name: "Claude" },
332
+ { path: ".cursorrules", name: "Cursor" },
333
+ { path: ".github/copilot-instructions.md", name: "GitHub Copilot" },
334
+ { path: ".windsurfrules", name: "Windsurf" },
335
+ { path: ".clinerules", name: "Cline" },
336
+ ];
337
+
338
+ let written = 0;
339
+ let skipped = 0;
340
+
341
+ console.log("\n Agent instructions:");
342
+ agentFiles.forEach(({ path: filePath, name }) => {
343
+ const fullPath = path.join(outputDir, filePath);
344
+ const dir = path.dirname(fullPath);
345
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
346
+
347
+ if (fs.existsSync(fullPath) && !force) {
348
+ console.log(` [skip] ${filePath} (${name}) — use --force to overwrite`);
349
+ skipped++;
350
+ } else {
351
+ fs.writeFileSync(fullPath, AGENT_INSTRUCTION);
352
+ console.log(` [done] ${filePath} (${name})`);
353
+ written++;
354
+ }
355
+ });
356
+
357
+ return { written, skipped };
358
+ }
359
+
276
360
  // ============================================================
277
361
  // INIT — install templates (free, or free + pro with --key)
278
362
  // ============================================================
@@ -307,8 +391,11 @@ async function init() {
307
391
  await downloadProZip(zipPath, licenseKey);
308
392
  const proResult = installFromZip(zipPath, outputDir, force);
309
393
 
310
- const totalCopied = freeResult.copied + proResult.copied;
311
- const totalSkipped = freeResult.skipped + proResult.skipped;
394
+ // Write agent instruction files
395
+ const agentResult = writeAgentFiles(outputDir, force);
396
+
397
+ const totalCopied = freeResult.copied + proResult.copied + agentResult.written;
398
+ const totalSkipped = freeResult.skipped + proResult.skipped + agentResult.skipped;
312
399
 
313
400
  console.log(`\n Done! ${totalCopied} files installed, ${totalSkipped} skipped.`);
314
401
  console.log("\n Next steps:");
@@ -330,7 +417,13 @@ async function init() {
330
417
  console.log(" Free templates:");
331
418
  const result = copyFiles(FREE_DIR, outputDir, force);
332
419
 
333
- console.log(`\n Done! ${result.copied} files added, ${result.skipped} skipped.`);
420
+ // Write agent instruction files
421
+ const agentResult = writeAgentFiles(outputDir, force);
422
+
423
+ const totalCopied = result.copied + agentResult.written;
424
+ const totalSkipped = result.skipped + agentResult.skipped;
425
+
426
+ console.log(`\n Done! ${totalCopied} files added, ${totalSkipped} skipped.`);
334
427
  console.log("\n Next steps:");
335
428
  console.log(" 1. Customize the templates for your project");
336
429
  console.log(" 2. Run: npx secure-repo audit");
@@ -374,9 +467,10 @@ function importPack() {
374
467
 
375
468
  try {
376
469
  const proResult = installFromZip(resolvedPath, outputDir, force);
470
+ const agentResult = writeAgentFiles(outputDir, force);
377
471
 
378
- const totalCopied = freeResult.copied + proResult.copied;
379
- const totalSkipped = freeResult.skipped + proResult.skipped;
472
+ const totalCopied = freeResult.copied + proResult.copied + agentResult.written;
473
+ const totalSkipped = freeResult.skipped + proResult.skipped + agentResult.skipped;
380
474
 
381
475
  console.log(`\n Done! ${totalCopied} files imported, ${totalSkipped} skipped.\n`);
382
476
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "secure-repo",
3
- "version": "1.0.9",
3
+ "version": "1.2.0",
4
4
  "description": "Drop production-grade security standards into any repo. Audit your repo for security issues. Templates for AI-assisted development.",
5
5
  "bin": {
6
6
  "secure-repo": "./bin/cli.js"
@@ -0,0 +1,99 @@
1
+ # Accessibility Policy
2
+
3
+ This repository must meet WCAG 2.1 Level AA standards. Treat accessibility requirements as **non-optional**.
4
+
5
+ ## Agent Rules (MUST FOLLOW)
6
+
7
+ - **Semantic HTML first**
8
+ - Use `<button>` for actions, `<a>` for navigation, `<nav>`, `<main>`, `<header>`, `<footer>`, `<section>`, `<article>` for structure.
9
+ - Never use `<div>` or `<span>` for interactive elements. If it's clickable, it must be a `<button>` or `<a>`.
10
+ - Use heading hierarchy (`h1` > `h2` > `h3`) — never skip levels.
11
+
12
+ - **All images must have alt text**
13
+ - Informative images: describe the content (`alt="Bar chart showing 40% growth in Q3"`).
14
+ - Decorative images: use empty alt (`alt=""`) or CSS background.
15
+ - Never use `alt="image"`, `alt="photo"`, or `alt="icon"`.
16
+
17
+ - **All form inputs must have labels**
18
+ - Use `<label htmlFor="id">` or `aria-label` / `aria-labelledby`.
19
+ - Never use placeholder text as the only label.
20
+ - Error messages must be associated with their input via `aria-describedby`.
21
+
22
+ - **Keyboard navigation is mandatory**
23
+ - Every interactive element must be reachable and operable with keyboard only (Tab, Enter, Escape, Arrow keys).
24
+ - Focus order must follow visual reading order.
25
+ - Never remove `:focus` or `:focus-visible` outlines without providing a visible alternative.
26
+ - Modal dialogs must trap focus and return focus on close.
27
+
28
+ - **Color is never the only indicator**
29
+ - Error states, status indicators, and required fields must use text, icons, or patterns in addition to color.
30
+ - Maintain minimum contrast ratios:
31
+ - Normal text: 4.5:1 against background.
32
+ - Large text (18px+ bold or 24px+): 3:1 against background.
33
+ - UI components and icons: 3:1 against adjacent colors.
34
+
35
+ - **Font sizes and readability**
36
+ - Minimum body text: 16px (1rem). Never go below 14px for any readable text.
37
+ - Use relative units (`rem`, `em`) not fixed `px` for font sizes — allows user browser zoom and font size preferences.
38
+ - Line height: minimum 1.5 for body text, 1.2 for headings.
39
+ - Paragraph max-width: 65–75 characters for comfortable reading.
40
+ - Never disable user text scaling — do not set `maximum-scale=1` in viewport meta.
41
+ - Touch targets: minimum 44x44px for buttons and links on mobile.
42
+
43
+ - **ARIA usage**
44
+ - Prefer native HTML elements over ARIA. ARIA is a last resort, not a first choice.
45
+ - If you use ARIA: `aria-label`, `aria-labelledby`, `aria-describedby`, `aria-live`, `aria-expanded`, `aria-hidden`.
46
+ - Never use `aria-hidden="true"` on focusable elements.
47
+ - Dynamic content updates must use `aria-live="polite"` or `aria-live="assertive"`.
48
+
49
+ - **Motion and animation**
50
+ - Respect `prefers-reduced-motion`. Wrap animations in `@media (prefers-reduced-motion: no-preference)`.
51
+ - Never auto-play video or audio without user consent.
52
+ - Avoid flashing content (no more than 3 flashes per second).
53
+
54
+ ## Required Checks Before Merge
55
+
56
+ - **Keyboard test**
57
+ - Tab through every interactive element on the page.
58
+ - Verify focus is visible, logical, and never trapped (except in modals).
59
+
60
+ - **Screen reader test**
61
+ - Headings, landmarks, form labels, and alt text must be announced correctly.
62
+ - Dynamic updates (toasts, errors, loading states) must be announced via `aria-live`.
63
+
64
+ - **Color contrast check**
65
+ - Run a contrast checker on all text and interactive elements.
66
+ - Verify no information is conveyed by color alone.
67
+
68
+ - **Zoom test**
69
+ - Page must be usable at 200% browser zoom with no content loss or overlap.
70
+
71
+ ## Patterns To Use
72
+
73
+ - **Skip navigation link**
74
+ - Add a "Skip to main content" link as the first focusable element.
75
+ - `<a href="#main" className="sr-only focus:not-sr-only">Skip to main content</a>`
76
+
77
+ - **Loading states**
78
+ - Use `aria-busy="true"` on containers that are loading.
79
+ - Announce completion with `aria-live="polite"`.
80
+
81
+ - **Error handling in forms**
82
+ - Show error summary at the top of the form.
83
+ - Link each error to its field with `aria-describedby`.
84
+ - Move focus to the first error field or the error summary.
85
+
86
+ - **Icon buttons**
87
+ - Every icon-only button must have `aria-label`.
88
+ - Example: `<button aria-label="Close dialog"><XIcon /></button>`
89
+
90
+ - **Tables**
91
+ - Use `<th scope="col">` for column headers and `<th scope="row">` for row headers.
92
+ - Use `<caption>` to describe the table's purpose.
93
+
94
+ ## Testing Tools
95
+
96
+ - axe DevTools (browser extension)
97
+ - Lighthouse accessibility audit
98
+ - VoiceOver (macOS) / NVDA (Windows) for screen reader testing
99
+ - `prefers-reduced-motion` emulation in DevTools