Spirit Agent
下載

擴充功能

套件佈局、spiritExtension 欄位、啟動 API,以及在官方註冊表中的列出方式。

擴充功能是一個包含 package.json 的資料夾,其中含有 spiritExtension。Spirit 會為每個使用者和每個主機安裝它,而不是放在工作區的 .spirit/ 目錄下。

主機路徑
Desktop{spiritDataDir}/extensions/desktop/
CLI{spiritDataDir}/extensions/cli/

這與 Skills (SKILL.md 資料夾)、MCP (外部伺服器) 和 Hooks (hooks.json 腳本) 不同。contributes.cli.hooks 樣式化 CLI TUI 插槽。它不是 hooks.json

沒有每個擴充功能的啟用開關。安裝後,擴充功能即會貢獻內容。CLI 面板的切換是佔位符。

套件佈局

example-extension/
  package.json
  dist/index.js
  assets/icon.svg
  styles/desktop.css
  cli-hooks.json
{
  "name": "@example/spirit-extension",
  "version": "0.1.0",
  "description": "Example Spirit Agent extension.",
  "author": { "name": "example" },
  "homepage": "https://example.com/spirit-extension",
  "main": "dist/index.js",
  "spiritExtension": {
    "schemaVersion": 1,
    "displayName": "Example extension",
    "icon": "assets/icon.svg",
    "supportedHosts": ["cli", "desktop"],
    "activationEvents": ["onStartup", "onUserMessage"],
    "requestedCapabilities": [
      "tool-definitions",
      "tool-execution",
      "system-prompt",
      "settings",
      "secret-storage",
      "desktop-ui",
      "cli-ui"
    ],
    "contributes": {
      "tools": [
        {
          "name": "lookup_item",
          "description": "Look up an item by id.",
          "inputSchema": {
            "type": "object",
            "properties": {
              "id": { "type": "string" }
            },
            "required": ["id"]
          },
          "approvalMode": "allowed",
          "executionMode": "foreground"
        }
      ],
      "desktop": {
        "css": [{ "path": "styles/desktop.css" }],
        "settingsPage": { "title": "Example extension" }
      },
      "cli": {
        "hooks": { "path": "cli-hooks.json" }
      }
    },
    "settingsSchema": [
      {
        "key": "region",
        "type": "select",
        "title": "Region",
        "required": true,
        "defaultValue": "us",
        "options": [
          { "value": "us", "label": "US" },
          { "value": "eu", "label": "EU" }
        ]
      }
    ],
    "secretSlots": [
      {
        "key": "api_token",
        "title": "API token",
        "required": true
      }
    ]
  }
}

