Merge pull request '釋出 jsc-assist 0.0.2:助理 domain 落地與 status 技能' (#2) from feat/assistant-domain-bootstrap/main into develop

Reviewed-on: #2
This commit was merged in pull request #2.
This commit is contained in:
2026-09-01 04:42:50 +00:00
12 changed files with 514 additions and 282 deletions
+89 -4
View File
@@ -1,12 +1,97 @@
{
"name": "template",
"name": "jsc",
"description": "jsc 跨 AI 助理技能組的統一 marketplace(claude / codex / copilot / antigravity / kiro)。",
"owner": {
"name": "JSC"
},
"plugins": [
{
"name": "jsc-template",
"name": "jsc-ask",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/template.git"
}
"url": "https://gitea.jsc.idv.tw/plugins/ask.git"
},
"description": "決策樹問詢與問詢紀錄(QUESTION_* wiki 頁)"
},
{
"name": "jsc-assist",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/assist.git"
},
"description": "助理:事件收攏、健康巡檢與待辦簿(MONITOR_* wiki 頁)"
},
{
"name": "jsc-cli",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/cli.git"
},
"description": "CLI 偵測、模型能力標籤與技能庫批次部署"
},
{
"name": "jsc-git",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/git.git"
},
"description": "Commit 分組認可與 Push Request 建立"
},
{
"name": "jsc-gitea",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/gitea.git"
},
"description": "Gitea API 工具、Wiki 讀寫與存取庫批次同步"
},
{
"name": "jsc-hooks",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/hooks.git"
},
"description": "跨 CLI hooks:STE100 語言強制、工時計時、技能用量記錄、SDLC 模型鎖、版本前置檢查"
},
{
"name": "jsc-log",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/log.git"
},
"description": "工作日誌(LOG_* wiki 頁)與技能使用統計"
},
{
"name": "jsc-meta",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/meta.git"
},
"description": "技能組自我管理:新建、更新、刪除技能與技能準則"
},
{
"name": "jsc-pkg",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/pkg.git"
},
"description": "套件批次更新(nodejs/python/dotnet),失敗還原"
},
{
"name": "jsc-review",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/review.git"
},
"description": "程式碼審查:Refactoring 壞味道六組、註解規範、淺模組"
},
{
"name": "jsc-sdlc",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/sdlc.git"
},
"description": "開發生命週期:規劃、分析、實作、維護(wiki 追蹤)"
}
]
}
+88 -5
View File
@@ -1,14 +1,97 @@
{
"name": "template",
"description": "JSC 跨 AI 助理共用 skills 的 Claude Code marketplace。",
"name": "jsc",
"description": "jsc 跨 AI 助理技能組的統一 marketplace(claude / codex / copilot / antigravity / kiro)。",
"owner": {
"name": "JSC"
},
"plugins": [
{
"name": "jsc-template",
"source": "./",
"description": "JSC 共用 skills(跨 AI 助理)"
"name": "jsc-ask",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/ask.git"
},
"description": "決策樹問詢與問詢紀錄(QUESTION_* wiki 頁)"
},
{
"name": "jsc-assist",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/assist.git"
},
"description": "助理:事件收攏、健康巡檢與待辦簿(MONITOR_* wiki 頁)"
},
{
"name": "jsc-cli",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/cli.git"
},
"description": "CLI 偵測、模型能力標籤與技能庫批次部署"
},
{
"name": "jsc-git",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/git.git"
},
"description": "Commit 分組認可與 Push Request 建立"
},
{
"name": "jsc-gitea",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/gitea.git"
},
"description": "Gitea API 工具、Wiki 讀寫與存取庫批次同步"
},
{
"name": "jsc-hooks",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/hooks.git"
},
"description": "跨 CLI hooks:STE100 語言強制、工時計時、技能用量記錄、SDLC 模型鎖、版本前置檢查"
},
{
"name": "jsc-log",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/log.git"
},
"description": "工作日誌(LOG_* wiki 頁)與技能使用統計"
},
{
"name": "jsc-meta",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/meta.git"
},
"description": "技能組自我管理:新建、更新、刪除技能與技能準則"
},
{
"name": "jsc-pkg",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/pkg.git"
},
"description": "套件批次更新(nodejs/python/dotnet),失敗還原"
},
{
"name": "jsc-review",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/review.git"
},
"description": "程式碼審查:Refactoring 壞味道六組、註解規範、淺模組"
},
{
"name": "jsc-sdlc",
"source": {
"source": "url",
"url": "https://gitea.jsc.idv.tw/plugins/sdlc.git"
},
"description": "開發生命週期:規劃、分析、實作、維護(wiki 追蹤)"
}
]
}
+19 -6
View File
@@ -1,12 +1,25 @@
{
"name": "jsc-template",
"version": "0.0.3",
"description": "JSC 跨 AI 助理共用 plugin 模板(Claude Code / Codex / Antigravity / OpenCode)。所有 skills 以 SKILL.md 為共通標準,於 Claude Code 以 /jsc-template: 前綴呼叫。",
"name": "jsc-assist",
"version": "0.0.2",
"description": "助理:事件收攏、健康巡檢與待辦簿(MONITOR_{HASH} wiki 頁)",
"skills": "./skills",
"author": {
"name": "JSC"
},
"homepage": "https://gitea.jsc.idv.tw/plugins/template",
"repository": "https://gitea.jsc.idv.tw/plugins/template.git",
"keywords": ["template", "skills", "cross-tool", "jsc"]
"homepage": "https://gitea.jsc.idv.tw/plugins/assist",
"repository": "https://gitea.jsc.idv.tw/plugins/assist.git",
"keywords": [
"jsc",
"assist",
"skills",
"cross-tool"
],
"jsc": {
"requires": {
"jsc-cli": ">=0.2.7",
"jsc-gitea": ">=0.2.0",
"jsc-hooks": ">=0.3.4",
"jsc-log": ">=0.1.4"
}
}
}
+12 -4
View File
@@ -1,6 +1,14 @@
{
"name": "jsc-template",
"version": "0.0.3",
"description": "JSC 跨 AI 助理共用 plugin 模板。所有 skills 以 SKILL.md 為共通標準。",
"skills": "./skills"
"name": "jsc-assist",
"version": "0.0.2",
"description": "助理:事件收攏、健康巡檢與待辦簿(MONITOR_{HASH} wiki 頁)",
"skills": "./skills",
"jsc": {
"requires": {
"jsc-cli": ">=0.2.7",
"jsc-gitea": ">=0.2.0",
"jsc-hooks": ">=0.3.4",
"jsc-log": ">=0.1.4"
}
}
}
+21 -10
View File
@@ -1,15 +1,26 @@
# jsc-template — 共用 Skills(跨 AI 助理)
# jsc-assist — 給 AI 助理的指引
本 repo 是一組以 **Agent Skills(`SKILL.md`)** 標準撰寫的共用 skills,可同時被 Claude Code、Codex、Antigravity、OpenCode 使用。
本 repo 是 jsc 技能組的 `assist` domain(技能助理:事件收攏、健康巡檢與待辦簿),Claude Code / Codex / Copilot / Antigravity / Kiro 都能安裝使用。
## 給 AI 助理的指引
## 規則
- 所有可用的 skills 位於本 repo 的 `skills/<name>/SKILL.md`。
- 在處理任務前,先比對使用者需求與各 skill `SKILL.md` frontmatter 的 `description`,若相符請載入並依其步驟執行。
- **呼叫慣例**:在 Claude Code 與 Antigravity 中,這些 skill 以 `/jsc-template:<name>` 呼叫;Codex 以 `$<name>`、OpenCode 由模型依描述自動觸發 — 兩者沒有 `/jsc-template:` 前綴,不需強制加。
- 完整清單與每個 skill 的用途,請見 `README.md` 的「Skills 目錄」。
1. 所有交談與輸出內容使用 STE100 繁體中文,帶擬人台灣感:短句、一句一指令、台灣用語、全形標點、去 AI 味、直接講重點。完整規則的唯一來源:`plugins/meta` 的 `references/ste100.md`。
2. 技能位於 `skills/{name}/SKILL.md`;處理任務前先比對需求與各技能的 `description`,相符就載入並依其步驟執行。
3. 技能準則的唯一來源:`plugins/meta` 存取庫的 `references/guidelines.md`。
4. 所有 hook 只放在 `jsc-hooks`;gitea 操作一律經由 `jsc-gitea` 的 `tools/gitea.sh`;問使用者一律依 `jsc-ask:ask` 的決策樹規則。
5. 主 agent 不需要處理細節的流程,一律建立 sub agent 處理。
## 慣例
## 助理的界線
- 新增 skill 一律放在 `skills/<name>/`,且 `<name>` 使用小寫與連字號。
- `description` 要寫清楚觸發條件(何時用、何時不用),這是跨助理自動載入的唯一依據。
助理在背景跑,問不到人,所以下面這幾件事一律不做:
1. 不做任何要問使用者的決策。背景巡檢時靜默套預設值,等於把逐項共識整條做掉。
2. 不參與閘門判定。閘門必須留在 hook:同步、不連網、毫秒級。助理只負責維持心跳。
3. 不寫程式碼存取庫、不 commit、不 push、不開 PR、不合併。
4. 不覆寫 wiki 頁,一律只附加。助理的寫入是背景行為,覆寫錯了沒人在現場。
5. 不刪除狀態檔、worktree 與 wiki 頁。破壞性操作留給人發動。
6. 不自動執行自己提出的建議。建議與執行是兩件事,自動接下去等於整條流程沒人按過同意就跑完。
## 呼叫慣例
Claude Code / Antigravity:`/jsc-assist:{name}`;Codex:`$name`;Copilot / Kiro / OpenCode:描述需求自動觸發。
+46 -210
View File
@@ -1,228 +1,64 @@
# jsc-template — 跨 AI 助理 Plugin 模板
# jsc-assist — 技能助理
一個可同時被 **Claude Code、Codex、Antigravity、OpenCode、GitHub Copilot** 安裝的 plugin 模板。
核心是以 [Agent Skills(`SKILL.md`)](https://agentskills.io) 標準撰寫的共用 skills(唯一真實來源放在 `skills/`),
搭配各助理各自的 plugin manifest,讓**同一個 repo** 可用各家**原生 plugin CLI** 安裝。
在 Claude Code 與 Antigravity 中,skill 以 **`/jsc-template:` 前綴**呼叫(例如 `/jsc-template:hello`)。
jsc 技能組的 assist domain:技能與 hook 每跑一次就留下事件,助理負責把事件收攏、判斷健康狀態、寫進 wiki 的監控頁(`MONITOR_{HASH}`)。
---
助理只做三件事:**觸發**既有技能、**巡檢**既有的唯讀腳本與狀態檔、把結果**提醒**給前景會話。它不做決策、不改程式碼、不覆寫 wiki。完整界線見 `AGENTS.md` 的「助理的界線」。
## 前綴與呼叫方式
## 安裝、更新、移除
| 助理 | 安裝方式 | 呼叫 | `/jsc-template:` 前綴 |
Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安裝 token 為 `jsc-assist@jsc`。每個指令一行:
| CLI | 安裝 | 更新 | 移除 |
| --- | --- | --- | --- |
| Claude Code | `claude plugin`(marketplace) | `/jsc-template:<name>` 或自動觸發 | ✅ |
| Codex | `codex plugin`(marketplace) | `$<name>` 或 `/skills` 選單 | ❌(用 `$name`) |
| Antigravity | `agy plugin install` | `/jsc-template:<name>` 或自動觸發 | ✅ |
| OpenCode | skills 目錄(複製/clone) | 描述需求自動觸發 | ❌(依名稱) |
| GitHub Copilot CLI | `copilot plugin`(marketplace) | 自然語言或 plugin skills | ❌(無 `/jsc-template:` 前綴) |
| claude | `claude plugin marketplace add https://gitea.jsc.idv.tw/plugins/meta.git && claude plugin install jsc-assist@jsc` | `claude plugin marketplace update jsc && claude plugin update jsc-assist@jsc` | `claude plugin uninstall jsc-assist@jsc` |
| codex | `codex plugin marketplace add https://gitea.jsc.idv.tw/plugins/meta.git && codex plugin add jsc-assist@jsc` | `codex plugin marketplace upgrade jsc` | `codex plugin remove jsc-assist@jsc` |
| copilot | `copilot plugin marketplace add https://gitea.jsc.idv.tw/plugins/meta.git && copilot plugin install jsc-assist@jsc` | `copilot plugin marketplace update jsc && copilot plugin update jsc-assist@jsc` | `copilot plugin uninstall jsc-assist@jsc` |
| antigravity | `git clone https://gitea.jsc.idv.tw/plugins/assist.git ~/plugins/assist && agy plugin install ~/plugins/assist` | `git -C ~/plugins/assist pull && agy plugin uninstall jsc-assist && agy plugin install ~/plugins/assist` | `agy plugin uninstall jsc-assist` |
| kiro | `kiro-cli plugin marketplace add https://gitea.jsc.idv.tw/plugins/meta.git && kiro-cli plugin install jsc-assist@jsc` | `kiro-cli plugin marketplace update jsc && kiro-cli plugin update jsc-assist@jsc` | `kiro-cli plugin uninstall jsc-assist@jsc` |
> Codex 不支援自訂前綴(skill 以 `$name` 呼叫);OpenCode 由模型依描述自動呼叫;Copilot CLI 透過原生 plugin 安裝後以自然語言或 plugin skills 使用。三者皆**不強制**前綴。
---
## 目錄結構
同一個 repo 同時帶四種 manifest,彼此以路徑隔離、互不干擾;各助理都讀同一份 `skills/`。
```
template/
├── .claude-plugin/
│ ├── plugin.json # Claude 外掛定義(name: "jsc-template")
│ └── marketplace.json # Claude marketplace(name: "template",source 指向本 repo)
├── .codex-plugin/
│ └── plugin.json # Codex 外掛定義(name: "jsc-template",skills: "./skills")
├── .agents/plugins/
│ └── marketplace.json # Codex marketplace(name: "template",url source 指向本 repo)
├── plugin.json # Antigravity 外掛定義(name: "jsc-template",skills: "./skills/")
├── skills/ # ★ 唯一真實來源:所有 skills
│ └── hello/SKILL.md
├── AGENTS.md # 跨助理共用指引
└── README.md
```
---
## 安裝 / 更新 / 移除(各助理)
> 指令中的 repo 網址換成你的:`https://gitea.jsc.idv.tw/plugins/template.git`
>
> **Claude / Codex 從 git URL 安裝(會 clone 遠端),請先把本 repo `push` 到 gitea。**
> **Antigravity 的 `agy plugin install <url>` 目前只支援 github.com**;gitea 請改用「clone + 本地路徑」(見 Antigravity 節)。
> 本機/離線:Claude 可用本地路徑加 marketplace;Antigravity 用本地路徑安裝。
> **⚠ 從 0.0.1 升上來的人請先移除再安裝。** 0.0.2 起 marketplace 名由 `jsc-plugins` 改為 `template`
> (舊名與 `jsc-persona` 的 marketplace 撞名)。各助理以 `<plugin 名>@<marketplace 名>` 當安裝識別鍵,
> 改名後是兩筆獨立條目,**不能用 update 遷移**:
>
> ```bash
> claude plugin uninstall jsc-template@jsc-plugins
> claude plugin marketplace remove jsc-plugins # 若你沒有裝 jsc-persona 才移除,它也用這個名字
> claude plugin marketplace add https://gitea.jsc.idv.tw/plugins/template.git
> claude plugin install jsc-template@template
> ```
>
> 移除後記得清掉 `~/.claude/settings.json` 裡 `enabledPlugins` 的舊鍵 `jsc-template@jsc-plugins`,
> 並重開工作階段。Codex/Copilot 同理(`remove`/`uninstall` 後重新 `add`+`install`)。
### Claude Code
```bash
# 安裝
claude plugin marketplace add https://gitea.jsc.idv.tw/plugins/template.git
claude plugin install jsc-template@template
# 更新
claude plugin marketplace update template
claude plugin update jsc-template@template
# 移除
claude plugin uninstall jsc-template@template
claude plugin marketplace remove template
```
- 工作階段內 slash 版(等價):把 `claude plugin` 換成 `/plugin`。
- 本機開發(免 push):`claude plugin marketplace add C:\Users\h3285\source\repos.plugins\template`(本地路徑)後再 install。
- **呼叫**:`/jsc-template:<name>`(例 `/jsc-template:hello`)。
### Codex
```bash
# 安裝
codex plugin marketplace add https://gitea.jsc.idv.tw/plugins/template.git
codex plugin add jsc-template@template
# 更新(重新抓取 marketplace 的 git 快照)
codex plugin marketplace upgrade template
# 移除
codex plugin remove jsc-template@template
codex plugin marketplace remove template
```
- 安裝 token `jsc-template@template` = plugin 名(`.codex-plugin/plugin.json` 的 `name`)@ marketplace 名(`.agents/plugins/marketplace.json` 的 `name`)。
- 本 repo 的 Codex marketplace 以 `url` 來源指向自己,故 Codex **一律從 gitea 安裝**(需先 push);安裝後重啟 Codex。
- **呼叫**:`$<name>`(例 `$hello`),或用 `/skills` 選單。
### Antigravity(`agy`)
> `agy plugin install <url>` 目前**只支援 github.com**;gitea 等自架 git 不支援 URL 安裝,請先 `git clone` 再用**本地路徑**安裝。
```bash
# 安裝:clone 後用本地路徑
git clone https://gitea.jsc.idv.tw/plugins/template.git ~/plugins/template
agy plugin install ~/plugins/template
# 更新(agy 無 update 子指令 → git pull 後重裝)
git -C ~/plugins/template pull
agy plugin uninstall jsc-template
agy plugin install ~/plugins/template
# 移除
agy plugin uninstall jsc-template
```
- 若把 skills 放到 GitHub,則可直接 `agy plugin install https://github.com/<owner>/<repo>`。
- 其他:`agy plugin list`、`agy plugin enable jsc-template` / `disable jsc-template`、`agy plugin validate <path>`。安裝後重啟工作階段。
- **呼叫**:`/jsc-template:<name>`(例 `/jsc-template:hello`)或依描述自動觸發。
### OpenCode
OpenCode 的「plugin」是 TypeScript/npm 套件,不適用於 skill 包;skills 改用**目錄安裝**。
OpenCode 會讀 `~/.config/opencode/skills/`(也會讀 `~/.claude/skills/`、`~/.agents/skills/`)。
```bash
# 安裝
git clone https://gitea.jsc.idv.tw/plugins/template.git ~/plugins/template
mkdir -p ~/.config/opencode/skills
cp -r ~/plugins/template/skills/* ~/.config/opencode/skills/
# 更新
git -C ~/plugins/template pull
cp -r ~/plugins/template/skills/* ~/.config/opencode/skills/
# 移除
rm -rf ~/.config/opencode/skills/hello
```
> **Windows PowerShell**:`cp -r A B` → `Copy-Item A B -Recurse -Force`、`rm -rf X` → `Remove-Item X -Recurse -Force`、`~` → `$HOME`。
- **呼叫**:直接描述需求,模型會依 skill 描述自動透過 skill 工具呼叫。
### GitHub Copilot CLI
Copilot CLI 支援與 Claude Code 類似的原生 plugin / marketplace 指令,可直接從 marketplace 安裝、更新與移除本 plugin。
```bash
# 安裝
copilot plugin marketplace add https://gitea.jsc.idv.tw/plugins/template.git
copilot plugin install jsc-template@template
# 更新
copilot plugin marketplace update template
copilot plugin update jsc-template@template
# 移除
copilot plugin uninstall jsc-template@template
copilot plugin marketplace remove template
```
- 安裝 token `jsc-template@template` = plugin 名(plugin manifest 的 `name`)@ marketplace 名。
- `copilot plugin marketplace add` 支援 GitHub `owner/repo`、git URL 與本地路徑;Gitea repo 可用上方 HTTPS URL。
- **呼叫**:在 Copilot CLI 中用自然語言描述需求,例如 `copilot -i "跑 hello 確認 plugin 裝好了"`。
---
## 用 CLI 直接執行 skill(headless / 一次性)
安裝好之後,不必進互動介面,一行指令就能叫某個 skill 跑完並印出結果:
| 助理 | headless 指令 | 執行 `hello` skill |
| --- | --- | --- |
| Claude Code | `claude -p "<prompt>"` | `claude -p "/jsc-template:hello"` |
| Codex | `codex exec "<prompt>"` | `codex exec '$hello'` |
| Antigravity | `agy -p "<prompt>"` | `agy -p "/jsc-template:hello"` |
| OpenCode | `opencode run "<message>"` | `opencode run "用 hello skill 打個招呼"` |
| GitHub Copilot CLI | `copilot -p "<message>"` | `copilot -p "用 hello skill 打個招呼"` |
- Claude / Antigravity 支援 `/jsc-template:` 前綴,直接 `-p "/jsc-template:<name>"` 即可。
- Codex 以 `$<name>` 觸發;在 shell 請用**單引號**避免 `$` 被展開:`codex exec '$hello'`。
- OpenCode 與 Copilot 沒有前綴,用自然語言描述需求;Copilot CLI 會讀取已安裝 plugin 提供的 skills。
- 帶引數就接在後面,例如 `claude -p "/jsc-template:hello 參數"`、`codex exec '$hello 參數'`。
---
> antigravity 不支援 gitea URL 安裝,改用本地 clone 路徑。批次操作五個 CLI:使用 `/jsc-cli:deploy`。
## Skills 目錄
> 此區塊列出本 plugin 內含的所有 skills(名稱/描述/使用方法)。
> 新增或修改 skill 後,請同步手動更新標記之間的內容。
呼叫方式:Claude / Antigravity `/jsc-assist:{name}`;Codex `${name}`;Copilot / Kiro 描述需求自動觸發。
<!-- JSC-SKILLS:START -->
### `hello`
### `status`
範例 skill,用來驗證 jsc plugin 是否安裝成功,也是新增 skill 的範本。當使用者輸入 hello、想測試 plugin、或想看 skill 模板長什麼樣子時觸發;回覆一句問候並簡述此 plugin 的用途。
- **Claude Code / Antigravity**:`/jsc-template:hello`
- **Codex**:`$hello`,或用 `/skills` 選單
- **OpenCode / GitHub Copilot CLI**:描述需求自動觸發
查助理現在的狀況,全程唯讀。讀心跳檔判斷助理是不是還在跑——檔案在、而且 `ts` 距現在不到 300 秒才算新鮮,過期就是沒在跑;接著列出待辦簿裡的每一筆,印成一張現況表。心跳檔不存在時印「助理未運行」,不當成錯誤。這支不寫檔、不寫 wiki、不碰閘門。
<!-- JSC-SKILLS:END -->
---
## 相依
## 新增一個 skill
| Plugin | 最低版本 | 用途 |
| --- | --- | --- |
| `jsc-cli` | `>=0.2.7` | CLI 偵測與委派 |
| `jsc-gitea` | `>=0.2.0` | 監控頁的所有 wiki 讀寫,一律經 `tools/gitea.sh` |
| `jsc-hooks` | `>=0.3.4` | 心跳、閘門與事件來源(`$JSC_HOME` 底下的狀態檔) |
| `jsc-log` | `>=0.1.4` | 使用統計與工作日誌的資料來源 |
1. 複製範本:`cp -r skills/hello skills/<your-skill-name>`
2. 編輯 `skills/<your-skill-name>/SKILL.md` 的 frontmatter:
- `name`:小寫、數字、連字號(`-`),最長 64 字元。**這就是 Claude Code / Antigravity 的 `/jsc-template:<name>`**。
- `description`:第三人稱,寫清楚「何時用、何時不用」與觸發關鍵字 — 這是各助理自動載入的唯一依據。
3. 在內文寫下 skill 的具體步驟。
4. 手動把這個 skill 補進上方「Skills 目錄」區塊。
5. **bump 版本並 push**:各助理都以 git 內容/版本判斷更新,請把 `.claude-plugin/plugin.json`、`.codex-plugin/plugin.json`、`plugin.json` 三個 manifest 的 `version` 一起 bump,commit 後 push 到 gitea。
6. 讓各助理更新:
- Claude:`claude plugin update jsc-template@template`
- Codex:`codex plugin marketplace upgrade template`
- Antigravity:`git -C ~/jsc-plugin pull && agy plugin uninstall jsc-template && agy plugin install ~/jsc-plugin`
- OpenCode:`git pull` 後重新複製 `skills/`
- Copilot:`copilot plugin marketplace update template && copilot plugin update jsc-template@template`
## 參考與工具
| 檔案 | 用途 |
| --- | --- |
| `references/behaviors.md` | 本 domain 的技能行為清單:一支技能一節,五列記下觸發時機、關鍵步驟、外部呼叫、完成條件、可驗證跡象,供稽核與驗證比對。格式合約見 `plugins/meta` 的 `references/guidelines.md`「技能行為清單」 |
| `templates/monitor-contents.md` | 目錄頁 `MONITOR_CONTENTS` 的範本。一列代表一台機器,雜湊來源是 `{主機名}/{登入帳號}`。寫入語意是**只更新自己那一列**:比對主機與帳號兩欄,別台機器的列原樣保留,禁止整頁覆蓋 |
| `templates/monitor-page.md` | 內容頁 `MONITOR_{HASH}` 的範本。記的是這台機器的巡檢軌跡。寫入語意與目錄頁相反,是**一律附加一節、不覆寫**:一次巡檢一節,節標題帶時間戳,既有的節一個字都不動 |
## 助理的狀態檔
全部放在 `$JSC_HOME/assistant/` 底下,一律純文字 key=value:
| 路徑 | 內容 |
| --- | --- |
| `heartbeat` | 心跳檔,欄位 `ts`、`pid`、`cli`、`session`。判準只看 `ts`,不看 pid 存活——五支 CLI 與容器裡的行程互相看不到彼此的 pid |
| `tasks/{id}` | 待辦簿,一筆一檔。一筆一檔是為了讓並行寫入不互相覆寫 |
## 相關 domain
- [`jsc-hooks`](https://gitea.jsc.idv.tw/plugins/hooks):閘門與心跳,跟 hook 一起裝
- [`jsc-gitea`](https://gitea.jsc.idv.tw/plugins/gitea):wiki 讀寫的唯一入口
- [`jsc-log`](https://gitea.jsc.idv.tw/plugins/log):使用統計與工作日誌
- [`jsc-cli`](https://gitea.jsc.idv.tw/plugins/cli):環境健檢與跨 CLI 委派
+13 -5
View File
@@ -1,6 +1,14 @@
{
"name": "jsc-template",
"version": "0.0.3",
"description": "JSC 跨 AI 助理共用 plugin 模板。所有 skills 以 SKILL.md 為共通標準;於 Antigravity 以 /jsc-template: 前綴呼叫。",
"skills": "./skills/"
}
"name": "jsc-assist",
"version": "0.0.2",
"description": "助理:事件收攏、健康巡檢與待辦簿(MONITOR_{HASH} wiki 頁)",
"skills": "./skills/",
"jsc": {
"requires": {
"jsc-cli": ">=0.2.7",
"jsc-gitea": ">=0.2.0",
"jsc-hooks": ">=0.3.4",
"jsc-log": ">=0.1.4"
}
}
}
+13
View File
@@ -0,0 +1,13 @@
# jsc-assist 技能行為清單
本頁記錄 jsc-assist 每支技能的行為基準,供技能驗證比對。技能異動時,在同一個 PR 內一起更新這一頁。
## status
| 項目 | 內容 |
| --- | --- |
| 觸發時機 | 有人問助理現在還在不在跑,或問待辦簿裡剩下哪幾筆時用。啟動與停止助理不走這支。執行環境健檢不走這支,走 `jsc-cli:doctor`。技能使用次數不走這支,走 `jsc-log:stats` |
| 關鍵步驟 | 解出 `$JSC_HOME`(未設定就退回 `~/.jsc`)並組出 `assistant/` 目錄、讀 `heartbeat` 的 `ts`、`pid`、`cli`、`session`、以 `ts` 距現在是否不到 300 秒判成新鮮或過期、不看 pid 存活、列出 `tasks/` 底下每一個檔案並解析 `state`、`title`、`next_run`、`fail_count`、把心跳區塊與逐筆待辦印成一張表、`fail_count` 大於 0 的列標上「已連續失敗 N 次」 |
| 外部呼叫 | 無。只讀 `$JSC_HOME/assistant/heartbeat` 與 `$JSC_HOME/assistant/tasks/` 底下的檔案。不呼叫腳本、不呼叫其他技能、不碰 wiki、不啟動也不停止助理 |
| 完成條件 | 印出現況表,或印出「助理未運行」並說明是哪個路徑讀不到。心跳檔不存在、待辦簿目錄不存在、待辦簿零筆,三種都算正常結束,不得以非 0 結束 |
| 可驗證跡象 | 無寫入跡象,只有回報內容 |
-38
View File
@@ -1,38 +0,0 @@
---
name: hello
description: 範例 skill,用來驗證 jsc plugin 是否安裝成功,也是新增 skill 的範本。當使用者輸入 hello、想測試 plugin、或想看 skill 模板長什麼樣子時觸發;回覆一句問候並簡述此 plugin 的用途。
---
# hello(範例 skill)
這是 `jsc-template` plugin 的範例 skill。它有兩個用途:
1. **驗證安裝** — 跨各家 AI 助理確認 skill 已被正確載入。
2. **作為範本** — 複製這個資料夾即可新增一個新的 skill。
## 呼叫方式
| 助理 | 呼叫方式 |
| --- | --- |
| Claude Code | `/jsc-template:hello` |
| Antigravity | `/jsc-template:hello`,或描述需求自動觸發 |
| Codex | 在提示詞輸入 `$hello`,或用 `/skills` 選單 |
| OpenCode | 直接描述需求,模型會透過 skill 工具自動呼叫 |
| GitHub Copilot CLI | 直接描述需求,Copilot 會讀取已安裝 plugin 的 skills |
## 行為
當這個 skill 被觸發時:
1. 回覆「Hello from **jsc** 👋」。
2. 用一句話說明 `jsc-template` 是一個跨 AI 助理的共用 skill 集合。
3. 提示使用者可以在 README 的「Skills 目錄」查看所有可用的 skills。
## 如何以此為範本新增 skill
1. 複製 `skills/hello/` 為 `skills/<your-skill-name>/`。
2. 修改 `SKILL.md` 的 frontmatter:
- `name`:小寫、數字、連字號(`-`),最長 64 字元。**這個名稱會成為 Claude Code / Antigravity 的 `/jsc-template:<name>` 指令**。
- `description`:第三人稱,寫清楚「什麼時候該用、什麼時候不該用」與觸發關鍵字 — 各家助理靠這段文字決定是否自動載入。
3. 在內文寫下 skill 的具體步驟。
4. 手動把新 skill 補進 README 的「Skills 目錄」區塊。
+55
View File
@@ -0,0 +1,55 @@
---
name: status
description: Report the background assistant's current state read-only, from the heartbeat file and the task book under $JSC_HOME/assistant/. Heartbeat counts as fresh only when the file exists and its ts is less than 300 seconds old, and pid liveness is never checked. Print one table covering heartbeat freshness, last heartbeat time, cli, session, task count, and every task's state, title, next_run and fail_count, flagging each task whose fail_count is above zero. A missing heartbeat file prints 助理未運行 and still counts as a normal result rather than an error. Use when someone asks whether the assistant is running or what is queued; not for starting or stopping it, not for environment health checks (jsc-cli:doctor), and not for skill usage counts (jsc-log:stats).
---
# status — assistant heartbeat and task book snapshot
Read-only snapshot of the background assistant. This skill reads two paths and prints one table. It writes no file, writes no wiki page, calls no gate, and never starts or stops the assistant.
No `tools/` script backs this skill. Two paths and one table stay below the extraction bar; re-evaluate when the assistant body itself lands.
## Data sources
| Path | Format | Keys |
| --- | --- | --- |
| `$JSC_HOME/assistant/heartbeat` | plain text, one `key=value` per line | `ts` (epoch seconds), `pid`, `cli`, `session` |
| `$JSC_HOME/assistant/tasks/{id}` | plain text, one `key=value` per line, one entry per file | `id`, `kind` (`check` or `todo`), `title`, `action`, `trigger`, `recur`, `repo`, `due`, `state` (`pending` / `done` / `paused`), `last_run`, `next_run`, `fail_count`, `origin` (`user` or `assistant`) |
`$JSC_HOME` defaults to `~/.jsc`.
**Freshness is time-based only.** The heartbeat is fresh when the file exists and `ts` is less than 300 seconds behind the current time. An older `ts` means the assistant is not running. Never test whether `pid` is alive: the five CLIs and the processes inside containers cannot see each other's pids, so a live-looking pid proves nothing and a missing one proves nothing either. Report `pid` as a hint for whoever has to find a blocking process, and give it no weight in the verdict.
## Steps
1. **Resolve the assistant directory.** Take `$JSC_HOME` from the environment; when it is unset or empty, use `~/.jsc`. Append `assistant/` to get the directory this skill reads. When that directory is absent or cannot be listed, print `助理未運行`, name the resolved path and the reason (the variable was unset and the default path does not exist, or the listing was denied), skip steps 2 to 6, and finish per step 7. Done when one absolute assistant directory path is recorded, or the not-running report naming that path is printed.
2. **Read the heartbeat.** Read `{assistant}/heartbeat` and split each line on its first `=`. Branch on the outcome.
| Outcome | Do |
| --- | --- |
| File absent | Set heartbeat state to `不存在`, print `助理未運行`, continue at step 4 — the task book is still worth printing |
| File unreadable (permission denied, I/O error) | Set heartbeat state to `不存在`, print `助理未運行`, name the error text as the reason, continue at step 4 |
| File present, `ts` absent or not an integer | Set heartbeat state to `過期`, name the malformed value, continue at step 4 |
| File present with an integer `ts` | Continue at step 3 |
Done when the heartbeat state holds one of `不存在`, `過期`, or a pending verdict handed to step 3, and the values of `pid`, `cli` and `session` are recorded as read or as absent.
3. **Judge freshness.** Subtract `ts` from the current epoch seconds. A difference below 300 sets the state to `新鮮`; 300 or above sets it to `過期`. Done when the state is `新鮮` or `過期` and the age in seconds is recorded.
4. **Read the task book.** List the regular files directly under `{assistant}/tasks/` and parse each one as `key=value` lines. Branch on the outcome.
| Outcome | Do |
| --- | --- |
| Directory absent | Report zero entries. This is a normal result, not an error |
| Directory present, no files | Report zero entries |
| A file cannot be read or holds no recognisable key | Keep it as one row, put the file name in the title column, name the read or parse error in that row, and carry on with the remaining files |
| A key is missing from a readable file | Print `-` in that column |
Done when every file under `tasks/` has produced exactly one row, or zero entries has been reported.
5. **Print the status table.** Lead with the heartbeat block — state (`新鮮` / `過期` / `不存在`), last heartbeat time rendered from `ts` in local time, `cli`, `session`, and the task count. Follow it with one row per task carrying `state`, `title`, `next_run` and `fail_count`, in the order the files were listed. Done when the heartbeat block holds all five values and the row count equals the task count reported in step 4.
6. **Flag the repeatedly failing tasks.** Append `已連續失敗 N 次` to every row whose `fail_count` is above 0, with `N` taken verbatim from the file. A broken entry that retries every round with nobody noticing is the reason this field exists, so let no such row leave the table unmarked. Done when every row with `fail_count` above 0 carries the marker and its number matches the file.
7. **Finish successfully.** `助理未運行`, an absent tasks directory and an empty tasks directory are normal results — never exit non-zero for any of them. Reserve a failure report for a condition none of the tables above covers, and state which path and which error produced it. Done when the report is printed and nothing under `$JSC_HOME` has been created, modified or deleted.
+44
View File
@@ -0,0 +1,44 @@
# 助理巡檢目錄
> 由 `jsc-assist` 維護。這是目錄頁 `MONITOR_CONTENTS`。
> 一列代表一台機器。雜湊來源是 `{主機名}/{登入帳號}`,所以一台機器一列、一頁,換一支 CLI 不另開列。
> `MONITOR_{HASH}` 的 `{HASH}` 交給 `jsc-gitea/tools/hash-id` 產生,雜湊來源見 `jsc-meta` 的 `references/guidelines.md`「Wiki 頁命名總表」。
| 監控頁 | 主機 | 帳號 | 心跳 | 最後巡檢 | 待辦筆數 | 連續失敗項 |
| --- | --- | --- | --- | --- | ---: | ---: |
| [[MONITOR_{HASH}]] | {主機名} | {登入帳號} | {新鮮、過期、不存在 三選一} | {yyyy-MM-dd HH:mm} | {n} | {n} |
## 欄位說明
| 欄位 | 內容 | 為什麼留這一欄 |
| --- | --- | --- |
| 監控頁 | 指向 `MONITOR_{HASH}` 的同 wiki 連結 | 少了連結就要人自己算雜湊才翻得到內容頁 |
| 主機 | 這台機器的主機名,與雜湊第一段相同 | 比對用的兩欄之一,決定要更新哪一列 |
| 帳號 | 助理執行時的登入帳號,與雜湊第二段相同 | 比對用的兩欄之一。同一台機器換帳號就是另一個巡檢對象 |
| 心跳 | 巡檢當下的心跳判定,判準只看 `ts` 距現在是否不到 300 秒 | 一眼看出這台機器的助理還在不在跑,不必逐頁翻 |
| 最後巡檢 | 該頁最新一節的時間戳 | 心跳新鮮而這一欄很舊,代表助理活著卻沒在巡 |
| 待辦筆數 | 待辦簿現有筆數 | 心跳新鮮而筆數為 0,代表助理空轉,沒有東西可跑 |
| 連續失敗項 | 該頁最新一節裡 `fail_count` 大於 0 的筆數 | 待辦簿的項目失敗不會自動暫停,每輪都重試。這一欄讓壞掉的項目在目錄頁就現形 |
## 寫入規則
這一頁是共用目錄,別台機器的列一律原樣保留。
```mermaid
flowchart TD
A[整頁讀回來] --> B{讀得到舊內容}
B -- 否 --> C[中止:不新增列,也不寫入]
B -- 是 --> D{主機與帳號兩欄都對得上}
D -- 是 --> E[只覆寫那一列的其餘欄位]
D -- 否 --> F[新增一列]
E --> G[其他機器的列原樣送回]
F --> G
```
- 先整頁讀回來,再比對主機與帳號兩欄。
- 兩欄都相同就更新那一列,其餘欄位覆寫成本次巡檢結果。
- 找不到兩欄都相同的列,才新增一列。
- 只動自己那一列,別台機器的列一個字都不改。
- 禁止整頁覆蓋。整頁覆蓋等於刪掉別台機器的紀錄。
- 讀不到舊內容就中止,不新增列,也不寫入。
- 內容頁 `MONITOR_{HASH}` 的寫入語意相反,那頁只附加一節、不覆寫,兩者不要混用。
+114
View File
@@ -0,0 +1,114 @@
# 助理巡檢 — {主機名}/{登入帳號}
> 由 `jsc-assist` 維護。這是監控頁 `MONITOR_{HASH}`。
> 這頁是這台機器的巡檢軌跡:一次巡檢附加一節,節標題帶時間戳,舊的節一個字都不動。
> 附加是刻意的。助理的寫入是背景行為,覆寫錯了沒人在現場,軌跡被抹掉也看不出斷在哪一輪。
> 目錄頁 `MONITOR_CONTENTS` 只更新自己那一列,寫入語意與這頁不同,不要混用。
```mermaid
flowchart LR
A[巡檢一輪] --> B[收攏六類結果]
B --> C[附加一節,節標題帶時間戳]
C --> D[既有的節原樣保留]
D --> E[回頭更新 MONITOR_CONTENTS 自己那一列]
```
## 本頁基本資料
建頁時寫一次,之後不再更動。
| 項目 | 內容 |
| --- | --- |
| 主機 | {主機名} |
| 帳號 | {登入帳號} |
| 雜湊來源 | `{主機名}/{登入帳號}` |
| 狀態檔根目錄 | `$JSC_HOME/assistant/`(`$JSC_HOME` 未設定就退回 `~/.jsc`) |
## 巡檢 {yyyy-MM-dd HH:mm}
一輪巡檢就是這樣一節,最新的一節放在最下面。六個子節固定都寫;某個來源讀不到,就在那個子節寫明是哪個路徑讀不到,不要整節略過。
| 項目 | 內容 |
| --- | --- |
| 巡檢時間 | {yyyy-MM-dd HH:mm} |
| 觸發方式 | {排程、事件、手動 三選一} |
| 本輪判定 | {正常、警示、異常 三選一} |
| 讀不到的來源 | {路徑清單,全部讀得到就寫「無」} |
### 心跳與閘門狀態
| 項目 | 內容 |
| --- | --- |
| 心跳 | {新鮮、過期、不存在 三選一} |
| 上次心跳 | {yyyy-MM-dd HH:mm},距這次巡檢 {n} 秒 |
| cli | {claude、codex、copilot、antigravity、kiro 五選一} |
| session | {工作階段代號} |
| pid | {數字}。只給要找行程的人參考,不參與判定 |
心跳的判準只看 `ts` 距現在是否不到 300 秒。不看 pid 存活:五支 CLI 與容器裡的行程互相看不到彼此的 pid。閘門的判定留在 hook,助理只維持心跳。
### 技能與呼叫鏈使用統計
資料出自 `$JSC_HOME/usage/skills.jsonl` 與 `$JSC_HOME/usage/chains.jsonl`,由 `jsc-log:stats` 聚合。
| 對象 | 類別 | 本輪次數 | 累計次數 |
| --- | --- | ---: | ---: |
| {技能名或呼叫鏈} | {技能、呼叫鏈 二選一} | {n} | {n} |
### hook 執行期錯誤
資料出自 `jsc-hooks` 的 `tools/scan-hook-errors.sh` 與 `tools/scan-logs.sh`。助理只記錄與發動 `jsc-hooks:repair`,不自己改 hook。
| 發生時間 | hook | CLI | 結束碼 | 錯誤摘要 | 已寫 ERROR 頁 |
| --- | --- | --- | ---: | --- | --- |
| {yyyy-MM-dd HH:mm} | {腳本檔名} | {CLI 代號} | {n} | {一句摘要} | {ERROR_{HASH} 連結或「否」} |
### 版本落差與重啟閘門
資料出自 `version-guard.sh report` 與 `restart-gate.sh report`。
| domain | 本機版本 | 應有版本 | 判定 |
| --- | --- | --- | --- |
| {domain} | {版本字串} | {版本字串} | {相符、落後、查不到 三選一} |
| CLI | 重啟閘門 | 升起時間 |
| --- | --- | --- |
| {CLI 代號} | {已升起、未升起 二選一} | {yyyy-MM-dd HH:mm 或「-」} |
### SDLC 階段鎖與工作包鎖現況
資料出自 `$JSC_HOME/sessions/{sid}.stage` 與 `$JSC_HOME/wp/*.pr`。只讀狀態,不做判定。
| 工作階段 | 階段 | 存取庫 | 登記時間 |
| --- | --- | --- | --- |
| {工作階段代號} | {plan、analyze、implement、maintain 四選一} | {owner}/{repo} | {yyyy-MM-dd HH:mm} |
| 存取庫 | 工作包 | PR | 歸屬工作階段 |
| --- | --- | --- | --- |
| {owner}/{repo} | {WP-nn} | {PR 連結} | {工作階段代號} |
### 待辦簿到期與逾期
資料出自 `$JSC_HOME/assistant/tasks/` 底下的每一個檔案,一筆一列。
| id | 標題 | 狀態 | 下次執行 | 到期 | 連續失敗 | 標記 |
| --- | --- | --- | --- | --- | ---: | --- |
| {id} | {title} | {pending、done、paused 三選一} | {next_run} | {due 或「-」} | {fail_count} | {已連續失敗 N 次,或「-」} |
`fail_count` 大於 0 的列,標記欄一律寫「已連續失敗 N 次」,`N` 照檔案原值抄。待辦簿的項目失敗不會自動暫停,會每輪重試;沒標出來,一個壞掉的項目會一直重試而沒人知道。
### 待人處理
助理只提醒,不代為執行。這一節列的是本輪要人接手的項目。
| 項目 | 來源子節 | 建議入口 |
| --- | --- | --- |
| {一句話講完要處理什麼} | {上面六個子節之一} | {技能名或指令} |
## 寫入規則
- 一次巡檢附加一節,節標題帶時間戳,節名不重複。
- 既有的節原樣保留,一個字都不改。
- 禁止整頁覆寫。覆寫等於把這台機器的巡檢軌跡刪掉。
- 讀不到舊內容就中止,不附加,也不寫入。
- 附加成功之後,才回頭更新 `MONITOR_CONTENTS` 自己那一列。