feat(model-config): 新增 SDLC 階段指定模型鏈解析工具
What:新增 tools/model-config.sh,提供 get {stage} 與 list 兩個子命令,解析 SDLC 各階段(plan、analyze、implement、maintain)的指定模型鏈。
Why:讓 jsc-sdlc 各階段閘門能以角色式模型路由指定模型與遞補鏈,而不是只靠能力標籤比對;同時讓專案能覆寫全域設定。
How:以 POSIX sh 加 awk 實作;先讀專案目錄 .jsc/models,該階段沒設定才退回 $JSC_HOME/models.conf(JSC_HOME 預設 ~/.jsc);設定格式 stage=model[,fallback...],同階段多行取最後一行;get 未設定時空輸出且 exit 0,list 每階段輸出 stage、chain、source(未設定印「-」)。
Who:jsc-cli models 技能與 jsc-sdlc 各階段的模型閘門。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Executable
+84
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env sh
|
||||
# model-config.sh — 解析 SDLC 各階段的指定模型鏈(角色式路由)。
|
||||
# 設定格式(一行一階段):stage=model[,fallback1[,fallback2...]]
|
||||
# 「#」開頭為註解,空白行忽略。階段限定:plan、analyze、implement、maintain。
|
||||
# 解析順序:
|
||||
# 1. 目前工作目錄的 ./.jsc/models(專案覆寫)
|
||||
# 2. $JSC_HOME/models.conf(JSC_HOME 預設 ~/.jsc)
|
||||
# 專案檔有設定的階段完全覆寫全域設定;其餘階段仍讀全域檔。
|
||||
# 用法:
|
||||
# model-config.sh get {stage} 印出該階段解析後的模型鏈(逗號分隔);未設定不印。兩種情況都 exit 0。
|
||||
# model-config.sh list 每階段一行:stage<TAB>chain<TAB>source(project 或 global);未設定的 chain 與 source 印「-」。
|
||||
set -u
|
||||
|
||||
JSC_HOME="${JSC_HOME:-$HOME/.jsc}"
|
||||
PROJECT_FILE=./.jsc/models
|
||||
GLOBAL_FILE="$JSC_HOME/models.conf"
|
||||
STAGES="plan analyze implement maintain"
|
||||
|
||||
# 取出單一設定檔裡某階段的模型鏈。
|
||||
# 同階段出現多行時取最後一行,結果才有確定性。
|
||||
read_chain() { # $1=設定檔 $2=階段
|
||||
[ -f "$1" ] || return 0
|
||||
awk -F= -v stage="$2" '
|
||||
{ sub(/\r$/, "") } # 去掉 CR
|
||||
/^[ \t]*#/ { next } # 註解行
|
||||
/^[ \t]*$/ { next } # 空白行
|
||||
index($0, "=") == 0 { next }
|
||||
{
|
||||
key = $1
|
||||
gsub(/[ \t]/, "", key)
|
||||
if (key != stage) next
|
||||
val = substr($0, index($0, "=") + 1)
|
||||
gsub(/[ \t]/, "", val)
|
||||
if (val != "") chain = val
|
||||
}
|
||||
END { if (chain != "") print chain }
|
||||
' "$1"
|
||||
}
|
||||
|
||||
# 解析單一階段:專案檔優先,該階段沒設定才退回全域檔。
|
||||
# 輸出:chain<TAB>source;兩檔都沒設定時不輸出。
|
||||
resolve() { # $1=階段
|
||||
chain=$(read_chain "$PROJECT_FILE" "$1")
|
||||
if [ -n "$chain" ]; then
|
||||
printf '%s\tproject\n' "$chain"
|
||||
return 0
|
||||
fi
|
||||
chain=$(read_chain "$GLOBAL_FILE" "$1")
|
||||
if [ -n "$chain" ]; then
|
||||
printf '%s\tglobal\n' "$chain"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "用法:model-config.sh get {plan|analyze|implement|maintain} | list" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
get)
|
||||
stage="${2:-}"
|
||||
case " $STAGES " in
|
||||
*" $stage "*) ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
resolve "$stage" | cut -f1
|
||||
exit 0
|
||||
;;
|
||||
list)
|
||||
for stage in $STAGES; do
|
||||
line=$(resolve "$stage")
|
||||
if [ -n "$line" ]; then
|
||||
printf '%s\t%s\n' "$stage" "$line"
|
||||
else
|
||||
printf '%s\t-\t-\n' "$stage"
|
||||
fi
|
||||
done
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user