package.jsonname 是擴充功能 ID。它必須符合 ^(?:@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*$

package.json 欄位

欄位描述
name必要。npm 套件名稱;用作擴充功能 ID
version必要。版本字串
spiritExtension必要。物件。請參閱下方
description選用。字串
author選用。字串或 { name }
homepage選用。字串
main選用。activate 進入點的相對路徑。當擴充功能使用 activationEvents、工具執行或系統提示時為必要

mainspiritExtension.icon、CSS 路徑和 CLI 鉤子路徑必須是相對的,且必須位於套件內部。

spiritExtension

欄位描述
schemaVersion選用。預設為 1。僅支援 1
displayName必要。使用者可見名稱
icon選用。相對於套件根目錄的路徑
supportedHosts必要。非空的 cli 和/或 desktop 陣列
activationEvents選用。請參閱 啟動事件
requestedCapabilities選用。請參閱 功能
contributes選用。toolsdesktop 和/或 cli
settingsSchema選用。設定定義
secretSlots選用。密鑰槽定義

功能

執行環境
tool-definitions需要搭配 tool-execution 才能將 contributes.tools 暴露給模型
tool-execution需要搭配 tool-definitions 才能執行那些工具
system-prompt需要搭配 main 才能貢獻系統提示片段
desktop-ui必須與 contributes.desktop 配對
cli-ui必須與 contributes.cli 配對
approval-flow僅宣告。核准由每個工具的 approvalMode 驅動
questions-flow僅宣告。問題由 approvalMode: need-questions 驅動
settings僅宣告。設定來自 settingsSchema
secret-storagesecretSlots 搭配使用
structured-results僅宣告

desktop-ui / cli-ui 和對應的 contributes 區塊必須同時存在或同時不存在。

啟動事件

事件觸發時機
onStartup主機預熱
onExtensionInstalled在 ZIP 或 marketplace 安裝之後
onSessionOpened會話變為啟用狀態
onSessionReset會話重置
onUserMessage使用者提交訊息
onToolCall工具即將執行
onToolResult工具結果可用時
onApprovalResolved核准決定已解決時

當擴充功能列出事件且具有可讀的 main 時,主機會呼叫 activate

contributes.tools

欄位描述
name必填。[a-z0-9]+(?:[._-][a-z0-9]+)*
description必填。顯示給模型
inputSchema必填。JSON Schema 物件
outputSchema選填。JSON Schema 物件
approvalMode選填。allowedneed-approvalneed-questions
executionMode選填。foregroundbackground

模型不會直接看到 name。主機會建構一個呼叫名稱,例如 extension__{id}__{tool}__{hash}

contributes.desktop

需要 desktop-ui

欄位描述
css[].path必填。相對於套件根目錄的 CSS 檔案
css[].media選填。CSS media query
settingsPage選填。true{}{ title } — 新增 Desktop 設定項目

contributes.cli

需要 cli-uihooks 是帶有 path 的物件,不是內聯陣列:

{
  "hooks": { "path": "cli-hooks.json" }
}

檔案必須是 { "hooks": [ ... ] }

欄位說明
slot必要。下列插槽之一
variant選用。defaultaccentedmutedwarningsuccessdanger
tokens選用。{ foreground?, border?, accent? }
prefix選用。字串
suffix選用。字串

插槽:message.usermessage.assistantmessage.toolassistant.thinkinginput.framebottom_formbottom_form.sectionslash_suggestionsapproval.panelquestions.panel

Token 角色:defaultprimarysecondarymutedaccentsuccesswarningdanger

{
  "hooks": [
    {
      "slot": "input.frame",
      "variant": "accented",
      "tokens": { "border": "accent" },
      "prefix": "[",
      "suffix": "]"
    }
  ]
}

settingsSchema

欄位說明
key必要。與工具名稱的模式相同
type必要。stringbooleannumberselect
title必要。UI 標籤
description選用
placeholder選用
required選用。布林值
defaultValue選用。必須符合 type
optionsselect 必填。{ value, label, description? } 的陣列

值為 stringnumberbooleannullnull 會清除非必要設定。

secretSlots

欄位說明
key必要
title必要
description選用
required選用。布林值

Desktop 將秘密儲存在作業系統鑰匙圈中。在 CLI 守護程式路徑下,secrets.set / secrets.delete 可能無法使用。

activate

main 會以動態 import 載入。匯出以下之一:

  • export function activate(ctx) { ... }
  • export default function activate(ctx) { ... }
  • export default { activate }

ctx

欄位說明
extension{ id, name, version, directoryPath, manifestPath, main }
host主機 API。Desktop 實作 showMessageBox。CLI 為 {}
log(message: string) => void
settingsget(key)getAll()set(key, value)setAll(values)
secretsget(key)has(key)set(key, value)delete(key) — 金鑰必須在 secretSlots 中宣告
activationEvent可選。{ type, detail? }

回傳值

回傳一個物件,或從模組匯出相同的欄位。

欄位描述
toolsRecord<string, (ctx) => unknown>。鍵為 manifest 工具名稱
invokeTool(ctx) => unknown。當存在時,用來取代 tools[name]
systemPrompt靜態系統片段
getSystemPrompt() => string | Promise<string>。當存在時,用來取代 systemPrompt
onEvent(event) => void
dispose() => void。在移除或重新載入時呼叫

工具處理器 ctx

欄位描述
extensionactivate 相同的執行時期資訊
host相同的主機 API
toolNameManifest 工具名稱
arguments來自模型的物件
log相同的記錄器
settings相同的設定存取器
secrets相同的密鑰存取器
toolCallId可選
questionsResult可選。當 approvalModeneed-questions 時設定

string 結果會直接傳遞。其他值會轉為 JSON.stringify(value, null, 2)undefined 變成 ""

Desktop host.showMessageBox

欄位描述
title必填。字串
message必填。字串
detail可選。字串
buttons可選。字串陣列
cancelId可選。數字
defaultId可選。數字
noLink可選。布林值
type可選。noneinfoerrorquestionwarning
export function activate(ctx) {
  return {
    systemPrompt: "Use lookup_item when the user asks for an item by id.",
    async invokeTool({ toolName, arguments: args, settings, secrets }) {
      if (toolName !== "lookup_item") {
        throw new Error(`Unknown tool: ${toolName}`);
      }
      const region = await settings.get("region");
      const token = await secrets.get("api_token");
      return { id: args.id, region, hasToken: Boolean(token) };
    },
    dispose() {
      ctx.log("example-extension disposed");
    },
  };
}

安裝

  • ZIP — 壓縮檔必須恰好包含一個 package.json(它可以位於子目錄中)。使用 spirit extension import ./extension.zip設定 → 擴充功能 匯入。
  • Marketplace tarball — 壓縮檔根目錄必須包含 package/ 目錄。

supportedHosts 必須包含目前的主機。相同 id 的第二次安裝預設不會取代現有副本。有關頻道和安裝介面,請參閱 Marketplace

發布到官方登錄檔

SpiritAgents/registry 儲存庫是 marketplace 索引。它不託管擴充功能原始碼、dist、ZIP 檔案或 tarball。

請依序執行下列步驟:

  1. 發布一個公開的 npm 套件。
  2. 開啟一個列出該套件的 pull request。

1. 發布 npm 套件

發布的 package.json 是主要依據,尤其是 spiritExtension。註冊表建置器需要:

  • spiritExtension.schemaVersion
  • spiritExtension.displayName
  • spiritExtension.supportedHosts
  • spiritExtension.requestedCapabilities

它也會讀取 nameversiondescriptionauthorrepositoryhomepagekeywords 以及選用的 spiritExtension.icon。如果您設定了 icon,請將該檔案包含在發布的套件中。缺少 spiritExtension 物件會導致該版本的註冊表建置失敗。

官方範例:@spiritagent/extension-system-message-demospiritagent.system-message-demo)。

