feat(assist): 樣板改成 jsc-assist domain,加上 status 技能

What:
- 三份 manifest 的 name 由 jsc-template 改成 jsc-assist,version 設為 0.0.1,description 改寫成助理的定位,並加上 jsc.requires 宣告對 jsc-cli、jsc-gitea、jsc-hooks、jsc-log 的最低版本。
- README.md 與 AGENTS.md 依 meta domain 的格式重寫,AGENTS.md 多一節「助理的界線」。
- 刪掉樣板的 hello 技能,新增 status 技能與 references/behaviors.md 行為清單。

Why:
- 這個存取庫原本整份是 template 的樣板,四份 manifest 都還叫 jsc-template。名字沒改,marketplace 認不出它是獨立的 domain,各 CLI 也裝不上。
- 助理的閘門、心跳與巡檢要有落點,前提是存取庫先認得出自己。
- 樣板的 hello 技能只是安裝驗證用,留著會讓助理的技能清單從第一天就帶著一支沒有用途的技能。換成唯讀的 status,行為檢查與 frontmatter 檢查也才有掃描對象。

How:
- status 全程唯讀:讀心跳檔判斷助理在不在跑,判準只看時間戳距現在是否不到 300 秒,不看 pid 存活——五支 CLI 與容器裡的行程互相看不到彼此的 pid。
- 心跳檔不存在時印「助理未運行」,這是正常結果,不以非 0 結束。
- 這支不新增 tools/ 腳本。讀兩個路徑印一張表還不到抽腳本的門檻,助理主體落地時再一併評估。
- 三份 manifest 的 version 由 sync-skill-manifest.sh 同步,README 的技能目錄區塊一起更新。

Who:
助理 domain 落地的第一步,後續的閘門、心跳與排程都接在這個基礎上。
This commit is contained in:
2026-09-01 11:20:52 +08:00
parent 7790283920
commit 6e18a373f3
8 changed files with 177 additions and 273 deletions
+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.1",
"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.1",
"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:描述需求自動觸發。
+44 -210
View File
@@ -1,228 +1,62 @@
# 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`「技能行為清單」 |
## 助理的狀態檔
全部放在 `$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 委派
+12 -4
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.1",
"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.