Token导航 LogoToken导航TokenDH.com
待分类权限需确认github未标认证来源可访问许可证需确认审计未展示

convex-file-system凸文件系统

Agent Skill

convex-file-system 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

710

周安装

29

GitHub Stars

1

下载量

230
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:convex-file-system(凸文件系统)
来源仓库:https://github.com/imfa-solutions/skills
仓库路径:skills/convex-file-system
安装命令:
npx skills add https://github.com/imfa-solutions/skills --skill convex-file-system
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/imfa-solutions/skills --skill convex-file-system

简介

用于文件存储和系统操作相关的功能扩展,具体能力需查看仓库文档。

  • 适用于需要处理上传文件、临时缓存或系统级 I/O 操作的场景。
  • 使用前应确认是否会触发敏感路径访问或产生副作用操作。
  • 当前无详细 SKILL.md 说明,建议结合源码和测试用例进一步验证。
  • convex-file-system 属于待分类类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

ConvexFS — File Storage for Convex

convex-fs — Path-based file storage with global CDN delivery via bunny.net.

Installation & Setup

1. Install

npm install convex-fs

2. Register component

// convex/convex.config.ts
import { defineApp } from "convex/server";
import fs from "convex-fs/convex.config.js";

const app = defineApp();
app.use(fs);
export default app;

3. Create ConvexFS instance

// convex/fs.ts
import { ConvexFS } from "convex-fs";
import { components } from "./_generated/api";

export const fs = new ConvexFS(components.fs, {
  storage: {
    type: "bunny",
    apiKey: process.env.BUNNY_API_KEY!,
    storageZoneName: process.env.BUNNY_STORAGE_ZONE!,
    cdnHostname: process.env.BUNNY_CDN_HOSTNAME!,
    tokenKey: process.env.BUNNY_TOKEN_KEY, // recommended for signed URLs
  },
});

4. Register HTTP routes

// convex/http.ts
import { httpRouter } from "convex/server";
import { registerRoutes } from "convex-fs";
import { components } from "./_generated/api";
import { fs } from "./fs";

const http = httpRouter();

registerRoutes(http, components.fs, fs, {
  pathPrefix: "/fs",
  uploadAuth: async (ctx) => {
    const identity = await ctx.auth.getUserIdentity();
    return identity !== null;
  },
  downloadAuth: async (ctx, blobId, path) => {
    const identity = await ctx.auth.getUserIdentity();
    return identity !== null;
  },
});

export default http;

Creates: POST /fs/upload (upload proxy) and GET /fs/blobs/{blobId} (302 redirect to CDN).

5. Environment variables

Set in Convex dashboard (Settings → Environment Variables):

BUNNY_API_KEY=your-api-key
BUNNY_STORAGE_ZONE=your-storage-zone-name
BUNNY_CDN_HOSTNAME=your-zone.b-cdn.net
BUNNY_TOKEN_KEY=your-token-auth-key
BUNNY_REGION=ny  # Optional: ny, la, sg, uk, se, br, jh, syd (default: Frankfurt)

Core Concepts

Architecture

React Client ──▶ Convex Backend (ConvexFS) ──▶ bunny.net CDN (File Storage + Edge)
  • File metadata (paths, content types, sizes) → Convex tables
  • File contents (blobs) → bunny.net Edge Storage

Paths

Any UTF-8 string. list() uses prefix matching (not directory listing):

  • prefix: "/users" matches /users/alice.txt AND /users-backup/data.bin
  • prefix: "/users/" matches only under /users/

Blob lifecycle

Upload → Pending (4h TTL) → Committed (refCount=1) → Deleted (refCount=0) → GC cleanup
  • Reference counting: copy increments refCount (zero-copy), delete decrements it.
  • Garbage collection: 3 automatic jobs — upload GC (hourly), blob GC (hourly), file expiration GC (every 15s).
  • Grace period: orphaned blobs retained for blobGracePeriod (default 24h) before permanent deletion.

Attributes

interface FileAttributes {
  expiresAt?: number; // Unix timestamp — auto-deleted by FGC
}

Attributes are path-specific: cleared on move, not inherited on copy, removed on overwrite.

Core API

Query methods

// Get file metadata by path
const file = await fs.stat(ctx, "/uploads/photo.jpg");
// Returns: { path, blobId, contentType, size, attributes } | null

// List files with pagination
const result = await fs.list(ctx, {
  prefix: "/uploads/",
  paginationOpts: { numItems: 50, cursor: null },
});
// Returns: { page: FileMetadata[], continueCursor, isDone }

Mutation methods