2. 列出套件

建立 registry/extensions/<extension-id>/,內容包含:

檔案說明
entry.json市集治理
README.md市集詳細資訊文字

請勿手動編輯這些(請重新產生):

  • registry/catalog.json
  • registry/extensions/<extension-id>/detail.json

extensionId 需要至少兩個以點分隔的區段,使用小寫字母和數字,區段內可包含點或連字號。範例:spiritagent.system-message-demoyourteam.some-extensionpackageNameextensionId 在儲存庫中必須是唯一的。

entry.json

欄位說明
schemaVersion必要。1
extensionId必要。請參閱上述規則
packageName必要。npm 套件名稱
status必要。listedhiddendeprecatedblocked
featured必要。布林值
defaultVersion必要。預設版本字串
defaultReviewStatus必要。unverifiedverifiedrevoked
versions必要。至少一個項目

每個 versions[] 項目:

欄位說明
version必要
channel必要。stablepreviewexperimental
reviewStatus必要。unverifiedverifiedrevoked
changelog選用。{ summary, body } — 存在時兩者皆為必要
{
  "schemaVersion": 1,
  "extensionId": "example.spirit-extension",
  "packageName": "@example/spirit-extension",
  "status": "listed",
  "featured": false,
  "defaultVersion": "0.1.0",
  "defaultReviewStatus": "unverified",
  "versions": [
    {
      "version": "0.1.0",
      "channel": "stable",
      "reviewStatus": "unverified",
      "changelog": {
        "summary": "Initial public release.",
        "body": "- Initial public release."
      }
    }
  ]
}

市集 README 應說明擴充功能的功能、套件名稱、預設核准版本、主機與能力相容性,以及給市集讀者的注意事項。

在本機重新產生衍生檔案:

./scripts/build-registry.ps1

此腳本會擷取所列版本的 npm 中繼資料,重建 catalog.json 和每個 detail.json,然後驗證一致性。

Pull request

包含 entry.json、市集 README.md 以及重新產生的 catalog.json / detail.json。僅列出已在 npm 上公開的版本。準確設定 reviewStatuschannel。新版本通常以 unverified 開始。

請勿提交擴充功能原始碼樹、dist、ZIP 檔案、tarball 或其他二進位成品。

開啟 pull request 並不保證會上架。在版本獲得核准或驗證之前,審查可能會要求變更。