sd-api-mcp 0.2.0__tar.gz
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.
- sd_api_mcp-0.2.0/.claude/rules/development.md +41 -0
- sd_api_mcp-0.2.0/.claude/settings.json +37 -0
- sd_api_mcp-0.2.0/.claude/statusline.sh +12 -0
- sd_api_mcp-0.2.0/.devcontainer/Dockerfile +32 -0
- sd_api_mcp-0.2.0/.devcontainer/devcontainer.json +33 -0
- sd_api_mcp-0.2.0/.devcontainer/docker-compose.yml +15 -0
- sd_api_mcp-0.2.0/.devcontainer/postCreate.sh +20 -0
- sd_api_mcp-0.2.0/.env.example +6 -0
- sd_api_mcp-0.2.0/.github/CODEOWNERS +1 -0
- sd_api_mcp-0.2.0/.github/pull_request_template.md +135 -0
- sd_api_mcp-0.2.0/.github/workflows/ci.yml +48 -0
- sd_api_mcp-0.2.0/.github/workflows/pr-template-check.yml +40 -0
- sd_api_mcp-0.2.0/.github/workflows/publish.yml +107 -0
- sd_api_mcp-0.2.0/.github/workflows/release.yml +46 -0
- sd_api_mcp-0.2.0/.gitignore +24 -0
- sd_api_mcp-0.2.0/.mise.toml +3 -0
- sd_api_mcp-0.2.0/.pre-commit-config.yaml +24 -0
- sd_api_mcp-0.2.0/CHANGELOG.md +31 -0
- sd_api_mcp-0.2.0/CLAUDE.md +115 -0
- sd_api_mcp-0.2.0/PKG-INFO +258 -0
- sd_api_mcp-0.2.0/README.md +236 -0
- sd_api_mcp-0.2.0/docs/superpowers/plans/2026-06-25-pypi-release-cicd.md +817 -0
- sd_api_mcp-0.2.0/docs/superpowers/plans/2026-06-25-sd-api-mcp-plan.md +217 -0
- sd_api_mcp-0.2.0/docs/superpowers/specs/2026-06-25-pypi-release-cicd-design.md +172 -0
- sd_api_mcp-0.2.0/docs/superpowers/specs/2026-06-25-sd-api-mcp-design.md +184 -0
- sd_api_mcp-0.2.0/pyproject.toml +78 -0
- sd_api_mcp-0.2.0/src/sd_api_mcp/__init__.py +3 -0
- sd_api_mcp-0.2.0/src/sd_api_mcp/client.py +118 -0
- sd_api_mcp-0.2.0/src/sd_api_mcp/server.py +287 -0
- sd_api_mcp-0.2.0/tests/__init__.py +1 -0
- sd_api_mcp-0.2.0/tests/conftest.py +19 -0
- sd_api_mcp-0.2.0/tests/test_client.py +185 -0
- sd_api_mcp-0.2.0/tests/test_server.py +133 -0
- sd_api_mcp-0.2.0/uv.lock +1764 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# 開発原則
|
|
2
|
+
|
|
3
|
+
このプロジェクトではt-wada式TDD・YAGNI・SOLID・DRYの原則を厳密に守ります。
|
|
4
|
+
|
|
5
|
+
## TDD(t-wada 式)
|
|
6
|
+
|
|
7
|
+
- **Red → Green → Refactor** の順を必ず守る
|
|
8
|
+
- コードより先にテストを書く
|
|
9
|
+
- テストが通る最小限の実装のみ書く(Greenフェーズ)
|
|
10
|
+
- リファクタは全テストがGreenの状態でのみ行う
|
|
11
|
+
- テストなしでコード変更を行わない
|
|
12
|
+
|
|
13
|
+
## YAGNI(You Aren't Gonna Need It)
|
|
14
|
+
|
|
15
|
+
- 現在の要件に明示されていない機能は実装しない
|
|
16
|
+
- 将来の拡張を見越した抽象化・インタフェース追加は行わない
|
|
17
|
+
- 不要なオプション引数・設定値・フラグは作らない
|
|
18
|
+
- 「あると便利かもしれない」という理由だけでコードを書かない
|
|
19
|
+
|
|
20
|
+
## SOLID
|
|
21
|
+
|
|
22
|
+
- **S (Single Responsibility)**: 各モジュールは1つの責務のみ持つ
|
|
23
|
+
- `server.py` = MCP プロトコル層のみ
|
|
24
|
+
- `client.py` = Stable Diffusion API通信のみ
|
|
25
|
+
- **O (Open/Closed)**: 変更にはテストを書いてから着手する
|
|
26
|
+
- **I (Interface Segregation)**: インタフェースはクライアントが必要とするメソッドのみ定義する
|
|
27
|
+
- 不要なメソッドを生やさない
|
|
28
|
+
- **D (Dependency Inversion)**: 上位レイヤーは下位レイヤーの具体型に依存しない
|
|
29
|
+
|
|
30
|
+
## DRY(Don't Repeat Yourself)
|
|
31
|
+
|
|
32
|
+
- 重複するロジックは共通ヘルパーに集約する
|
|
33
|
+
- テストの共通セットアップは conftest.py フィクスチャに集約する
|
|
34
|
+
- エラー変換パターンは1か所に集める
|
|
35
|
+
- コピペコードを避ける
|
|
36
|
+
|
|
37
|
+
## コメント
|
|
38
|
+
|
|
39
|
+
- デフォルトはコメント不要
|
|
40
|
+
- WHYが非自明な場合のみコメントを書く
|
|
41
|
+
- 「何をしているか」は良い命名で表現する
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
|
3
|
+
"language": "japanese",
|
|
4
|
+
"model": "claude-sonnet-4-6",
|
|
5
|
+
"attribution": {
|
|
6
|
+
"commit": "",
|
|
7
|
+
"pr": ""
|
|
8
|
+
},
|
|
9
|
+
"enabledMcpjsonServers": [
|
|
10
|
+
"plugin_serena_serena"
|
|
11
|
+
],
|
|
12
|
+
"statusLine": {
|
|
13
|
+
"type": "command",
|
|
14
|
+
"command": ".claude/statusline.sh"
|
|
15
|
+
},
|
|
16
|
+
"enabledPlugins": {
|
|
17
|
+
"superpowers@claude-plugins-official": true,
|
|
18
|
+
"pyright-lsp@claude-plugins-official": true,
|
|
19
|
+
"context7@claude-plugins-official": true,
|
|
20
|
+
"bash-language-server@claude-code-lsps": true,
|
|
21
|
+
"criticalthink@criticalthink": true
|
|
22
|
+
},
|
|
23
|
+
"extraKnownMarketplaces": {
|
|
24
|
+
"claude-code-lsps": {
|
|
25
|
+
"source": {
|
|
26
|
+
"source": "github",
|
|
27
|
+
"repo": "boostvolt/claude-code-lsps"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"criticalthink": {
|
|
31
|
+
"source": {
|
|
32
|
+
"source": "github",
|
|
33
|
+
"repo": "abagames/slash-criticalthink"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -u
|
|
3
|
+
|
|
4
|
+
input=$(cat)
|
|
5
|
+
MODEL=$(printf '%s' "$input" | jq -r '.model.display_name // "unknown"')
|
|
6
|
+
PCT=$(printf '%s' "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
|
|
7
|
+
|
|
8
|
+
if BRANCH=$(git branch --show-current 2>/dev/null) && [ -n "$BRANCH" ]; then
|
|
9
|
+
echo "${MODEL} | ${PCT}% | ${BRANCH}"
|
|
10
|
+
else
|
|
11
|
+
echo "${MODEL} | ${PCT}%"
|
|
12
|
+
fi
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
FROM debian:bookworm-slim
|
|
2
|
+
|
|
3
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
4
|
+
curl git ca-certificates gnupg jq shellcheck \
|
|
5
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
6
|
+
|
|
7
|
+
# GitHub CLI (gh)
|
|
8
|
+
RUN install -d -m 0755 /etc/apt/keyrings \
|
|
9
|
+
&& curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
|
|
10
|
+
-o /etc/apt/keyrings/githubcli-archive-keyring.gpg \
|
|
11
|
+
&& chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
|
|
12
|
+
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
|
|
13
|
+
> /etc/apt/sources.list.d/github-cli.list \
|
|
14
|
+
&& apt-get update && apt-get install -y --no-install-recommends gh \
|
|
15
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
16
|
+
|
|
17
|
+
RUN groupadd --gid 1000 vscode \
|
|
18
|
+
&& useradd --uid 1000 --gid 1000 --create-home --shell /bin/bash vscode
|
|
19
|
+
USER vscode
|
|
20
|
+
|
|
21
|
+
# mise (Python + Node.js version management)
|
|
22
|
+
ENV PATH="/home/vscode/.local/share/mise/shims:/home/vscode/.local/bin:$PATH"
|
|
23
|
+
RUN curl https://mise.run | sh && mise use --global python@3.13 node@22
|
|
24
|
+
|
|
25
|
+
# uv (Python package manager)
|
|
26
|
+
RUN curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/home/vscode/.local/bin sh
|
|
27
|
+
|
|
28
|
+
# bash-language-server (consumed by the claude-code-lsps bash plugin)
|
|
29
|
+
RUN npm install -g bash-language-server pyright
|
|
30
|
+
|
|
31
|
+
# Claude Code (native install, stable channel)
|
|
32
|
+
RUN curl -fsSL https://claude.ai/install.sh | bash -s stable
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sd-api-mcp",
|
|
3
|
+
"dockerComposeFile": "docker-compose.yml",
|
|
4
|
+
"service": "app",
|
|
5
|
+
"workspaceFolder": "/workspaces/sd-api-mcp",
|
|
6
|
+
"customizations": {
|
|
7
|
+
"vscode": {
|
|
8
|
+
"extensions": [
|
|
9
|
+
"astral-sh.ty",
|
|
10
|
+
"charliermarsh.ruff",
|
|
11
|
+
"ms-python.python",
|
|
12
|
+
"tamasfe.even-better-toml",
|
|
13
|
+
"anthropic.claude-code"
|
|
14
|
+
],
|
|
15
|
+
"settings": {
|
|
16
|
+
"python.defaultInterpreterPath": "${containerWorkspaceFolder}/.venv/bin/python",
|
|
17
|
+
"python.analysis.typeCheckingMode": "off",
|
|
18
|
+
"ty.enable": true,
|
|
19
|
+
"editor.formatOnSave": true,
|
|
20
|
+
"editor.defaultFormatter": "charliermarsh.ruff",
|
|
21
|
+
"[python]": {
|
|
22
|
+
"editor.defaultFormatter": "charliermarsh.ruff",
|
|
23
|
+
"editor.codeActionsOnSave": {
|
|
24
|
+
"source.organizeImports": "explicit"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"ruff.nativeServer": "on"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"postCreateCommand": "bash .devcontainer/postCreate.sh",
|
|
32
|
+
"remoteUser": "vscode"
|
|
33
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
app:
|
|
5
|
+
build:
|
|
6
|
+
context: ..
|
|
7
|
+
dockerfile: .devcontainer/Dockerfile
|
|
8
|
+
env_file:
|
|
9
|
+
- ../.env
|
|
10
|
+
extra_hosts:
|
|
11
|
+
- "host.docker.internal:host-gateway"
|
|
12
|
+
volumes:
|
|
13
|
+
- ..:/workspaces/sd-api-mcp:cached
|
|
14
|
+
working_dir: /workspaces/sd-api-mcp
|
|
15
|
+
command: sleep infinity
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Python/Node バージョンをインストール
|
|
5
|
+
mise trust
|
|
6
|
+
mise install
|
|
7
|
+
|
|
8
|
+
# Python 依存関係をインストール
|
|
9
|
+
uv sync --dev
|
|
10
|
+
uv tool install ty
|
|
11
|
+
|
|
12
|
+
# pre-commit フックをインストール
|
|
13
|
+
uv run pre-commit install
|
|
14
|
+
|
|
15
|
+
# Claude Code プラグインをインストール
|
|
16
|
+
claude plugin install superpowers@claude-plugins-official
|
|
17
|
+
claude plugin install pyright-lsp@claude-plugins-official
|
|
18
|
+
claude plugin install context7@claude-plugins-official
|
|
19
|
+
claude plugin install bash-language-server@claude-code-lsps
|
|
20
|
+
claude plugin install criticalthink@criticalthink
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @HizZaniya
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
<!-- PRタイトルの形式:type(scope): 命令形の説明(日本語可)
|
|
2
|
+
|
|
3
|
+
例:
|
|
4
|
+
feat(server): generate_image ツールを追加
|
|
5
|
+
fix(client): タイムアウト時のリトライ処理を修正
|
|
6
|
+
refactor(client): HTTPセッション管理をヘルパーに集約
|
|
7
|
+
chore: fastmcp を 3.4.0 にアップデート
|
|
8
|
+
ci: ruff CI ジョブを追加
|
|
9
|
+
-->
|
|
10
|
+
|
|
11
|
+
## 概要
|
|
12
|
+
|
|
13
|
+
<!-- 必須。2〜4文で「何を・なぜ」変更するか記述すること。
|
|
14
|
+
ユーザーへの影響またはエンジニアリング上の理由に焦点を当てる。
|
|
15
|
+
関連Issueがある場合はリンクを記載:「Closes #123」または「Ref #456」 -->
|
|
16
|
+
|
|
17
|
+
## ラベル
|
|
18
|
+
|
|
19
|
+
<!-- 必ず1つだけチェックし、GitHub UI(右サイドバー > Labels)でも同じラベルを付与すること。
|
|
20
|
+
ラベルは `gh release create --generate-notes` のカテゴリ分類に使われる。 -->
|
|
21
|
+
|
|
22
|
+
- [ ] `breaking-change` — MCPツールのシグネチャ変更など、利用者対応が必要な変更
|
|
23
|
+
- [ ] `feature` — 新しいツール・機能の追加
|
|
24
|
+
- [ ] `enhancement` — 既存ツール・機能の改善
|
|
25
|
+
- [ ] `bug` — ユーザー影響のあるリグレッション
|
|
26
|
+
- [ ] `fix` — リグレッションでない不具合修正
|
|
27
|
+
- [ ] `server` — MCP プロトコル層の変更(`server.py`)
|
|
28
|
+
- [ ] `client` — SD WebUI API 通信層の変更(`client.py`)
|
|
29
|
+
- [ ] `performance` — 計測可能な速度・メモリ改善(ベンチマーク結果必須)
|
|
30
|
+
- [ ] `docs` — ドキュメントのみ(README、インラインコメント、ガイド)
|
|
31
|
+
- [ ] `ci` — GitHub Actions ワークフローの変更
|
|
32
|
+
- [ ] `build` — pyproject.toml・uv・ツールチェーンの設定変更
|
|
33
|
+
- [ ] `dependencies` — 依存関係のバージョン更新
|
|
34
|
+
- [ ] `skip-changelog` — リリースノートから意図的に除外するもの
|
|
35
|
+
|
|
36
|
+
## 完了条件(Definition of Done)
|
|
37
|
+
|
|
38
|
+
> **マージ前に全項目をチェックすること。未チェック項目があるPRはマージ不可。**
|
|
39
|
+
> 適用外の項目は理由をコメントで明記した上でチェックすること。
|
|
40
|
+
|
|
41
|
+
### CI/CD(自動チェック)
|
|
42
|
+
|
|
43
|
+
- [ ] `lint` ジョブがグリーン(`uv run ruff check .`)
|
|
44
|
+
- [ ] `format` ジョブがグリーン(`uv run ruff format --check .`)
|
|
45
|
+
- [ ] `type-check` ジョブがグリーン(`uv run ty check`)
|
|
46
|
+
- [ ] `test` ジョブがグリーン(`uv run pytest`)
|
|
47
|
+
|
|
48
|
+
### コード品質(手動確認)
|
|
49
|
+
|
|
50
|
+
- [ ] `uv run ruff check .` がローカルで警告ゼロで通過する
|
|
51
|
+
- [ ] `uv run ruff format --check .` がローカルで差分ゼロで通過する
|
|
52
|
+
- [ ] `uv run ty check` がローカルでエラーゼロで通過する
|
|
53
|
+
- [ ] デバッグ用 `print()` がプロダクションコードに残っていない
|
|
54
|
+
- [ ] ハードコードされた認証情報・URLが含まれていない
|
|
55
|
+
|
|
56
|
+
### テスト(手動確認)
|
|
57
|
+
|
|
58
|
+
- [ ] TDDサイクル(Red → Green → Refactor)を完了した
|
|
59
|
+
- [ ] 新規ロジックに対応するテストが書かれている
|
|
60
|
+
- [ ] `uv run pytest` がローカルで全テストグリーンで通過する
|
|
61
|
+
|
|
62
|
+
### アーキテクチャ(レイヤー分離)
|
|
63
|
+
|
|
64
|
+
- [ ] `server.py` に SD WebUI API 直接呼び出しがない(MCP プロトコル層のみ)
|
|
65
|
+
- [ ] `client.py` に MCP ツール定義がない(API 通信層のみ)
|
|
66
|
+
|
|
67
|
+
## テスト証跡
|
|
68
|
+
|
|
69
|
+
<!-- CI設定・ドキュメントのみの変更はこのセクションを削除すること -->
|
|
70
|
+
|
|
71
|
+
### 追加・変更したテスト
|
|
72
|
+
|
|
73
|
+
| テストファイル | 追加・変更したテストケース名 |
|
|
74
|
+
|--------------|--------------------------|
|
|
75
|
+
| <!-- 例: tests/test_client.py --> | <!-- 例: test_generate_image_timeout --> |
|
|
76
|
+
|
|
77
|
+
### 手動確認手順
|
|
78
|
+
|
|
79
|
+
<!-- ローカルで実施したハッピーパスと異常系を記載する。手順が自明な場合は省略可 -->
|
|
80
|
+
|
|
81
|
+
1.
|
|
82
|
+
2.
|
|
83
|
+
|
|
84
|
+
## セキュリティチェック
|
|
85
|
+
|
|
86
|
+
<!-- 新規機能を追加した場合のみ記入すること。
|
|
87
|
+
既存機能の修正・ドキュメント変更では「適用外」とだけ記載すること(セクション自体は残す)。 -->
|
|
88
|
+
|
|
89
|
+
- [ ] ユーザー入力(プロンプト・パラメータ)がバリデーションされている
|
|
90
|
+
- [ ] 認証情報(SD_AUTH_USER / SD_AUTH_PASS)がログ・レスポンスに漏洩しない
|
|
91
|
+
- [ ] エラーレスポンスに機密情報が含まれていない
|
|
92
|
+
- [ ] 環境変数以外の方法で認証情報を受け取っていない
|
|
93
|
+
|
|
94
|
+
## パフォーマンス影響
|
|
95
|
+
|
|
96
|
+
- [ ] パフォーマンスへの影響を確認した
|
|
97
|
+
|
|
98
|
+
**影響の有無と理由:**
|
|
99
|
+
<!-- `performance` ラベル:ベンチマーク結果(before / after)を以下に貼り付けること -->
|
|
100
|
+
<!-- その他のラベル:「影響なし。〇〇のみの変更のため」と一行で記載 -->
|
|
101
|
+
|
|
102
|
+
## 破壊的変更
|
|
103
|
+
|
|
104
|
+
<!-- `breaking-change` ラベルの場合のみ記入すること。
|
|
105
|
+
それ以外のPRでは「適用外」とだけ記載すること(セクション自体は残す)。 -->
|
|
106
|
+
|
|
107
|
+
### 変更前後の動作
|
|
108
|
+
|
|
109
|
+
**変更前:** <!-- 旧動作を説明 -->
|
|
110
|
+
|
|
111
|
+
**変更後:** <!-- 新動作を説明 -->
|
|
112
|
+
|
|
113
|
+
### 移行手順
|
|
114
|
+
|
|
115
|
+
<!-- MCPクライアント側が対応するための手順を記載する。 -->
|
|
116
|
+
|
|
117
|
+
## レビュアーへの案内
|
|
118
|
+
|
|
119
|
+
### 重点的にレビューしてほしい部分
|
|
120
|
+
|
|
121
|
+
<!-- どこを特に見てほしいか、その理由とともに記載する -->
|
|
122
|
+
|
|
123
|
+
-
|
|
124
|
+
|
|
125
|
+
### テストが難しかった部分・未テストの部分
|
|
126
|
+
|
|
127
|
+
<!-- テストを書かなかった・書けなかった部分とその理由を明記する。なければ「なし」と記載 -->
|
|
128
|
+
|
|
129
|
+
-
|
|
130
|
+
|
|
131
|
+
### 設計上の判断とトレードオフ
|
|
132
|
+
|
|
133
|
+
<!-- 他の実装アプローチを検討した場合、なぜこの設計を選んだかを説明する。自明な場合は「なし」と記載 -->
|
|
134
|
+
|
|
135
|
+
-
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.13"
|
|
17
|
+
- run: uv sync --frozen --group dev
|
|
18
|
+
- run: uv run ruff check .
|
|
19
|
+
|
|
20
|
+
format:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.13"
|
|
27
|
+
- run: uv sync --frozen --group dev
|
|
28
|
+
- run: uv run ruff format --check .
|
|
29
|
+
|
|
30
|
+
typecheck:
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
35
|
+
with:
|
|
36
|
+
python-version: "3.13"
|
|
37
|
+
- run: uv sync --frozen --group dev
|
|
38
|
+
- run: uv run ty check
|
|
39
|
+
|
|
40
|
+
test:
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v4
|
|
44
|
+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
45
|
+
with:
|
|
46
|
+
python-version: "3.13"
|
|
47
|
+
- run: uv sync --frozen --group dev
|
|
48
|
+
- run: uv run pytest -v
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: PR Template Check
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, edited, reopened, synchronize]
|
|
6
|
+
branches: [main]
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
validate-template:
|
|
10
|
+
name: PR Template Validation
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Validate required sections and label
|
|
14
|
+
uses: actions/github-script@v7
|
|
15
|
+
with:
|
|
16
|
+
script: |
|
|
17
|
+
const body = context.payload.pull_request.body ?? '';
|
|
18
|
+
|
|
19
|
+
const required = [
|
|
20
|
+
'## 概要',
|
|
21
|
+
'## ラベル',
|
|
22
|
+
'## 完了条件',
|
|
23
|
+
'## パフォーマンス影響',
|
|
24
|
+
'## レビュアーへの案内',
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
const missing = required.filter(s => !body.includes(s));
|
|
28
|
+
const hasLabel = /- \[x\]/i.test(body);
|
|
29
|
+
|
|
30
|
+
const errors = [];
|
|
31
|
+
if (missing.length > 0) {
|
|
32
|
+
errors.push(`必須セクションが不足しています:\n${missing.map(s => ` • ${s}`).join('\n')}`);
|
|
33
|
+
}
|
|
34
|
+
if (!hasLabel) {
|
|
35
|
+
errors.push('ラベルが未選択です(## ラベル セクションで `- [x]` を1つチェックしてください)');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (errors.length > 0) {
|
|
39
|
+
core.setFailed(errors.join('\n\n'));
|
|
40
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_run:
|
|
5
|
+
workflows: [Release]
|
|
6
|
+
types: [completed]
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
id-token: write
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
build:
|
|
15
|
+
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
outputs:
|
|
18
|
+
version: ${{ steps.version.outputs.version }}
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
with:
|
|
22
|
+
ref: main
|
|
23
|
+
|
|
24
|
+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.13"
|
|
27
|
+
|
|
28
|
+
- name: Extract version
|
|
29
|
+
id: version
|
|
30
|
+
run: |
|
|
31
|
+
VERSION=$(python3 -c "import tomllib; d=tomllib.loads(open('pyproject.toml').read()); print(d['project']['version'])")
|
|
32
|
+
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
|
33
|
+
|
|
34
|
+
- run: uv build
|
|
35
|
+
|
|
36
|
+
- uses: actions/upload-artifact@v4
|
|
37
|
+
with:
|
|
38
|
+
name: dist
|
|
39
|
+
path: dist/
|
|
40
|
+
|
|
41
|
+
publish-testpypi:
|
|
42
|
+
needs: build
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
environment: testpypi
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/download-artifact@v4
|
|
47
|
+
with:
|
|
48
|
+
name: dist
|
|
49
|
+
path: dist/
|
|
50
|
+
|
|
51
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
52
|
+
with:
|
|
53
|
+
repository-url: https://test.pypi.org/legacy/
|
|
54
|
+
skip-existing: true
|
|
55
|
+
|
|
56
|
+
verify-testpypi:
|
|
57
|
+
needs: [build, publish-testpypi]
|
|
58
|
+
runs-on: ubuntu-latest
|
|
59
|
+
steps:
|
|
60
|
+
- uses: actions/setup-python@v5
|
|
61
|
+
with:
|
|
62
|
+
python-version: "3.13"
|
|
63
|
+
|
|
64
|
+
- name: Wait and verify TestPyPI installation
|
|
65
|
+
env:
|
|
66
|
+
VERSION: ${{ needs.build.outputs.version }}
|
|
67
|
+
run: |
|
|
68
|
+
for i in $(seq 1 10); do
|
|
69
|
+
pip install \
|
|
70
|
+
--index-url https://test.pypi.org/simple/ \
|
|
71
|
+
--extra-index-url https://pypi.org/simple/ \
|
|
72
|
+
"sd-api-mcp==${VERSION}" && break
|
|
73
|
+
[ "$i" -eq 10 ] && { echo "All retries failed"; exit 1; }
|
|
74
|
+
echo "Retry ${i}/10..."
|
|
75
|
+
sleep 30
|
|
76
|
+
done
|
|
77
|
+
python -c "import sd_api_mcp; print('import OK')"
|
|
78
|
+
|
|
79
|
+
publish-pypi:
|
|
80
|
+
needs: verify-testpypi
|
|
81
|
+
runs-on: ubuntu-latest
|
|
82
|
+
environment: pypi
|
|
83
|
+
steps:
|
|
84
|
+
- uses: actions/download-artifact@v4
|
|
85
|
+
with:
|
|
86
|
+
name: dist
|
|
87
|
+
path: dist/
|
|
88
|
+
|
|
89
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
90
|
+
|
|
91
|
+
install-test:
|
|
92
|
+
needs: [build, publish-pypi]
|
|
93
|
+
runs-on: ubuntu-latest
|
|
94
|
+
steps:
|
|
95
|
+
- uses: actions/setup-python@v5
|
|
96
|
+
with:
|
|
97
|
+
python-version: "3.13"
|
|
98
|
+
|
|
99
|
+
- name: Wait for PyPI propagation
|
|
100
|
+
run: sleep 60
|
|
101
|
+
|
|
102
|
+
- name: Install and verify from PyPI
|
|
103
|
+
env:
|
|
104
|
+
VERSION: ${{ needs.build.outputs.version }}
|
|
105
|
+
run: |
|
|
106
|
+
pip install "sd-api-mcp==${VERSION}"
|
|
107
|
+
python -c "import sd_api_mcp; print('import OK')"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: write
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
release:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
with:
|
|
15
|
+
fetch-depth: 0
|
|
16
|
+
|
|
17
|
+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.13"
|
|
20
|
+
|
|
21
|
+
- run: uv sync --frozen --group dev
|
|
22
|
+
|
|
23
|
+
- name: Configure git
|
|
24
|
+
run: |
|
|
25
|
+
git config user.name "github-actions[bot]"
|
|
26
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
27
|
+
|
|
28
|
+
- name: Bump version
|
|
29
|
+
run: uv run cz bump --yes
|
|
30
|
+
|
|
31
|
+
- name: Push commits and tags
|
|
32
|
+
run: git push origin main --follow-tags
|
|
33
|
+
|
|
34
|
+
- name: Extract version
|
|
35
|
+
id: version
|
|
36
|
+
run: |
|
|
37
|
+
VERSION=$(python3 -c "import tomllib; d=tomllib.loads(open('pyproject.toml').read()); print(d['project']['version'])")
|
|
38
|
+
echo "version=v${VERSION}" >> "$GITHUB_OUTPUT"
|
|
39
|
+
|
|
40
|
+
- name: Create GitHub Release
|
|
41
|
+
env:
|
|
42
|
+
GH_TOKEN: ${{ github.token }}
|
|
43
|
+
run: |
|
|
44
|
+
gh release create "${{ steps.version.outputs.version }}" \
|
|
45
|
+
--generate-notes \
|
|
46
|
+
--title "${{ steps.version.outputs.version }}"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Claude Code
|
|
2
|
+
.claude/settings.local.json
|
|
3
|
+
|
|
4
|
+
# Serena
|
|
5
|
+
.serena/
|
|
6
|
+
|
|
7
|
+
# Python
|
|
8
|
+
__pycache__/
|
|
9
|
+
*.py[cod]
|
|
10
|
+
*.pyo
|
|
11
|
+
.venv/
|
|
12
|
+
*.egg-info/
|
|
13
|
+
dist/
|
|
14
|
+
build/
|
|
15
|
+
|
|
16
|
+
# Tools cache
|
|
17
|
+
.ruff_cache/
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.mypy_cache/
|
|
20
|
+
|
|
21
|
+
# Environment
|
|
22
|
+
.env
|
|
23
|
+
.env.*
|
|
24
|
+
!.env.example
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.6.9
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
|
|
9
|
+
- repo: local
|
|
10
|
+
hooks:
|
|
11
|
+
- id: ty
|
|
12
|
+
name: ty type check
|
|
13
|
+
entry: uv run ty check
|
|
14
|
+
language: system
|
|
15
|
+
types: [python]
|
|
16
|
+
pass_filenames: false
|
|
17
|
+
|
|
18
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
19
|
+
rev: v5.0.0
|
|
20
|
+
hooks:
|
|
21
|
+
- id: trailing-whitespace
|
|
22
|
+
- id: end-of-file-fixer
|
|
23
|
+
- id: check-yaml
|
|
24
|
+
- id: check-toml
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.1.0] - 2026-06-25
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- `txt2img`: テキストプロンプトから画像を生成
|
|
8
|
+
- `img2img`: 入力画像とプロンプトから画像を生成
|
|
9
|
+
- `get_sd_models`: 利用可能な Stable Diffusion モデル一覧を取得
|
|
10
|
+
- `set_sd_model`: アクティブモデルを変更
|
|
11
|
+
- `get_sd_upscalers`: 利用可能なアップスケーラー一覧を取得
|
|
12
|
+
- `upscale_images`: 画像をアップスケーリング
|
|
13
|
+
- `get_controlnet_models`: ControlNet モデル一覧を取得
|
|
14
|
+
- `get_controlnet_modules`: ControlNet プリプロセッサ一覧を取得
|
|
15
|
+
|
|
16
|
+
## v0.2.0 (2026-06-25)
|
|
17
|
+
|
|
18
|
+
### Fix
|
|
19
|
+
|
|
20
|
+
- **ci**: guard publish against failed release and add retry exit code
|
|
21
|
+
|
|
22
|
+
## v0.1.0 (2026-06-25)
|
|
23
|
+
|
|
24
|
+
### Feat
|
|
25
|
+
|
|
26
|
+
- SDWebUIClientとMCPツール8個を実装
|
|
27
|
+
- プロジェクト初期セットアップ
|
|
28
|
+
|
|
29
|
+
### Fix
|
|
30
|
+
|
|
31
|
+
- **client**: type: ignore を assert isinstance に置き換えて型チェックを通す
|