Continuum

io.github.pouyahasanamreji由 GitHub 帳號 pouyahasanamreji 發布v0.3.0更新於 Oct 24, 2026

Shared memory + orchestration for your coding agents. Local-first MCP, vector RAG.

概覽

AI 產生的概覽

一個本地優先的 MCP 伺服器,為編碼代理提供共享的向量記憶與協作協定,用來協調多個 git worktree 中的平行工作。

可以做什麼
Continuum 將專案經驗以嵌入向量存入本機 SQLite 資料庫,並使用 sqlite-vec 索引,任何接入的 MCP 用戶端都能進行語意檢索。工具涵蓋專案、PLOT.md 協作協定、知識條目(列出、搜尋、取得、建立、更新、刪除),以及具狀態轉換與保留路徑追蹤的代理註冊表。讀取 plot 的用戶端會成為協調者:負責研究、驗證、寫入派送紀錄,並回傳一段可直接貼給新代理的提示詞,讓它在隔離的 worktree 中工作。另有網頁面板供人瀏覽專案、代理、plot 與知識。
適用情境
當多個編碼代理同時處理同一個程式碼倉庫,而你反覆解釋慣例或經常遇到檔案衝突時適用。它適合希望已完成任務的經驗能跨工作階段、跨模型、跨用戶端保留,並偏好使用本機資料庫而非託管服務的團隊。
執行需求
以本機程序執行,僅限桌面端。可用 Docker 映像,或裸機執行,需要 Node >=22.12.0 與 pnpm 10.33+。選用環境變數:EMBEDDER_URL、EMBEDDER_MODEL、EMBEDDER_DIM、ORCHESTRATOR_DB_PATH;僅在呼叫 token 計數端點時需要 ANTHROPIC_API_KEY。用戶端透過 Streamable HTTP 連線。
安裝前請注意
代理可以建立、更新與刪除專案、知識條目與派送紀錄,project_delete 會串聯刪除代理與經驗。plot 透過統一 diff 修改,知識更新為整份內容替換。若設定 HTTP 嵌入服務,經驗文字會傳送到該端點;使用內建 TEI 設定可能需要 Hugging Face 權杖。未宣告任何驗證機制,請勿將連接埠暴露到公開網路。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Continuum,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

[Continuum]

Shared memory + orchestration for your coding agents.

One MCP server. Tell any client to read the plot — it becomes the orchestrator.
Dispatches fresh agents in isolated worktrees, shares lessons across every Claude Code / Codex / Cline chat on the project.

[Node] [pnpm] [NestJS] [Astro] [sqlite-vec] [MCP]

Quick Start • Memory & Vectors • Workflow • MCP Tools • Wire It In • Configuration

[Two Claude Code chats sharing memory through Continuum — left reads the plot and dispatches, right runs the work and updates status]


Your agents forget. Continuum remembers.

Point any MCP client at Continuum and tell it to read the plot. The client becomes an orchestrator — it researches the codebase, verifies the plan, persists a dispatch record, and hands you a ready-to-paste prompt for a fresh agent in an isolated git worktree. Every other Claude Code / Codex / Cline chat on the project sees what's reserved, shares what's been learned, and never re-explains the codebase. One local server: vector knowledge base, orchestration protocol, agent registry — shared across every MCP-speaking app on your machine.

mermaid
flowchart TD    CC["Claude Code"]    CX["Codex"]    CL["Cline"]    YOU["YOU"]
    subgraph CONTINUUM["CONTINUUM ORCHESTRATOR"]        direction LR        PLOT["PLOT.md<br/>protocol"]        KNOW["KNOWLEDGE<br/>(vectorized)"]        AGENTS["AGENTS<br/>registry"]        PANEL["WEB PANEL<br/>(humans)"]    end
    DB[("SQLite + sqlite-vec<br/>one file, your disk")]
    CC -- MCP --> CONTINUUM    CX -- MCP --> CONTINUUM    CL -- MCP --> CONTINUUM    YOU -- HTTP --> CONTINUUM    CONTINUUM --> DB

No SaaS. No telemetry. No keys to manage. Boots in seconds. Survives reboots. Scales with you.


