feat(cli): 章節與寫作命令(fox chapters/fox generate,issue #43)

- fox chapters list/get/create/update/delete:對接 #40 章節 CRUD 端點;
  公開命令(list/get)在持有 token 時自動帶上(作者本人可見 draft/hidden)。
- fox generate draft/continue/rewrite/usages:對接 #42 生成 API;
  需 generate scope 的 access token。
- 補齊 M3:fox novels list/create/update(Bearer 授權)+
  tokens create --scopes。
- --content/--prompt/--previous-context 支援 '-' 從 stdin 讀多行內容。
- 輸出維持單一 JSON(stdout)、exit code 0/1/2 規範不變。
- cli/README.md:命令表、授權說明與 M3 里程碑更新。

本機後端(Postgres+NestJS,echo 供應商)端到端實測 44 項全過。
This commit is contained in:
2026-09-06 23:32:48 +08:00
parent 7e05fd87c3
commit 77f30c1b6f
3 changed files with 421 additions and 17 deletions
+18 -7
View File
@@ -1,6 +1,6 @@
# Fox CLI — 與 Fox 後端互動的命令列工具
> 專案狀態:M0–M2 已實作(M1:HTTP client、設定讀取、`tokens verify`/`auth status`;M2:`tokens create/list/revoke`、公開的 `novels get`)|日期:2026-09-04
> 專案狀態:M0–M3 已實作(M1:HTTP client、設定讀取、`tokens verify`/`auth status`;M2:`tokens create/list/revoke`、公開的 `novels get`;M3:`novels list/create/update`、`chapters …`、`generate …`)|日期:2026-09-06
`fox` 是一個命令列工具,讓人與 **AI agent** 不經過前端,直接與 Fox 後端 API 互動:查詢/建立/編輯作品、管理 access token 等。目標是「一句命令拿到機器可解析的結果」,方便腳本、CI 與 agent 排程使用。
@@ -31,15 +31,26 @@
|------|----------|------|
| `fox auth status` | `GET /auth/status` | 查詢登入/SSO 設定(公開) |
| `fox tokens verify` | `GET /access-tokens/verify` | 驗證手中 token 是否有效 |
| `fox tokens create --name <名稱> [--expires-at <ISO8601>]` | `POST /access-tokens` | 建立新 token(回傳只出現一次的原始值) |
| `fox tokens create --name <名稱> [--expires-at <ISO8601>] [--scopes read,write,generate]` | `POST /access-tokens` | 建立新 token(回傳只出現一次的原始值) |
| `fox tokens list` | `GET /access-tokens` | 列出 token(不含 hash/原始值) |
| `fox tokens revoke <id>` | `DELETE /access-tokens/:id` | 撤銷 token(冪等) |
| `fox novels get <slug>` | `GET /novels/:slug` | 查單一作品(公開) |
| `fox novels list` | `GET /novels` | 列出自己的作品(需授權,見下) |
| `fox novels create --title <書名> [--slug <slug>] [--synopsis <簡介>]` | `POST /novels` | 建立作品(需授權,見下) |
| `fox novels update <slug> [--title ...] [--slug ...] [--synopsis ...]` | `PATCH /novels/:slug` | 更新作品(需授權,見下) |
| `fox novels list` | `GET /novels` | 列出自己的作品(需授權) |
| `fox novels create --title <書名> [--slug <slug>] [--synopsis <簡介>] [--tags <標籤1,標籤2>]` | `POST /novels` | 建立作品(需授權;標題非拉丁字元時建議附 `--slug`) |
| `fox novels update <slug> [--title …] [--slug …] [--synopsis …] [--tags …] [--status <狀態>]` | `PATCH /novels/:slug` | 更新作品(需授權;只傳要改的欄位) |
| `fox chapters list <novelSlug>` | `GET /novels/:novelSlug/chapters` | 列章節(公開僅 published;帶作者 token 可見全部) |
| `fox chapters get <novelSlug> <chapterSlug>` | `GET /novels/:novelSlug/chapters/:chapterSlug` | 查單一章節(draft 僅作者/admin) |
| `fox chapters create <novelSlug> --title <標題> [--slug <slug>] [--content <內容|->] [--sort-order <N>] [--status <狀態>]` | `POST /novels/:novelSlug/chapters` | 建立章節(需授權;狀態預設 draft) |
| `fox chapters update <novelSlug> <chapterSlug> [--title …] [--slug …] [--content …] [--sort-order …] [--status …]` | `PATCH /novels/:novelSlug/chapters/:chapterSlug` | 更新章節(需授權;只傳要改的欄位) |
| `fox chapters delete <novelSlug> <chapterSlug>` | `DELETE /novels/:novelSlug/chapters/:chapterSlug` | 刪除章節(需授權;冪等) |
| `fox generate draft <novelSlug> --prompt <指示|-> [--previous-context <前文摘要|->]` | `POST /novels/:novelSlug/generate` | 草稿生成(需授權;token 需 generate scope) |
| `fox generate continue <novelSlug> --previous-context <前文摘要|-> [--prompt <指示|->]` | `POST /novels/:novelSlug/generate/continue` | 續寫(前文摘要必填) |
| `fox generate rewrite <novelSlug> --prompt <原文|-> [--previous-context …]` | `POST /novels/:novelSlug/generate/rewrite` | 改寫(原文放在 `--prompt`) |
| `fox generate usages <novelSlug>` | `GET /novels/:novelSlug/generate/usages` | 查詢生成用量記帳(需授權) |
> **授權(issue #16 已補齊)**:受保護端點(`novels list/create/update`、`auth me`)的 `AuthGuard` 現在同時接受 `Authorization: Bearer <access token>` 與瀏覽器 session(cookie);Bearer 優先。access token 需綁定帳號(`POST /access-tokens` 帶 `accountId`,或由管理員建立時指定),未綁帳號的系統 token 只能用於 `tokens verify`。CLI 待 M3 補齊 `novels list/create/update` 命令。
> **授權**:受保護端點的 `AuthGuard` 同時接受 `Authorization: Bearer <access token>` 與瀏覽器 session(Bearer 優先)。access token 需綁定帳號(`POST /access-tokens` 帶 `accountId`,或由管理員建立時指定),未綁帳號的系統 token 只能用於 `tokens verify`。**生成命令需具備 `generate` scope**(建立 token 時 `--scopes read,write,generate`;缺 scope 回 403)。
> **多行內容**:`--content`/`--prompt`/`--previous-context` 的值為 `-` 時改從 stdin 讀入全部內容,適合管線傳入多行文字:`cat 章節.md | fox chapters create <novelSlug> --title <標題> --content -`。
## 四、AI agent 使用指引
@@ -57,7 +68,7 @@
- **M0**:子項目目錄+README(完成)。
- **M1**:HTTP client、設定讀取、`tokens verify`/`auth status`(完成,見 `src/http.ts`、`src/config.ts`)。
- **M2**:`tokens create/list/revoke`、公開的 `novels get`(完成)。
- **M3**:`novels list/create/update`(視後端授權進度)、`--pretty`、錯誤處理打磨。
- **M3**:`novels list/create/update`、`chapters list/get/create/update/delete`、`generate draft/continue/rewrite/usages`(完成,2026-09-06,issue #43)。
## 開發