# 创建包 — AI Game Dev 应用与 CLI · AI Game Developer Wiki

编写你自己的 AI Game Dev 包：aigd-package.json 清单、命令、斜杠命令、MCP 工具，用 gamedev pkg dev 本地开发，以及分享。

本页由英文机器翻译而成。[阅读英文原文](https://ai-game.dev/docs/wiki/app/creating-packages)。

包并不专属于第一方功能：你也可以自己编写包，用来与团队分享重复性任务、为 agent 添加工具，或预览自定义文件格式。本页介绍包的目录结构、一个最小可用的包、主要清单字段、如何添加 MCP 工具、如何针对正在运行的应用开发包，以及如何分享它。

## 你需要什么

- AI Game Dev 桌面应用或 `gamedev` CLI，版本 0.18.0 或更高。
- 一个文本编辑器。JavaScript 是可选的：包可以只有清单。

包遵循 VS Code 扩展的模型：一个包含清单 `aigd-package.json` 的文件夹，以及可选的代码，代码导出 `activate(ctx)` 和 `deactivate()`。你的代码只能通过 `ctx.aigd` 访问应用。它运行在独立的扩展宿主进程中，每个打开的项目一个，并在需要时惰性启动。

## 包的目录结构

```text
my-first-package/
  aigd-package.json     the manifest (required)
  extension.js          the code named by "main" (optional)
  media/                icons and images (optional)
  LICENSE
```

包必须自包含：应用不会为它运行 `npm install`。如果你的代码使用了库，请把它们打包进 `main` 指向的文件中。

## 一个最小的包

这个包添加了一个 `/my-first` 斜杠命令、一个命令面板条目、一个编写器工具栏按钮、一个状态栏项和一个设置。

```json
{
  "publisher": "you",
  "name": "my-first-package",
  "version": "0.1.0",
  "displayName": "My First Package",
  "description": "A /my-first slash command, a palette command, a toolbar button and a status bar item.",
  "license": "MIT",
  "main": "extension.js",
  "engines": { "aigd": ">=0.18.0" },
  "activationEvents": ["onSlashCommand:/my-first", "onCommand:you.my-first-package.hello"],
  "contributes": {
    "commands": [
      { "command": "you.my-first-package.hello", "title": "Say hello", "category": "My First Package", "icon": "$(smile)" }
    ],
    "slashCommands": [
      { "name": "/my-first", "description": "Say hello from my first package", "argumentHint": "[name]" }
    ],
    "menus": {
      "composer/toolbar": [{ "command": "you.my-first-package.hello", "group": "navigation" }]
    },
    "statusBar": [
      { "id": "you.my-first-package.status", "text": "My package", "command": "you.my-first-package.hello", "alignment": "left" }
    ],
    "settings": {
      "name": { "type": "string", "default": "game dev", "description": "Who /my-first greets", "scope": "project" }
    }
  }
}
```

以及代码 `extension.js`（CommonJS）：

```text
const ID = "you.my-first-package";

exports.activate = function activate(ctx) {
  const { aigd } = ctx;
  let count = 0;

  ctx.subscriptions.push(
    aigd.commands.registerCommand(`${ID}.hello`, async () => {
      count++;
      await aigd.window.showInformationMessage(`Hello #${count} from my first package!`);
      return count;
    }),
    // Works in the desktop chat and in the CLI.
    aigd.commands.registerSlashCommand("/my-first", (inv) => {
      const who = inv.args.trim() || aigd.settings.get("name") || "game dev";
      inv.say(`Hi ${who}!`);
    }),
  );

  ctx.log.info("activated");
};

