Files
gitea/README.md
T
jiantw83 8467b89a09 feat(wiki): 頁型別新增 MONITOR
What:
- resolve_wiki_repo 的型別白名單與檔頭註解加上 MONITOR,check-wiki-rules.sh 的 TYPES 一併加入。
- README 的兩處型別列舉加上 MONITOR,環境變數表補一列 JSC_WIKI_REPO_MONITOR。
- wiki 技能的 allowed types 與行為清單的呼叫端補上這個型別與它的擁有者。
- 三份 manifest 的版本一起提升。

Why:
- 技能助理要把巡檢結果寫進 wiki,落點就是監控頁。型別不在白名單裡,wiki-repo 會直接回「unknown wiki type」而拒絕解析,助理連寫都寫不出去。
- 型別串散在五個檔案,只改一處會讓解析通過但檢核工具漏掉,或反過來。所以一次改齊。

How:
- MONITOR 放在型別串尾端,接在 TOOLING 之後。既有順序是依用途分群,不是字母序,所以不重排。
- 環境變數的規則完全沿用既有型別:先讀 JSC_WIKI_REPO_MONITOR,再退回 JSC_WIKI_REPO,不得跨型別代用。這一條由 resolve_wiki_repo 統一處理,新型別自動繼承,不必另寫分支。
- 雜湊來源的規則不寫在這個存放庫。README 已載明雜湊規則的唯一來源是技能準則的命名總表,這裡不複述。
- wiki 技能的 description 原本逐一列舉呼叫端,已經接近長度上限。這次改成括號標注頁型的濃縮寫法,加了一個呼叫端之後整行反而變短,句數維持在上限內。

Who:
技能助理落地帶出來的頁型別需求,四個存放庫同一批改。
2026-09-01 12:10:40 +08:00

