Merge remote-tracking branch 'origin/main' into fix/cloud-wiring-isep90
# Conflicts: # docs/TESTING.md
This commit is contained in:
Executable
+69
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env bash
|
||||
# countdown-milestone-refresh.sh — 把「主線 milestone 的期限」寫進倒數用的快取
|
||||
# (inkstone/ISEP#63 的第二個基準)
|
||||
#
|
||||
# 為什麼是一支獨立腳本、而不是寫在 hook 裡:
|
||||
# 倒數那一行走在 **UserPromptSubmit** 上,也就是每一則訊息的關鍵路徑。
|
||||
# 在那裡打 HTTP = leo 每講一句話都先等一次網路。
|
||||
# ⇒ hook 只讀快取(`hooks/lib/countdown.py` 從不打網路),
|
||||
# 快取由本支在 **SessionStart** 更新一次。不是輪詢、不掛排程(守 D14 紅線)。
|
||||
#
|
||||
# 寫出來的檔:`$ISEP_COUNTDOWN_STATE_DIR/milestone-due`,一行 `YYYY-MM-DD|<名稱>`。
|
||||
# 拿不到 token/拿不到期限 ⇒ **不寫、不報錯、不留舊資料以外的東西**:
|
||||
# 倒數那一行寧可少一段,也不要顯示一個編出來的日期。
|
||||
set -uo pipefail
|
||||
|
||||
HOST="${TICKET_HOST:-https://git.uncle6.me}"
|
||||
TOKEN="${GITEA_TOKEN_CLAUDE_CODE:-${GITEA_TOKEN:-}}"
|
||||
REPOS="${ISEP_COUNTDOWN_REPOS:-inkstone/InkStoneCo inkstone/ISEP}"
|
||||
|
||||
DIR="${ISEP_COUNTDOWN_STATE_DIR:-$HOME/.claude/isep-countdown}"
|
||||
mkdir -p "$DIR" 2>/dev/null || exit 0
|
||||
OUT="$DIR/milestone-due"
|
||||
|
||||
[ -n "$TOKEN" ] || exit 0
|
||||
|
||||
RAW=""
|
||||
for repo in $REPOS; do
|
||||
body=$(curl -s --max-time 4 -H "Authorization: token $TOKEN" \
|
||||
"$HOST/api/v1/repos/$repo/milestones?state=open" 2>/dev/null) || continue
|
||||
RAW="$RAW$body"$'\n'
|
||||
done
|
||||
|
||||
printf '%s' "$RAW" | ISEP_OUT="$OUT" python3 -c '
|
||||
import json, os, sys
|
||||
from datetime import datetime, timezone
|
||||
|
||||
best = None
|
||||
for chunk in sys.stdin.read().split("\n"):
|
||||
chunk = chunk.strip()
|
||||
if not chunk:
|
||||
continue
|
||||
try:
|
||||
rows = json.loads(chunk)
|
||||
except Exception:
|
||||
continue
|
||||
if not isinstance(rows, list):
|
||||
continue
|
||||
for m in rows:
|
||||
due = (m or {}).get("due_on") or ""
|
||||
if not due:
|
||||
continue # 沒設期限的 milestone 不是節拍器
|
||||
try:
|
||||
dt = datetime.fromisoformat(due.replace("Z", "+00:00"))
|
||||
except Exception:
|
||||
continue
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=timezone.utc)
|
||||
# 最近的那一個=現在真的在追的那一個
|
||||
if best is None or dt < best[0]:
|
||||
best = (dt, (m or {}).get("title") or "主線")
|
||||
|
||||
if best is None:
|
||||
raise SystemExit(0)
|
||||
dt, title = best
|
||||
with open(os.environ["ISEP_OUT"], "w") as f:
|
||||
f.write("%s|%s\n" % (dt.astimezone().strftime("%Y-%m-%d"), title))
|
||||
' 2>/dev/null || true
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user