exports.deactivate = function deactivate() {};
```

斜杠命令、工具栏按钮和状态栏项在任何代码运行之前就由清单呈现出来；第一次使用其中任意一项时才会调用 `activate`。

## ID 与命名规则

- 包 ID 为 `publisher.name`，全部小写：此处是 `you.my-first-package`。发布者名称长度为 2 到 40 个字符（字母、数字、单个连字符）。请使用你自己的发布者名称；`aigd` 是 AI Game Dev 的。
- 包贡献的每个 ID（命令、视图、状态栏项、教程）都以包 ID 开头：`you.my-first-package.hello`。
- `engines.aigd` 是必需的：它表示该包所需的最低 AI Game Dev 版本，例如 `">=0.18.0"`。较旧的应用会拒绝该包，并说明它需要哪个版本。
- `version` 遵循 semver。安装会按 ID 和版本缓存，因此你发布的每次更改都需要更高的版本号。

## 主要清单字段

| 字段 | 必需 | 用途 |
| --- | --- | --- |
| `publisher`、`name`、`version` | 是 | ID 和版本 |
| `engines.aigd` | 是 | 最低应用版本 |
| `displayName`、`description`、`icon`、`license`、`homepage`、`repository`、`keywords` | 否 | Packages 窗口显示的内容 |
| `main` | 否 | 代码入口；没有它，包就是仅贡献型 |
| `activationEvents` | 否 | 额外的启动代码事件，例如 `onStartupFinished` |
| `hosts` | 否 | `desktop`、`cli` 或两者 |
| `dependencies` | 否 | 其他包，`{ "<id>": "<range>" }` |
| `claudePlugins` | 否 | 包所需的 Claude 插件，`{ "<plugin>@<marketplace>": "<range>" }` |
| `contributes` | 否 | 包添加的所有内容（见下文） |

`contributes` 中的贡献点包括 `commands`、`slashCommands`、`capabilities`（会话 Tools 行中的开关）、`mcpServers`、`settings`、`panels`、`viewsContainers` 和 `views`（侧边面板中的树视图或 webview 视图）、`menus` 和 `submenus`、`keybindings`、`customEditors`、`statusBar` 和 `tutorials`。菜单使用固定 ID，例如 `commandPalette`、`composer/toolbar`、`explorer/context`、`editor/title` 和 `view/item/context`，每个都可带可选的 `when` 子句。CLI 会显示斜杠命令、Tools 行、消息、快速选择、输入框和表单；菜单和面板仅桌面端可用。

## 通过 MCP 服务器为 agent 提供工具

编写包最常见的原因就是给 agent 提供新工具。声明一个 MCP 服务器，并用一个能力按会话启用它：

```json
{
  "publisher": "you",
  "name": "level-tools",
  "version": "0.1.0",
  "engines": { "aigd": ">=0.18.0" },
  "contributes": {
    "capabilities": [
      {
        "id": "you.level-tools",
        "label": "Level tools",
        "description": "Counts collectibles in the level files.",
        "defaultEnabled": false,
        "mcpServer": "you--level-tools"
      }
    ],
    "mcpServers": {
      "you--level-tools": {
        "command": "${node}",
        "args": ["${packageDir}/server.js"]
      }
    }
  }
}
```

- 服务器名称必须是包 ID 形式的 `<publisher>--<name>`（或 `<publisher>--<name>-<suffix>`），最多 96 个字符，这样不同作者的名称永远不会冲突。不带限定前缀的名称会报错。
- 在 stdio 服务器中可使用的变量：`${node}`、`${packageDir}`、`${projectDir}` 和 `${globalStorage}`。
- 如果某个会话中已经配置了同名 MCP 服务器，则不会添加包中的服务器，并且会话中会显示一条提示。

## 针对正在运行的应用进行开发

将项目指向你的文件夹，而不是已发布的版本。该文件夹会被就地使用，当它携带的文件发生变化时会重新加载，并且永远不会自动更新。默认级别是 **Local**，它永远不会被提交。

```bash
cd <your project>
gamedev pkg link <path-to-your-package>      # use the folder (default --local)
gamedev pkg list                             # shows "(local dev)" and which level it overrides
gamedev pkg unlink you.my-first-package      # back to the published version
```

如果你的包带有构建步骤（`src/` 会构建到 `dist/`），请改用 `gamedev pkg dev`。它会运行包的 `dev` 脚本，或在每次源码变更后重新运行 `build`，在首次构建成功后链接该文件夹，并在你按下 Ctrl+C 时停止它启动的所有进程：

```bash
gamedev pkg dev <path-to-your-package>
```

在桌面应用中，同样的操作位于 Packages 窗口：选中包并选择 **Use a local folder…**，若要还原则选择 **Stop using local folder**。如果某个文件夹的 manifest 声明的是另一个 id，它会被拒绝。

**提示**

来自你的包的日志（`ctx.log`、`console.*`）会出现在应用日志中，并带有 `pkg:<your id>` 标签；运行失败的包会在 Packages 窗口的 **Errors** 选项卡中列出其错误。

## 分享你的包

AI Game Dev 注册表收录了第一方包。要分享你自己的包，可将其发布到 GitHub 或 npm；之后任何人都可以通过链接添加它：

```bash
gamedev pkg add github:you/my-first-package           # not pinned: receives updates
gamedev pkg add github:you/my-first-package@v0.1.0    # a tag (never auto-updated)
gamedev pkg add npm:my-first-package                  # an npm package
gamedev pkg add npm:my-first-package@^0.1.0           # with a version range
```

如果是团队使用，请在 **Project** 级别添加它，这样它会被提交到 `.ai-game-dev/packages.json` 中，每位队友都能获得，并由项目锁文件固定版本。

在发布新版本之前，请先提升 `aigd-package.json` 中的 `version`。如果版本号未变而文件发生了改动，这项改动永远不会到达已经安装了该版本的安装实例。

## 良好实践

- 让工具保持专注。智能体看到的每个工具都会占用上下文；一个小巧且描述清晰的工具往往更容易被正确使用。
- 在 manifest 中尽可能声明所有内容，这样在你的代码启动之前，UI 就已经可见。
- 对于团队应当共享的设置，使用 `scope: "project"`；对于某台计算机上的路径，使用 `scope: "machine"`。
- 包以你用户的权限运行，且没有沙箱。不要在包中携带密钥，并告知用户你的包会做什么。

## 了解更多

- [Packages](https://ai-game.dev/zh-hans/docs/wiki/app/packages) 介绍层级、更新和设置。
- [Packages catalog](https://ai-game.dev/zh-hans/docs/wiki/app/packages-catalog) 介绍各个第一方包的功能。
- 博文 [packages, Claude plugins and MCP servers](https://ai-game.dev/zh-hans/blog/ai-game-dev-packages-plugins-mcp) 介绍如何向实时聊天中添加 MCP 服务器。

---

Source (HTML): https://ai-game.dev/zh-hans/docs/wiki/app/creating-packages

Machine-translated (zh-Hans) from the English page: https://ai-game.dev/docs/wiki/app/creating-packages