167 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# jsc-gitea — Gitea 操作
jsc 技能組的 gitea domain:Gitea API 的統一入口。所有 jsc 技能需要操作 gitea(wiki、repo、PR)時,一律經由本 domain 的工具或技能,不可自行拼 API 呼叫。
## 安裝、更新、移除
Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安裝 token 為 `jsc-gitea@jsc`。每個指令一行:
| CLI | 安裝 | 更新 | 移除 |
| --- | --- | --- | --- |
| claude | `claude plugin marketplace add https://gitea.jsc.idv.tw/plugins/meta.git && claude plugin install jsc-gitea@jsc` | `claude plugin marketplace update jsc && claude plugin update jsc-gitea@jsc` | `claude plugin uninstall jsc-gitea@jsc` |
| codex | `codex plugin marketplace add https://gitea.jsc.idv.tw/plugins/meta.git && codex plugin add jsc-gitea@jsc` | `codex plugin marketplace upgrade jsc` | `codex plugin remove jsc-gitea@jsc` |
| copilot | `copilot plugin marketplace add https://gitea.jsc.idv.tw/plugins/meta.git && copilot plugin install jsc-gitea@jsc` | `copilot plugin marketplace update jsc && copilot plugin update jsc-gitea@jsc` | `copilot plugin uninstall jsc-gitea@jsc` |
| antigravity | `git clone https://gitea.jsc.idv.tw/plugins/gitea.git ~/plugins/gitea && agy plugin install ~/plugins/gitea` | `git -C ~/plugins/gitea pull && agy plugin uninstall jsc-gitea && agy plugin install ~/plugins/gitea` | `agy plugin uninstall jsc-gitea` |
| kiro | `kiro-cli plugin marketplace add https://gitea.jsc.idv.tw/plugins/meta.git && kiro-cli plugin install jsc-gitea@jsc` | `kiro-cli plugin marketplace update jsc && kiro-cli plugin update jsc-gitea@jsc` | `kiro-cli plugin uninstall jsc-gitea@jsc` |
> antigravity 不支援 gitea URL 安裝,改用本地 clone 路徑。批次操作五個 CLI:使用 `/jsc-cli:deploy`。
> 舊入口 `plugins/jsc` 已移除,marketplace 正本移到 `plugins/meta`。marketplace 名稱仍是 `jsc`(取自 marketplace.json 的 `name` 欄位,與存取庫名無關),安裝 token 不變;已從舊入口安裝過的人先執行 `claude plugin marketplace remove jsc`,再依上表重新 add。
## 工具
`tools/gitea.sh`(POSIX shell + curl):
```
gitea.sh owners # 列出可讀取的 owner
gitea.sh repos <owner> # 列出 owner 的 repo 全名
gitea.sh default-branch <owner>/<repo>
gitea.sh clone-url <owner>/<repo>
gitea.sh hash-id <text> # 產生 8 碼大寫 SHA-1;首碼 0-9/A/B/C 時改成 Hxxxxxxx
gitea.sh wiki-repo <TYPE> # 解析頁面類型的 wiki 位置(TYPE = QUESTION / PLAN / ANALYZE / DELIVER / MAINTAIN / REPO / LOG / LEARN / ERROR / CHECK / REPORT / SKILLSET / TOOLING / MONITOR)
gitea.sh wiki-list <owner>/<repo>
gitea.sh wiki-get <owner>/<repo> <page> # 不存在 exit 4
gitea.sh wiki-put <owner>/<repo> <page> <file> # 自動判斷新建或更新;會先要求確認
gitea.sh wiki-url <owner>/<repo> <page> # 印出 wiki 頁絕對網址(取自 API 的 html_url);跨存取庫連結用
gitea.sh pr-create <owner>/<repo> <head> <base> <title> <body-file> # 會先要求確認
gitea.sh pr-status <owner>/<repo> <pr-index> # 印出 {state} {merged} {mergeable}
gitea.sh pr-get <owner>/<repo> <pr-index> # 印出 PR 的標題、base 分支與描述,供呼叫端比對有沒有差
# 前三行固定 title、base、body 三個標記,第 4 行起是描述原文
gitea.sh pr-of-branch <owner>/<repo> <branch> # 印出該分支目前開啟中的 PR(比對 head.ref)
# 第 1 行 number,接著 title、base、body 三個標記,第 5 行起是描述原文
# 結束碼 0=找到、2=用法錯誤、3=該分支沒有開啟中的 PR、4=API 失敗
# 「沒有 PR」用 3 不用 4:混用會把金鑰失效讀成沒開過 PR,接著開出重複的 PR
gitea.sh pr-edit <owner>/<repo> <pr-index> <title> <body-file> # 會先要求確認
# 更新 PR 的標題與描述;描述從檔案讀,裝得下多行
gitea.sh pr-comments <owner>/<repo> <pr-index> # 印出所有留言(issue 留言、審查評語、行內留言),第三欄帶 #id,依時間排序
gitea.sh comment-reply <owner>/<repo> <pr-index> <issue|review|inline> <comment-id> <body-file> # 會先要求確認
# 回覆本輪處理過的 PR 留言;inline 走 review comment reply,其餘補一則 PR 留言
gitea.sh pr-depend <owner>/<repo> <pr-index> <dep-owner>/<dep-repo> <dep-index> # 會先要求確認
# 把 PR 掛上前置 PR 依賴;依賴未關閉前 Gitea 會阻擋合併
gitea.sh repo-set <owner>/<repo> <description> [website] # 會先要求確認
gitea.sh markdown <file> # markdown 檔渲染成 HTML 片段(走 /markdown/raw)
gitea.sh api <METHOD> <path> [json-file]
# 全腳本共用結束碼: 0=成功、1=api 子命令請求失敗、2=用法錯誤
# 3=wiki-repo 沒設定或 pr-of-branch 查無 PR、4=找不到(404)與 PR 系列 API 失敗
# 5=wiki 頁沒有 html_url、7=金鑰失效或權限不足(401/403)、8=其他 API 失敗
# 7 與 8 一定要跟 4 分開:認證失敗若被讀成「頁面不存在」,
# 附加寫入就會變成整頁覆蓋,舊紀錄直接消失
hash-id <text> # 與 gitea.sh hash-id 相同
repo-sync.sh <owner>/<repo> [target-dir] # 同步單一存取庫;印出 cloned、updated、dirty {分支} 或 failed {原因}
# 基準分支的優先序只在這支腳本裡;dirty 會把解析好的分支帶出來當 PR 的 base
check-wiki-rules.sh # 驗證 wiki repo 解析與 hash fallback 規則
pr-watch.sh <owner>/<repo> <pr-index> [state-file]
# 盯著一支 PR,直到它合併或關閉,不自動逾時退場
# 退出碼 0 = 已合併或關閉、10 = 有新留言要接手、2 = 參數錯誤、3 = 查不到該 PR
# 已回報過的留言記在狀態檔,預設 $JSC_HOME/pr-watch/{owner}-{repo}-{index}.seen
```
`pr-watch.sh` 的退出碼 10 是設計重點:腳本只負責偵測,決策交回呼叫端。收到 10 就把印出來的留言丟進決策樹,處理完再重新盯一次。
議題與 HTML 產出:
```
gitea-link.sh parse <url> # 解析 wiki 或議題連結;不是這兩種就 exit 3(呼叫端據此中止)
issue.sh labels|label-ids|projects <owner>/<repo>
issue.sh title|body|labels-of <owner>/<repo> <index>
issue.sh show <owner>/<repo> <index> # 一次拿齊標題、標籤與正文,只打一次 API
# 四段固定格式:title、labels、body 標記,第 4 行起是正文
issue.sh create <owner>/<repo> <title> <body-file> [--labels <ids>] [--milestone <id>] # 會先要求確認
html-style.sh get|set|unset|list|layouts|styles # 種類對版型與風格的設定
html-style.sh key wiki <頁名> # 推導種類:取第一個底線前的字首
html-style.sh key issue <owner>/<repo> <編號> [--labels <名稱>[,<名稱>]]
# 推導種類:依序試每個標籤,第一個設定過的勝出,都沒有就回 ISSUE:DEFAULT
# 輸出一行「{種類}<TAB>{依據}」;結束碼 1=取不到標籤
html-render.sh --markdown <檔案> --title <標題> --out <輸出檔> [--layout] [--style] [--subtitle] [--source-url]
```
## 參考資料
- `references/wiki-links.md`:寫 wiki 頁才需要的連結規則。同類型用 `[[顯示文字|頁名]]`(顯示文字在左),跨類型用 `wiki-url` 給的絕對網址。
## HTML 範本
版型(`templates/html/layout/*.html`)決定內容怎麼排,風格(`templates/html/style/*.css`)決定看起來長怎樣。兩者自由搭配,六乘五共三十種。
| 版型 | 內容排法 |
| --- | --- |
| `report` | 左側目錄加章節內文,長文件用 |
| `slide` | 一個 `##` 一張投影片,鍵盤左右鍵翻頁 |
| `dashboard` | 每個 `##` 一張卡片並排 |
| `spec` | 表格表頭固定、程式碼區塊放大,API 文件用 |
| `timeline` | 每個 `##` 一個節點串成一條線 |
| `onepager` | 窄欄單頁,印出來剛好一頁 |
| 風格 | 視覺 |
| --- | --- |
| `minimal` | 白底細線、無襯線,資訊密度優先 |
| `corporate` | 深藍主色、表頭反白,正式對外 |
| `dark` | 深底亮字 |
| `print` | 襯線字、A4 邊界,列印或轉 PDF |
| `vivid` | 高彩度、圓角卡片、漸層標題 |
哪一種頁面套哪一組,由 `html-style.sh` 的設定決定:專案的 `./.jsc/html-styles` 優先,其次 `$JSC_HOME/html-styles.conf`,種類對不到就退 `DEFAULT`,再對不到才用內建的 `report`/`minimal`。設定的 key 是 `WIKI:{頁名前綴}`、`ISSUE:{標籤名}` 或 `DEFAULT`。
自訂範本:版型放進 `templates/html/layout/`,風格放進 `templates/html/style/`,檔案第一行寫一句繁中說明——那句話就是技能問使用者時顯示的選項說明。版型檔可用的佔位有 `{{TITLE}}`、`{{SUBTITLE}}`、`{{CONTENT}}`、`{{BASE}}`、`{{BASE_JS}}`、`{{STYLE}}`、`{{SOURCE}}`、`{{GENERATED}}`、`{{LAYOUT}}`、`{{STYLE_NAME}}`。
## Skills 目錄
呼叫方式:Claude / Antigravity `/jsc-gitea:{name}`;Codex `${name}`;Copilot / Kiro 描述需求自動觸發。
<!-- JSC-SKILLS:START -->
### `wiki`
Gitea wiki 頁讀寫的統一入口:依頁面類型(QUESTION / PLAN / ANALYZE / DELIVER / MAINTAIN / REPO / LOG / LEARN / ERROR / CHECK / REPORT / SKILLSET / TOOLING / MONITOR)解析 wiki 所在的 `{owner}/{repo}`,先讀對應的 `JSC_WIKI_REPO_{TYPE}`,再退回 `JSC_WIKI_REPO`,不同類型不可互相代用。頁面內容以圖表優先(mermaid 圖、markdown 表格),純文字每節最多三句。
### `repo-sync`
存取庫批次同步:列出 owner → 使用者選擇 → 各存取庫併行(一個 repo 一個 sub agent)呼叫 `tools/repo-sync.sh` clone 或更新;回報 `dirty {分支}` 的存取庫交給 `jsc-git:pr`,base 直接用腳本帶出來的那個分支;PR 依 `jsc-meta/references/pr-report.md` 集中成表。
### `html-export`
把一頁 wiki 或一筆議題輸出成單一 HTML 檔:解析連結 → 判斷種類 → 查該種類的版型與風格 → 用 Gitea 自己的 markdown 渲染出圖。CSS 與腳本全部內嵌,檔案拿到哪裡都打得開。**沒有連結就直接中止**,不猜存取庫、不猜頁名、不猜議題編號。
### `html-style`
設定「哪一種 wiki 頁或議題,出 HTML 時用哪一種版型與風格」:六種版型與五種風格全部列給使用者選,再寫進專案的 `.jsc/html-styles` 或全域的 `$JSC_HOME/html-styles.conf`。`html-export` 讀的就是這份設定。
### `wiki-to-issue`
把一頁 wiki 轉成同一個存取庫的議題:讀頁面 → sub agent 起草標題與正文(開頭附來源連結)→ 從既有標籤挑合適的 → 關聯專案看板 → 建立議題。標籤只從存取庫既有的挑,不自己發明;站台沒有看板 API 時據實回報請使用者手動拖,不假裝關聯成功。**沒有連結就直接中止**。
<!-- JSC-SKILLS:END -->
## 環境變數
| 變數 | 用途 | 未設定時 |
| --- | --- | --- |
| `GITEA_HOST` | Gitea 站台(可省略 scheme,預設 https) | 詢問使用者 |
| `GITEA_TOKEN` | Gitea API token;缺少或遇 401/403 時自動退回 tea CLI 登入 token | 詢問使用者 |
| `JSC_WIKI_REPO_{TYPE}` | 各類型 wiki 頁的 `{owner}/{repo}`;TYPE = QUESTION / PLAN / ANALYZE / DELIVER / MAINTAIN / REPO / LOG / LEARN / ERROR / CHECK / REPORT | 退回 `JSC_WIKI_REPO`,不做跨類型代用 |
| `JSC_WIKI_REPO_SKILLSET` | `SKILLSET_CONTENTS`、`SKILLSET_{HASH}`(技能組異動報告)的 `{owner}/{repo}` | 退回 `JSC_WIKI_REPO`,不做跨類型代用 |
| `JSC_WIKI_REPO_TOOLING` | `TOOLING_CONTENTS`、`TOOLING_{HASH}`(技能盤點)的 `{owner}/{repo}` | 退回 `JSC_WIKI_REPO`,不做跨類型代用 |
| `JSC_WIKI_REPO_MONITOR` | `MONITOR_CONTENTS`、`MONITOR_{HASH}`(助理巡檢監控)的 `{owner}/{repo}` | 退回 `JSC_WIKI_REPO`,不做跨類型代用 |
| `JSC_WIKI_REPO` | 共用預設的 wiki `{owner}/{repo}` | 詢問使用者 |
| `JSC_HOME` | `pr-watch.sh` 狀態檔的根目錄 | 預設 `~/.jsc` |
| `JSC_PR_WATCH_INTERVAL` | `pr-watch.sh` 的輪詢間隔秒數(正整數) | 預設 60 |
## Hash 規則
`{HASH}` 一律由 `tools/hash-id` 產生。長度、大小寫、`H` 前綴與各頁型的雜湊來源,唯一來源是 `jsc-meta` 的 [`references/guidelines.md`](https://gitea.jsc.idv.tw/plugins/meta/src/branch/master/references/guidelines.md)「Wiki 頁命名總表」,這裡不再複述一份。
## 相關 domain
- [`jsc-ask`](https://gitea.jsc.idv.tw/plugins/ask):wiki 位置未設定時的決策樹詢問
- [`jsc-git`](https://gitea.jsc.idv.tw/plugins/git):repo-sync 的 commit 與 PR