﻿# Agentic 實戰：讓 AI Agent 完成 CLI 開發與 npm Trusted Publishing 發佈

最近我陸續上架了好幾個**專門給 Agent 用的 CLI 工具**，讓 Agent 可以直接透過終端機呼叫功能、傳入參數，再讀取結構化的結果。工具做好之後，接下來就是把它們發佈到 npm，讓其他人和 Agent 也能直接安裝使用。我原本想，這件事以前就做過了，而且一月還寫過[如何利用全新的 Trusted publishing 方法發佈 npm 套件](https://blog.miniasp.com/post/2026/01/06/How-to-publish-npm-packages-using-the-new-Trusted-publishing-method)，這次應該可以把整個流程交給 Agent 處理。

結果還是有幾個地方值得記錄：Agent 會寫程式，不代表它已經登入 npm；Workflow 寫好了，不代表 npm 已經信任它；終端機印出發佈成功，也不代表使用者馬上就能安裝。最後還有一個小插曲，我只是合併一份驗證文件，npm 就多出了一個 `0.1.1` 版本。回頭看才發現，這其實完全符合我自己下的指令。

這篇就用這次的實作過程，整理如何讓 Agent 從建立 CLI、準備 npm 套件、建立 GitHub 儲存庫，一路做到 Trusted Publisher 與 CI/CD 驗證。重點不只是那份 YAML，而是**把要做的事、發佈的時機，以及怎樣才算完成，事先講清楚**。

![AI Agent 從終端機建立 CLI，經過測試與 OIDC 信任驗證，將套件送到 npm registry；人工負責首次雙因素認證](https://stwillblogassets.blob.core.windows.net/files/images/2026/10/agentic-npm-publishing/agentic-npm-publishing-banner.webp)

> 本文整理 2026 年 10 月的操作經驗，開發環境為 macOS 26.6.2、Node.js 24.22.1、npm 12.2.1，CI 另外驗證 Node.js 22 與 24。下文統一用 `my-agent-cli` 作為示意套件名稱、`my-agent` 作為命令名稱，`your-github-account` 與 `your-npm-account` 則是示意帳號；它們不代表本文作者已發佈的特定作品。套用範例時請換成自己的資料。文中不包含登入連結、OTP、Access Token 或其他一次性認證資訊。

* * *

### 先釐清：Agent、登入帳號與 CI 是三件事

我這裡說的 Agent，是指能讀寫專案檔案、執行終端機命令，必要時還能操作瀏覽器的 AI 工具。它不是只在聊天視窗裡貼一段設定給我，而是真的會去建立檔案、執行測試、查詢遠端狀態，再根據結果繼續處理。

不過，這個能力不等於帳號權限。這次的分工可以整理成下面這張表：

| 工作  | 由誰執行 | 怎樣才算完成 |
| --- | --- | --- |
| 建立 CLI、測試與 npm 封裝 | Agent 操作本機專案 | 測試通過，封裝內容正確，安裝後能執行 |
| 首次 npm 登入與人工驗證 | Agent 啟動流程，我完成認證 | `npm whoami` 回傳預期帳號 |
| 建立公開 GitHub 儲存庫 | Agent 使用已授權的 GitHub CLI | 遠端儲存庫存在，而且能取得程式碼 |
| 設定 Trusted Publisher | Agent 操作 npm 網站，我完成必要的 2FA | 設定確實儲存，第一次 OIDC 發佈驗證成功 |
| 後續自動發佈 | GitHub Actions | 測試、OIDC 發佈、registry 驗證都成功 |

**Agent 負責操作，帳號擁有者負責完成必要的身分驗證。** 兩者可以接力，但不要把「請 AI 幫我發佈」理解成「AI 應該想辦法跳過登入」。

文中的操作提示詞也整理成[純文字附件](/attachments/2026/10/agentic-npm-publishing/agentic-publishing-prompts.txt)，可以下載後換成自己的套件名稱與 GitHub 資料。

另外，npm 帳號與 GitHub 帳號不一定相同。假設 npm 使用者是 `your-npm-account`，GitHub 使用者是 `your-github-account`，Trusted Publisher 裡面就應該填入後者。這裡要核對的是 **GitHub 的 owner 與 repository**，不是看見 npm 帳號就直接照填。這種看似很小的細節，反而很適合讓 Agent 查完之後列出來，再繼續設定。

* * *

### 步驟一：先把 CLI 的需求與驗收方式交代完整

專門給 Agent 使用的 CLI，我會特別在意輸入與輸出能不能穩定地被程式處理。例如參數要有清楚的說明、支援 STDIN、輸出 JSON、錯誤訊息與結果分流，以及用退出碼表示成功或失敗。這些約定比互動式選單更適合放進 Agent 的工作流程。

如果要重新做一次，我會把提示詞整理成這樣：

```
請在目前工作目錄建立 my-agent-cli 子資料夾，實作一個給 Agent 使用的 Node.js CLI。

請先閱讀需求及相關 API 的官方文件，列出功能、輸入與輸出契約。

需求：
- npm 套件名稱為 my-agent-cli，命令名稱為 my-agent。
- 支援以 --input 指定輸入檔案，也能從 STDIN 接收內容。
- 支援 --format json，讓 Agent 能穩定解析結果。
- 結果寫入 STDOUT；進度與錯誤寫入 STDERR。
- 以明確的退出碼區分成功、參數錯誤與執行失敗。
- 寫入檔案或呼叫遠端服務的操作，提供不產生副作用的 --dry-run。
- 提供 --help、--version、Makefile 與 README。
- 加入參數、STDIN、錯誤處理及核心功能的自動測試。

請實際執行測試、檢查 npm 封裝，並從封裝安裝後驗證 CLI。
請建立獨立 Git 儲存庫，每個完成階段使用詳細繁體中文 commit 記錄。
涉及外部服務的功能，請區分離線測試與真實服務驗證，不要混為一談。
這一步先完成本機專案，不要先發佈到 npm。
```

我特別保留 `--dry-run`，因為這會讓後續驗證簡單很多。Agent 可以先檢查參數解析、STDIN 與預計執行的操作，不必在每次測試時真的修改檔案或呼叫遠端服務。下面以支援檔案與文字輸入的示意 CLI 為例：

```bash
# 以旗標指定輸入檔案
node src/cli.js --input ./input.txt --format json --dry-run

# 從 STDIN 輸入內容
printf '%s\n' '待處理的內容' |
  node src/cli.js --format json --dry-run
```

這裡還有一個很實用的驗收點：第二個例子的 STDOUT 應該是乾淨的 JSON，不能混進「正在讀檔」或 npm script 的提示文字。CLI 要能接管線，這些小地方比多做幾個參數更重要。

如果 CLI 要存取外部服務，也要在 README 說明認證方式、可測試的範圍，以及哪些操作真的會產生副作用。不要讓 Agent 把「離線測試通過」寫成「所有外部服務都已驗證」。

* * *

### 步驟二：先確認 npm 裝到的到底是什麼

npm 的套件名稱與使用者在終端機輸入的命令名稱可以不同。以下使用示意名稱：

```json
{
  "name": "my-agent-cli",
  "version": "0.1.0",
  "type": "module",
  "bin": {
    "my-agent": "src/cli.js"
  },
  "files": ["src", "README.md", "examples", "LICENSE"],
  "engines": {
    "node": ">=22"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/your-github-account/my-agent-cli.git"
  },
  "publishConfig": {
    "access": "public",
    "registry": "https://registry.npmjs.org/"
  }
}
```

這是重點欄位節錄，實際套件還有相依套件與 scripts。`bin` 指到的檔案要有 Node.js 的 shebang，像這樣：

```javascript
#!/usr/bin/env node
```

我會要求 Agent 檢查下面幾件事，而不是看到 `package.json` 就算完成：

```
請驗證 npm 封裝：
1. 執行 npm pack --dry-run，列出將發佈的檔案。
2. 確認沒有 .env、API 金鑰、node_modules、測試暫存資料。
3. 實際產生 tgz，安裝到獨立暫存目錄。
4. 使用安裝後的 my-agent 執行 --version、--help 與 --dry-run。
5. 確認 --version 讀的是封裝內的 package.json，不是寫死在程式裡。
```

最後一點在自動升版時很容易出錯。假設 CI 把版本改成 `0.1.1`，但 CLI 裡仍然寫死 `0.1.0`，使用者安裝成功後看到的版本就會不一致。這次後來也把版本顯示改成讀取套件本身的 metadata。

`repository.url` 也要指向實際發佈的 GitHub 儲存庫，不能留著範本專案的網址。後面要驗證 provenance 時，這個來源資訊會派上用場。

* * *

### 步驟三：用最小套件完成第一次發佈

Trusted Publisher 是針對 npm 上已經存在的套件設定。這次我先發佈一個最小版本，把套件建立起來，再接 GitHub Actions。

**這是這次選用的初始化方式，不代表每個專案都應該先發佈空套件。** 如果你的 CLI 已經準備好，也可以直接手動發佈第一個可用版本；如果這個 npm 套件原本就存在，更不需要再做一次初始化。

我當時已經有完整 CLI，所以沒有把根目錄的程式刪掉，而是另外建立 `release/placeholder/`：

```
release/placeholder/
├── package.json
├── README.md
└── LICENSE
```

裡面的 `package.json` 只有最基本的資訊：

```json
{
  "name": "my-agent-cli",
  "version": "0.0.0",
  "description": "Initial placeholder for an agent-oriented CLI.",
  "license": "MIT",
  "files": ["README.md", "LICENSE"],
  "publishConfig": {
    "access": "public",
    "registry": "https://registry.npmjs.org/"
  }
}
```

我下給 Agent 的指令是：

```
請先確認 my-agent-cli 在 npm 的名稱狀態與目前登入帳號。
準備 0.0.0 的最小套件，清楚標示這個版本不含可執行 CLI。
保留根目錄已完成的實作，只發佈 release/placeholder/。
先檢查 tarball 內容，再發佈；需要登入或 2FA 時讓我在瀏覽器完成。
```

實際會用到這幾個命令：

```bash
npm whoami --registry=https://registry.npmjs.org/
npm view my-agent-cli versions --json
npm pack ./release/placeholder --dry-run
npm login --registry=https://registry.npmjs.org/
npm publish ./release/placeholder --access public
```

第一次的 `npm whoami` 回傳 `401 Unauthorized`，因此 Agent 啟動登入流程，讓我在 npm 的網頁完成認證。登入成功後，再次查詢才看到預期的帳號。

這裡不要把查詢套件時的 `404` 當成「這個名稱一定可以註冊」的保證。它只能說明當下這次查詢沒有取得套件，真正能不能發佈，還是要看 registry 的驗證結果。

* * *

### 步驟四：建立 GitHub 儲存庫，先決定什麼時候發佈

接著我要求 Agent 把專案放到公開 GitHub 儲存庫，並且加入 PR 驗證與 npm Trusted Publishing。這一步建議把 GitHub 帳號、儲存庫名稱、workflow 檔名與發佈規則一起寫清楚：

```
請將這個專案發佈到我的公開 GitHub 儲存庫：
your-github-account/my-agent-cli

建立以下 CI/CD：
- PR 對 main 執行測試與封裝檢查，不發布套件。
- 測試 Node.js 22 與 24，作業系統包含 Linux、macOS、Windows。
- 所有測試通過後才允許發布。
- npm 發布 workflow 檔名固定為 publish.yml。
- 使用 GitHub-hosted runner 與名為 npm 的 GitHub environment。
- 使用 OIDC Trusted Publishing，不設定 NPM_TOKEN 或 NODE_AUTH_TOKEN。
- workflow_dispatch 可以手動重跑。

這次採用的發布規則：每次 main push 都發布新的穩定版本，
包含文件變更；第一個完整版本是 0.1.0，之後自動遞增 patch。
請不要把 CI 產生的版本更新再 commit 回 main。
相同 commit 已發布時，重跑必須跳過，不能重複發布。
```

最後那一段，最好在一開始就決定。

我這次最初只說「main 有新的 commits 就發佈」，後來 Agent 合併一份驗證文件，果然就觸發了 `0.1.1`。當我問「為什麼又發佈一個版本」，回頭看規則才發現，**文件 commit 也是 commit**。

如果你的預期是「只有調整 `package.json` 版本才發佈」，就要明確指定這個條件，並要求已存在的版本直接跳過。不要一邊採用每次 push 自動升版，一邊期待文件變更不會產生版本。

這不是要多加一道確認流程，而是避免把兩種不同的發佈策略混在一起。

* * *

### 步驟五：把 PR 測試與發佈權限分開

其中一個專案的 CI 使用六組測試環境：三種作業系統，各跑 Node.js 22 與 24。當時共有 28 項自動測試，涵蓋參數、STDIN、錯誤處理、核心功能與版本選擇。不同工具的測試內容會不同，但都要驗證 Agent 實際依賴的輸入與輸出契約。

`ci.yml` 的結構如下。下面保留主要設定；實際專案會把 Actions 固定到完整 commit SHA，可以交給 Agent 依專案的測試命令產生對應檔案。

```yaml
name: CI

on:
  pull_request:
    branches: [main]
  workflow_call:
  workflow_dispatch:

permissions:
  contents: read

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node: [22, 24]
    steps:
      - uses: actions/checkout@v7.0.1
        with:
          persist-credentials: false
      - uses: actions/setup-node@v7.1.0
        with:
          node-version: ${{ matrix.node }}
          cache: npm
      - run: npm ci
      - run: npm run check
      - run: npm test
      - run: npm pack --dry-run

  passed:
    name: Tests passed
    needs: test
    if: always()
    runs-on: ubuntu-latest
    steps:
      - name: Require all test jobs to pass
        env:
          TEST_RESULT: ${{ needs.test.result }}
        run: test "$TEST_RESULT" = success
```

`Tests passed` 是一個統一的檢查名稱，可以放進 main 分支的必要檢查。`if: always()` 是讓前面的測試失敗時，這個檢查仍然有機會執行；它接著會檢查測試結果，並不是把失敗變成成功。

不過，看到 Workflow 有這個 job，還不能直接說「PR 已經不能亂合併」。要再確認 GitHub 的分支保護規則真的把它列為必要檢查，以及管理員是否保留略過規則的權限。這次的設定有保留管理員略過，因此不能宣稱任何人都無法直接推送。

我另外讓 Agent 建立一個小型文件 PR，實際跑完六組 CI，看到必要檢查通過後才合併。這比只檢查 YAML 語法，更能證明 PR 事件與檢查名稱接得起來。

* * *

### 步驟六：在 npm 網站設定 Trusted Publisher

這次我直接要求 Agent 使用瀏覽器操作 npm 網站：

```
請使用瀏覽器，開啟 my-agent-cli 的 npm Settings。
新增 GitHub Actions Trusted Publisher，設定為：

Organization or user: your-github-account
Repository: my-agent-cli
Workflow filename: publish.yml
Environment name: npm
Allowed actions: 允許 npm publish

請實際完成儲存並核對畫面上的設定。
如果出現登入、2FA 或需要我操作的瀏覽器認證，
停在該畫面交由我完成；完成後請繼續，不要把它當成設定已成功。
```

這幾個欄位要能對得起來：

| npm 設定 | 對應的 GitHub 設定 |
| --- | --- |
| Organization or user：`your-github-account` | 儲存庫擁有者 |
| Repository：`my-agent-cli` | 儲存庫名稱 |
| Workflow filename：`publish.yml` | `.github/workflows/publish.yml`，欄位只填檔名 |
| Environment name：`npm` | 發佈 job 的 `environment: npm` |
| 允許 `npm publish` | Workflow 確實執行 `npm publish` |

`Environment name` 不是 npm 的帳號，也不是儲存庫名稱。我另外把 GitHub 的 `npm` environment 限制成只允許 main 分支部署，讓這個發佈入口有明確範圍。

還有一個與一月文章不同的地方：目前的介面有 **Allowed actions**。依[官方文件](https://docs.npmjs.com/trusted-publishers/#for-github-actions)，新連線會允許 `npm stage publish`；如果要像這次一樣直接發佈，還要允許 `npm publish`，不能只把前面幾個文字欄位填好就結束。

這次我先完成了一次登入認證，送出 Trusted Publisher 表單時，npm 又要求了一次 2FA。Agent 因此停在驗證畫面等我接手。**已登入 npm 網站，不代表每一個帳號設定操作都不需要再次驗證。**

完成後，畫面先顯示連線已加入，狀態則是 `Pending validation`。等到 GitHub Actions 真正用 OIDC 發佈成功，才看到 `Valid`。所以我把「已填表」、「已儲存」與「已驗證」當成三個不同的進度，不再只看 Agent 說了一句完成。

* * *

### 步驟七：讓 GitHub Actions 自己取得發佈身分

先更新一個版本資訊：一月那篇文章的環境說明，不能原封不動沿用到現在。本文查閱時，npm 的 [Trusted Publishing 文件](https://docs.npmjs.com/trusted-publishers/)列出 npm CLI 至少 `11.5.1`、Node.js 至少 `22.14.0`。我這次的發佈 job 使用 Node.js 24，另外明確安裝 npm `12.2.1`。

不要只寫「LTS 應該夠新」就算了，請讓 Agent 查目前支援範圍，再把實際測試版本記錄下來。

下面是搭配前面 `ci.yml` 的發佈流程。為了閱讀方便，Actions 使用版本標籤；實際專案固定完整 SHA。這份範例在發佈 job 關閉 `setup-node` 快取，CI 測試仍可使用自己的 npm 快取。它會用到下方說明的兩個版本管理腳本，並不是單獨貼一份 YAML 就能完成的範例。

```yaml
name: Publish npm

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: npm-publish
  queue: max
  cancel-in-progress: false

jobs:
  ci:
    uses: ./.github/workflows/ci.yml

  publish:
    needs: ci
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: npm
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@v7.0.1
        with:
          persist-credentials: false
      - uses: actions/setup-node@v7.1.0
        with:
          node-version: 24
          package-manager-cache: false
      - run: npm install --global npm@12.2.1
      - run: npm ci
      - name: Select an unpublished version
        id: release
        run: node scripts/prepare-release.mjs
      - name: Publish using GitHub OIDC
        if: steps.release.outputs.publish == 'true'
        run: npm publish --provenance --access public --tag latest
      - name: Verify registry propagation
        if: steps.release.outputs.publish == 'true'
        run: node scripts/verify-release.mjs
```

這裡有幾個設計是刻意分開的：

-   PR 測試只需要 `contents: read`，沒有 `id-token: write`。
-   發佈 job 才取得 OIDC 權限，而且必須等 `ci` 成功。
-   沒有設定 `NPM_TOKEN` 或 `NODE_AUTH_TOKEN` 來執行 `npm publish`。
-   `environment: npm` 必須與 npm 網站的設定一致。
-   測試可以重用 workflow，但這次把真正的 `npm publish` 留在 `publish.yml`，減少辨識發佈 workflow 時的混淆。

範例保留 `--provenance`，讓命令的意圖清楚。以本文使用的公開 GitHub 儲存庫與 npm 套件而言，目前 Trusted Publishing 也會自動產生 provenance；它不是要求另外建立一個祕密變數。

這次都是公開相依套件。如果你的 `npm ci` 必須安裝私有套件，那是另一個需要處理的讀取授權，不能因為發佈已經有 OIDC，就推論私有套件安裝也不用認證。

套用時請讓 Agent 把這兩份 workflow 與專案的 scripts 一起驗證。上面的發佈範例另外需要 [prepare-release.mjs](/attachments/2026/10/agentic-npm-publishing/prepare-release.mjs) 與 [verify-release.mjs](/attachments/2026/10/agentic-npm-publishing/verify-release.mjs)；下載後放到專案的 `scripts/`，或由 Agent 依相同規則實作。

* * *

### 步驟八：處理自動升版與重跑，避免下一次發佈撞版本

如果選擇「每次 main push 都發佈」，就不能永遠把 `package.json` 留在同一個版本，然後期待 `npm publish` 自動幫你遞增。

範例中的 [prepare-release.mjs](/attachments/2026/10/agentic-npm-publishing/prepare-release.mjs) 會先讀取 registry，再決定這次是否需要發佈：

```
查詢 registry 的所有版本
如果目前 commit 已經發布過：
    輸出 publish=false，跳過
否則：
    找出最高的穩定版本
    如果專案設定的版本比它高，使用專案版本
    否則，把最高穩定版本的 patch 加一
    只更新 CI 工作目錄的版本與 gitHead
```

例如，registry 只有初始化的 `0.0.0`，專案版本是 `0.1.0`，第一次就發佈 `0.1.0`。下一次 main push 再變成 `0.1.1`。如果我要開始 `0.2.0`，則可以明確調整專案版本。

**不要為了自動升版，把版本更新再推回 main，然後又觸發下一次自動升版。** 這次只修改 runner 的工作目錄，不建立版本 commit。

我也要求 Agent 把「同一個 commit 重跑」納入測試。發佈失敗後重試很正常，但若前一次其實已經成功，下一次就應該辨識出來並跳過，而不是憑空多產生一個版本。

另外，這個查版本、再發佈的過程需要排隊，避免兩個工作同時算出同一個下一版。上面的 `queue: max` 是依本文查閱時的 [GitHub concurrency 文件](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency)設定；一般 concurrency 預設只保留一個 pending 工作，不能想當然地以為每次 push 都會完整排隊等待。這個設定也不是無限佇列，官方上限是 100 個等待工作。

* * *

### 步驟九：不要只看見成功訊息，就說已經上架

這次最值得補進驗收提示詞的，就是下面這段：

```
請逐項驗證，不要把不同階段混成一句「已完成」：

1. Trusted Publisher 的設定已儲存，欄位與 GitHub 相符。
2. GitHub Actions 的測試工作全部通過。
3. 發佈 job 使用 OIDC 成功，不需要人工 npm login 或寫入 token。
4. npm registry 能查到指定版本，latest 指向預期版本。
5. registry 的 gitHead 對應本次發佈 commit。
6. tarball 能下載，且可找到 provenance 資訊。
7. 用指定版本安裝後，實際執行 CLI 的 --version 與 --dry-run。

如果 npm 仍在處理，請回報「發布請求已接受，尚未驗證可下載」，
不要重複發布同一版，也不要改用另一個版本掩蓋尚未查明的問題。
```

我第一次發佈時，終端機印出了成功訊息，但 registry 還查不到指定版本。Agent 一度只確認到名稱已建立，後來才確認版本真的能下載。這兩個時間點應該分開記錄。

完整版本的檢查可以這樣做：

```bash
npm view my-agent-cli@0.1.0 version gitHead dist.tarball --json
npm view my-agent-cli dist-tags --json
npm view my-agent-cli@0.1.0 dist.attestations --json

npm exec --yes --package=my-agent-cli@0.1.0 -- my-agent --version
npm exec --yes --package=my-agent-cli@0.1.0 -- \
  my-agent --input ./input.txt --format json --dry-run
```

上面的套件名稱與命令名稱都是示意，請換成自己已審查並發佈的工具，再執行 `npm exec`。最後一個命令只驗證安裝後的 CLI 與 dry-run 行為；如果工具會存取外部服務，不能拿這個結果宣稱真實服務的整合也已完成。

這次最後確認到：`0.1.0` 是透過 GitHub Actions 的 OIDC 發佈，registry 有對應的 `gitHead` 與 provenance 資訊，安裝後的 `--version` 與 `--dry-run` 也能正常執行。後續文件合併觸發的 `0.1.1`，同樣有成功的 workflow 紀錄。

* * *

### 初始化版本用完了，清理也要精準指定

正式版本完成後，我要求 Agent 下架初始化的 `0.0.0` 與當時出現的 `0.0.0-stage`，留下可用的 CLI 版本：

```bash
npm unpublish my-agent-cli@0.0.0
npm unpublish my-agent-cli@0.0.0-stage
```

這裡要明確指定版本。**不要把只想移除兩個測試版本的需求，改寫成移除整個套件。** 能否下架仍受 [npm unpublish 規則](https://docs.npmjs.com/cli/v12/commands/npm-unpublish/)限制，而且同一個套件名稱與版本在下架後不能重新使用。

`0.0.0-stage` 也不能跟我自己建立的 `0.0.0` 混為一談。[npm 的 staged publishing 文件](https://docs.npmjs.com/staged-publishing/)有說明這個 placeholder 版本；這次確實在 registry 看過它，但當時的 `npm stage list` 是空的，所以我沒有要求 Agent 憑這個版本名稱就推論還有一個等待人工核准的工作。

實際清理時，npm 對兩次下架分別要求了瀏覽器驗證。完成後，Agent 再查版本清單與兩份 tarball，確認版本已消失、下載回傳 `404`，同時 `0.1.0` 與 `0.1.1` 都還存在。這才算清理完成。

* * *

### 總結

這次從 CLI 開發到 npm 上架，大部分的檔案與網站操作確實都交給 Agent 做了。它可以查文件、寫測試、建立儲存庫、設定 workflow、操作 npm 表單，也可以在失敗後繼續找原因。我需要做的，則是說清楚需求與發佈策略，完成必要的帳號驗證，再看它拿出的證據。

我覺得 Agentic 版本最有價值的地方，是把原本散在終端機、GitHub 與 npm 網站的操作接起來。但接起來之後，**更要分清楚哪一步只是已送出、哪一步已經被接受、哪一步真的可以交付給使用者**。

下次要交給 Agent 做類似工作，我會先講清楚三件事：**發佈什麼、何時發佈、如何驗收**。至於「main 有 commit 就發佈」這句話，現在我會連文件變更也一起想清楚，再交出去。

* * *

### 相關連結

-   [如何利用全新的 Trusted publishing 方法發佈 npm 套件](https://blog.miniasp.com/post/2026/01/06/How-to-publish-npm-packages-using-the-new-Trusted-publishing-method)
-   [Trusted publishing for npm packages](https://docs.npmjs.com/trusted-publishers/)
-   [Staged publishing for npm packages](https://docs.npmjs.com/staged-publishing/)
-   [npm unpublish](https://docs.npmjs.com/cli/v12/commands/npm-unpublish/)
-   [GitHub Actions：Control workflow concurrency](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency)
