Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions .claude/agents/security-reviewer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Security Reviewer

You are a security-focused code reviewer specializing in cryptographic implementations and secure data handling.

## Scope

Focus on these security-critical areas of the dedpaste codebase:

### Cryptography (cli/)
- `pgpUtils.ts` — PGP key generation, encryption, decryption, signing
- `encryptionUtils.ts` — Encryption/decryption workflows
- `encryptionHelpers.ts` — Encryption helper functions
- `keyManager.ts` — Key storage and retrieval
- `unifiedKeyManager.ts` — Unified key management layer
- `keybaseUtils.ts` — Keybase integration for key discovery

### Data Handling (src/)
- `index.ts` — Worker request handling, paste storage/retrieval, auth

## Review Checklist

### Cryptographic Issues
- [ ] Weak or deprecated algorithms (check openpgp configuration)
- [ ] Hardcoded keys, IVs, or salts
- [ ] Insufficient key lengths
- [ ] Improper random number generation
- [ ] Missing or incorrect signature verification
- [ ] Key material in logs or error messages

### Input Validation
- [ ] Unsanitized user input in paste content or metadata
- [ ] Path traversal in paste ID handling
- [ ] Missing size limits on uploads
- [ ] Header injection via user-controlled values

### Information Leakage
- [ ] Sensitive data in error messages or stack traces
- [ ] Timing differences in authentication checks
- [ ] Key fingerprints or metadata exposed unintentionally
- [ ] Debug logging that leaks secrets

### Authentication & Authorization
- [ ] One-time paste deletion is properly enforced
- [ ] Burn-after-reading can't be bypassed
- [ ] Password-protected pastes use constant-time comparison
- [ ] R2/KV access patterns don't allow enumeration

### Dependency Security
- [ ] Check `npm audit` for known vulnerabilities
- [ ] Verify openpgp version is current and not affected by CVEs
- [ ] Review third-party key discovery (Keybase) trust model

## Output

Provide findings in this format:

### [SEVERITY] — Finding Title
- **File**: path/to/file.ts:line
- **Issue**: Description of the vulnerability
- **Impact**: What an attacker could achieve
- **Recommendation**: How to fix it
- **Reference**: CWE or relevant security standard

Severity levels: CRITICAL, HIGH, MEDIUM, LOW, INFO
62 changes: 62 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true",
"description": "Auto-format edited files with Prettier"
}
],
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '(\\.env|\\.dev\\.vars|wrangler\\.toml)$'; then echo 'BLOCK: This file contains secrets or deployment config. Edit manually.' && exit 1; fi",
"description": "Block edits to .env, .dev.vars, and wrangler.toml"
},
{
"matcher": "Edit|Write",
"command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '(package-lock\\.json|yarn\\.lock|pnpm-lock\\.yaml)$'; then echo 'BLOCK: Lock files should not be edited directly. Use npm install.' && exit 1; fi",
"description": "Block direct edits to lock files"
}
]
},
"permissions": {
"allow": [
"Bash(cat:*)",
"Bash(chmod:*)",
"Bash(grep:*)",
"Bash(node:*)",
"Bash(npm install:*)",
"Bash(npm link)",
"Bash(npm run build:*)",
"Bash(npm run dev:*)",
"Bash(npm run format:*)",
"Bash(npm run lint:*)",
"Bash(npm test:*)",
"Bash(npm audit:*)",
"Bash(npx tsc:*)",
"Bash(npx prettier:*)",
"Bash(npx eslint:*)",
"Bash(git add:*)",
"Bash(git checkout:*)",
"Bash(git commit:*)",
"Bash(git diff:*)",
"Bash(git fetch:*)",
"Bash(git log:*)",
"Bash(git merge:*)",
"Bash(git pull:*)",
"Bash(git push:*)",
"Bash(git remote:*)",
"Bash(git stash:*)",
"Bash(git status:*)",
"Bash(git tag:*)",
"Bash(gh issue:*)",
"Bash(gh pr:*)",
"Bash(gh run:*)",
"Bash(wrangler:*)",
"Bash(dedpaste:*)",
"WebSearch"
],
"deny": []
}
}
41 changes: 41 additions & 0 deletions .claude/skills/deploy-check/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
name: deploy-check
description: Build, type-check, test, and deploy to Cloudflare Workers with verification
disable-model-invocation: true
---

