如果把 OpenClaw 想成一個很忙的機器人公司,那 ClawHub 就不是公司的某個部門,而比較像「外部供應商市場」。
有人把 skill 做成可以被安裝的包,像是特定任務的操作手冊。
也有人把 plugin 做成可以被載入的擴充模組,像是讓系統多一隻手、多一個感測器,甚至多一條新管線。
第 26 天我想先回答一個很直白的問題:
ClawHub 到底是什麼?它怎麼把 skill 和 plugin 送進 OpenClaw?
這篇不急著講「怎麼選」,先把舞台本身看懂。
因為如果你不知道舞台長什麼樣子,後面再講演員、道具和出場順序,都只是零碎資訊。
我會把 ClawHub 想成四層:
skill 跟 plugin 都會經過這套舞台,但兩者的落點不太一樣。
換句話說:
ClawHub 不只是下載中心,而是 OpenClaw 對外部擴充做治理的入口。
先看 ClawHub skill install 的主流程,這是整個舞台的骨架。
📄 原始碼:
src/skills/lifecycle/clawhub.ts:1589-1601
export async function installSkillFromClawHub(params: {
workspaceDir: string;
slug: string;
version?: string;
baseUrl?: string;
force?: boolean;
forceInstall?: boolean;
acknowledgeClawHubRisk?: boolean;
onClawHubRisk?: (request: ClawHubRiskAcknowledgementRequest) => boolean | Promise<boolean>;
logger?: Logger;
config?: OpenClawConfig;
}): Promise<InstallClawHubSkillResult> {
return await installRequestedSkillFromClawHub(params);
}
這裡看起來很薄,但它不是沒事做,而是把真正的 install 決策包在內部 helper。
這樣 CLI、onboarding、測試都可以共用同一條流程。
再往下看真正的 install 核心。
📄 原始碼:
src/skills/lifecycle/clawhub.ts:1089-1315
async function performClawHubSkillInstall(
params: ClawHubInstallParams,
): Promise<InstallClawHubSkillResult> {
try {
const targetDir = resolveWorkspaceSkillInstallDir(params.workspaceDir, params.slug);
const registry = resolveClawHubBaseUrl(params.baseUrl);
const clawhubAuthority = isDefaultClawHubBaseUrl(params.baseUrl) ? "openclaw" : "third-party";
if (!params.force && (await pathExists(targetDir))) {
return {
ok: false,
error: `Skill already exists at ${targetDir}. Re-run with force/update.`,
};
}
這段先做兩件很重要的事:
這不是小事。
因為如果安裝流程一開始就沒先擋住,後面不管驗證做得多漂亮,還是可能把舊的覆蓋掉。
再看 trust gate。
📄 原始碼:
src/skills/lifecycle/clawhub.ts:1340-1346
const trust = await ensureClawHubSkillTrustAcknowledged({
...params,
version,
skipClawHubTrustCheck: officialClawHubSkill,
});
if (!trust.ok) {
return { ...trust, version };
}
這裡的重點是:
這不是單純「信任或不信任」的二分法,而是把來源分級。
OpenClaw 會把 trust 作為 install 的前置條件,而不是安裝完再補問一句「你要不要小心一點」。
再看下載來源有兩條:
📄 原始碼:
src/skills/lifecycle/clawhub.ts:1376-1408
if (latestResolution.installKind === "github") {
version = latestResolution.github.commit;
archive = await downloadClawHubGitHubSkillArchive({
repo: latestResolution.github.repo,
commit: latestResolution.github.commit,
});
} else {
version = latestResolution.archive.version;
archive = await downloadClawHubSkillArchiveUrl({
url: latestResolution.archive.downloadUrl,
baseUrl: params.baseUrl,
});
}
這一段很能代表 ClawHub 的平台屬性:
ClawHub 不是只會「給你一個檔案」,而是會先決定你拿到的是 release package 還是 source-derived package。
最後看它怎麼把結果留痕。
📄 原始碼:
src/skills/lifecycle/clawhub.ts:1464-1485
const installedAt = Date.now();
const artifact = buildDownloadedArtifactLock(archive);
const [skillFile, verification] = await Promise.all([
readInstalledSkillFileLock(install.targetDir),
fetchInstallVerificationLock({
slug: params.slug,
...(params.ownerHandle ? { ownerHandle: params.ownerHandle } : {}),
version: verificationVersion,
baseUrl: params.baseUrl,
}),
]);
const sourceUrl =
readInstallResolutionSourceUrl(latestResolution) ??
readVerifiedClawHubSkillSourceUrl(verification?.provenance);
await writeClawHubSkillOrigin(install.targetDir, {
version: 1,
registry: resolveClawHubBaseUrl(params.baseUrl),
slug: params.slug,
installedVersion: version,
installedAt,
...(sourceUrl ? { sourceUrl } : {}),
artifact,
...(skillFile ? { skillFile } : {}),
});
這裡其實是在做「可追蹤性」。
OpenClaw 不只把檔案裝進去,還記錄:
這些資料後面會變成查詢、更新、稽核的基礎。
ClawHub 的心智模型,其實很像一個有門禁的倉儲系統。
你不是看到貨就搬回家,而是要先回答幾個問題:
skill 的部分尤其明顯。
ClawHub 會把 install 變成一個可治理的事件,而不是一個檔案複製動作。
plugin 更進一步。
所以 plugin 的問題不是「能不能裝」,而是:
這個東西裝進來之後,OpenClaw 會不會因此變成另一台機器?
這也是為什麼 ClawHub 對 skill 和 plugin 都很重要。
它不是單純商店,而是供應鏈入口。
但這個代價是值得的。
因為 OpenClaw 不是展示用 demo,而是會真的讓東西裝進去、跑起來、留紀錄的系統。