Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
{
"name": "ndf",
"source": "./plugins/ndf",
"description": "Claude Code plugin (v10.17.0): 8 specialized agents and 45 focused NDF skills for PR/review workflows, cross-review, implementation planning, plan-to-spec, Docker container access, statusline, external AI delegation (Codex/agy), transcript retention guard, and optional Slack notifications.",
"description": "Claude Code plugin (v10.17.1): 8 specialized agents and 45 focused NDF skills for PR/review workflows, cross-review, implementation planning, plan-to-spec, Docker container access, statusline, external AI delegation (Codex/agy), transcript retention guard, and optional Slack notifications.",
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
Expand Down
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<!-- 実行したコマンドと結果を書く。実行していないものはチェックを付けず、理由を残す -->

- [ ] `uv run --project plugins/playwright-kit/skills/playwright-kit-ops --with pytest pytest . -q`
- [ ] `uv run --project plugins/playwright-kit/skills/playwright-kit-ops --with pytest pytest . -q -n auto`
- [ ] `python3 scripts/check-skill-frontmatter.py`
- [ ] `python3 scripts/check-doc-staleness.py`
- [ ] `python3 scripts/check-markdown-links.py --root .`
Expand Down
34 changes: 29 additions & 5 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ name: Python tests
# 「成功」ではなく「実行されていない」として扱うため、絞り込んだままだと対象外の変更で
# マージ可能にならない。push の側は絞り込みを残す(マージの可否を決めないため)
#
# push の branches に release/** を置かない。release/** から出した Pull Request では
# pull_request の側が必ず回るため、push の側も起動すると同じテストを 2 回回す(#884)。
# main / develop はマージ後の確認として残す
#
# push の絞り込みは pytest . の収集範囲に合わせる。テストの置き場所(plugins / scripts /
# tests)に加えて、収集の仕方そのものを変える根の設定ファイルも対象へ入れる
on:
Expand All @@ -13,7 +17,6 @@ on:
branches:
- main
- develop
- "release/**"
paths:
- ".github/workflows/pytest.yml"
- "plugins/**"
Expand All @@ -24,18 +27,39 @@ on:
- "pyproject.toml"

jobs:
pytest:
# ファイル単位で 2 つのジョブへ分けて回す(#882)。割り当ては根の conftest.py が
# SHARD_TOTAL / SHARD_INDEX から決める。各ジョブの中は -n auto で runner のコア数だけ
# 並列に回す(pytest-xdist は --project が指す pyproject.toml の依存に入っている)
pytest-shard:
name: pytest (${{ matrix.shard }}/2)
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shard: [0, 1]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install uv
run: python3 -m pip install --upgrade uv
# 起点はリポジトリの根に置き、1 回の起動で全件を回す。playwright-kit のテストは
# その skill の pyproject.toml が宣言する依存を使うため、--project でそこを指す。
# 起点はリポジトリの根に置く。playwright-kit のテストはその skill の pyproject.toml が
# 宣言する依存を使うため、--project でそこを指す。
#
# 前提のコマンドの確認と git の身元の設定は、根の conftest.py が行う。前提を
# ワークフローの側にも置くと、増えたときに片方だけが更新される
- run: uv run --project plugins/playwright-kit/skills/playwright-kit-ops --with pytest pytest . -q
- run: uv run --project plugins/playwright-kit/skills/playwright-kit-ops --with pytest pytest . -q -n auto
env:
SHARD_TOTAL: 2
SHARD_INDEX: ${{ matrix.shard }}

# ruleset の必須の検査は `pytest` という名前の結果を 1 つ待つ。分けたジョブの結果を
# ここで 1 つにまとめる。名前を変えると ruleset の変更が要る。
# always() で分けたジョブが落ちても走らせ、失敗・取り消しを失敗として返す
pytest:
needs: pytest-shard
if: always()
runs-on: ubuntu-latest
steps:
- run: test "${{ needs.pytest-shard.result }}" = success
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ ai-plugins/

## NDFプラグインについて

**NDFプラグイン**は、このマーケットプレイスの主要プラグインです(v10.17.0)。plugin 名は全ランタイムで `ndf` を維持し、配布物は `plugins/ndf/` の1ディレクトリにまとまっています。
**NDFプラグイン**は、このマーケットプレイスの主要プラグインです(v10.17.1)。plugin 名は全ランタイムで `ndf` を維持し、配布物は `plugins/ndf/` の1ディレクトリにまとまっています。
- Skill の実体は `plugins/ndf/skills/` の1箇所。配布先は `plugins/ndf/manifests/*-skills.txt` が決める
- Claude Code版は 8個の専門サブエージェント、公開Skills、PreToolUse/SessionStart/Stopフックを提供
- Codex版は Codex向け公開Skillsと任意Slack通知hookを提供
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@
**開発版(接尾辞の付いた版)は載せない。** `9.8.0` は `9.8.0-dev.1` までしか出ておらず、
その内容は `10.0.0` で届いている。

## [ndf 10.17.1] - 2026-09-23

### 変更

- **全体テストを並列で回し、継続的統合ではファイル単位で 2 つのジョブへ分けた**(#882)。案内するコマンドを
`-n auto` の形にし、根の `conftest.py` が `SHARD_TOTAL` / `SHARD_INDEX` を読んで自分の分のファイルだけを
残す。まとめジョブの名前を `pytest` にしたため、必須の検査は変わらない。Skill・スクリプト・hook の振る舞いは変わらない
- **重複した競合試験を共通実装への 1 通りへ寄せ、繰り返しの回数を減らした**(#884)。
`release/**` の push を継続的統合の契機から外し、2 重の実行をやめた

## [ndf 10.17.0] - 2026-09-23

### 追加
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ cd .worktrees/feature/<名前>
検査です。リポジトリの根から実行します。

```bash
# 1. テスト(継続的統合と同じ範囲を 1 回の起動で回す)
uv run --project plugins/playwright-kit/skills/playwright-kit-ops --with pytest pytest . -q
# 1. テスト(継続的統合と同じ範囲を 1 回の起動で回す。-n auto でコア数だけ並列に回す)
uv run --project plugins/playwright-kit/skills/playwright-kit-ops --with pytest pytest . -q -n auto

# 2. Skill の frontmatter の規約
python3 scripts/check-skill-frontmatter.py
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Claude Code / Codex / Kiro CLI / agy 向けのスキル・MCP設定を共有す

このマーケットプレイスは、チーム全体でAI開発ツール(Claude Code / Codex / Kiro CLI / agy)の導入を加速するための事前設定されたプラグインを提供します。

**NDFプラグイン v10.17.0** は、同じ `ndf@ai-plugins` という名前で Claude Code / Codex / Kiro CLI / agy へ配布されるプラグインです。配布物は `plugins/ndf/` の1ディレクトリにまとまっており、Skill の実体は `plugins/ndf/skills/` の1箇所だけです。どのランタイムへ配るかは `plugins/ndf/manifests/*-skills.txt` が決めます。
**NDFプラグイン v10.17.1** は、同じ `ndf@ai-plugins` という名前で Claude Code / Codex / Kiro CLI / agy へ配布されるプラグインです。配布物は `plugins/ndf/` の1ディレクトリにまとまっており、Skill の実体は `plugins/ndf/skills/` の1箇所だけです。どのランタイムへ配るかは `plugins/ndf/manifests/*-skills.txt` が決めます。

- **公開Skills**: Claude Code向け core 45個、Kiro向け core 44個、Codex向け core 43個、agy向け core 43個に分離。
- **元Skills(45個)**:
Expand Down Expand Up @@ -110,7 +110,7 @@ hook を効かせる手順と、新しい版へ入れ替える手順は

| プラグイン名 | バージョン | 説明 | 詳細 |
|------------|----------|------|------|
| **ndf** | 10.17.0 | Claude Code / Codex / Kiro CLI / agy へ 1 ディレクトリから配布する NDF プラグイン。8個の専門エージェント(Claude版)、公開Skills(Claude Code向け core 45個、Kiro向け core 44個、Codex向け core 43個、agy向け core 43個)、4ランタイム共通の作業ツリー運用フック(PreToolUse / SessionStart / userPromptSubmit / agentSpawn / PreInvocation)、Claude Stopフック、Codex/Kiro向け通知・実行補助を提供。v4.0.0 で Codex MCP サーバを廃止し、`/ndf:external-ai` skill + `corder` エージェント経由の CLI 直接実行に一本化。 | [README](./plugins/ndf/README.md) |
| **ndf** | 10.17.1 | Claude Code / Codex / Kiro CLI / agy へ 1 ディレクトリから配布する NDF プラグイン。8個の専門エージェント(Claude版)、公開Skills(Claude Code向け core 45個、Kiro向け core 44個、Codex向け core 43個、agy向け core 43個)、4ランタイム共通の作業ツリー運用フック(PreToolUse / SessionStart / userPromptSubmit / agentSpawn / PreInvocation)、Claude Stopフック、Codex/Kiro向け通知・実行補助を提供。v4.0.0 で Codex MCP サーバを廃止し、`/ndf:external-ai` skill + `corder` エージェント経由の CLI 直接実行に一本化。 | [README](./plugins/ndf/README.md) |
| **playwright-kit** | 2.0.3 | Playwright による E2E テストの計画・実装・証跡管理を提供するプラグイン。ページ役割からのテスト計画、動画 / trace 付きスクリプト実装、レポート生成と Drive 保管、playwright_kit ランタイム(init、a11y / CWV スキャン)の 4 Skill。NDF v7.0.0 で分離。 | [README](./plugins/playwright-kit/README.md) |

### 変更履歴
Expand Down
40 changes: 40 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
状態を保存するテストが、実行した人の状態ディレクトリへ要約を書かない(#662 の AC72)
5. テストの実行中だけ監視の上限を指す環境変数(接頭辞 `MONITOR_`)を外す。上限を延ばした
シェルから起動しても、既定値を前提にするテストが同じ結果になる(#678)
6. `SHARD_TOTAL` と `SHARD_INDEX` が与えられたら、収集した項目をファイル単位で分け、
自分の分だけを残す。継続的統合がジョブを分けて回すために使う(#882)

どの束のディレクトリを起点にしても読まれるよう、テストの基準のディレクトリ(rootdir)は
根の設定ファイル(`pytest.ini`)がリポジトリの根へ固定する。
Expand All @@ -24,6 +26,7 @@
import os
import shutil
import tempfile
import zlib
from pathlib import Path

import pytest
Expand Down Expand Up @@ -122,7 +125,44 @@ def pytest_unconfigure(config) -> None:
_saved_monitor_env.clear()


# ジョブの分割(#882)。**分ける単位はファイルで、割り当てはパスの剰余だけで決める。**
# 同じファイルのテストは同じジョブへ入るため、ファイル単位の前提(モジュールの読み込み・
# 一時ディレクトリ)が割れない。偏りが出たら実測時間での割り当てへ進む。
SHARD_TOTAL_ENV = "SHARD_TOTAL"
SHARD_INDEX_ENV = "SHARD_INDEX"


def _shard() -> tuple[int, int] | None:
"""`(index, total)` を返す。指定が無ければ `None`(分けない)。"""
total = os.environ.get(SHARD_TOTAL_ENV, "")
if total == "":
return None
index = os.environ.get(SHARD_INDEX_ENV, "")
if not (total.isdigit() and index.isdigit() and int(index) < int(total)):
raise pytest.UsageError(
f"{SHARD_TOTAL_ENV}={total!r} / {SHARD_INDEX_ENV}={index!r}: "
f"0 <= {SHARD_INDEX_ENV} < {SHARD_TOTAL_ENV} の整数を指定してください"
)
return int(index), int(total)


def _select_shard(config, items) -> None:
shard = _shard()
if shard is None:
return
index, total = shard
kept, dropped = [], []
for item in items:
path = Path(str(item.fspath)).resolve()
rel = path.relative_to(ROOT).as_posix() if path.is_relative_to(ROOT) else path.as_posix()
(kept if zlib.crc32(rel.encode()) % total == index else dropped).append(item)
if dropped:
config.hook.pytest_deselected(items=dropped)
items[:] = kept


def pytest_collection_modifyitems(config, items) -> None:
_select_shard(config, items)
bundles = {b for item in items if (b := _bundle_of(Path(str(item.fspath)))) is not None}
missing = _missing(bundles)
if not missing:
Expand Down
12 changes: 11 additions & 1 deletion docs/ndf-version-decisions.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# NDF の版ごとの決定と理由(v10.12.0〜v10.17.0)
# NDF の版ごとの決定と理由(v10.12.0〜v10.17.1)

`CLAUDE.md` から移した、出た版の記録である。**その版で何を決め、なぜそう決めたか**を残す。
変更点の列挙は `CHANGELOG.md` にあり、こちらは判断の理由を持つ。**`CLAUDE.md` へ書くのは
Expand Down Expand Up @@ -277,3 +277,13 @@ v10.17.0 で待つ間の問い合わせと、長い conductor の会話を止め
**hook は Claude Code にだけ置く**(#829 #830)。代わりの待ち方(`run_in_background` の通知と
`Monitor`)と文脈量を読む記録を持つのが Claude Code だけで、#827 の実測も Claude Code の記録だけで
ある。Codex / Kiro / agy は規約と引き継ぎの 1 行で守り、CLI 側の消費を測った後に改めて決める。

v10.17.1 で全体テストの待ちを縮めた(マイルストーン 26「17 トークン消費の削減」の 2'、#882 #884)。
計画と実測は `issues/issue-882-884-test-speedup.md` と PR #891 にある。

**継続的統合はファイル単位で 2 つのジョブへ分け、まとめジョブの名前を `pytest` にする**(#882)。
`-n auto` だけではジョブが 2 分を超えた。まとめジョブが必須の検査の名前を引き継ぐため、ruleset を
変えずに済む。**分け方が項目を落としても各ジョブは成功しうるため、分割の漏れと重なりは継続的統合の
外のテストで見る**(`scripts/tests/test_root_conftest.py`)。**本番のスクリプトを変える高速化は
この版で行わない** ── `bg-wait.sh` の間隔とロックの上限の注入は振る舞いの変更で、`light` の範囲を
超える。#884 は開いたまま残す。
6 changes: 3 additions & 3 deletions docs/plugin-development-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ bash scripts/build-runtime-plugins.sh --check
bash scripts/validate-runtime-plugins.sh
python3 scripts/check-doc-staleness.py --root .
python3 scripts/check-skill-frontmatter.py
uv run --with pytest pytest scripts/tests -q
uv run --with pytest --with pytest-xdist pytest scripts/tests -q -n auto
```

## 既存プラグインの削除
Expand Down Expand Up @@ -275,10 +275,10 @@ bash scripts/validate-runtime-plugins.sh
`scripts/` 自体を変更した場合は、その検査のテストも実行します。

```bash
uv run --with pytest pytest scripts/tests -q
uv run --with pytest --with pytest-xdist pytest scripts/tests -q -n auto
```

`--with pytest` を省くと `Failed to spawn: pytest` で終わります。リポジトリの根に uv の
`--with pytest` を省くと `Failed to spawn: pytest` で終わります。`-n auto` は `pytest-xdist` の指定で、コア数だけ並列に回します(`--with pytest-xdist` を省くと `-n` を解釈できずに終わります)。リポジトリの根に uv の
対象プロジェクト(`pyproject.toml`)が無く、`pytest` が環境にも入っていないためです。
`plugins/ndf/skills/*/tests/` の既存のテストも同じ形で実行します。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ clone した全員で同じ値のまま残る。
| 区切り・プロセス置換・引用符の中の `<` で出力が変わらない | 同上 |
| 手順 0 が `init` の失敗で止まることが本文に書かれている | 同 `test_setup.py`(本文の抜き出し) |

実行は `uv run --with pytest pytest scripts/tests plugins/ndf -q`。配布物の同期は
実行は `uv run --with pytest --with pytest-xdist pytest scripts/tests plugins/ndf -q -n auto`。配布物の同期は
`bash scripts/build-runtime-plugins.sh --check`、定義の検査は `claude plugin validate .` で見る。

## 運用
Expand Down
2 changes: 1 addition & 1 deletion docs/specifications/test-monitor-env-isolation.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@

| 観点 | 確かめ方 |
| --- | --- |
| 監視の環境変数を設定したシェルでも、全体のテストの失敗が 0 件で、設定しないシェルと件数が一致すること | `MONITOR_TIMEOUT_AGY=1800 MONITOR_STALL_AGY=1800 uv run --with pytest pytest scripts/tests plugins/ndf -q` と、設定しない同じコマンドを比べる |
| 監視の環境変数を設定したシェルでも、全体のテストの失敗が 0 件で、設定しないシェルと件数が一致すること | `MONITOR_TIMEOUT_AGY=1800 MONITOR_STALL_AGY=1800 uv run --with pytest --with pytest-xdist pytest scripts/tests plugins/ndf -q -n auto` と、設定しない同じコマンドを比べる |
| 実行中のテストに接頭辞 `MONITOR_` の環境変数が 1 つも残らないこと | `scripts/tests/test_root_conftest.py` |
| テストが自分で設定した値は観測できること | 同上 |
| 別プロセスへ受け継がれないこと | 同上 |
Expand Down
4 changes: 2 additions & 2 deletions docs/versioning-and-distribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ semver の順序で除外されるのは、プラグイン間の依存解決(`

| 版 | 形 | 意味 |
| --- | --- | --- |
| 正式版 | `10.17.0` | 利用者が常用してよい |
| 正式版 | `10.17.1` | 利用者が常用してよい |
| 開発版 | `10.18.0-dev.1` | 検証中。入れたくない利用者は取得を控えられる |
| 公開前の確認版 | `10.18.0-rc.1` | 正式版の候補。残るのは確認だけ |

- 接尾辞は**次に出す正式版の版数へ付ける**。`10.17.0` の次を開発するなら `10.18.0-dev.1`
- 接尾辞は**次に出す正式版の版数へ付ける**。`10.17.1` の次を開発するなら `10.18.0-dev.1`
- 連番は開発版を出すたびに増やす。**同じ版数で中身を差し替えない**。差し替えると、利用者の
手元にある版と `main` の版が同じ番号で別物になり、何を確かめたのかが分からなくなる
- **正式版を出すときは接尾辞を外す。** `10.18.0-dev.3` の次は `10.18.0`
Expand Down
Loading
Loading