@torus-engineering/tas-kit 1.5.1 → 1.6.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.
Files changed (110) hide show
  1. package/.claude/agents/README.md +83 -0
  2. package/.claude/agents/architect.md +53 -0
  3. package/.claude/agents/aws-reviewer.md +71 -0
  4. package/.claude/agents/build-resolver.md +59 -0
  5. package/.claude/agents/code-architect.md +62 -0
  6. package/.claude/agents/code-explorer.md +63 -0
  7. package/.claude/agents/code-simplifier.md +53 -0
  8. package/.claude/agents/comment-analyzer.md +59 -0
  9. package/.claude/agents/conversation-analyzer.md +57 -0
  10. package/.claude/agents/csharp-reviewer.md +62 -0
  11. package/.claude/agents/database-reviewer.md +73 -0
  12. package/.claude/agents/doc-updater.md +66 -0
  13. package/.claude/agents/docs-lookup.md +55 -0
  14. package/.claude/agents/e2e-runner.md +61 -0
  15. package/.claude/agents/harness-optimizer.md +62 -0
  16. package/.claude/agents/loop-operator.md +56 -0
  17. package/.claude/agents/performance-optimizer.md +78 -0
  18. package/.claude/agents/planner.md +82 -0
  19. package/.claude/agents/pr-test-analyzer.md +68 -0
  20. package/.claude/agents/python-reviewer.md +67 -0
  21. package/.claude/agents/pytorch-build-resolver.md +76 -0
  22. package/.claude/agents/refactor-cleaner.md +70 -0
  23. package/.claude/agents/security-reviewer.md +79 -0
  24. package/.claude/agents/seo-specialist.md +75 -0
  25. package/.claude/agents/silent-failure-hunter.md +69 -0
  26. package/.claude/agents/tdd-guide.md +84 -0
  27. package/.claude/agents/type-design-analyzer.md +75 -0
  28. package/.claude/agents/typescript-reviewer.md +65 -0
  29. package/.claude/commands/ado-create.md +2 -1
  30. package/.claude/commands/ado-delete.md +3 -2
  31. package/.claude/commands/ado-get.md +2 -1
  32. package/.claude/commands/ado-status.md +2 -1
  33. package/.claude/commands/ado-update.md +2 -1
  34. package/.claude/commands/tas-adr.md +13 -12
  35. package/.claude/commands/tas-bug.md +97 -50
  36. package/.claude/commands/tas-design.md +3 -1
  37. package/.claude/commands/tas-dev.md +115 -0
  38. package/.claude/commands/tas-epic.md +4 -2
  39. package/.claude/commands/tas-feature.md +5 -3
  40. package/.claude/commands/tas-fix.md +47 -0
  41. package/.claude/commands/tas-plan.md +184 -0
  42. package/.claude/commands/tas-prd.md +3 -1
  43. package/.claude/commands/tas-review.md +104 -0
  44. package/.claude/commands/tas-sad.md +3 -1
  45. package/.claude/commands/tas-security.md +80 -0
  46. package/.claude/commands/tas-spec.md +50 -0
  47. package/.claude/commands/tas-story.md +77 -40
  48. package/.claude/commands/tas-verify.md +8 -0
  49. package/.claude/hooks/code-quality.js +127 -0
  50. package/.claude/hooks/session-end.js +116 -0
  51. package/.claude/rules/.gitkeep +0 -0
  52. package/.claude/rules/common/agents.md +65 -0
  53. package/.claude/rules/common/code-review.md +124 -0
  54. package/.claude/rules/common/coding-style.md +90 -0
  55. package/.claude/rules/common/development-workflow.md +44 -0
  56. package/.claude/rules/common/git-workflow.md +24 -0
  57. package/.claude/rules/common/hooks.md +30 -0
  58. package/.claude/rules/common/patterns.md +31 -0
  59. package/.claude/rules/common/performance.md +55 -0
  60. package/.claude/rules/common/post-review-agent.md +39 -0
  61. package/.claude/rules/common/project-status.md +80 -0
  62. package/.claude/rules/common/security.md +29 -0
  63. package/.claude/rules/common/stack-detection.md +29 -0
  64. package/.claude/rules/common/testing.md +57 -0
  65. package/.claude/rules/csharp/coding-style.md +72 -0
  66. package/.claude/rules/csharp/hooks.md +25 -0
  67. package/.claude/rules/csharp/patterns.md +50 -0
  68. package/.claude/rules/csharp/security.md +58 -0
  69. package/.claude/rules/csharp/testing.md +46 -0
  70. package/.claude/rules/python/coding-style.md +42 -0
  71. package/.claude/rules/python/hooks.md +19 -0
  72. package/.claude/rules/python/patterns.md +39 -0
  73. package/.claude/rules/python/security.md +30 -0
  74. package/.claude/rules/python/testing.md +38 -0
  75. package/.claude/rules/typescript/coding-style.md +199 -0
  76. package/.claude/rules/typescript/hooks.md +22 -0
  77. package/.claude/rules/typescript/patterns.md +52 -0
  78. package/.claude/rules/typescript/security.md +28 -0
  79. package/.claude/rules/typescript/testing.md +18 -0
  80. package/.claude/rules/web/coding-style.md +96 -0
  81. package/.claude/rules/web/design-quality.md +63 -0
  82. package/.claude/rules/web/hooks.md +120 -0
  83. package/.claude/rules/web/patterns.md +79 -0
  84. package/.claude/rules/web/performance.md +64 -0
  85. package/.claude/rules/web/security.md +57 -0
  86. package/.claude/rules/web/testing.md +55 -0
  87. package/.claude/settings.json +37 -0
  88. package/.claude/settings.local.json +38 -0
  89. package/.claude/skills/ado-integration/SKILL.md +44 -1
  90. package/.claude/skills/agent-harness-construction/SKILL.md +77 -0
  91. package/.claude/skills/agent-introspection-debugging/SKILL.md +157 -0
  92. package/.claude/skills/ai-regression-testing/SKILL.md +364 -0
  93. package/.claude/skills/api-design/SKILL.md +528 -0
  94. package/.claude/skills/architecture-decision-records/SKILL.md +184 -0
  95. package/.claude/skills/backend-patterns/SKILL.md +602 -0
  96. package/.claude/skills/benchmark/SKILL.md +98 -0
  97. package/.claude/skills/browser-qa/SKILL.md +92 -0
  98. package/.claude/skills/canary-watch/SKILL.md +104 -0
  99. package/.claude/skills/tas-conventions/SKILL.md +51 -3
  100. package/.claude/skills/tas-implementation-complete/SKILL.md +97 -0
  101. package/.claude/skills/tas-tdd/SKILL.md +72 -16
  102. package/.tas/README.md +29 -24
  103. package/.tas/tas-example.yaml +2 -1
  104. package/.tas/templates/Story.md +18 -18
  105. package/CLAUDE-Example.md +1 -1
  106. package/README.md +20 -5
  107. package/package.json +1 -1
  108. package/.claude/commands/tas-dev-story.md +0 -61
  109. package/.claude/commands/tas-review-code.md +0 -42
  110. package/.claude/commands/tas-security-check.md +0 -30