// Commit uploaded blobs to paths
await fs.commitFiles(ctx, [
  { path: "/file.txt", blobId: "uuid-here" },                     // overwrite if exists
  { path: "/new.txt", blobId: "uuid", basis: null },               // FAIL if exists
  { path: "/update.txt", blobId: "new-uuid", basis: "old-uuid" },  // CAS: fail if changed
]);

// Atomic multi-operation transaction
await fs.transact(ctx, [
  { op: "move", source: file, dest: { path: "/new/path.txt" } },
  { op: "copy", source: file, dest: { path: "/backup.txt", basis: null } },
  { op: "delete", source: file },
  { op: "setAttributes", source: file, attributes: { expiresAt: Date.now() + 3600000 } },
]);

// Convenience methods
await fs.move(ctx, "/old.txt", "/new.txt");  // throws if source missing or dest exists
await fs.copy(ctx, "/a.txt", "/b.txt");      // throws if source missing or dest exists
await fs.delete(ctx, "/file.txt");           // idempotent (no-op if missing)

Basis values (for commitFiles and transact destinations):

ValueMeaning
undefinedNo check — overwrite if exists
nullFile must NOT exist
"blobId"File's current blobId must match (compare-and-swap)

Action methods

// Generate signed download URL
const url = await fs.getDownloadUrl(ctx, blobId, { extraParams: { filename: "doc.pdf" } });

// Download blob data
const data = await fs.getBlob(ctx, blobId); // ArrayBuffer | null

// Download file contents + metadata
const result = await fs.getFile(ctx, "/file.txt"); // { data, contentType, size } | null

// Upload data and get blobId
const blobId = await fs.writeBlob(ctx, imageData, "image/webp");

// Upload + commit in one call
await fs.writeFile(ctx, "/report.pdf", pdfData, "application/pdf");

Client utilities

import { buildDownloadUrl } from "convex-fs";

const url = buildDownloadUrl(siteUrl, "/fs", file.blobId, file.path, { filename: "doc.pdf" });

Upload & Serve Flow

Upload (React)

const handleUpload = async (file: File) => {
  const siteUrl = (import.meta.env.VITE_CONVEX_URL ?? "").replace(/\.cloud$/, ".site");

  // 1. Upload blob
  const res = await fetch(`${siteUrl}/fs/upload`, {
    method: "POST",
    headers: { "Content-Type": file.type },
    body: file,
  });
  const { blobId } = await res.json();

  // 2. Commit to path (via mutation)
  await commitFile({ blobId, filename: file.name });
};

Serve (React)

import { buildDownloadUrl } from "convex-fs";

function Image({ path }: { path: string }) {
  const file = useQuery(api.files.getFile, { path });
  const siteUrl = (import.meta.env.VITE_CONVEX_URL ?? "").replace(/\.cloud$/, ".site");

  if (!file) return <div>Loading...</div>;
  const url = buildDownloadUrl(siteUrl, "/fs", file.blobId, file.path);
  return <img src={url} alt={path} />;
}

Security Rules

  1. Always authenticate uploads — open upload endpoints are a serious risk.
  2. Use path-based authorization — validate path ownership in downloadAuth.
  3. Enable token authentication on bunny.net — prevents URL tampering.
  4. Set appropriate URL TTLs: sensitive content 60–300s, general 3600s (default), streaming 3600s+.

Conflict Handling

import { ConvexError } from "convex/values";
import { isConflictError } from "convex-fs";

try {
  await fs.commitFiles(ctx, files);
} catch (e) {
  if (e instanceof ConvexError && isConflictError(e.data)) {
    // e.data: { code, path, expected, found }
    // Codes: SOURCE_NOT_FOUND, SOURCE_CHANGED, DEST_EXISTS, DEST_NOT_FOUND, DEST_CHANGED, CAS_CONFLICT
  }
}

Constructor Options

OptionTypeDefaultDescription
storageStorageConfigrequiredBunny.net backend config
downloadUrlTtlnumber3600Signed URL expiration (seconds)
blobGracePeriodnumber86400Orphaned blob retention (seconds)

Reference Files

  • Patterns & examples: User files, temp files, atomic ops, CAS updates, retry, pagination, React hooks → See references/examples.md
  • Advanced topics: Multiple filesystems, disaster recovery, testing, GC details, Bunny.net setup, TypeScript types, troubleshooting → See references/advanced.md

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

35.43%
按下载量换算81

Claude

30.08%
按下载量换算69

Cursor

19.66%
按下载量换算45

Gemini CLI

9.49%
按下载量换算22

安全审计

暂无安全审计结果可展示。

权限和风险

权限需确认

当前来源未能明确判断权限范围,默认进入异常复核队列。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills