file-upload
- Repo stars 0
- Author updated Live
- Author repo skills-registry
- Domain
- Other
- Compatible agents
-
- Claude Code
- Cursor
- Cline
- Codex
- Windsurf
- Gemini CLI
- +20
- Trust score
- 88 / 100 · community maintained
- Author / version / license
- @tomevault-io · no license declared
- Token usage
- Lean
- Setup complexity
- Guided setup
- External API key
- Not required
- Operating systems
- macOS · Linux · Windows
- Runtime requirements
- Node.js · Python
- Permissions
-
- Read-only
- Write / modify
- Network behavior
- Local-only
- Install commands
- 26 variants
Profile is derived at build time from SKILL.md and install vectors. Subject to drift from author intent.
Heads up: 未限定 allowed-tools,默认拥有全部工具权限。
---
name: file-upload
description: | Use when this capability is needed. import multer from 'multer'; import path from 'path'; impo…
category: other
runtime: Node.js / Python
---
# file-upload output preview
## PART A: Task fit
- Use case: | Use when this capability is needed. import multer from 'multer'; import path from 'path'; import crypto from 'crypto'; // Storage configuration const storage = multer.diskStorage({ runs entirely locally; runs on Node.js. Works with Claude Code, Cursor, Cline and 23 more..
- Inputs: target material, constraints, expected output, and acceptance criteria.
- Evidence boundary: follow “Node.js (Multer — recommended) / Memory storage (for cloud forwarding) / Python (FastAPI)” and do not present inference as author intent.
## PART B: Execution result
- **01** The card summarizes the use case; runtime output centers on “| Use when this capability is needed. import multer from 'multer'; import path from 'path'; import crypto from 'crypto'; // Storage configuration const storage = multer.diskStorage({ runs entirely locally; runs on Node.js. Works with Claude Code, Cursor, Cline and 23 more.”.
- **02** When the source has headings, the agent prioritizes “Node.js (Multer — recommended) / Memory storage (for cloud forwarding) / Python (FastAPI)” so the result follows the author’s structure.
- **03** Typical output includes task judgment, concrete steps, required commands or file edits, validation, and follow-up options.
- **04** Risk context follows the fingerprint: read files, write/modify files; mostly runs locally; usually needs no extra API key.
## Running Rules
- read files, write/modify files; mostly runs locally; usually needs no extra API key.
- Validate with a small sample before expanding scope.
- Return the result, validation criteria, and next iteration options. The source mentions slash commands such as `/uploads`; use them first when your agent supports command triggers.
Name target files or source material, expected output, forbidden changes, and whether network or shell access is allowed. Permission fingerprint: read files, write/modify files.
Start with a small task and check whether the result follows “Node.js (Multer — recommended) / Memory storage (for cloud forwarding) / Python (FastAPI)”. Inspect diffs, logs, previews, or tests before expanding scope.
Confirm the final output includes a concrete result, evidence, and next action. If it stays generic, tighten inputs, boundaries, and acceptance criteria.
---
name: file-upload
description: | Use when this capability is needed. import multer from 'multer'; import path from 'path'; impo…
category: other
source: tomevault-io/skills-registry
---
# file-upload
## When to use
- | Use when this capability is needed. import multer from 'multer'; import path from 'path'; import crypto from 'crypto…
- Use it when the task has clear inputs, repeatable steps, and validation criteria.
## What to provide
- Target material, scope, expected result, and forbidden changes.
- Whether network, commands, file writes, or external services are allowed.
## Execution rules
- Organize steps around “Node.js (Multer — recommended) / Memory storage (for cloud forwarding) / Python (FastAPI)” and keep inference separate from source facts.
- read files, write/modify files; mostly runs locally; usually needs no extra API key.
- Validate with a small sample before expanding the task.
## Output requirements
- Return the deliverable, key evidence, validation method, and next action.
- Mark missing information as unknown; do not invent commands, platforms, or dependencies. The author source anchors workflow facts; repository files anchor sources and commands; Fluxly only adds fit, limitations, and quality judgment.
skill "file-upload" {
input -> user goal + target files + boundaries + acceptance criteria
context -> Node.js (Multer — recommended) / Memory storage (for cloud forwarding) / Python (FastAPI)
rules -> SKILL.md triggers / order / output contract
runtime -> Node.js / Python | read files, write/modify files | mostly runs locally
guardrails -> usually needs no extra API key + small-sample validation + diff/log review
output -> copyable result + checklist + next iteration
} File Upload Handling
Node.js (Multer — recommended)
import multer from 'multer';
import path from 'path';
import crypto from 'crypto';
// Storage configuration
const storage = multer.diskStorage({
destination: './uploads',
filename: (req, file, cb) => {
const uniqueName = `${crypto.randomUUID()}${path.extname(file.originalname)}`;
cb(null, uniqueName);
},
});
// File filter
const fileFilter = (req: Express.Request, file: Express.Multer.File, cb: multer.FileFilterCallback) => {
const allowedMimes = ['image/jpeg', 'image/png', 'image/webp', 'application/pdf'];
if (allowedMimes.includes(file.mimetype)) {
cb(null, true);
} else {
cb(new Error(`File type ${file.mimetype} not allowed`));
}
};
const upload = multer({
storage,
fileFilter,
limits: { fileSize: 10 * 1024 * 1024 }, // 10MB
});
// Single file
app.post('/upload', upload.single('file'), (req, res) => {
res.json({ filename: req.file!.filename, size: req.file!.size });
});
// Multiple files
app.post('/upload/multiple', upload.array('files', 10), (req, res) => {
res.json({ count: (req.files as Express.Multer.File[]).length });
});
// Error handling
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
if (err instanceof multer.MulterError) {
if (err.code === 'LIMIT_FILE_SIZE') return res.status(413).json({ error: 'File too large' });
return res.status(400).json({ error: err.message });
}
if (err.message.includes('not allowed')) return res.status(415).json({ error: err.message });
next(err);
});
Memory storage (for cloud forwarding)
const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 10 * 1024 * 1024 } });
app.post('/upload', upload.single('file'), async (req, res) => {
// req.file.buffer contains the file — forward to S3
await s3.send(new PutObjectCommand({
Bucket: bucket, Key: key, Body: req.file!.buffer, ContentType: req.file!.mimetype,
}));
});
Python (FastAPI)
from fastapi import UploadFile, File, HTTPException
import aiofiles, uuid
ALLOWED_TYPES = {"image/jpeg", "image/png", "application/pdf"}
MAX_SIZE = 10 * 1024 * 1024 # 10MB
@app.post("/upload")
async def upload_file(file: UploadFile = File(...)):
if file.content_type not in ALLOWED_TYPES:
raise HTTPException(415, f"Type {file.content_type} not allowed")
content = await file.read()
if len(content) > MAX_SIZE:
raise HTTPException(413, "File too large")
filename = f"{uuid.uuid4()}{Path(file.filename).suffix}"
async with aiofiles.open(f"uploads/{filename}", "wb") as f:
await f.write(content)
return {"filename": filename, "size": len(content)}
Java (Spring Boot)
@PostMapping("/upload")
public ResponseEntity<Map<String, String>> upload(
@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) throw new ResponseStatusException(BAD_REQUEST, "Empty file");
if (file.getSize() > 10_000_000) throw new ResponseStatusException(PAYLOAD_TOO_LARGE);
String ext = StringUtils.getFilenameExtension(file.getOriginalFilename());
String filename = UUID.randomUUID() + "." + ext;
Path dest = Path.of("uploads", filename);
file.transferTo(dest);
return ResponseEntity.ok(Map.of("filename", filename));
}
Spring config:
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
File Validation Beyond MIME
// Validate actual file content (magic bytes), not just extension
import { fileTypeFromBuffer } from 'file-type';
const type = await fileTypeFromBuffer(req.file!.buffer);
if (!type || !['image/jpeg', 'image/png'].includes(type.mime)) {
return res.status(415).json({ error: 'Invalid file content' });
}
Anti-Patterns
| Anti-Pattern | Fix |
|---|---|
| Trust client MIME type only | Validate magic bytes with file-type |
| Original filename as storage key | Use UUID to prevent path traversal and collisions |
| No file size limit | Always set limits.fileSize |
| Sync disk writes on upload | Use streams or async writes |
| Storing uploads in app directory | Use separate /uploads or cloud storage |
| No cleanup of temp files | Implement lifecycle/cron cleanup |
Production Checklist
- File size limits configured
- MIME type whitelist (validate magic bytes, not just extension)
- UUID filenames (never use original filename for storage)
- Multer error handler middleware
- Virus scanning for user uploads (ClamAV)
- Rate limiting on upload endpoints
- Cleanup strategy for orphaned files
Source: claude-dev-suite/claude-dev-suite — distributed by TomeVault.
Decide Fit First
Design Intent
How To Use It
Boundaries And Review