# 封裝規範 <Badge type="warning" text="尚未發布" />

Mini App 的已簽章封裝要讓 Micromeet 簽章、讓 Cowork 開啟，必須符合的規則：每條規則是什麼、誰檢查、不符合會怎樣。怎麼做出這個封裝請見[打包與簽章](https://docs.micromeet.ai/zh-tw/miniapp-sdk/build.md)；`micromeet-miniapp verify` 會先在你的電腦上把這些檢查跑一遍。本頁講的是已簽章的 Mini App 封裝，不是[套件](https://docs.micromeet.ai/zh-tw/miniapp-sdk/package.md)模組裡的 Cowork 套件。

| 檢查方 | 什麼時候 |
|---|---|
| **工具** | 你電腦上的 `micromeet-miniapp`（`pack`、`verify`、`zip`）和 Vite 外掛 |
| **Micromeet** | Micromeet 登記並簽章一個版本時 |
| **安裝** | Cowork 安裝這個封裝時 |
| **開啟** | Cowork 每次開啟這個 Mini App 時，以及頁面每次讀取檔案時 |

## 檔案

```text
ai.example.app-1.0.0.zip
  manifest.json
  app.asar
  app.asar.unpacked/    選用：大的媒體檔案
  INSTALL.md            選用：給安裝它的 Agent 的步驟
```

| 規則 | 檢查方 | 不符合時 |
|---|---|---|
| 這四項放在 zip（或資料夾）的根目錄；Cowork 只保留這些 | 安裝 | 其他檔案不會裝上 |
| zip：最多 100,000 個項目、解開後最多 8 GB；不能加密，不能有絕對路徑、`..`、反斜線或符號連結 | 工具、安裝 | 不安裝 |
| 不能有名為 `.DS_Store`、`__MACOSX`、`.git`、`node_modules` 的檔案或資料夾 | 工具 | `pack` 會略過它們；`app.asar.unpacked/` 裡有的話 `verify` 不通過 |

## manifest.json

| 欄位 | 規則 | 檢查方 | 不符合時 |
|---|---|---|---|
| `appId` | Micromeet 登記的 AppID：小寫反向網域，例如 `ai.example.app`，最多 128 個字元 | 工具、Micromeet、安裝 | 拒收 |
| `name` | 字串，或 `{ zh, en }`（至少一個）；1–60 個字元。不納入簽章：登入確認卡顯示的是 Micromeet 登記的名稱 | 工具、安裝 | 拒收 |
| `version` | 以字母或數字開頭；字母、數字、`.`、`+`、`-`；最多 32 個 | 工具、Micromeet | 拒收 |
| `version_code` | 12 位數字的字串，建置時間 `YYMMDDHHmmss` | 工具、安裝 | 拒收 |
| `entry` | 打包在 `app.asar` 裡（不能放在 unpacked）的檔案；相對路徑，最多 256 個字元，不能有 `..`、反斜線或控制字元。預設 `index.html` | 工具、Micromeet、安裝 | 拒收 |
| `asar` | 封存檔的檔名：字母、數字、`.`、`_`、`-`，以 `.asar` 結尾。預設 `app.asar` | 工具、安裝 | 拒收 |
| `domains` | 選用；只有要用 Micromeet 登入的 Mini App 才需要（[伺服器網域](https://docs.micromeet.ai/zh-tw/miniapp-sdk/build.md#伺服器網域)）。`https://主機[:連接埠]`，小寫、不帶路徑、不能是 IP；或 `http(s)://localhost[:連接埠]` / `127.0.0.1[:連接埠]`。不能重複，最多 20 個 | 工具、Micromeet、安裝 | 拒收。每個網域都已為這個 AppID 驗證過，Micromeet 才登記這個版本 |
| `asarHeaderSha256` | `app.asar` 前 8 + 檔頭長度個位元組的 SHA-256；由工具寫入 | 工具、Micromeet、開啟 | 視為未簽章：Cowork 不開啟 |
| `signature` | `{ kid, alg: "Ed25519", value }`，依 Micromeet 的回覆寫入 | 工具、開啟 | 視為未簽章：Cowork 不開啟 |
| `extension` | 已簽章的封裝裡不能有 | 工具、安裝 | 拒收 |

## app.asar

| 規則 | 檢查方 | 不符合時 |
|---|---|---|
| 用 `@electron/asar` 3.x 打包；檔頭與它寫出的一字不差，最大 64 MB | 工具、Micromeet、安裝 | 拒收 |
| 每個檔案（含 unpacked）都有 `integrity`：SHA-256，以 4 MB 分塊 | 工具、Micromeet、開啟 | 拒收；Cowork 視為未簽章 |
| 不能有符號連結，`app.asar` 裡和 `app.asar.unpacked/` 裡都不行 | 工具、Micromeet、安裝 | 拒收 |
| 檔名和資料夾名不能為空、`.` 或 `..`，不能含 `/`、反斜線或 NUL | 工具、Micromeet | 拒收 |
| `app.asar` 最大 512 MB；影片、音訊放進 `app.asar.unpacked/` | 工具、Micromeet | 拒收 |
| `app.asar.unpacked/` 最多 100,000 個檔案、8 GB；每個檔案的大小與檔頭記錄的一致 | 工具、安裝 | 拒收 |
| 每個檔案的位元組與它的摘要一致 | 工具、Micromeet、開啟 | Micromeet 不簽章；Cowork 關閉這個 Mini App，提示檔案被改動 |
| HTML 裡不能有內嵌 `<script>`：頁面的內容政策是 `script-src 'self'` | 工具（`pack`） | `pack` 拒收；在頁面裡這段腳本也不會執行 |

Cowork 從 `miniapp://<appId>/` 提供檔案，所以 `/assets/app.js` 這樣的絕對路徑可以用。請求其他服務不受限制。

## 簽章

Micromeet 以 Ed25519 對下面這些位元組簽章。`domains` 排序後以一個空格連接，沒有網域時最後一行為空。`name` 和圖示不納入簽章。

```text
miniapp-sig-v2
<appId>
<version>
<entry>
<asarHeaderSha256>
<domains>
```

2026-11-10 之前登記的版本用的是 `miniapp-sig-v1`（前五行，沒有網域），清單裡沒有 `domains` 時仍然有效。

| Cowork | 視為已簽章 |
|---|---|
| 正式版 Cowork | `cowork-prod-1`：Micromeet 正式環境簽章的版本 |
| Cowork Preview | `cowork-preview-1` |
| 開發執行（未打包） | 自己頻道的金鑰、`cowork-preview-1` 和 `cowork-test-1` |

## 版本與交付

| 規則 | 檢查方 | 不符合時 |
|---|---|---|
| 一個版本只能登記一次：每次交出新的建置都要改 `version` | Micromeet | 拒收 |
| 改了任何檔案、`entry` 或 `domains`，都要新版本、重新簽章 | 開啟 | 視為未簽章：Cowork 不開啟 |
| 用 zip 或資料夾單獨安裝（`miniapp_install`）：每個 `version_code` 放在自己的資料夾，舊版本在它的分頁關閉後刪除 | 安裝 | — |
| 也可以放進 Cowork 套件，複製安裝或 link 安裝；複製安裝的套件最多 2,000 個檔案、50 MB（含 `app.asar`） | 安裝 | 整個套件拒收 |

## Cowork 開啟時

- 沒有簽章、簽章的金鑰這個 Cowork 不認，或讀不出來：Cowork 不開啟，告訴使用者這個 Mini App 未經認證。
- 頁面讀取檔案時，某個檔案與摘要對不上：Cowork 關閉這個 Mini App，提示檔案被改動。
- 每個 Cowork 帳號各有一份這個 Mini App 的儲存空間，一個人看不到另一個人存的東西。
- 頁面只在 `miniapp://<appId>/` 裡跳轉；`http(s)` 連結用系統瀏覽器開啟。
- 要讓人登入，還需要 AppID 和版本在 Micromeet 處於啟用狀態，並且 `domains` 裡至少有一個驗證過的伺服器網域（請見[登入](https://docs.micromeet.ai/zh-tw/miniapp-sdk/auth.md)）。

## 相關

- [打包與簽章](https://docs.micromeet.ai/zh-tw/miniapp-sdk/build.md): 做出這個封裝並交給 Micromeet 簽章
- [登入](https://docs.micromeet.ai/zh-tw/miniapp-sdk/auth.md): 在 Mini App 裡讓使用者登入
- [概覽](https://docs.micromeet.ai/zh-tw/miniapp-sdk/overview.md): Mini App SDK 的全部模組