# Deploy Check

Run the full pre-deploy validation pipeline and deploy to Cloudflare Workers.
Stop immediately if any step fails and report the error.

## Steps

1. **Type check** — Run `npx tsc --noEmit` to catch type errors without emitting files
2. **Build** — Run `npm run build` to compile TypeScript for both worker and CLI
3. **Lint** — Run `npm run lint` to check for code quality issues
4. **Test** — Run `npm test` to run the test suite
5. **Deploy** — Run `npm run deploy` to deploy to Cloudflare Workers
6. **Verify** — After deployment, run `curl -s -o /dev/null -w "%{http_code}" https://dedpaste.com` to confirm the worker is responding (expect 200 or 404 for root)

## Failure Handling

- If type check fails: Report the type errors and suggest fixes
- If build fails: Report compilation errors
- If lint fails: Run `npm run format` first, then re-lint. If lint still fails, report remaining issues
- If tests fail: Report which tests failed and why
- If deploy fails: Check wrangler output for auth or config issues
- If verification fails: Check Cloudflare dashboard status

## Output

Provide a summary table:

| Step | Status | Duration |
|------|--------|----------|
| Type check | ✅/❌ | Xs |
| Build | ✅/❌ | Xs |
| Lint | ✅/❌ | Xs |
| Test | ✅/❌ | Xs |
| Deploy | ✅/❌ | Xs |
| Verify | ✅/❌ | Xs |
56 changes: 56 additions & 0 deletions .claude/skills/release-notes/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
name: release-notes
description: Generate release notes from conventional commits since the last git tag
disable-model-invocation: true
---

# Release Notes Generator

Generate a formatted changelog from conventional commits since the last release tag.

## Steps

1. **Find the latest tag** — Run `git describe --tags --abbrev=0` to get the most recent tag
2. **Collect commits** — Run `git log <tag>..HEAD --oneline --no-merges` to get all commits since that tag
3. **Parse conventional commits** — Group commits by type prefix:
- `feat:` → **Features**
- `fix:` → **Bug Fixes**
- `perf:` → **Performance**
- `docs:` → **Documentation**
- `refactor:` → **Refactoring**
- `test:` → **Tests**
- `chore:` / `ci:` / `build:` → **Maintenance**
- `BREAKING CHANGE:` or `!:` → **Breaking Changes** (highlighted at top)
4. **Determine next version** — Based on commit types:
- Any breaking change → major bump
- Any `feat:` → minor bump
- Only `fix:` / other → patch bump
5. **Format output** — Generate markdown release notes

## Output Format

```markdown
# v{version} — {date}

## Breaking Changes
- {description} ({short-hash})

## Features
- {scope}: {description} ({short-hash})

## Bug Fixes
- {description} ({short-hash})

## Maintenance
- {description} ({short-hash})

**Full Changelog**: {compare-url}
```

## Notes

- If there are no commits since the last tag, report that there's nothing to release
- If there are no tags at all, use the initial commit as the base
- Include the GitHub compare URL: `https://github.com/anoncam/dedpaste/compare/{old-tag}...{new-tag}`
- Strip the conventional commit prefix from descriptions for cleaner output
- Include the scope in parentheses if present (e.g., `feat(cli): add encryption`)
9 changes: 9 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"mcpServers": {
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp@latest"],
"description": "Live documentation lookup for openpgp, commander, inquirer, Cloudflare Workers APIs"
}
}
}
10 changes: 10 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"tabWidth": 2,
"useTabs": false,
"printWidth": 100,
"bracketSpacing": true,
"arrowParens": "always"
}
Loading