@@ -0,0 +1,52 @@
1
+ ---
2
+ paths:
3
+ - "**/*.ts"
4
+ - "**/*.tsx"
5
+ - "**/*.js"
6
+ - "**/*.jsx"
7
+ ---
8
+ # TypeScript/JavaScript Patterns
9
+
10
+ > This file extends [common/patterns.md](../common/patterns.md) with TypeScript/JavaScript specific content.
11
+
12
+ ## API Response Format
13
+
14
+ ```typescript
15
+ interface ApiResponse<T> {
16
+ success: boolean
17
+ data?: T
18
+ error?: string
19
+ meta?: {
20
+ total: number
21
+ page: number
22
+ limit: number
23
+ }
24
+ }
25
+ ```
26
+
27
+ ## Custom Hooks Pattern
28
+
29
+ ```typescript
30
+ export function useDebounce<T>(value: T, delay: number): T {
31
+ const [debouncedValue, setDebouncedValue] = useState<T>(value)
32
+
33
+ useEffect(() => {
34
+ const handler = setTimeout(() => setDebouncedValue(value), delay)
35
+ return () => clearTimeout(handler)
36
+ }, [value, delay])
37
+
38
+ return debouncedValue
39
+ }
40
+ ```
41
+
42
+ ## Repository Pattern
43
+
44
+ ```typescript
45
+ interface Repository<T> {
46
+ findAll(filters?: Filters): Promise<T[]>
47
+ findById(id: string): Promise<T | null>
48
+ create(data: CreateDto): Promise<T>
49
+ update(id: string, data: UpdateDto): Promise<T>
50
+ delete(id: string): Promise<void>
51
+ }
52
+ ```
@@ -0,0 +1,28 @@
1
+ ---
2
+ paths:
3
+ - "**/*.ts"
4
+ - "**/*.tsx"
5
+ - "**/*.js"
6
+ - "**/*.jsx"
7
+ ---
8
+ # TypeScript/JavaScript Security
9
+
10
+ > This file extends [common/security.md](../common/security.md) with TypeScript/JavaScript specific content.
11
+
12
+ ## Secret Management
13
+
14
+ ```typescript
15
+ // NEVER: Hardcoded secrets
16
+ const apiKey = "sk-proj-xxxxx"
17
+
18
+ // ALWAYS: Environment variables
19
+ const apiKey = process.env.OPENAI_API_KEY
20
+
21
+ if (!apiKey) {
22
+ throw new Error('OPENAI_API_KEY not configured')
23
+ }
24
+ ```
25
+
26
+ ## Agent Support
27
+
28
+ - Use **security-reviewer** skill for comprehensive security audits
@@ -0,0 +1,18 @@
1
+ ---
2
+ paths:
3
+ - "**/*.ts"
4
+ - "**/*.tsx"
5
+ - "**/*.js"
6
+ - "**/*.jsx"
7
+ ---
8
+ # TypeScript/JavaScript Testing
9
+
10
+ > This file extends [common/testing.md](../common/testing.md) with TypeScript/JavaScript specific content.
11
+
12
+ ## E2E Testing
13
+
14
+ Use **Playwright** as the E2E testing framework for critical user flows.
15
+
16
+ ## Agent Support
17
+
18
+ - **e2e-runner** - Playwright E2E testing specialist
@@ -0,0 +1,96 @@
1
+ > This file extends [common/coding-style.md](../common/coding-style.md) with web-specific frontend content.
2
+
3
+ # Web Coding Style
4
+
5
+ ## File Organization
6
+
7
+ Organize by feature or surface area, not by file type:
8
+
9
+ ```text
10
+ src/
11
+ ├── components/
12
+ │ ├── hero/
13
+ │ │ ├── Hero.tsx
14
+ │ │ ├── HeroVisual.tsx
15
+ │ │ └── hero.css
16
+ │ ├── scrolly-section/
17
+ │ │ ├── ScrollySection.tsx
18
+ │ │ ├── StickyVisual.tsx
19
+ │ │ └── scrolly.css
20
+ │ └── ui/
21
+ │ ├── Button.tsx
22
+ │ ├── SurfaceCard.tsx
23
+ │ └── AnimatedText.tsx
24
+ ├── hooks/
25
+ │ ├── useReducedMotion.ts
26
+ │ └── useScrollProgress.ts
27
+ ├── lib/
28
+ │ ├── animation.ts
29
+ │ └── color.ts
30
+ └── styles/
31
+ ├── tokens.css
32
+ ├── typography.css
33
+ └── global.css
34
+ ```
35
+
36
+ ## CSS Custom Properties
37
+
38
+ Define design tokens as variables. Do not hardcode palette, typography, or spacing repeatedly:
39
+
40
+ ```css
41
+ :root {
42
+ --color-surface: oklch(98% 0 0);
43
+ --color-text: oklch(18% 0 0);
44
+ --color-accent: oklch(68% 0.21 250);
45
+
46
+ --text-base: clamp(1rem, 0.92rem + 0.4vw, 1.125rem);
47
+ --text-hero: clamp(3rem, 1rem + 7vw, 8rem);
48
+
49
+ --space-section: clamp(4rem, 3rem + 5vw, 10rem);
50
+
51
+ --duration-fast: 150ms;
52
+ --duration-normal: 300ms;
53
+ --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
54
+ }
55
+ ```
56
+
57
+ ## Animation-Only Properties
58
+
59
+ Prefer compositor-friendly motion:
60
+ - `transform`
61
+ - `opacity`
62
+ - `clip-path`
63
+ - `filter` (sparingly)
64
+
65
+ Avoid animating layout-bound properties:
66
+ - `width`
67
+ - `height`
68
+ - `top`
69
+ - `left`
70
+ - `margin`
71
+ - `padding`
72
+ - `border`
73
+ - `font-size`
74
+
75
+ ## Semantic HTML First
76
+
77
+ ```html
78
+ <header>
79
+ <nav aria-label="Main navigation">...</nav>
80
+ </header>
81
+ <main>
82
+ <section aria-labelledby="hero-heading">
83
+ <h1 id="hero-heading">...</h1>
84
+ </section>
85
+ </main>
86
+ <footer>...</footer>
87
+ ```
88
+
89
+ Do not reach for generic wrapper `div` stacks when a semantic element exists.
90
+
91
+ ## Naming
92
+
93
+ - Components: PascalCase (`ScrollySection`, `SurfaceCard`)
94
+ - Hooks: `use` prefix (`useReducedMotion`)
95
+ - CSS classes: kebab-case or utility classes
96
+ - Animation timelines: camelCase with intent (`heroRevealTl`)
@@ -0,0 +1,63 @@
1
+ > This file extends [common/patterns.md](../common/patterns.md) with web-specific design-quality guidance.
2
+
3
+ # Web Design Quality Standards
4
+
5
+ ## Anti-Template Policy
6
+
7
+ Do not ship generic template-looking UI. Frontend output should look intentional, opinionated, and specific to the product.
8
+
9
+ ### Banned Patterns
10
+
11
+ - Default card grids with uniform spacing and no hierarchy
12
+ - Stock hero section with centered headline, gradient blob, and generic CTA
13
+ - Unmodified library defaults passed off as finished design
14
+ - Flat layouts with no layering, depth, or motion
15
+ - Uniform radius, spacing, and shadows across every component
16
+ - Safe gray-on-white styling with one decorative accent color
17
+ - Dashboard-by-numbers layouts with sidebar + cards + charts and no point of view
18
+ - Default font stacks used without a deliberate reason
19
+
20
+ ### Required Qualities
21
+
22
+ Every meaningful frontend surface should demonstrate at least four of these:
23
+
24
+ 1. Clear hierarchy through scale contrast
25
+ 2. Intentional rhythm in spacing, not uniform padding everywhere
26
+ 3. Depth or layering through overlap, shadows, surfaces, or motion
27
+ 4. Typography with character and a real pairing strategy
28
+ 5. Color used semantically, not just decoratively
29
+ 6. Hover, focus, and active states that feel designed
30
+ 7. Grid-breaking editorial or bento composition where appropriate
31
+ 8. Texture, grain, or atmosphere when it fits the visual direction
32
+ 9. Motion that clarifies flow instead of distracting from it
33
+ 10. Data visualization treated as part of the design system, not an afterthought
34
+
35
+ ## Before Writing Frontend Code
36
+
37
+ 1. Pick a specific style direction. Avoid vague defaults like "clean minimal".
38
+ 2. Define a palette intentionally.
39
+ 3. Choose typography deliberately.
40
+ 4. Gather at least a small set of real references.
41
+ 5. Use ECC design/frontend skills where relevant.
42
+
43
+ ## Worthwhile Style Directions
44
+
45
+ - Editorial / magazine
46
+ - Neo-brutalism
47
+ - Glassmorphism with real depth
48
+ - Dark luxury or light luxury with disciplined contrast
49
+ - Bento layouts
50
+ - Scrollytelling
51
+ - 3D integration
52
+ - Swiss / International
53
+ - Retro-futurism
54
+
55
+ Do not default to dark mode automatically. Choose the visual direction the product actually wants.
56
+
57
+ ## Component Checklist
58
+
59
+ - [ ] Does it avoid looking like a default Tailwind or shadcn template?
60
+ - [ ] Does it have intentional hover/focus/active states?
61
+ - [ ] Does it use hierarchy rather than uniform emphasis?
62
+ - [ ] Would this look believable in a real product screenshot?
63
+ - [ ] If it supports both themes, do both light and dark feel intentional?
@@ -0,0 +1,120 @@
1
+ > This file extends [common/hooks.md](../common/hooks.md) with web-specific hook recommendations.
2
+
3
+ # Web Hooks
4
+
5
+ ## Recommended PostToolUse Hooks
6
+
7
+ Prefer project-local tooling. Do not wire hooks to remote one-off package execution.
8
+
9
+ ### Format on Save
10
+
11
+ Use the project's existing formatter entrypoint after edits:
12
+
13
+ ```json
14
+ {
15
+ "hooks": {
16
+ "PostToolUse": [
17
+ {
18
+ "matcher": "Write|Edit",
19
+ "command": "pnpm prettier --write \"$FILE_PATH\"",
20
+ "description": "Format edited frontend files"
21
+ }
22
+ ]
23
+ }
24
+ }
25
+ ```
26
+
27
+ Equivalent local commands via `yarn prettier` or `npm exec prettier --` are fine when they use repo-owned dependencies.
28
+
29
+ ### Lint Check
30
+
31
+ ```json
32
+ {
33
+ "hooks": {
34
+ "PostToolUse": [
35
+ {
36
+ "matcher": "Write|Edit",
37
+ "command": "pnpm eslint --fix \"$FILE_PATH\"",
38
+ "description": "Run ESLint on edited frontend files"
39
+ }
40
+ ]
41
+ }
42
+ }
43
+ ```
44
+
45
+ ### Type Check
46
+
47
+ ```json
48
+ {
49
+ "hooks": {
50
+ "PostToolUse": [
51
+ {
52
+ "matcher": "Write|Edit",
53
+ "command": "pnpm tsc --noEmit --pretty false",
54
+ "description": "Type-check after frontend edits"
55
+ }
56
+ ]
57
+ }
58
+ }
59
+ ```
60
+
61
+ ### CSS Lint
62
+
63
+ ```json
64
+ {
65
+ "hooks": {
66
+ "PostToolUse": [
67
+ {
68
+ "matcher": "Write|Edit",
69
+ "command": "pnpm stylelint --fix \"$FILE_PATH\"",
70
+ "description": "Lint edited stylesheets"
71
+ }
72
+ ]
73
+ }
74
+ }
75
+ ```
76
+
77
+ ## PreToolUse Hooks
78
+
79
+ ### Guard File Size
80
+
81
+ Block oversized writes from tool input content, not from a file that may not exist yet:
82
+
83
+ ```json
84
+ {
85
+ "hooks": {
86
+ "PreToolUse": [
87
+ {
88
+ "matcher": "Write",
89
+ "command": "node -e \"let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const i=JSON.parse(d);const c=i.tool_input?.content||'';const lines=c.split('\\n').length;if(lines>800){console.error('[Hook] BLOCKED: File exceeds 800 lines ('+lines+' lines)');console.error('[Hook] Split into smaller modules');process.exit(2)}console.log(d)})\"",
90
+ "description": "Block writes that exceed 800 lines"
91
+ }
92
+ ]
93
+ }
94
+ }
95
+ ```
96
+
97
+ ## Stop Hooks
98
+
99
+ ### Final Build Verification
100
+
101
+ ```json
102
+ {
103
+ "hooks": {
104
+ "Stop": [
105
+ {
106
+ "command": "pnpm build",
107
+ "description": "Verify the production build at session end"
108
+ }
109
+ ]
110
+ }
111
+ }
112
+ ```
113
+
114
+ ## Ordering
115
+
116
+ Recommended order:
117
+ 1. format
118
+ 2. lint
119
+ 3. type check
120
+ 4. build verification
@@ -0,0 +1,79 @@
1
+ > This file extends [common/patterns.md](../common/patterns.md) with web-specific patterns.
2
+
3
+ # Web Patterns
4
+
5
+ ## Component Composition
6
+
7
+ ### Compound Components
8
+
9
+ Use compound components when related UI shares state and interaction semantics:
10
+
11
+ ```tsx
12
+ <Tabs defaultValue="overview">
13
+ <Tabs.List>
14
+ <Tabs.Trigger value="overview">Overview</Tabs.Trigger>
15
+ <Tabs.Trigger value="settings">Settings</Tabs.Trigger>
16
+ </Tabs.List>
17
+ <Tabs.Content value="overview">...</Tabs.Content>
18
+ <Tabs.Content value="settings">...</Tabs.Content>
19
+ </Tabs>
20
+ ```
21
+
22
+ - Parent owns state
23
+ - Children consume via context
24
+ - Prefer this over prop drilling for complex widgets
25
+
26
+ ### Render Props / Slots
27
+
28
+ - Use render props or slot patterns when behavior is shared but markup must vary
29
+ - Keep keyboard handling, ARIA, and focus logic in the headless layer
30
+
31
+ ### Container / Presentational Split
32
+
33
+ - Container components own data loading and side effects
34
+ - Presentational components receive props and render UI
35
+ - Presentational components should stay pure
36
+
37
+ ## State Management
38
+
39
+ Treat these separately:
40
+
41
+ | Concern | Tooling |
42
+ |---------|---------|
43
+ | Server state | TanStack Query, SWR, tRPC |
44
+ | Client state | Zustand, Jotai, signals |
45
+ | URL state | search params, route segments |
46
+ | Form state | React Hook Form or equivalent |
47
+
48
+ - Do not duplicate server state into client stores
49
+ - Derive values instead of storing redundant computed state
50
+
51
+ ## URL As State
52
+
53
+ Persist shareable state in the URL:
54
+ - filters
55
+ - sort order
56
+ - pagination
57
+ - active tab
58
+ - search query
59
+
60
+ ## Data Fetching
61
+
62
+ ### Stale-While-Revalidate
63
+
64
+ - Return cached data immediately
65
+ - Revalidate in the background
66
+ - Prefer existing libraries instead of rolling this by hand
67
+
68
+ ### Optimistic Updates
69
+
70
+ - Snapshot current state
71
+ - Apply optimistic update
72
+ - Roll back on failure
73
+ - Emit visible error feedback when rolling back
74
+
75
+ ### Parallel Loading
76
+
77
+ - Fetch independent data in parallel
78
+ - Avoid parent-child request waterfalls
79
+ - Prefetch likely next routes or states when justified
@@ -0,0 +1,64 @@
1
+ > This file extends [common/performance.md](../common/performance.md) with web-specific performance content.
2
+
3
+ # Web Performance Rules
4
+
5
+ ## Core Web Vitals Targets
6
+
7
+ | Metric | Target |
8
+ |--------|--------|
9
+ | LCP | < 2.5s |
10
+ | INP | < 200ms |
11
+ | CLS | < 0.1 |
12
+ | FCP | < 1.5s |
13
+ | TBT | < 200ms |
14
+
15
+ ## Bundle Budget
16
+
17
+ | Page Type | JS Budget (gzipped) | CSS Budget |
18
+ |-----------|---------------------|------------|
19
+ | Landing page | < 150kb | < 30kb |
20
+ | App page | < 300kb | < 50kb |
21
+ | Microsite | < 80kb | < 15kb |
22
+
23
+ ## Loading Strategy
24
+
25
+ 1. Inline critical above-the-fold CSS where justified
26
+ 2. Preload the hero image and primary font only
27
+ 3. Defer non-critical CSS or JS
28
+ 4. Dynamically import heavy libraries
29
+
30
+ ```js
31
+ const gsapModule = await import('gsap');
32
+ const { ScrollTrigger } = await import('gsap/ScrollTrigger');
33
+ ```
34
+
35
+ ## Image Optimization
36
+
37
+ - Explicit `width` and `height`
38
+ - `loading="eager"` plus `fetchpriority="high"` for hero media only
39
+ - `loading="lazy"` for below-the-fold assets
40
+ - Prefer AVIF or WebP with fallbacks
41
+ - Never ship source images far beyond rendered size
42
+
43
+ ## Font Loading
44
+
45
+ - Max two font families unless there is a clear exception
46
+ - `font-display: swap`
47
+ - Subset where possible
48
+ - Preload only the truly critical weight/style
49
+
50
+ ## Animation Performance
51
+
52
+ - Animate compositor-friendly properties only
53
+ - Use `will-change` narrowly and remove it when done
54
+ - Prefer CSS for simple transitions
55
+ - Use `requestAnimationFrame` or established animation libraries for JS motion
56
+ - Avoid scroll handler churn; use IntersectionObserver or well-behaved libraries
57
+
58
+ ## Performance Checklist
59
+
60
+ - [ ] All images have explicit dimensions
61
+ - [ ] No accidental render-blocking resources
62
+ - [ ] No layout shifts from dynamic content
63
+ - [ ] Motion stays on compositor-friendly properties
64
+ - [ ] Third-party scripts load async/defer and only when needed
@@ -0,0 +1,57 @@
1
+ > This file extends [common/security.md](../common/security.md) with web-specific security content.
2
+
3
+ # Web Security Rules
4
+
5
+ ## Content Security Policy
6
+
7
+ Always configure a production CSP.
8
+
9
+ ### Nonce-Based CSP
10
+
11
+ Use a per-request nonce for scripts instead of `'unsafe-inline'`.
12
+
13
+ ```text
14
+ Content-Security-Policy:
15
+ default-src 'self';
16
+ script-src 'self' 'nonce-{RANDOM}' https://cdn.jsdelivr.net;
17
+ style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
18
+ img-src 'self' data: https:;
19
+ font-src 'self' https://fonts.gstatic.com;
20
+ connect-src 'self' https://*.example.com;
21
+ frame-src 'none';
22
+ object-src 'none';
23
+ base-uri 'self';
24
+ ```
25
+
26
+ Adjust origins to the project. Do not cargo-cult this block unchanged.
27
+
28
+ ## XSS Prevention
29
+
30
+ - Never inject unsanitized HTML
31
+ - Avoid `innerHTML` / `dangerouslySetInnerHTML` unless sanitized first
32
+ - Escape dynamic template values
33
+ - Sanitize user HTML with a vetted local sanitizer when absolutely necessary
34
+
35
+ ## Third-Party Scripts
36
+
37
+ - Load asynchronously
38
+ - Use SRI when serving from a CDN
39
+ - Audit quarterly
40
+ - Prefer self-hosting for critical dependencies when practical
41
+
42
+ ## HTTPS and Headers
43
+
44
+ ```text
45
+ Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
46
+ X-Content-Type-Options: nosniff
47
+ X-Frame-Options: DENY
48
+ Referrer-Policy: strict-origin-when-cross-origin
49
+ Permissions-Policy: camera=(), microphone=(), geolocation=()
50
+ ```
51
+
52
+ ## Forms
53
+
54
+ - CSRF protection on state-changing forms
55
+ - Rate limiting on submission endpoints
56
+ - Validate client and server side
57
+ - Prefer honeypots or light anti-abuse controls over heavy-handed CAPTCHA defaults
@@ -0,0 +1,55 @@
1
+ > This file extends [common/testing.md](../common/testing.md) with web-specific testing content.
2
+
3
+ # Web Testing Rules
4
+
5
+ ## Priority Order
6
+
7
+ ### 1. Visual Regression
8
+
9
+ - Screenshot key breakpoints: 320, 768, 1024, 1440
10
+ - Test hero sections, scrollytelling sections, and meaningful states
11
+ - Use Playwright screenshots for visual-heavy work
12
+ - If both themes exist, test both
13
+
14
+ ### 2. Accessibility
15
+
16
+ - Run automated accessibility checks
17
+ - Test keyboard navigation
18
+ - Verify reduced-motion behavior
19
+ - Verify color contrast
20
+
21
+ ### 3. Performance
22
+
23
+ - Run Lighthouse or equivalent against meaningful pages
24
+ - Keep CWV targets from [performance.md](performance.md)
25
+
26
+ ### 4. Cross-Browser
27
+
28
+ - Minimum: Chrome, Firefox, Safari
29
+ - Test scrolling, motion, and fallback behavior
30
+
31
+ ### 5. Responsive
32
+
33
+ - Test 320, 375, 768, 1024, 1440, 1920
34
+ - Verify no overflow
35
+ - Verify touch interactions
36
+
37
+ ## E2E Shape
38
+
39
+ ```ts
40
+ import { test, expect } from '@playwright/test';
41
+
42
+ test('landing hero loads', async ({ page }) => {
43
+ await page.goto('/');
44
+ await expect(page.locator('h1')).toBeVisible();
45
+ });
46
+ ```
47
+
48
+ - Avoid flaky timeout-based assertions
49
+ - Prefer deterministic waits
50
+
51
+ ## Unit Tests
52
+
53
+ - Test utilities, data transforms, and custom hooks
54
+ - For highly visual components, visual regression often carries more signal than brittle markup assertions
55
+ - Visual regression supplements coverage targets; it does not replace them
@@ -17,5 +17,42 @@
17
17
  "Read:**/.env",
