feat(hooks): 匯入 jsc-hooks 技能組並統一 marketplace 為 jsc #2

Merged
admin merged 9 commits from develop into master 2026-08-21 06:39:53 +00:00
6 changed files with 134 additions and 0 deletions
Showing only changes of commit b774df23ae - Show all commits
+19
View File
@@ -0,0 +1,19 @@
{
"hooks": {
"SessionStart": [
{ "hooks": [ { "type": "command", "command": "sh \"${CLAUDE_PLUGIN_ROOT}/hooks/session-timer.sh\" start" } ] }
],
"UserPromptSubmit": [
{ "hooks": [ { "type": "command", "command": "sh \"${CLAUDE_PLUGIN_ROOT}/hooks/ste100-guard.sh\"" } ] }
],
"Stop": [
{ "hooks": [ { "type": "command", "command": "sh \"${CLAUDE_PLUGIN_ROOT}/hooks/session-timer.sh\" mark" } ] }
],
"SessionEnd": [
{ "hooks": [ { "type": "command", "command": "sh \"${CLAUDE_PLUGIN_ROOT}/hooks/session-timer.sh\" mark" } ] }
],
"PostToolUse": [
{ "matcher": "Skill", "hooks": [ { "type": "command", "command": "sh \"${CLAUDE_PLUGIN_ROOT}/hooks/skill-usage.sh\"" } ] }
]
}
}
Executable
+35
View File
@@ -0,0 +1,35 @@
#!/usr/bin/env sh
# lib.sh — jsc hooks 共用函式。所有 hook 腳本 source 此檔。
# 輸入相容:Claude 式 stdin JSON、或環境變數(codex/copilot/antigravity/kiro 接線時設定)。
# 缺資料時安靜降級,hook 永遠 exit 0,不可中斷宿主 CLI。
JSC_HOME="${JSC_HOME:-$HOME/.jsc}"
mkdir -p "$JSC_HOME/sessions" "$JSC_HOME/usage" 2>/dev/null || true
# 讀完 stdin(可能為空;非阻塞宿主)
read_stdin() {
if [ -t 0 ]; then STDIN_JSON=""; else STDIN_JSON=$(cat 2>/dev/null || true); fi
}
# 從 stdin JSON 取字串欄位(naive 但足夠應付各 CLI 的扁平 payload)
json_str() { # $1=欄位名
printf '%s' "$STDIN_JSON" | tr -d '\n' \
| sed -n "s/.*\"$1\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p" | head -n1
}
# 目前 session id:stdin JSON > 環境變數 > 固定值
session_id() {
sid=$(json_str session_id)
[ -n "$sid" ] || sid="${JSC_SESSION_ID:-${CLAUDE_SESSION_ID:-default}}"
printf '%s' "$sid"
}
# 目前 CLI 名稱:環境變數 > 依 stdin 特徵猜測 > unknown
cli_name() {
if [ -n "${JSC_CLI:-}" ]; then printf '%s' "$JSC_CLI"
elif [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then printf 'claude'
else printf 'unknown'; fi
}
now_epoch() { date +%s; }
now_iso() { date -u +%Y-%m-%dT%H:%M:%SZ; }
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env sh
# session-timer.sh — 記錄工作階段花費時間(供 jsc-log:worklog 取用)。
# 用法:
# session-timer.sh start # SessionStart:記錄起始時間
# session-timer.sh mark # Stop/SessionEnd:更新最後活動時間
# session-timer.sh report [sid] # 印出 {sid} {seconds};無紀錄印 0
HERE=$(dirname "$0"); . "$HERE/lib.sh"
read_stdin
sid=$(session_id)
case "${1:-mark}" in
start)
f="$JSC_HOME/sessions/$sid.start"
[ -f "$f" ] || now_epoch > "$f" ;;
mark)
now_epoch > "$JSC_HOME/sessions/$sid.end" ;;
report)
rsid="${2:-$sid}"
s=$(cat "$JSC_HOME/sessions/$rsid.start" 2>/dev/null || echo "")
e=$(cat "$JSC_HOME/sessions/$rsid.end" 2>/dev/null || now_epoch)
if [ -n "$s" ]; then echo "$rsid $((e - s))"; else echo "$rsid 0"; fi ;;
esac
exit 0
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env sh
# skill-usage.sh — 記錄技能使用與呼叫鏈(供 jsc-log:stats 統計)。
# Claude: PostToolUse(matcher=Skill) 接線;其他 CLI 由 wrapper 以
# JSC_SKILL=<name> skill-usage.sh 呼叫。
# 產出:
# $JSC_HOME/usage/skills.jsonl {ts,cli,session,skill}
# $JSC_HOME/usage/chains.jsonl {ts,cli,session,from,to}(同 session 內前一技能 → 本技能)
HERE=$(dirname "$0"); . "$HERE/lib.sh"
read_stdin
skill="${JSC_SKILL:-$(json_str skill)}"
[ -n "$skill" ] || exit 0
sid=$(session_id); cli=$(cli_name); ts=$(now_iso)
printf '{"ts":"%s","cli":"%s","session":"%s","skill":"%s"}\n' \
"$ts" "$cli" "$sid" "$skill" >> "$JSC_HOME/usage/skills.jsonl"
last_f="$JSC_HOME/sessions/$sid.lastskill"
last=$(cat "$last_f" 2>/dev/null || echo "")
if [ -n "$last" ]; then
printf '{"ts":"%s","cli":"%s","session":"%s","from":"%s","to":"%s"}\n' \
"$ts" "$cli" "$sid" "$last" "$skill" >> "$JSC_HOME/usage/chains.jsonl"
fi
printf '%s' "$skill" > "$last_f"
exit 0
+6
View File
@@ -0,0 +1,6 @@
#!/usr/bin/env sh
# ste100-guard.sh — 於每次使用者提示時注入語言規則(hook > prompt 的強制層)。
# Claude: UserPromptSubmit 的 stdout 會成為額外 context。
# 其他 CLI: 由 hooks-install 以各自的規則檔(AGENTS.md 等)落地,本腳本仍可被 wrapper 呼叫。
echo "[jsc] 輸出規則:所有回覆基於 STE100 使用繁體中文(短句、一句一指令、主動語態、術語一致、UTF-8 無亂碼)。"
exit 0
+30
View File
@@ -0,0 +1,30 @@
---
name: hooks-install
description: Wire jsc hooks (STE100 guard, session timer, skill usage logger) into every installed AI CLI. Detect CLIs via jsc-cli detect-clis.sh, then apply native hook config per CLI or fall back to instruction files. Use after installing or updating the jsc plugin set; not for writing new hooks.
---
# hooks-install — 將 jsc hooks 接線到所有已安裝的 CLI
目標:讓三支 hook(`ste100-guard.sh`、`session-timer.sh`、`skill-usage.sh`)在每個 CLI 生效。
細節流程**必須以 sub agent 執行**,主 agent 只回報結果摘要。
## 步驟
1. 執行 `jsc-cli/tools/detect-clis.sh` 取得已安裝的 CLI 與路徑。
2. 對每個 CLI 依下表接線(hook 優先,無 hook 系統就降級為規則檔):
| CLI | 接線方式 |
| --- | --- |
| claude | plugin 安裝時自動載入 `jsc-hooks/hooks/hooks.json`,只需驗證:`claude plugin list` 有 `jsc-hooks` 且 `/hooks` 顯示已註冊 |
| codex | `~/.codex/config.toml` 設定 `notify` 指向 `session-timer.sh mark`(帶 `JSC_CLI=codex`);STE100 規則追加到 `~/.codex/AGENTS.md`(prompt 降級) |
| copilot | 無 hook 系統:STE100 規則追加到 `~/.config/copilot/copilot-instructions.md`(prompt 降級) |
| antigravity | 無公開 hook 系統:STE100 規則追加到全域 rules 檔(prompt 降級) |
| kiro | 於工作區 `.kiro/hooks/` 建立 agent hook,觸發時執行對應腳本(帶 `JSC_CLI=kiro`) |
3. 規則檔追加內容一律使用 `ste100-guard.sh` 的輸出文字,且以 `<!-- jsc-hooks -->` 標記包住,重複執行時整段取代不重複追加。
4. 回報每個 CLI 的接線結果(成功 / 降級為 prompt / 跳過原因)。
## 注意
- Hook 腳本同時接受 stdin JSON 與環境變數(`JSC_CLI`、`JSC_SESSION_ID`、`JSC_SKILL`),wrapper 只需設環境變數。
- 資料落在 `$JSC_HOME`(預設 `~/.jsc`),供 `jsc-log:worklog` 與 `jsc-log:stats` 取用。