feat: 加入 herdr 技能並將 herdr-issue 併入為 gitea-issue #21
@@ -18,12 +18,7 @@
|
||||
{
|
||||
"name": "herdr",
|
||||
"source": "./plugins/herdr",
|
||||
"description": "控制 Herdr 終端多工器(workspace、tab、pane、指令與其他 agent)的技能"
|
||||
},
|
||||
{
|
||||
"name": "herdr-issue",
|
||||
"source": "./plugins/herdr-issue",
|
||||
"description": "透過 Herdr 讓 Claude agent 逐一實作 Gitea 議題(每個議題一個 worktree 與 tab)"
|
||||
"description": "控制 Herdr 終端多工器(workspace、tab、pane、指令與其他 agent),並可透過 gitea-issue 技能逐一實作 Gitea 議題"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,8 +6,7 @@ JSC 自用 Claude Code mods。每個 mod 皆可單獨安裝、更新與移除。
|
||||
| --- | --- |
|
||||
| [statusbar](plugins/statusbar) | 輸入框上方單行狀態列:模型、目錄、分支、5h/7d 額度與重置、context、CPU/記憶體/磁碟 |
|
||||
| [companion](plugins/companion) | 小說角色陪伴:人設注入、語氣、心情與好感、互動記憶、主動關心與待辦,並可用 ingest skill 解析小說建立角色 |
|
||||
| [herdr](plugins/herdr) | 控制 Herdr 終端多工器的技能(workspace、tab、pane、指令與其他 agent;需 Herdr) |
|
||||
| [herdr-issue](plugins/herdr-issue) | 透過 Herdr 讓 Claude agent 逐一實作 Gitea 議題,每個議題一個 worktree 與 tab(skill,需 Herdr 與 tea) |
|
||||
| [herdr](plugins/herdr) | 控制 Herdr 終端多工器的技能(workspace、tab、pane、指令與其他 agent;另含 gitea-issue 技能,逐一實作 Gitea 議題,需 Herdr 與 tea) |
|
||||
|
||||
## 安裝
|
||||
|
||||
@@ -18,7 +17,6 @@ claude plugin marketplace add https://gitea.jsc.idv.tw/jiantw83/jsc-marketplace.
|
||||
claude plugin install statusbar@jsc-marketplace
|
||||
claude plugin install companion@jsc-marketplace
|
||||
claude plugin install herdr@jsc-marketplace
|
||||
claude plugin install herdr-issue@jsc-marketplace
|
||||
```
|
||||
|
||||
## 指令
|
||||
@@ -26,7 +24,7 @@ claude plugin install herdr-issue@jsc-marketplace
|
||||
- `/statusbar on | off | compact`:切換狀態列
|
||||
- `/companion status | switch <角色> | off | setup | todo | quiet`:角色陪伴控制(`todo add <內容> [due=YYYY-MM-DDTHH:MM]`、`todo done <編號>`、`quiet [分鐘]`)
|
||||
- `herdr` skill:提到 Herdr 時自動用於操作 pane、tab、workspace 與其他 agent
|
||||
- `/herdr-issue:herdr-issue <議題連結>`:交給 Herdr 裡的 Claude agent 實作 Gitea 議題
|
||||
- `/herdr:gitea-issue <議題連結>`:交給 Herdr 裡的 Claude agent 實作 Gitea 議題
|
||||
|
||||
## 更新
|
||||
|
||||
@@ -35,7 +33,6 @@ claude plugin marketplace update jsc-marketplace
|
||||
claude plugin update statusbar@jsc-marketplace
|
||||
claude plugin update companion@jsc-marketplace
|
||||
claude plugin update herdr@jsc-marketplace
|
||||
claude plugin update herdr-issue@jsc-marketplace
|
||||
```
|
||||
|
||||
更新後需重新啟動 Claude Code 才會生效。
|
||||
@@ -46,7 +43,6 @@ claude plugin update herdr-issue@jsc-marketplace
|
||||
claude plugin uninstall statusbar@jsc-marketplace
|
||||
claude plugin uninstall companion@jsc-marketplace
|
||||
claude plugin uninstall herdr@jsc-marketplace
|
||||
claude plugin uninstall herdr-issue@jsc-marketplace
|
||||
claude plugin marketplace remove jsc-marketplace
|
||||
```
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "herdr-issue",
|
||||
"version": "0.0.1",
|
||||
"description": "透過 Herdr 讓 Claude agent 逐一實作 Gitea 議題(每個議題一個 worktree 與 tab)",
|
||||
"license": "MIT",
|
||||
"skills": "./skills",
|
||||
"author": {
|
||||
"name": "JSC"
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "herdr",
|
||||
"version": "0.0.1",
|
||||
"description": "控制 Herdr 終端多工器(workspace、tab、pane、指令與其他 agent)的技能",
|
||||
"version": "0.0.2",
|
||||
"description": "控制 Herdr 終端多工器(workspace、tab、pane、指令與其他 agent),並可透過 gitea-issue 技能逐一實作 Gitea 議題",
|
||||
"license": "MIT",
|
||||
"skills": "./skills",
|
||||
"author": {
|
||||
|
||||
+4
-4
@@ -1,11 +1,11 @@
|
||||
---
|
||||
name: herdr-issue
|
||||
description: "Run Gitea issues through Herdr: one Claude agent per issue in its own worktree and tab, watch the issue to closure, then offer the next unblocked issues. Use only when the user runs /herdr-issue or explicitly asks to drive a Gitea issue or repo link with Herdr."
|
||||
name: gitea-issue
|
||||
description: "Run Gitea issues through Herdr: one Claude agent per issue in its own worktree and tab, watch the issue to closure, then offer the next unblocked issues. Use only when the user runs /herdr:gitea-issue or explicitly asks to drive a Gitea issue or repo link with Herdr."
|
||||
---
|
||||
|
||||
# herdr-issue
|
||||
# gitea-issue
|
||||
|
||||
把 Gitea 議題交給 Herdr 裡的 Claude agent 實作。所有確定性的工作都在 `scripts/` 裡,你只在「要做決定」的時刻出手。腳本都要在該 repo 的 clone 裡執行;`S` 代表 `~/.claude/skills/herdr-issue/scripts`。
|
||||
把 Gitea 議題交給 Herdr 裡的 Claude agent 實作。所有確定性的工作都在 `scripts/` 裡,你只在「要做決定」的時刻出手。腳本都要在該 repo 的 clone 裡執行;`S` 代表 `~/.claude/skills/gitea-issue/scripts`。
|
||||
|
||||
## 使用者身分
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# herdr-issue 共用函式。每個腳本都 source 這個檔。
|
||||
# gitea-issue 共用函式。每個腳本都 source 這個檔。
|
||||
set -euo pipefail
|
||||
|
||||
LABEL="in-progress"
|
||||
@@ -9,7 +9,7 @@ INTERVAL="${HERDR_ISSUE_INTERVAL:-300}"
|
||||
MODEL="${HERDR_ISSUE_MODEL:-claude-sonnet-5-5}"
|
||||
SCRIPTS="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
die() { echo "herdr-issue: $*" >&2; exit 1; }
|
||||
die() { echo "gitea-issue: $*" >&2; exit 1; }
|
||||
|
||||
# tea 的預設使用者。在 clone 裡 tea 會依 remote URL 挑第一個符合的 login(可能不是預設的),
|
||||
# 所以明確取 default 那個 login,所有 tea 呼叫都加 --login。可用 HERDR_ISSUE_LOGIN 覆寫。
|
||||
@@ -17,7 +17,7 @@ if [ -z "${HERDR_ISSUE_LOGIN:-}" ]; then
|
||||
HERDR_ISSUE_LOGIN="$(tea login list --output json | python3 -c "import sys,json
|
||||
print(next((l['name'] for l in json.load(sys.stdin) if str(l.get('default')).lower()=='true'),''))")"
|
||||
fi
|
||||
[ -n "$HERDR_ISSUE_LOGIN" ] || { echo "herdr-issue: tea 沒有預設 login,請先 tea login default <name>" >&2; exit 1; }
|
||||
[ -n "$HERDR_ISSUE_LOGIN" ] || { echo "gitea-issue: tea 沒有預設 login,請先 tea login default <name>" >&2; exit 1; }
|
||||
export HERDR_ISSUE_LOGIN
|
||||
|
||||
# 忽略所有 TLS 檢查:tea 的 insecure 只能寫在設定檔(沒有環境變數),所以把所有 login 設成 insecure: true(冪等);
|
||||
@@ -39,7 +39,7 @@ tea() {
|
||||
out="$(command tea "$1" --login "$HERDR_ISSUE_LOGIN" "${@:2}" 2>"$ef")" && rc=0 || rc=$?
|
||||
err="$(cat "$ef")"
|
||||
if [ "$rc" -eq 0 ] || ! grep -qiE 'tls|x509|certificate|handshake' <<<"$out$err"; then break; fi
|
||||
echo "herdr-issue: tea 遇到 TLS/憑證錯誤(第 $try/$max 次),3 秒後重試" >&2
|
||||
echo "gitea-issue: tea 遇到 TLS/憑證錯誤(第 $try/$max 次),3 秒後重試" >&2
|
||||
rc=${rc/#0/1}; sleep 3
|
||||
done
|
||||
rm -f "$ef"
|
||||
@@ -125,7 +125,7 @@ raw=sys.stdin.read()
|
||||
try: d=json.loads(raw)
|
||||
except Exception: d=None
|
||||
if not isinstance(d,list):
|
||||
sys.stderr.write('herdr-issue: 讀取 #$2 的依賴失敗:'+raw.strip()[:300]+'\n'); sys.exit(1)
|
||||
sys.stderr.write('gitea-issue: 讀取 #$2 的依賴失敗:'+raw.strip()[:300]+'\n'); sys.exit(1)
|
||||
for i in d:
|
||||
if i.get('state')=='open':
|
||||
r=(i.get('repository') or {}).get('full_name','')
|
||||
+1
-1
@@ -38,7 +38,7 @@ def open_blockers(n):
|
||||
try: d = json.loads(raw)
|
||||
except Exception: d = None
|
||||
if not isinstance(d, list):
|
||||
sys.exit(f"herdr-issue: 讀取 #{n} 的依賴失敗:{raw.strip()[:300]}")
|
||||
sys.exit(f"gitea-issue: 讀取 #{n} 的依賴失敗:{raw.strip()[:300]}")
|
||||
out = []
|
||||
for i in d:
|
||||
if i.get("state") != "open": continue
|
||||
+1
-1
@@ -77,7 +77,7 @@ PROMPT_ERR="$(mktemp)"
|
||||
if PROMPT_OUT="$(herdr agent prompt "issue-$N" "$PROMPT" --wait --until working --until blocked --timeout 15000 2>"$PROMPT_ERR")"; then
|
||||
rm -f "$PROMPT_ERR"
|
||||
else
|
||||
echo "herdr-issue: 送出提示詞後 agent 沒有反應,已回滾" >&2
|
||||
echo "gitea-issue: 送出提示詞後 agent 沒有反應,已回滾" >&2
|
||||
cat "$PROMPT_ERR" >&2; rm -f "$PROMPT_ERR"
|
||||
rollback
|
||||
exit 1
|
||||
+1
-1
@@ -16,7 +16,7 @@ NOTIFIED=false
|
||||
close_if_done() { # $1=X $2=label
|
||||
[ "$(issue_state "$REPO" "$1")" = open ] || { echo skip; return; }
|
||||
if [ "$(open_count_with_label "$REPO" "$2")" = 0 ]; then
|
||||
tea comment "$1" --repo "$REPO" "底下的議題全部關閉,由 herdr-issue 自動關閉。" >/dev/null
|
||||
tea comment "$1" --repo "$REPO" "底下的議題全部關閉,由 gitea-issue 自動關閉。" >/dev/null
|
||||
tea issues close "$1" --repo "$REPO" >/dev/null
|
||||
echo closed
|
||||
else
|
||||
Reference in New Issue
Block a user