diff --git a/docs.json b/docs.json index ec40b98fb..92dd1f2a9 100644 --- a/docs.json +++ b/docs.json @@ -670,6 +670,7 @@ { "group": "Plugin Development", "pages": [ + "en/plugin/certified-plugins", "en/plugin/dev/tutor", "en/plugin/dev/basic-info", "en/plugin/dev/directory-structure", @@ -973,6 +974,7 @@ { "group": "插件开发", "pages": [ + "zh/plugin/certified-plugins", "zh/plugin/dev/tutor", "zh/plugin/dev/basic-info", "zh/plugin/dev/directory-structure", @@ -1271,6 +1273,7 @@ { "group": "プラグイン開発", "pages": [ + "ja/plugin/certified-plugins", "ja/plugin/dev/tutor", "ja/plugin/dev/basic-info", "ja/plugin/dev/directory-structure", diff --git a/en/plugin/certified-plugins.mdx b/en/plugin/certified-plugins.mdx new file mode 100644 index 000000000..87babac82 --- /dev/null +++ b/en/plugin/certified-plugins.mdx @@ -0,0 +1,27 @@ +--- +title: "Certified Plugins" +description: "How LangBot identifies reviewed plugin releases and how the allowance works in Cloud." +--- + +A **Certified Plugin** is a specific plugin release that LangBot has reviewed for the certified-plugin requirements. Certification belongs to the exact published version, not to the author account or plugin name alone. + +## What you see + +Certified Plugin releases show a **Certified Plugin** badge in the marketplace and plugin details. A plugin without the badge is still a normal plugin; it is not treated as unsafe simply because it is not certified. + +In LangBot Cloud, Certified Plugins and other plugins use separate allowances. The install screen shows which allowance applies before you install. Existing installations are not removed just because an older release does not carry certification. + +## Using a Certified Plugin + +1. Open the plugin in the marketplace and select a version carrying the Certified Plugin badge. +2. Install or update it from LangBot's plugin management page. +3. Configure it for your workspace as usual. +4. Use the plugin log view for workspace-scoped diagnostic records when available. + +## For plugin authors + +Certification is requested by declaring the supported certified-runtime mode in the plugin manifest and submitting a new immutable release. The declaration is only a request: LangBot Space performs an advisory automated review, a human reviewer makes the publication decision, and certification is issued only for the exact reviewed package. + +Authors should keep configuration, storage, logs, background work, and credentials scoped to the active installation and workspace. Do not rely on mutable process-global state or raw process logs. If a release cannot meet those requirements, publish it as a normal dedicated plugin instead. + +See [publishing to the marketplace](/en/plugin/dev/publish/market) for submission guidance. \ No newline at end of file diff --git a/en/plugin/dev/publish/market.mdx b/en/plugin/dev/publish/market.mdx index 76f1d3166..5b0c3926a 100644 --- a/en/plugin/dev/publish/market.mdx +++ b/en/plugin/dev/publish/market.mdx @@ -78,6 +78,14 @@ Plugin built successfully: dist/tmp/RockChinQ-HelloPlugin-0.1.0.lbpkg You can now check your plugin submission task at [LangBot Plugin Marketplace](https://space.langbot.app/market). Please wait for approval, after which you can view your plugin in the marketplace. +## Request Certified Plugin review + +If your release is designed for the Certified Plugin requirements, declare the supported certified runtime mode in `manifest.yaml` and submit a **new version**. This declaration requests review; it does not grant a badge or change runtime behavior by itself. + +LangBot Space checks the exact submitted package, runs an advisory code review, and requires a human approval before a Certified Plugin badge can be issued. Certification is bound to the reviewed package version and checksum. Keep workspace configuration, storage, credentials, logs, and background work scoped to the active installation. Do not rely on mutable process-global state. + +If the review finds that the release cannot meet these requirements, publish it as a normal dedicated plugin and address the findings in a later immutable version. See [Certified Plugins](/en/plugin/certified-plugins) for user-visible behavior. + If you have any questions, you can send an email to `hello@langbot.app` or contact us through [Community](/en/insight/community). diff --git a/en/plugin/plugin-intro.mdx b/en/plugin/plugin-intro.mdx index add342e22..c49c57d27 100644 --- a/en/plugin/plugin-intro.mdx +++ b/en/plugin/plugin-intro.mdx @@ -4,7 +4,7 @@ title: "LangBot Plugins" LangBot is composed of various internal components such as Large Language Model tools, commands, messaging platform adapters, LLM requesters, and more. To meet extensibility and flexibility requirements, we have implemented a production-grade plugin system. -Each plugin runs in an independent process, managed uniformly by the Plugin Runtime. +Plugins are managed uniformly by the Plugin Runtime. Most plugins use a dedicated runtime; a reviewed release may be shown as a [Certified Plugin](/en/plugin/certified-plugins) and use the Certified Plugin allowance in LangBot Cloud. diff --git a/ja/plugin/certified-plugins.mdx b/ja/plugin/certified-plugins.mdx new file mode 100644 index 000000000..77e61d4c1 --- /dev/null +++ b/ja/plugin/certified-plugins.mdx @@ -0,0 +1,27 @@ +--- +title: "認証プラグイン" +description: "LangBot が審査済みのプラグインリリースを示す方法と、Cloud の利用枠について説明します。" +--- + +**認証プラグイン**は、LangBot の認証要件を満たした特定のプラグインリリースです。認証は作者アカウントやプラグイン名ではなく、公開済みの正確なバージョンに紐付きます。 + +## 表示される内容 + +認証済みリリースには、マーケットプレイスとプラグイン詳細に**認証プラグイン**の表示が出ます。表示がないプラグインも通常のプラグインであり、未認証だからといって安全でないことを意味しません。 + +LangBot Cloud では、認証プラグインとその他のプラグインで利用枠が分かれています。インストール前に、どちらの利用枠を使用するかが表示されます。以前の認証がないバージョンをすでに利用していても、自動的に削除されることはありません。 + +## 認証プラグインを使う + +1. マーケットプレイスでプラグインを開き、認証プラグイン表示のあるバージョンを選びます。 +2. LangBot のプラグイン管理画面からインストールまたは更新します。 +3. ワークスペースに合わせて通常どおり設定します。 +4. 利用できる場合は、プラグインログで現在のワークスペースに関連する診断記録を確認します。 + +## プラグイン作者向け + +作者は manifest で認証ランタイムモードの対応を宣言し、新しい不変リリースを提出できます。宣言は申請に過ぎません。LangBot Space は補助的なコードレビューを行い、人が公開を承認します。認証されるのは審査済みの正確なパッケージだけです。 + +設定、ストレージ、ログ、バックグラウンド処理、資格情報は、現在のインストールとワークスペースに必ず紐付けてください。可変なプロセスグローバル状態や生のプロセスログに依存しないでください。要件を満たせないリリースは、通常の専用プラグインとして公開できます。 + +提出方法は[マーケットプレイスへの公開](/ja/plugin/dev/publish/market)を参照してください。 \ No newline at end of file diff --git a/ja/plugin/dev/publish/market.mdx b/ja/plugin/dev/publish/market.mdx index 959b76ea3..21f71c1b9 100644 --- a/ja/plugin/dev/publish/market.mdx +++ b/ja/plugin/dev/publish/market.mdx @@ -78,6 +78,14 @@ Plugin built successfully: dist/tmp/RockChinQ-HelloPlugin-0.1.0.lbpkg [LangBotプラグインマーケットプレイス](https://space.langbot.app/market)でプラグイン提出タスクを確認できます。承認をお待ちください。承認後、マーケットプレイスでプラグインを表示できます。 +## 認証プラグイン審査を申請する + +認証プラグイン要件に対応するリリースでは、`manifest.yaml` に対応する認証ランタイムモードを宣言し、**新しいバージョン**を提出します。宣言は審査申請であり、表示の付与やランタイム動作の変更を単独で行うものではありません。 + +LangBot Space は提出された正確なパッケージを確認し、補助的なコードレビューを実行したうえで、人による承認後にのみ認証プラグインの表示を発行します。認証は審査済みのパッケージバージョンとチェックサムに紐付きます。ワークスペース設定、ストレージ、資格情報、ログ、バックグラウンド処理は、現在のインストールに必ず紐付けてください。可変なプロセスグローバル状態に依存しないでください。 + +要件を満たせない場合は通常の専用プラグインとして公開し、後続の不変バージョンで修正してください。ユーザー向けの説明は[認証プラグイン](/ja/plugin/certified-plugins)を参照してください。 + ご質問がある場合は、`hello@langbot.app`にメールを送信するか、[コミュニティ](/ja/insight/community)を通じてお問い合わせください。 diff --git a/ja/plugin/plugin-intro.mdx b/ja/plugin/plugin-intro.mdx index 68dd420a5..f23ffd760 100644 --- a/ja/plugin/plugin-intro.mdx +++ b/ja/plugin/plugin-intro.mdx @@ -4,7 +4,7 @@ title: "LangBotプラグイン" LangBotは、大規模言語モデルツール、コマンド、メッセージングプラットフォームアダプター、LLMリクエスターなど、さまざまな内部コンポーネントで構成されています。拡張性と柔軟性の要件を満たすために、本番環境グレードのプラグインシステムを実装しました。 -各プラグインは独立したプロセスで実行され、Plugin Runtimeによって統一的に管理されます。 +プラグインは Plugin Runtime により統一して管理されます。多くのプラグインは専用ランタイムを使用し、審査済みのリリースは[認証プラグイン](/ja/plugin/certified-plugins)として表示され、LangBot Cloud では認証プラグインの利用枠を使用します。 diff --git a/sitemap-alternates.xml b/sitemap-alternates.xml index 88cd9ce3d..86f94335d 100644 --- a/sitemap-alternates.xml +++ b/sitemap-alternates.xml @@ -1911,6 +1911,27 @@ + + https://langbot.app/docs/en/plugin/certified-plugins + + + + + + + https://langbot.app/docs/zh/plugin/certified-plugins + + + + + + + https://langbot.app/docs/ja/plugin/certified-plugins + + + + + https://langbot.app/docs/en/plugin/compatibility diff --git a/tests/agent-static-build.test.mjs b/tests/agent-static-build.test.mjs index 0abc55a5a..9ee1c33f0 100644 --- a/tests/agent-static-build.test.mjs +++ b/tests/agent-static-build.test.mjs @@ -22,7 +22,7 @@ function links(node, result = []) { } test("every sitemap page has meaningful canonical Markdown and HTML discovery", async () => { - assert.equal(urls.length, 482); + assert.equal(urls.length, 485); for (const url of urls) { const route = relative(url); const text = await read(`${route}.md`); diff --git a/tests/fumapress-migration.test.mjs b/tests/fumapress-migration.test.mjs index 7738db42c..a99888ae5 100644 --- a/tests/fumapress-migration.test.mjs +++ b/tests/fumapress-migration.test.mjs @@ -170,8 +170,8 @@ test("MDX compatibility normalization removes internal .html route suffixes", () test("canonical MDX and nested OpenAPI sources are discovered", async () => { const docs = JSON.parse(await readFile(path.join(root, "docs.json"), "utf8")); const pages = await collectMdxDocuments(root); - assert.equal(pages.length, 305); - assert.deepEqual(Object.fromEntries([...pages.reduce((acc, page) => acc.set(page.split("/", 1)[0], (acc.get(page.split("/", 1)[0]) ?? 0) + 1), new Map()).entries()]), { en: 97, zh: 111, ja: 97 }); + assert.equal(pages.length, 308); + assert.deepEqual(Object.fromEntries([...pages.reduce((acc, page) => acc.set(page.split("/", 1)[0], (acc.get(page.split("/", 1)[0]) ?? 0) + 1), new Map()).entries()]), { en: 98, zh: 112, ja: 98 }); assert.deepEqual(collectOpenApiSources(docs), [ { locale: "en", source: "openapi/service-api-en.json", directory: "en/api-reference" }, { locale: "zh", source: "openapi/service-api-zh.json", directory: "zh/api-reference" }, @@ -216,7 +216,7 @@ test("prebuild is deterministic and preserves local assets and SEO files", async const first = await prepareFumapress({ root, outRoot: temp }); const second = await prepareFumapress({ root, outRoot: temp }); assert.deepEqual(first, second); - assert.equal(first.documents, 305); + assert.equal(first.documents, 308); assert.equal(first.fallbackDefaults, 0); assert.equal(first.localeOnlyDocuments, 14); assert.equal(first.redirects, 103); diff --git a/tests/fumapress-static-build.test.mjs b/tests/fumapress-static-build.test.mjs index 6f46f0495..a371ca471 100644 --- a/tests/fumapress-static-build.test.mjs +++ b/tests/fumapress-static-build.test.mjs @@ -43,9 +43,9 @@ function staticHtmlForUrlPath(urlPath) { return path.join(publicRoot, ...parts, "index.html"); } -test("all 305 canonical localized documents have static HTML", async () => { +test("all 308 canonical localized documents have static HTML", async () => { const documents = await collectMdxDocuments(root); - assert.equal(documents.length, 305); + assert.equal(documents.length, 308); const missing = []; for (const document of documents) { try { @@ -202,6 +202,7 @@ test("canonical sitemap routes match the legacy Mintlify directory structure", a // New guides added after migration extend, rather than replace, the legacy routes. for (const locale of ["en", "zh", "ja"]) { legacy.add(`/${locale}/usage/platforms/mattermost`); + legacy.add(`/${locale}/plugin/certified-plugins`); } const sitemap = await readFile(path.join(publicRoot, "sitemap.xml"), "utf8"); const actual = new Set([...sitemap.matchAll(/https:\/\/langbot\.app\/docs(\/[^<]+)<\/loc>/g)] diff --git a/tests/locale-static-build.test.mjs b/tests/locale-static-build.test.mjs index 96cb1900d..3cd370884 100644 --- a/tests/locale-static-build.test.mjs +++ b/tests/locale-static-build.test.mjs @@ -35,6 +35,6 @@ test("every localized HTML payload includes the preference client provider", asy } } for (const locale of ["en", "zh", "ja"]) await visit(path.join(root, locale)); - // 482 canonical content pages plus one framework 404 page per locale. - assert.equal(count, 485); + // 485 canonical content pages plus one framework 404 page per locale. + assert.equal(count, 488); }); diff --git a/zh/plugin/certified-plugins.mdx b/zh/plugin/certified-plugins.mdx new file mode 100644 index 000000000..af406e372 --- /dev/null +++ b/zh/plugin/certified-plugins.mdx @@ -0,0 +1,27 @@ +--- +title: "认证插件" +description: "了解 LangBot 如何标识已审核的插件版本,以及 Cloud 中的额度使用方式。" +--- + +**认证插件**是通过 LangBot 审核要求的某个具体插件版本。认证绑定到已发布的精确版本,而不是作者账号或插件名称。 + +## 你会看到什么 + +认证版本会在扩展市场和插件详情中显示**认证插件**标识。没有该标识的插件仍是正常插件;未认证不等于不安全。 + +在 LangBot Cloud 中,认证插件与其他插件使用不同的额度。安装前,界面会明确提示本次安装使用哪一类额度。已有安装不会因为旧版本没有认证而被自动删除。 + +## 使用认证插件 + +1. 在市场打开插件,选择带有认证插件标识的版本。 +2. 从 LangBot 的插件管理页面安装或更新。 +3. 按工作区正常配置并使用。 +4. 可用时,通过插件日志查看与当前工作区相关的诊断记录。 + +## 给插件作者 + +作者可在 manifest 中声明希望支持的认证运行模式,并提交新的不可变版本。声明只是申请:LangBot Space 会先进行辅助代码审查,再由人工审核发布;只有经过审核的精确插件包才会获得认证。 + +请让配置、存储、日志、后台工作和凭据都与当前安装和工作区绑定。不要依赖可变的进程全局状态或原始进程日志。无法满足这些要求的版本,仍可作为普通专属插件发布。 + +提交说明请参阅[发布到插件市场](/zh/plugin/dev/publish/market)。 \ No newline at end of file diff --git a/zh/plugin/dev/publish/market.mdx b/zh/plugin/dev/publish/market.mdx index 5b0de4aa2..fd5f8ce3b 100644 --- a/zh/plugin/dev/publish/market.mdx +++ b/zh/plugin/dev/publish/market.mdx @@ -78,6 +78,14 @@ Plugin built successfully: dist/tmp/RockChinQ-HelloPlugin-0.1.0.lbpkg 您现在可以在[LangBot 插件市场](https://space.langbot.app/market)查看您的插件提交任务。请等待审核通过后,您可以在插件市场查看您的插件。 +## 申请认证插件审核 + +如果该版本准备满足认证插件要求,请在 `manifest.yaml` 中声明支持的认证运行模式,并提交一个**新版本**。声明只是申请,不会自行获得标识,也不会自行改变运行行为。 + +LangBot Space 会检查本次提交的精确插件包,进行辅助代码审查,并在人工批准后才签发认证插件标识。认证绑定到已审核的插件版本与校验和。请让工作区配置、存储、凭据、日志和后台工作都与当前安装绑定,不要依赖可变的进程全局状态。 + +如果审核发现该版本无法满足要求,请先作为普通专属插件发布,并在后续不可变版本中修复问题。用户侧说明见[认证插件](/zh/plugin/certified-plugins)。 + 有任何问题,您可以发送邮件到`hello@langbot.app`或通过[社区](/zh/insight/community)联系我们。 diff --git a/zh/plugin/plugin-intro.mdx b/zh/plugin/plugin-intro.mdx index 23bc67feb..c6d29f052 100644 --- a/zh/plugin/plugin-intro.mdx +++ b/zh/plugin/plugin-intro.mdx @@ -4,7 +4,7 @@ title: "LangBot 插件" LangBot 内部由多种组件组成,如大模型工具、命令、消息平台适配器、大模型请求器等。为了满足扩展性和灵活性的需求,我们实现了一套生产级的插件系统。 -每个插件被运行在独立的进程中,由 Plugin Runtime 统一管理。 +插件由 Plugin Runtime 统一管理。大多数插件使用专属运行时;通过审核的版本会显示为[认证插件](/zh/plugin/certified-plugins),并在 LangBot Cloud 中使用认证插件额度。