diff --git a/.github/instructions/context-engineering.instructions.md b/.github/instructions/context-engineering.instructions.md new file mode 100644 index 000000000..99658fd52 --- /dev/null +++ b/.github/instructions/context-engineering.instructions.md @@ -0,0 +1,44 @@ +--- +description: 'Guidelines for structuring code and projects to maximize GitHub Copilot effectiveness through better context management' +applyTo: '**' +--- + +# Context Engineering + +Principles for helping GitHub Copilot understand your codebase and provide better suggestions. + +## Project Structure + +- **Use descriptive file paths**: `src/auth/middleware.ts` > `src/utils/m.ts`. Copilot uses paths to infer intent. +- **Colocate related code**: Keep components, tests, types, and hooks together. One search pattern should find everything related. +- **Export public APIs from index files**: What's exported is the contract; what's not is internal. This helps Copilot understand boundaries. + +## Code Patterns + +- **Prefer explicit types over inference**: Type annotations are context. `function getUser(id: string): Promise` tells Copilot more than `function getUser(id)`. +- **Use semantic names**: `activeAdultUsers` > `x`. Self-documenting code is AI-readable code. +- **Define constants**: `MAX_RETRY_ATTEMPTS = 3` > magic number `3`. Named values carry meaning. + +## Working with Copilot + +- **Keep relevant files open in tabs**: Copilot uses open tabs as context signals. Working on auth? Open auth-related files. +- **Position cursor intentionally**: Copilot prioritizes code near your cursor. Put cursor where context matters. +- **Use Copilot Chat for complex tasks**: Inline completions have minimal context. Chat mode sees more files. + +## Context Hints + +- **Add a COPILOT.md file**: Document architecture decisions, patterns, and conventions Copilot should follow. +- **Use strategic comments**: At the top of complex modules, briefly describe the flow or purpose. +- **Reference patterns explicitly**: "Follow the same pattern as `src/api/users.ts`" gives Copilot a concrete example. + +## Multi-File Changes + +- **Describe scope first**: Tell Copilot all files involved before asking for changes. "I need to update the User model, API endpoint, and tests." +- **Work incrementally**: One file at a time, verifying each change. Don't ask for everything at once. +- **Check understanding**: Ask "What files would you need to see?" before complex refactors. + +## When Copilot Struggles + +- **Missing context**: Open the relevant files in tabs, or explicitly paste code snippets. +- **Stale suggestions**: Copilot may not see recent changes. Re-open files or restart the session. +- **Generic answers**: Be more specific. Add constraints, mention frameworks, reference existing code. diff --git a/.github/instructions/self-explanatory-code-commenting.instructions.md b/.github/instructions/self-explanatory-code-commenting.instructions.md new file mode 100644 index 000000000..5ffa68fa8 --- /dev/null +++ b/.github/instructions/self-explanatory-code-commenting.instructions.md @@ -0,0 +1,162 @@ +--- +description: 'Guidelines for GitHub Copilot to write comments to achieve self-explanatory code with less comments. Examples are in JavaScript but it should work on any language that has comments.' +applyTo: '**' +--- + +# Self-explanatory Code Commenting Instructions + +## Core Principle +**Write code that speaks for itself. Comment only when necessary to explain WHY, not WHAT.** +We do not need comments most of the time. + +## Commenting Guidelines + +### ❌ AVOID These Comment Types + +**Obvious Comments** +```javascript +// Bad: States the obvious +let counter = 0; // Initialize counter to zero +counter++; // Increment counter by one +``` + +**Redundant Comments** +```javascript +// Bad: Comment repeats the code +function getUserName() { + return user.name; // Return the user's name +} +``` + +**Outdated Comments** +```javascript +// Bad: Comment doesn't match the code +// Calculate tax at 5% rate +const tax = price * 0.08; // Actually 8% +``` + +### ✅ WRITE These Comment Types + +**Complex Business Logic** +```javascript +// Good: Explains WHY this specific calculation +// Apply progressive tax brackets: 10% up to 10k, 20% above +const tax = calculateProgressiveTax(income, [0.10, 0.20], [10000]); +``` + +**Non-obvious Algorithms** +```javascript +// Good: Explains the algorithm choice +// Using Floyd-Warshall for all-pairs shortest paths +// because we need distances between all nodes +for (let k = 0; k < vertices; k++) { + for (let i = 0; i < vertices; i++) { + for (let j = 0; j < vertices; j++) { + // ... implementation + } + } +} +``` + +**Regex Patterns** +```javascript +// Good: Explains what the regex matches +// Match email format: username@domain.extension +const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; +``` + +**API Constraints or Gotchas** +```javascript +// Good: Explains external constraint +// GitHub API rate limit: 5000 requests/hour for authenticated users +await rateLimiter.wait(); +const response = await fetch(githubApiUrl); +``` + +## Decision Framework + +Before writing a comment, ask: +1. **Is the code self-explanatory?** → No comment needed +2. **Would a better variable/function name eliminate the need?** → Refactor instead +3. **Does this explain WHY, not WHAT?** → Good comment +4. **Will this help future maintainers?** → Good comment + +## Special Cases for Comments + +### Public APIs +```javascript +/** + * Calculate compound interest using the standard formula. + * + * @param {number} principal - Initial amount invested + * @param {number} rate - Annual interest rate (as decimal, e.g., 0.05 for 5%) + * @param {number} time - Time period in years + * @param {number} compoundFrequency - How many times per year interest compounds (default: 1) + * @returns {number} Final amount after compound interest + */ +function calculateCompoundInterest(principal, rate, time, compoundFrequency = 1) { + // ... implementation +} +``` + +### Configuration and Constants +```javascript +// Good: Explains the source or reasoning +const MAX_RETRIES = 3; // Based on network reliability studies +const API_TIMEOUT = 5000; // AWS Lambda timeout is 15s, leaving buffer +``` + +### Annotations +```javascript +// TODO: Replace with proper user authentication after security review +// FIXME: Memory leak in production - investigate connection pooling +// HACK: Workaround for bug in library v2.1.0 - remove after upgrade +// NOTE: This implementation assumes UTC timezone for all calculations +// WARNING: This function modifies the original array instead of creating a copy +// PERF: Consider caching this result if called frequently in hot path +// SECURITY: Validate input to prevent SQL injection before using in query +// BUG: Edge case failure when array is empty - needs investigation +// REFACTOR: Extract this logic into separate utility function for reusability +// DEPRECATED: Use newApiFunction() instead - this will be removed in v3.0 +``` + +## Anti-Patterns to Avoid + +### Dead Code Comments +```javascript +// Bad: Don't comment out code +// const oldFunction = () => { ... }; +const newFunction = () => { ... }; +``` + +### Changelog Comments +```javascript +// Bad: Don't maintain history in comments +// Modified by John on 2023-01-15 +// Fixed bug reported by Sarah on 2023-02-03 +function processData() { + // ... implementation +} +``` + +### Divider Comments +```javascript +// Bad: Don't use decorative comments +//===================================== +// UTILITY FUNCTIONS +//===================================== +``` + +## Quality Checklist + +Before committing, ensure your comments: +- [ ] Explain WHY, not WHAT +- [ ] Are grammatically correct and clear +- [ ] Will remain accurate as code evolves +- [ ] Add genuine value to code understanding +- [ ] Are placed appropriately (above the code they describe) +- [ ] Use proper spelling and professional language + +## Summary + +Remember: **The best comment is the one you don't need to write because the code is self-documenting.** diff --git a/packages/core/src/routes/admin-media.ts b/packages/core/src/routes/admin-media.ts index 9c97009e4..1ae8370d0 100644 --- a/packages/core/src/routes/admin-media.ts +++ b/packages/core/src/routes/admin-media.ts @@ -496,9 +496,9 @@ adminMediaRoutes.post('/upload', async (c) => { } // Extract image dimensions if it's an image - let width: number | undefined - let height: number | undefined - + let width: number | null = null + let height: number | null = null + if (file.type.startsWith('image/') && !file.type.includes('svg')) { try { const dimensions = await getImageDimensions(arrayBuffer) @@ -511,7 +511,7 @@ adminMediaRoutes.post('/upload', async (c) => { // Generate URLs - use public serving route const publicUrl = `/files/${r2Key}` - const thumbnailUrl = file.type.startsWith('image/') ? publicUrl : undefined + const thumbnailUrl = file.type.startsWith('image/') ? publicUrl : null // Save to database const stmt = c.env.DB.prepare(`