18
18
  "Read:**/*.env"
19
19
  ]
20
+ },
21
+ "hooks": {
22
+ "PreToolUse": [
23
+ {
24
+ "matcher": "Write|Edit|MultiEdit",
25
+ "hooks": [
26
+ {
27
+ "type": "command",
28
+ "command": "node -e \"const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); const p=(d.tool_input||{}).file_path||''; const s=['.env','.prod.','.production.','appsettings.Production','secrets/','terraform/','.pem','.key','credentials'].find(x=>p.toLowerCase().includes(x.toLowerCase())); if(s) console.log('[TAS] WARNING: Sensitive file ('+s+'): '+p+' → Confirm this edit is intentional.');\"",
29
+ "description": "Warn before editing sensitive files"
30
+ }
31
+ ]
32
+ }
33
+ ],
34
+ "PostToolUse": [
35
+ {
36
+ "matcher": "Write|Edit|MultiEdit",
37
+ "hooks": [
38
+ {
39
+ "type": "command",
40
+ "command": "node .claude/hooks/code-quality.js",
41
+ "description": "Auto format source files: prettier (TS/JS), ruff/black (Python), dotnet format (C#)"
42
+ }
43
+ ]
44
+ }
45
+ ],
46
+ "Stop": [
47
+ {
48
+ "hooks": [
49
+ {
50
+ "type": "command",
51
+ "command": "node .claude/hooks/session-end.js",
52
+ "description": "Run test suite, check project-status.yaml updated, remind next steps"
53
+ }
54
+ ]
55
+ }
56
+ ]
20
57
  }
21
58
  }