What you get

🧠 Vectorized memoryEvery lesson your agents learn becomes a 768-dim embedding indexed in sqlite-vec. Recall is semantic, fuzzy, and instant — no exact-match games.
🔍 RAG-native searchknowledge_search({q: "how do we handle webhook retries?"}) returns ranked metadata (slug + kind + agentSlug + timestamps); follow up with knowledge_get({slug}) for the body. Metadata first keeps top-K context cheap; only fetch what's worth reading.
🗺️ Canonical workflowEvery project gets a PLOT.md seeded with a 4-phase dispatch protocol — Intake → Research → Verify → Handoff. Stop re-explaining your process.
🤖 Multi-agent registryState machine + reserved-path tracking stops parallel agents from clobbering each other across git worktrees.
📚 Two-tier knowledgefundamental lessons are binding rules loaded on every dispatch. situational lessons surface via semantic search when relevant.
🖥️ Human web panelAstro + React UI to browse projects, agents, plot, and knowledge while AI clients drive everything via MCP.
🔌 Client-agnosticStandard MCP / Streamable HTTP. Works with Claude Code, Codex, Cline, Cursor, or anything that speaks the protocol.
🔒 Local-firstOne SQLite file. WAL mode. No cloud. Optional embedder is your call (Ollama, TEI, anything OpenAI-shaped).
📦 One container in prodSingle image, one HTTP port, one mounted volume. Drop on any host, point your MCP clients at it.

Why Continuum exists

Without ContinuumWith Continuum
Session ends → context gone.Lessons persist as embedded vectors. Recall survives reboots, models, and clients.
You re-explain conventions every session.knowledge_search ranks lessons by relevance; knowledge_get pulls the body when needed.
Two parallel agents edit the same file.reserved_paths + status state machine surfaces collisions before dispatch.
Each new task improvises orchestration.PLOT.md protocol seeded into every project — Intake → Research → Verify → Handoff.
"What did Claude do last week?"registry_list paginates dispatch metadata (slug, status, branch, reserved paths). agent_get({slug}) pulls the full record.
Knowledge scattered across chat logs.One SQLite database. One vector index. One source of truth.

Quick start

🐳 The easy path — one Docker command

bash
docker compose -f docker-compose.dev.yml up

That's it. The whole stack comes up with hot reload, a SQLite browser, and a single shared volume — no Node, no pnpm, no native-build dance on your host machine.

What you get:

ServiceURLWhat it is
apihttp://localhost:6685NestJS + MCP server. Swagger at /docs. Hot-reloaded on file change.
webhttp://localhost:6680Astro + React panel. Hot-reloaded.
sqlite-webhttp://localhost:6667Browser UI for the live SQLite database — inspect projects, agents, knowledge, vectors. Loads sqlite-vec automatically.
embedder (optional)http://localhost:8080Hugging Face TEI running an HTTP embedder. Off by default.

The API embeds in-process by default (Snowflake/snowflake-arctic-embed-m-v1.5 via Transformers.js, 768-dim, ONNX q8). No external service required for semantic search. Override via EMBEDDER_URL to point at any HTTP-based embedder (Ollama, TEI, OpenAI-compatible). Turn the bundled TEI container on with the embedder profile:

bash
HF_TOKEN=hf_xxx docker compose -f docker-compose.dev.yml --profile embedder up

Bind mounts keep the source tree on your host — edits are instant. Named volumes hold node_modules so installs survive restarts. Database lives at ./.local-data/dev-orchestrator.db on your host, gitignored, safe to wipe.

Stop everything:

bash
docker compose -f docker-compose.dev.yml down            # keep datadocker compose -f docker-compose.dev.yml down -v         # nuke volumes too

🛠️ Or run on bare metal

bash
pnpm installpnpm dev
API + MCPhttp://localhost:7776 (Swagger at /docs)
Web panelhttp://localhost:7777

Dev SQLite at ./.local-data/orchestrator.db. Gitignored. Wipe to reset — next boot recreates and migrates forward.

Requires Node >=22.12.0 and pnpm 10.33+. The compose path skips both.


Memory & vectors

This is the headline. Continuum's knowledge layer is what makes your agents stop being amnesiac.

How a lesson becomes memory

agent finishes a dispatch        │        ▼knowledge_create({  project, agentSlug, slug,  content: "When wiring rate-limit guards in Nest,            register them in app.module.ts AFTER            the auth guard, not before. Order matters.",  kind: 'situational'})        │        ▼content → embedder (in-process by default, or Ollama / TEI / OpenAI-compatible)        │       Snowflake Arctic Embed v1.5 → 768-dim vector        ▼SQLite row + sqlite-vec index entry        │       freshness profile = (URL, model, dim)        ▼forever queryable by ANY future agent on this project

How recall works

Phase 1 of every dispatch (the orchestrator does this automatically):

knowledge_list({ project, kind: 'fundamental' })  └─ returns metadata for every binding lesson — slug + agentSlug + timestamps.knowledge_get({ project, slug })  // for each fundamental slug  └─ full body — base branch, worktree convention, no-AI-attribution, etc.
knowledge_search({ project, q: "rate limit middleware nest interceptor order" })  └─ vector similarity over your prose  └─ returns top-K ranked metadata (no content)  └─ does NOT need exact wording — natural language worksknowledge_get({ project, slug })  // for each relevant hit  └─ pulls the full lesson body

Search and list return metadata only — slug + kind + agentSlug + timestamps. Call knowledge_get for the body of any lesson worth reading. Keeps top-K context cheap; the orchestrator triages first, fetches second.

The result: the agent that's about to plan your task already knows what your last five agents learned the hard way. No prompt engineering. No "here's our convention" copy-paste.

Two kinds of knowledge

KindLoaded whenUse for
fundamentalEvery dispatch, unconditionallyProject-wide rules: base branch, worktree naming, commit conventions, append-only files
situationalOnly if semantically relevant to the taskSpecific gotchas: "auth guard ordering," "regen artifact merge strategy," "Stripe webhook idempotency keys"

The freshness profile

Vectors are pinned to a (EMBEDDER_URL, EMBEDDER_MODEL, EMBEDDER_DIM) triple. Change any one and Continuum marks stale vectors for rebuild on next boot. You stay in control of which embedder owns your memory — local Ollama, self-hosted TEI, or anything OpenAI-shaped.

Pluggable embedders

The embedder is required and runs in-process by default (Snowflake/snowflake-arctic-embed-m-v1.5, 768-dim, ONNX q8). The model weights are bundled in the API image — no extra container, no extra config, semantic search works out of the box.

Override via EMBEDDER_URL to delegate embedding to an HTTP service:

bash
# Option A — Ollama (simplest, fully local)ollama pull <embedding-model># EMBEDDER_URL=http://127.0.0.1:11434/api/embed# EMBEDDER_MODEL=<embedding-model>   EMBEDDER_DIM=768
# Option B — Hugging Face TEI (production-grade, batched)HF_TOKEN=hf_xxx docker compose -f docker-compose.dev.yml --profile embedder up embedder# EMBEDDER_URL=http://127.0.0.1:8080/v1/embeddings# EMBEDDER_MODEL=<repo-id>   EMBEDDER_DIM=768
# Option C — anything OpenAI-compatible /v1/embeddings# Works out of the box. Match the dim.

Built on sqlite-vec

The vector index lives in the same SQLite file as your projects, agents, and plot. One file. One backup. One restore. No separate vector DB to provision, no Pinecone bill, no Chroma daemon to babysit. WAL mode keeps reads concurrent with writes; foreign keys keep your registry consistent; busy_timeout = 5000 keeps things calm under contention.


Wire it into your AI client

Claude Code

jsonc
// ~/.claude.json  →  mcpServers{  "mcpServers": {    "continuum": {      "transport": "streamable-http",      "url": "http://127.0.0.1:7776/mcp"    }  }}

Restart Claude Code. Tools appear under mcp__continuum__*.

Codex

toml
# ~/.codex/config.toml[mcp_servers.continuum]transport = "streamable-http"url = "http://127.0.0.1:7776/mcp"

Anything else (Cline, Cursor, custom)

Point any MCP-compatible client at http://127.0.0.1:7776/mcp. Streamable HTTP, stateful sessions (UUID-keyed). Server name continuum.


Your first project

Inside any wired client:

Create a Continuum project for /absolute/path/to/my/repo,then read the PLOT.md and act as orchestratorfor the following task: <describe what you want done>.

What happens:

  1. Client calls project_create({project: "/absolute/path/..."})
  2. Server seeds PLOT.md (the orchestration protocol) and an empty knowledge base
  3. Client calls plot({project}), reads the protocol, enters orchestrator mode
  4. Client follows the 4-phase workflow — researches, verifies, persists a dispatch record, hands you a ready-to-paste prompt for a fresh agent in a git worktree

You paste the prompt into a new Claude Code / Codex session. That agent codes inside an isolated worktree against its reserved paths. Other parallel agents see the new agent's reservations via the coordination brief.

When work merges, the orchestrator records what was learned via knowledge_create — and every future dispatch on this project benefits from it forever.


The workflow

1. Intake

registry_list({project, status:'active'})     // paginated metadata: slug + reservedPaths + timestampsagent_get({project, slug})                    // bodies (request/plan/implPrompt/coordinationBrief) per active agentknowledge_list({project, kind:'fundamental'}) // binding-rule metadataknowledge_get({project, slug})                // body per fundamental slug — read every oneknowledge_search({project, q: "<task intent>"}) // RAG → ranked metadataknowledge_get({project, slug})                // body for each relevant hit

2. Research

Spawn an Explore / Plan subagent. It reads the codebase against the loaded knowledge. Produces a file-by-file plan: create / modify / delete. Plan only — no code.

3. Verify

Spawn a critique agent. It challenges every file touched, looks for orphans and broken call sites, cross-checks against active agents' reserved paths. Returns annotated deltas.

4. Handoff

