spec-runner 1.0.0-alpha.1 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/spec-runner.js +14 -5
- package/package.json +1 -1
- package/templates/base/scripts/spec-runner.sh +58 -22
- package/templates/claude/.claude/commands/sr-design-high.md +1 -1
- package/templates/claude/.claude/commands/sr-init.md +1 -1
- package/templates/claude/.claude/commands/sr-review.md +1 -1
- package/templates/claude/.claude/commands/sr-set-gate.md +1 -1
- package/templates/copilot/.github/prompts/sr-init.prompt.md +2 -2
- package/templates/cursor/.cursor/commands/sr-design-high.md +1 -1
- package/templates/cursor/.cursor/commands/sr-init.md +1 -1
- package/templates/cursor/.cursor/commands/sr-review.md +1 -1
- package/templates/cursor/.cursor/commands/sr-set-gate.md +1 -1
package/bin/spec-runner.js
CHANGED
|
@@ -94,12 +94,13 @@ async function prompt(questions) {
|
|
|
94
94
|
const answers = {};
|
|
95
95
|
for (const q of questions) {
|
|
96
96
|
if (q.type === 'select') {
|
|
97
|
-
const choices = q.choices.map((c, i) => ` ${i + 1}) ${c}`).join('\n');
|
|
97
|
+
const choices = q.choices.map((c, i) => ` ${i + 1}) ${(c && c.name) != null ? c.name : c}`).join('\n');
|
|
98
98
|
const answer = await new Promise(resolve => {
|
|
99
99
|
rl.question(`${q.message}\n${choices}\n番号を入力: `, resolve);
|
|
100
100
|
});
|
|
101
101
|
const idx = parseInt(answer, 10) - 1;
|
|
102
|
-
|
|
102
|
+
const chosen = q.choices[idx] || q.choices[0];
|
|
103
|
+
answers[q.name] = (chosen && chosen.value != null) ? chosen.value : chosen;
|
|
103
104
|
} else if (q.type === 'multiselect') {
|
|
104
105
|
const choiceList = q.choices.map((c, i) => ` ${i + 1}) ${c.name || c}`).join('\n');
|
|
105
106
|
const answer = await new Promise(resolve => {
|
|
@@ -201,9 +202,9 @@ async function main() {
|
|
|
201
202
|
log('');
|
|
202
203
|
answers = await prompt([
|
|
203
204
|
{
|
|
204
|
-
type: '
|
|
205
|
+
type: 'select',
|
|
205
206
|
name: 'tools',
|
|
206
|
-
message: 'どの AI
|
|
207
|
+
message: 'どの AI ツール用の設定をインストールしますか?(矢印で移動・Enter で確定)',
|
|
207
208
|
choices: [
|
|
208
209
|
{ name: 'Claude Code', value: 'claude' },
|
|
209
210
|
{ name: 'Cursor', value: 'cursor' },
|
|
@@ -240,7 +241,15 @@ async function main() {
|
|
|
240
241
|
tdd: true,
|
|
241
242
|
};
|
|
242
243
|
|
|
243
|
-
|
|
244
|
+
// Select は単一値で返るので配列に統一。name で返る場合もあるので value に正規化
|
|
245
|
+
const toolValueMap = { 'claude code': 'claude', 'cursor': 'cursor', 'github copilot': 'copilot' };
|
|
246
|
+
const raw = answers.tools;
|
|
247
|
+
const toolsArr = Array.isArray(raw) ? raw : (raw ? [raw] : []);
|
|
248
|
+
answers.tools = toolsArr.map((t) => {
|
|
249
|
+
const s = (typeof t === 'string' ? t : '').toLowerCase();
|
|
250
|
+
return toolValueMap[s] || s || null;
|
|
251
|
+
}).filter(Boolean);
|
|
252
|
+
if (answers.tools.length === 0) {
|
|
244
253
|
answers.tools = ['claude', 'cursor', 'copilot'];
|
|
245
254
|
}
|
|
246
255
|
|
package/package.json
CHANGED
|
@@ -824,11 +824,43 @@ cmd_set_gate() {
|
|
|
824
824
|
ok "ゲートフラグ設定: $gate = true"
|
|
825
825
|
}
|
|
826
826
|
|
|
827
|
+
# ── status 表示用:フェーズ・ゲートの日本語ラベル ─────────────────────────────
|
|
828
|
+
phase_ja() {
|
|
829
|
+
case "$1" in
|
|
830
|
+
require) echo "要件定義" ;;
|
|
831
|
+
require-approved) echo "要件承認済み" ;;
|
|
832
|
+
design-high) echo "概要設計" ;;
|
|
833
|
+
design-detail*) echo "詳細設計" ;;
|
|
834
|
+
test-design) echo "テスト設計" ;;
|
|
835
|
+
implement) echo "実装" ;;
|
|
836
|
+
complete) echo "完了" ;;
|
|
837
|
+
fix) echo "修正" ;;
|
|
838
|
+
*) echo "$1" ;;
|
|
839
|
+
esac
|
|
840
|
+
}
|
|
841
|
+
gate_ja() {
|
|
842
|
+
case "$1" in
|
|
843
|
+
require_approved) echo "要件レビュー済み" ;;
|
|
844
|
+
glossary_checked) echo "用語集確認済み" ;;
|
|
845
|
+
high_level_reviewed) echo "概要設計レビュー済み" ;;
|
|
846
|
+
domain_model_reviewed) echo "ドメインモデルレビュー済み" ;;
|
|
847
|
+
usecase_design_reviewed) echo "ユースケース設計レビュー済み" ;;
|
|
848
|
+
table_design_reviewed) echo "テーブル設計レビュー済み" ;;
|
|
849
|
+
infra_design_reviewed) echo "インフラ設計レビュー済み" ;;
|
|
850
|
+
test_design_reviewed) echo "テスト設計レビュー済み" ;;
|
|
851
|
+
test_code_committed) echo "テストコードコミット済み" ;;
|
|
852
|
+
*) echo "$1" ;;
|
|
853
|
+
esac
|
|
854
|
+
}
|
|
855
|
+
|
|
827
856
|
# ── status ─────────────────────────────────────────────────────────────────────
|
|
828
857
|
cmd_status() {
|
|
829
858
|
if [[ ! -f "$STATE_FILE" ]]; then
|
|
830
859
|
info "作業中のユースケースはありません"
|
|
831
|
-
info "
|
|
860
|
+
info ""
|
|
861
|
+
info "開始するには: チャットで /sr-init <ユースケース名> またはターミナルで下記を実行してください。"
|
|
862
|
+
info " 例(チャット): /sr-init 会員登録 会員"
|
|
863
|
+
info " 例(ターミナル): ./scripts/spec-runner.sh init 会員登録 会員"
|
|
832
864
|
return
|
|
833
865
|
fi
|
|
834
866
|
|
|
@@ -838,12 +870,15 @@ cmd_status() {
|
|
|
838
870
|
branch=$(state_get "branch")
|
|
839
871
|
agg_branch=$(state_get "aggregate_branch")
|
|
840
872
|
|
|
873
|
+
local phase_ja_label
|
|
874
|
+
phase_ja_label=$(phase_ja "$phase")
|
|
875
|
+
|
|
841
876
|
echo ""
|
|
842
877
|
echo -e "${BOLD}════════════════════════════════════════${NC}"
|
|
843
878
|
echo -e "${BOLD} 現在の作業状況${NC}"
|
|
844
879
|
echo -e "${BOLD}════════════════════════════════════════${NC}"
|
|
845
880
|
echo -e " ユースケース : ${CYAN}$usecase${NC}"
|
|
846
|
-
echo -e " フェーズ : ${YELLOW}$
|
|
881
|
+
echo -e " フェーズ : ${YELLOW}$phase_ja_label${NC}"
|
|
847
882
|
echo -e " ブランチ : ${BLUE}$branch${NC}"
|
|
848
883
|
[[ -n "$agg_branch" ]] && echo -e " 集約ブランチ: ${BLUE}$agg_branch${NC}"
|
|
849
884
|
echo ""
|
|
@@ -854,63 +889,64 @@ cmd_status() {
|
|
|
854
889
|
domain_model_reviewed usecase_design_reviewed \
|
|
855
890
|
table_design_reviewed infra_design_reviewed \
|
|
856
891
|
test_design_reviewed test_code_committed; do
|
|
857
|
-
local val
|
|
892
|
+
local val gate_label
|
|
858
893
|
val=$(state_get "gates.$gate")
|
|
894
|
+
gate_label=$(gate_ja "$gate")
|
|
859
895
|
if [[ "$val" == "true" ]]; then
|
|
860
|
-
echo -e " ${GREEN}✓${NC} $
|
|
896
|
+
echo -e " ${GREEN}✓${NC} $gate_label"
|
|
861
897
|
else
|
|
862
|
-
echo -e " ${RED}✗${NC} $
|
|
898
|
+
echo -e " ${RED}✗${NC} $gate_label"
|
|
863
899
|
fi
|
|
864
900
|
done
|
|
865
901
|
|
|
866
902
|
echo ""
|
|
867
|
-
echo -e "${BOLD} 次にやるべきこと${NC}"
|
|
903
|
+
echo -e "${BOLD} 次にやるべきこと${NC} ${CYAN}(チャットでは /sr-* スラッシュコマンドが使えます)${NC}"
|
|
868
904
|
local req_file high_file
|
|
869
905
|
req_file=$(uc_req)
|
|
870
906
|
high_file=$(uc_high)
|
|
871
907
|
case "$phase" in
|
|
872
908
|
require)
|
|
873
909
|
echo -e " 1. ${CYAN}$req_file${NC} を編集"
|
|
874
|
-
echo -e " 2.
|
|
875
|
-
echo -e " 3.
|
|
876
|
-
echo -e " 4.
|
|
910
|
+
echo -e " 2. /sr-review $req_file"
|
|
911
|
+
echo -e " 3. /sr-set-gate glossary_checked"
|
|
912
|
+
echo -e " 4. /sr-design-high"
|
|
877
913
|
;;
|
|
878
914
|
design-high)
|
|
879
915
|
echo -e " 1. ${CYAN}$high_file${NC} を編集"
|
|
880
|
-
echo -e " 2.
|
|
881
|
-
echo -e " 3.
|
|
916
|
+
echo -e " 2. /sr-review $high_file"
|
|
917
|
+
echo -e " 3. /sr-design-detail domain"
|
|
882
918
|
;;
|
|
883
|
-
design-detail)
|
|
919
|
+
design-detail*)
|
|
884
920
|
if [[ "$(state_get "gates.domain_model_reviewed")" != "true" ]]; then
|
|
885
921
|
echo -e " 1. docs/detailed/$(uc_slug)/domain.md を編集"
|
|
886
|
-
echo -e " 2. review
|
|
922
|
+
echo -e " 2. /sr-review のあと /sr-design-detail usecase"
|
|
887
923
|
elif [[ "$(state_get "gates.usecase_design_reviewed")" != "true" ]]; then
|
|
888
924
|
echo -e " 1. docs/detailed/$(uc_slug)/usecase.md を編集"
|
|
889
|
-
echo -e " 2. review
|
|
925
|
+
echo -e " 2. /sr-review のあと /sr-design-detail table"
|
|
890
926
|
elif [[ "$(state_get "gates.table_design_reviewed")" != "true" ]]; then
|
|
891
927
|
echo -e " 1. docs/detailed/$(uc_slug)/table.md を編集"
|
|
892
|
-
echo -e " 2. review
|
|
928
|
+
echo -e " 2. /sr-review のあと /sr-design-detail infra"
|
|
893
929
|
elif [[ "$(state_get "gates.infra_design_reviewed")" != "true" ]]; then
|
|
894
930
|
echo -e " 1. docs/detailed/$(uc_slug)/infra.md を編集"
|
|
895
|
-
echo -e " 2. review
|
|
931
|
+
echo -e " 2. /sr-review のあと /sr-test-design"
|
|
896
932
|
else
|
|
897
|
-
echo -e "
|
|
933
|
+
echo -e " /sr-test-design"
|
|
898
934
|
fi
|
|
899
935
|
;;
|
|
900
936
|
test-design)
|
|
901
937
|
echo -e " 1. docs/test-design/$(uc_slug).md を編集し、テストコードを書く(Red)"
|
|
902
|
-
echo -e " 2. テストコードをコミット →
|
|
903
|
-
echo -e " 3.
|
|
904
|
-
echo -e " 4.
|
|
938
|
+
echo -e " 2. テストコードをコミット → /sr-set-gate test_code_committed"
|
|
939
|
+
echo -e " 3. /sr-review docs/test-design/$(uc_slug).md"
|
|
940
|
+
echo -e " 4. /sr-implement"
|
|
905
941
|
;;
|
|
906
942
|
implement)
|
|
907
|
-
echo -e " 実装してテストを Green にしたら:
|
|
943
|
+
echo -e " 実装してテストを Green にしたら: /sr-complete"
|
|
908
944
|
;;
|
|
909
945
|
complete)
|
|
910
946
|
echo -e " 完了。PR を作成してマージしてください。"
|
|
911
947
|
;;
|
|
912
948
|
fix)
|
|
913
|
-
echo -e " 案内に従って該当ドキュメントを修正し、必要なら design-detail 等から再実行。"
|
|
949
|
+
echo -e " 案内に従って該当ドキュメントを修正し、必要なら /sr-design-detail 等から再実行。"
|
|
914
950
|
;;
|
|
915
951
|
*)
|
|
916
952
|
echo -e " ./scripts/spec-runner.sh help でコマンド一覧を確認"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /sr-init
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**チャットで使うコマンド**。$ARGUMENTS にはユーザーがスラッシュの後に続けて入力した文字列が入ります。以下を**ターミナルで実行**してください(例: ユーザーが `/sr-init 顧客登録 顧客管理` と入力した場合)。
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
./scripts/spec-runner.sh init $ARGUMENTS
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /sr-review
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**チャットで使うコマンド**。$ARGUMENTS にレビュー通過させるファイルパスを指定し、以下を**ターミナルで実行**してください(例: `/sr-review docs/requirements/顧客登録.md`)。
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
./scripts/spec-runner.sh review-pass $ARGUMENTS
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
agent: 'agent'
|
|
3
|
-
description: 'spec-runner:
|
|
3
|
+
description: 'spec-runner: ユースケースを初期化(未設定なら詳細設定の対話から)。チャットで /sr-init ユースケース名 集約名 と入力して使う'
|
|
4
4
|
argument-hint: 'ユースケース名 集約名(例: 顧客登録 顧客管理)。空なら設定対話のみ'
|
|
5
5
|
tools: ['shell']
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
**チャットで /sr-init と入力して使う**。以下を**必ずシェルで実行**してください。
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
./scripts/spec-runner.sh init ${input:args:ユースケース名 集約名(スペース区切り。集約名は省略可)}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /sr-init
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**チャットで使うコマンド**。ユーザーが `/sr-init` の後に続けて入力した文字列を引数として、以下を**ターミナルで実行**してください(例: ユーザーが `/sr-init 顧客登録 顧客管理` と入力した場合)。
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
./scripts/spec-runner.sh init <ユーザーが入力した引数>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /sr-review
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**チャットで使うコマンド**。ユーザーが `/sr-review` の後に続けて入力したファイルパスで、以下を**ターミナルで実行**してください(例: `/sr-review docs/requirements/顧客登録.md`)。
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
./scripts/spec-runner.sh review-pass <ユーザーが入力したファイルパス>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /sr-set-gate
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**チャットで使うコマンド**。ユーザーが `/sr-set-gate` の後に続けて入力したゲート名で、以下を**ターミナルで実行**してください(例: `/sr-set-gate glossary_checked`)。
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
./scripts/spec-runner.sh set-gate <ユーザーが入力したゲート名>
|