agent_create({  project, slug, branch, worktree,  reservedPaths,        // paths this agent owns  request,              // verbatim human task  plan,                 // final agreed plan  implPrompt,           // self-contained prompt for the dispatched agent  coordinationBrief,    // short block for every other active agent})

Agent lands as draft. Promote with agent_update({status:'active'}) when you dispatch. On merge, record the SHA and bank the lesson:

agent_update({ project, slug, status:'merged', mergedCommit, postMergeNotes })knowledge_create({ project, agentSlug, slug, content, kind:'situational' })

The orchestrator never edits source, runs regen, merges branches, or pushes commits. It researches, verifies, coordinates, and persists. Code lives in fresh agents inside isolated worktrees.


MCP tools

Every tool takes project (canonical absolute path) as its first argument.

Project

ToolPurpose
project_listEnumerate registered projects
project_getFetch one project
project_createRegister project, seed PLOT.md + knowledge
project_renameRename a project
project_deleteCascade delete (project + agents + lessons)

Plot — the orchestration protocol

ToolPurpose
plotRead PLOT.md
plot_updateApply a unified git-format diff (zero fuzz, exact context match)

plot_update validates --- a/PLOT.md / +++ b/PLOT.md / @@ headers strictly. Context mismatch throws hunk_mismatch with the failing hunk header. Re-read with plot, regenerate the diff, retry. No silent overwrites.

Knowledge — the vector memory

ToolPurpose
knowledge_listLesson metadata (slug, kind, agentSlug, timestamps). Optional kind filter. No content.
knowledge_searchSemantic query → ranked metadata. q free-text intent, optional kind, optional limit. No content.
knowledge_getRead one lesson by slug — full body
knowledge_createRecord a new lesson — kind: 'fundamental' | 'situational'. Embedded automatically.
knowledge_updateReplace lesson content. Re-embeds on save.
knowledge_deleteRetire a lesson

knowledge_search runs vector lookup over the sqlite-vec index. Pass natural prose — questions, task statements, descriptions all work. SQL wildcard syntax does not. Response is ranked metadata; call knowledge_get({project, slug}) for the body of any hit worth reading. Same pattern for knowledge_list (use kind: 'fundamental' to enumerate the binding set, then get each).

Agents

ToolPurpose
registry_listPaginated agent metadata — {data, page, limit, hasNextPage}. Each data row: slug, status, branch, worktree, reservedPaths, timestamps, mergedCommit, abandonedReason. Optional status filter; default limit 10, max 50. No artifact bodies.
agent_getFull record by slug — includes request, plan, implPrompt, coordinationBrief, postMergeNotes
agent_createPersist a draft dispatch record
agent_updateTransition status, edit fields

Allowed transitions: draft → active → merged | abandoned. merged requires a 7–40 char commit SHA. abandoned requires a reason. Only active agents reserve paths.

registry_list returns the collision matrix metadata in one paginated envelope. To inspect a dispatch's plan or implPrompt, follow with agent_get({project, slug}). Page through with page until hasNextPage is false.


Example session

human: orchestrate adding rate-limit middleware to /api routes
claude: → registry_list({project, status:'active'})  // 0 active        → knowledge_list({project, kind:'fundamental'})                                              // metadata for binding rules        → knowledge_get({project, slug:'base-branch'})       // → main        → knowledge_get({project, slug:'worktree-convention'}) // → ../<slug>/        → knowledge_search({project, q:'rate limit middleware nest interceptor'})                                              // ✨ 2 ranked hits on guard ordering (metadata)        → knowledge_get({project, slug:'rate-limit-guard-ordering'}) // bodies fetched        → spawn Plan subagent → plan returned        → spawn critique subagent → 1 issue: missed `app.module.ts` registration → fixed        → agent_create({            slug: 'rate-limit-middleware',            branch: 'feature/rate-limit',            worktree: '/abs/path/../rate-limit-middleware',            reservedPaths: ['apps/api/src/common/rate-limit/**', 'apps/api/src/app.module.ts'],            request: 'orchestrate adding rate-limit middleware to /api routes',            plan: '...',            implPrompt: '...',            coordinationBrief: 'reserves common/rate-limit/**, edits app.module.ts (additive)'          })        → here's the impl prompt to paste into a fresh session: ...
[ task ships ]
claude: → agent_update({slug:'rate-limit-middleware', status:'merged', mergedCommit:'a1b2c3d'})        → knowledge_create({            agentSlug: 'rate-limit-middleware',            slug: 'rate-limit-guard-ordering',            kind: 'situational',            content: 'Rate-limit guards must register AFTER auth guard in app.module.ts.                      Order in providers array decides execution order. Reverse → 401s                      bypass rate limiting.'          })        // ✅ lesson embedded → vector indexed → permanent memory

Next time anyone — you, Claude, Codex — touches anything rate-limit-shaped on this project, that lesson surfaces automatically.


Web panel

[Agents registry — slug, status, branch, reserved-path count, timestamps]

[Knowledge browser — a fundamental lesson opened, metadata + content]

Astro 6 + React 19 islands. Tailwind v4. shadcn/ui.

PageWhat
/Landing
/projectsProjects list — TanStack Table, sortable, filterable
/agentsRegistry / status board across projects
/knowledgeMarkdown viewer — GFM, syntax highlight, anchored sections, search
/plotPlot viewer + editor with diff preview
/settingsEmbedder URL + model + dim, tokenizer key, REST gate, log level

Settings stored in app_settings (SQLite) override env vars. Headless deploys still work via env alone.


Configuration

Both env vars and panel settings supported. Panel takes precedence.

VarDefaultPurpose
PORT7776HTTP port
CORS_ORIGINunset* or comma-separated origins
ORCHESTRATOR_DB_PATH/data/orchestrator.dbSQLite path. Dev scripts override to ./.local-data/orchestrator.db
PANEL_REST_ENABLEDfalseMount /api/orchestrator/* REST surface (panel uses it)
NODE_ENVunsetProduction blocks destructive migrations
ORCHESTRATOR_ALLOW_DESTRUCTIVE_MIGRATEunsetSet 1 to override in production
ANTHROPIC_API_KEYunsetToken-count endpoints (server-side only)
ANTHROPIC_TOKENIZER_MODELclaude-opus-4-7Model name for count_tokens
EMBEDDER_URLunsetHTTP embedding endpoint (Ollama / TEI / OpenAI-compatible). Unset → in-process embedder
EMBEDDER_MODELSnowflake/snowflake-arctic-embed-m-v1.5Model id (in-process default; passed through to HTTP embedder when configured)
EMBEDDER_DIM768Expected embedding dimension

Stack

LayerTech
Memorysqlite-vec vector index • Snowflake Arctic Embed v1.5 in-process via Transformers.js (default) • Ollama / TEI / OpenAI-compatible embedders via EMBEDDER_URL • freshness-pinned vectors
APINestJS 11 • @rekog/mcp-nest • @modelcontextprotocol/sdk 1.10 • Zod 4 • Swagger
Persistencebetter-sqlite3 (WAL, FK, busy_timeout 5s)
Diff enginediff 9 (zero-fuzz unified-diff applier)
WebAstro 6 • React 19 • Tailwind 4 • shadcn/ui • TanStack Table • rehype/remark • highlight.js
ToolingTurborepo 2 • pnpm 10.33 • TypeScript 5.9 • Prettier 3 • Jest

Scripts

bash
pnpm dev          # turbo run dev — api + web in watchpnpm build        # turbo run buildpnpm lint         # turbo run lintpnpm check-types  # turbo run check-typespnpm format       # prettier across ts/tsx/js/astro/md/json
pnpm -F @continuum/api dev          # api only — nest start --watchpnpm -F @continuum/api mcp:dev      # api with local SQLite at .local-data/pnpm -F @continuum/api test         # jest unit testspnpm -F @continuum/api test:e2e     # jest e2e
pnpm -F @continuum/web dev          # web only — astro devpnpm -F @continuum/web build        # astro build → dist/

Conventions

  • project is always a canonical absolute path. Pass the project root, never a worktree subdirectory. Worktree paths throw project_not_found.
  • Plot mutations flow through unified diffs. No full-text writes. Bad context → server rejects with the failing @@ header.
  • Knowledge updates are whole-content replace. Pass the full new content. Re-embedded on save.
  • Reserved paths are JSON arrays of globs. Only active agents reserve.
  • Migrations are forward-only on boot. Production blocks destructive migrations unless explicitly opted in.

Troubleshooting

SymptomLikely cause
project_not_foundPassing a worktree path. Use the canonical project root registered with project_create.
hunk_mismatch from plot_updateStale diff. Re-read with plot, regenerate against current content, retry.
knowledge_search / knowledge_list returns empty / weird resultsEmbedder unreachable, model mismatch, or dim mismatch (search only). Check /settings. Backfill stale vectors. Remember: both return metadata — call knowledge_get({project, slug}) for the body.
Vectors not regenerating after embedder swapFreshness profile (URL + model + dim) must change. Restart server to trigger backfill.
invalid_transition from agent_updateAllowed: draft → active → merged | abandoned. Anything else throws.
missing_merged_commit / invalid_merged_commitmerged requires a 7–40 char SHA.
Schema migration refuses in productionSet ORCHESTRATOR_ALLOW_DESTRUCTIVE_MIGRATE=1 if you really mean it.

Roadmap

  • Cross-project knowledge sharing (kind: 'global')
  • Embedding re-rank with a small reranker model
  • One-shot import of existing CLAUDE.md / AGENTS.md / Cursor rules → fundamentals
  • Read-only public knowledge mirror (publish a project's lessons as a static site)
  • Built-in observation hooks for SessionStart / SessionEnd events

Contributing

Contributions welcome. Fork, branch, test, PR. Match Prettier defaults (100-col, double quotes, semicolons, ES5 trailing commas). Keep MCP tool changes Zod-typed.


Support

IssuesGitHub Issues
Docsthis README + Swagger UI at /docs + the seeded PLOT.md inside each project
MCP spechttps://modelcontextprotocol.io

Stop letting your agents forget.

pnpm install && pnpm dev — and they never will again.

來源:README.md,提交 c5718cd

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

1
  1. v0.3.0最新Sep 16, 2026

評分

已滿足適用檢查項的 40%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分

    請在儲存庫或註冊中心條目中宣告授權條款。