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
45 changes: 45 additions & 0 deletions .github/workflows/runtime-plugin-authenticated-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Runtime plugin authenticated smoke

on:
workflow_dispatch:
inputs:
runtime:
description: Runtime to test
required: true
default: all
type: choice
options:
- all
- claude
- codex
- kiro

jobs:
authenticated-smoke:
runs-on: ubuntu-latest
environment: runtime-smoke
steps:
- uses: actions/checkout@v4
- name: Run authenticated runtime smoke
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
BIGQUERY_PROJECT: ${{ secrets.BIGQUERY_PROJECT }}
BIGQUERY_LOCATION: ${{ secrets.BIGQUERY_LOCATION }}
BIGQUERY_DATASET: ${{ secrets.BIGQUERY_DATASET }}
BIGQUERY_KEY_FILE_JSON: ${{ secrets.BIGQUERY_KEY_FILE_JSON }}
run: |
extra_args=()
if [ -n "$BIGQUERY_KEY_FILE_JSON" ]; then
mkdir -p tmp/runtime-smoke-secrets
export BIGQUERY_KEY_FILE="$PWD/tmp/runtime-smoke-secrets/bigquery-key-file.json"
printf '%s' "$BIGQUERY_KEY_FILE_JSON" > "$BIGQUERY_KEY_FILE"
extra_args+=(--secret-file "bigquery-key-file=$BIGQUERY_KEY_FILE")
fi
bash scripts/runtime-smoke-test.sh --runtime "${{ inputs.runtime }}" --with-secrets=auto "${extra_args[@]}"
- name: Upload smoke artifacts
uses: actions/upload-artifact@v4
if: always()
with:
name: runtime-smoke-authenticated
path: tmp/runtime-smoke
37 changes: 37 additions & 0 deletions .github/workflows/runtime-plugin-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Runtime plugin smoke

on:
pull_request:
paths:
- "plugins/**"
- "scripts/runtime-smoke-test.sh"
- "tests/runtime-smoke/**"
- ".github/workflows/runtime-plugin-smoke.yml"
- ".github/workflows/runtime-plugin-authenticated-smoke.yml"
push:
branches:
- main
- "release/**"
paths:
- "plugins/**"
- "scripts/runtime-smoke-test.sh"
- "tests/runtime-smoke/**"
- ".github/workflows/runtime-plugin-smoke.yml"

jobs:
runtime-smoke:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
runtime: [claude, codex, kiro]
steps:
- uses: actions/checkout@v4
- name: Run unauthenticated runtime smoke
run: bash scripts/runtime-smoke-test.sh --runtime "${{ matrix.runtime }}" --with-secrets=off
- name: Upload smoke artifacts
uses: actions/upload-artifact@v4
if: always()
with:
name: runtime-smoke-${{ matrix.runtime }}
path: tmp/runtime-smoke/${{ matrix.runtime }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ yarn-error.log*
# Temporary files
*.tmp
*.bak
tmp/

# Python
__pycache__/
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,15 @@ bash scripts/build-runtime-plugins.sh
bash scripts/validate-runtime-plugins.sh
```

実ランタイムのインストール経路を確認する場合は、Docker コンテナ内で smoke test を実行します。

```bash
bash scripts/runtime-smoke-test.sh
bash scripts/runtime-smoke-test.sh --runtime claude
bash scripts/runtime-smoke-test.sh --runtime codex
bash scripts/runtime-smoke-test.sh --runtime kiro
```

ローカル hook を使う場合は以下を実行します。

```bash
Expand Down
7 changes: 6 additions & 1 deletion docs/ndf-plugin-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,16 @@ bash scripts/build-runtime-plugins.sh --check
bash scripts/validate-runtime-plugins.sh
claude plugin validate plugins/ndf-claude
python3 -m json.tool plugins/ndf-codex/.codex-plugin/plugin.json >/dev/null
bash plugins/ndf-kiro/install.sh --help
bash plugins/ndf-kiro/install.sh --dry-run
bash scripts/runtime-smoke-test.sh --runtime claude
bash scripts/runtime-smoke-test.sh --runtime codex
bash scripts/runtime-smoke-test.sh --runtime kiro
```

`--check` は `plugins/ndf-*` と `plugins/mcp/claude|codex|kiro` の生成物が共通編集元と同期していることを検証します。`validate-runtime-plugins.sh` は生成物同期、JSON / manifest、marketplace source、Kiro installer、Markdown ローカルリンクをまとめて確認します。

`runtime-smoke-test.sh` は Docker コンテナ内に repo copy、`/tmp/runtime-home`、`/tmp/runtime-project`、`/tmp/runtime-secrets` を分離して作成し、Claude / Codex / Kiro それぞれで `ndf` と `mcp-bigquery` 相当の実 install、Skill / MCP / hook / agent config の assertion、JUnit / log artifact 出力を確認します。PR CI は `--with-secrets=off` の非認証 smoke のみを実行し、認証付き smoke は `runtime-plugin-authenticated-smoke.yml` の protected workflow で実行します。

ローカル hook を使う場合は `bash scripts/install-dev-hooks.sh` で `.githooks/` を有効化します。

## 外部 AI 委譲
Expand Down
49 changes: 24 additions & 25 deletions issues/agent-runtime-plugin-split.md
Original file line number Diff line number Diff line change
Expand Up @@ -551,15 +551,14 @@ base branch: `main`
| merge 済み | #49 | `feature/runtime-split-kiro` | Task 4: `plugins/ndf-kiro` を作成し、Kiro installer / docs / templates を移動 | cross-review approved。`release/runtime-plugin-split` へ merge 済み。worktree / local branch cleanup 済み |
| merge 済み | #50 | `feature/runtime-split-docs-cleanup` | Task 5: README / AGENTS / docs / specs 更新、旧 `plugins/ndf` の削除 | cross-review approved。`release/runtime-plugin-split` へ merge 済み。merge 後検証済み |
| merge 済み | #51 / #54 | `feature/runtime-split-mcp-plugins` | Task 6: MCP plugin を runtime 別に分離 | #51 はローテーションで close。#54 が cross-review approved、`release/runtime-plugin-split` へ merge 済み |
| 実装中 | #52 | `feature/runtime-split-validation` | Task 7: validate script、dev hook、CI、リンク検証 | `validate-runtime-plugins.sh`、`.githooks/`、GitHub Actions、Markdown link check を追加。ローカル検証通過 |
| 未着手 | #53 | `feature/runtime-split-container-smoke` | Task 8: runtime smoke test | PR7 merge |
| merge 済み | #52 | `feature/runtime-split-validation` | Task 7: validate script、dev hook、CI、リンク検証 | cross-review approved。`release/runtime-plugin-split` へ merge 済み。merge 後検証済み |
| 実装済み | #53 | `feature/runtime-split-container-smoke` | Task 8: runtime smoke test | `scripts/runtime-smoke-test.sh`、runtime 別 Containerfile / adapter / assertion、secret 注入、CI workflow、docs を追加。この PR で cross-review / merge 後検証予定 |

再開時の前提:

- 現在の作業ブランチは `feature/runtime-split-validation`。
- `release/runtime-plugin-split` には PR #46 / #47 / #48 / #49 / #50 / #54 が merge 済み。
- 次は PR #52 の validation 実装を push し、cross-review 後に `release/runtime-plugin-split` へ merge する。
- PR #52 merge 後に PR #53 `feature/runtime-split-container-smoke` を進める。
- 現在の作業ブランチは `feature/runtime-split-container-smoke`。
- `release/runtime-plugin-split` には PR #46 / #47 / #48 / #49 / #50 / #52 / #54 が merge 済み。
- 次は PR #53 の container smoke 実装を cross-review し、`release/runtime-plugin-split` へ merge する。

## 影響範囲

Expand Down Expand Up @@ -608,25 +607,25 @@ base branch: `main`

詳細なテスト設計は `issues/runtime-plugin-container-test-plan.md` に分離する。この親計画では以下を完了条件として追跡する。

- [ ] `bash scripts/build-runtime-plugins.sh --check`
- [ ] `bash scripts/validate-runtime-plugins.sh`
- [ ] `bash scripts/runtime-smoke-test.sh --runtime claude`
- [ ] `bash scripts/runtime-smoke-test.sh --runtime codex`
- [ ] `bash scripts/runtime-smoke-test.sh --runtime kiro`
- [ ] `.github/workflows/runtime-plugin-validate.yml` が build check / validate / link check を実行する
- [ ] `.github/workflows/runtime-plugin-smoke.yml` が軽量コンテナで runtime smoke を実行する
- [ ] `rg "plugins/ndf($|[^-])|plugins/ndf/" README.md AGENTS.md CLAUDE.md KIRO.md docs plugins scripts .claude-plugin .agents` で旧 NDF パス残存を確認
- [ ] `rg "plugins/mcp-[a-z]" README.md AGENTS.md CLAUDE.md KIRO.md docs plugins scripts .claude-plugin .agents` で旧 MCP パス残存を確認
- [x] `bash scripts/build-runtime-plugins.sh --check`
- [x] `bash scripts/validate-runtime-plugins.sh`
- [x] `bash scripts/runtime-smoke-test.sh --runtime claude`
- [x] `bash scripts/runtime-smoke-test.sh --runtime codex`
- [x] `bash scripts/runtime-smoke-test.sh --runtime kiro`
- [x] `.github/workflows/runtime-plugin-validate.yml` が build check / validate / link check を実行する
- [x] `.github/workflows/runtime-plugin-smoke.yml` が軽量コンテナで runtime smoke を実行する
- [x] `rg "plugins/ndf($|[^-])|plugins/ndf/" README.md AGENTS.md CLAUDE.md KIRO.md docs plugins scripts .claude-plugin .agents` で旧 NDF パス残存を確認
- [x] `rg "plugins/mcp-[a-z]" README.md AGENTS.md CLAUDE.md KIRO.md docs plugins scripts .claude-plugin .agents` で旧 MCP パス残存を確認

## 完了の定義

- [ ] Claude / Codex / Kiro の配布単位が別ディレクトリになっている
- [ ] `plugins/ndf` が削除または README stub のみに縮退している
- [ ] marketplace source がランタイム別ディレクトリを指している
- [ ] Kiro installer が Claude manifest に依存していない
- [ ] 共通 Skill の編集元と生成先の同期チェックがある
- [ ] MCP plugin が `plugins/mcp/shared|claude|codex|kiro` に分離されている
- [ ] Claude / Codex / Kiro の各導入手順で `mcp-bigquery@ai-plugins` が同じ名前で使える
- [ ] README / docs が新構成を案内している
- [ ] 各ランタイムの検証手順が通っている
- [ ] 各ランタイムの実インストール smoke test がコンテナ内で通っている
- [x] Claude / Codex / Kiro の配布単位が別ディレクトリになっている
- [x] `plugins/ndf` が削除または README stub のみに縮退している
- [x] marketplace source がランタイム別ディレクトリを指している
- [x] Kiro installer が Claude manifest に依存していない
- [x] 共通 Skill の編集元と生成先の同期チェックがある
- [x] MCP plugin が `plugins/mcp/shared|claude|codex|kiro` に分離されている
- [x] Claude / Codex / Kiro の各導入手順で `mcp-bigquery@ai-plugins` が同じ名前で使える
- [x] README / docs が新構成を案内している
- [x] 各ランタイムの検証手順が通っている
- [x] 各ランタイムの実インストール smoke test がコンテナ内で通っている
26 changes: 13 additions & 13 deletions issues/runtime-plugin-container-test-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -453,16 +453,16 @@ base branch: `release/runtime-plugin-split` (親計画の PR7 merge 後。親計

## 完了の定義

- [ ] `scripts/runtime-smoke-test.sh` で runtime を選択できる
- [ ] Claude / Codex / Kiro の container image が分かれている
- [ ] smoke は host HOME と credential directory を mount しない
- [ ] secret が存在する場合は許可リストに従って `--rm --tmpfs /tmp/runtime-secrets` container へ注入され、container 内 path へ env が再設定される
- [ ] `--with-secrets=auto|required` と `--keep-container` の併用が拒否される
- [ ] `ndf@ai-plugins` の実 install を確認する
- [ ] `mcp-bigquery@ai-plugins` 相当の実 install を全 runtime で確認する
- [ ] Skill / MCP / hook / agents または Kiro agent config の assertion がある
- [ ] hook script は fixture payload で非認証実行できる
- [ ] secret が存在する場合は認証付き Skill / MCP smoke が実行される
- [ ] ブラウザ認証しかない runtime、または `--with-secrets=off` の非認証 smoke だけ、認証準備完了までを合格条件にする
- [ ] CI で smoke test log と JUnit を artifact 化する
- [ ] secret 値が log / JUnit / artifact に出力されない
- [x] `scripts/runtime-smoke-test.sh` で runtime を選択できる
- [x] Claude / Codex / Kiro の container image が分かれている
- [x] smoke は host HOME と credential directory を mount しない
- [x] secret が存在する場合は許可リストに従って `--rm --tmpfs /tmp/runtime-secrets` container へ注入され、container 内 path へ env が再設定される
- [x] `--with-secrets=auto|required` と `--keep-container` の併用が拒否される
- [x] `ndf@ai-plugins` の実 install を確認する
- [x] `mcp-bigquery@ai-plugins` 相当の実 install を全 runtime で確認する
- [x] Skill / MCP / hook / agents または Kiro agent config の assertion がある
- [x] hook script は fixture payload で非認証実行できる
- [x] secret が存在する場合は認証付き Skill / MCP smoke が実行される
- [x] ブラウザ認証しかない runtime、または `--with-secrets=off` の非認証 smoke だけ、認証準備完了までを合格条件にする
- [x] CI で smoke test log と JUnit を artifact 化する
- [x] secret 値が log / JUnit / artifact に出力されない
20 changes: 15 additions & 5 deletions plugins/mcp/kiro/mcp-aws-docs/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ PLUGIN_NAME="$(basename "$SCRIPT_DIR")"
PROJECT_ROOT="$(pwd)"
KIRO_DIR="$PROJECT_ROOT/.kiro"
KIRO_AGENT_FILE="$KIRO_DIR/agents/default.json"
KIRO_PLUGIN_LINK="$KIRO_DIR/plugins/$PLUGIN_NAME"
KIRO_PLUGIN_LINK="$KIRO_DIR/mcp_runtime/$PLUGIN_NAME"
KIRO_SKILLS_DIR="$KIRO_DIR/skills"
TARGET_MCP="$PROJECT_ROOT/.mcp.json"
SOURCE_MCP="$SCRIPT_DIR/.mcp.json"
Expand All @@ -16,14 +16,24 @@ DRY_RUN=false

usage() {
cat <<'USAGE'
Usage: bash install.sh [--dry-run]
Usage: bash install.sh [--project PATH] [--dry-run]

Install this MCP plugin into the current project's Kiro settings.
USAGE
}

while [ "$#" -gt 0 ]; do
case "$1" in
--project)
[ "$#" -ge 2 ] || { echo "ERROR: --project requires a path" >&2; exit 2; }
PROJECT_ROOT="$(cd "$2" && pwd)"
KIRO_DIR="$PROJECT_ROOT/.kiro"
KIRO_AGENT_FILE="$KIRO_DIR/agents/default.json"
KIRO_PLUGIN_LINK="$KIRO_DIR/mcp_runtime/$PLUGIN_NAME"
KIRO_SKILLS_DIR="$KIRO_DIR/skills"
TARGET_MCP="$PROJECT_ROOT/.mcp.json"
shift
;;
--dry-run) DRY_RUN=true ;;
-h|--help) usage; exit 0 ;;
*) echo "Unknown option: $1" >&2; usage >&2; exit 2 ;;
Expand All @@ -48,12 +58,12 @@ if [ "$DRY_RUN" = true ]; then
exit 0
fi

mkdir -p "$KIRO_DIR/plugins" "$KIRO_SKILLS_DIR" "$(dirname "$KIRO_AGENT_FILE")"
mkdir -p "$KIRO_DIR/mcp_runtime" "$KIRO_SKILLS_DIR" "$(dirname "$KIRO_AGENT_FILE")"
if [ -e "$KIRO_PLUGIN_LINK" ] && [ ! -L "$KIRO_PLUGIN_LINK" ]; then
echo "ERROR: $KIRO_PLUGIN_LINK already exists and is not a symlink" >&2
exit 1
fi
ln -sfn "../../plugins/mcp/kiro/$PLUGIN_NAME" "$KIRO_PLUGIN_LINK"
ln -sfn "$SCRIPT_DIR" "$KIRO_PLUGIN_LINK"

if [ -d "$SOURCE_SKILLS" ]; then
find "$SOURCE_SKILLS" -mindepth 1 -maxdepth 1 -type d | sort | while IFS= read -r skill_dir; do
Expand All @@ -64,7 +74,7 @@ if [ -d "$SOURCE_SKILLS" ]; then
echo "ERROR: $skill_link already exists and is not a symlink" >&2
exit 1
fi
ln -sfn "../plugins/$PLUGIN_NAME/skills/$skill_name" "$skill_link"
ln -sfn "$skill_dir" "$skill_link"
echo "Linked Kiro skill: $skill_name"
done
fi
Expand Down
20 changes: 15 additions & 5 deletions plugins/mcp/kiro/mcp-bigquery/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ PLUGIN_NAME="$(basename "$SCRIPT_DIR")"
PROJECT_ROOT="$(pwd)"
KIRO_DIR="$PROJECT_ROOT/.kiro"
KIRO_AGENT_FILE="$KIRO_DIR/agents/default.json"
KIRO_PLUGIN_LINK="$KIRO_DIR/plugins/$PLUGIN_NAME"
KIRO_PLUGIN_LINK="$KIRO_DIR/mcp_runtime/$PLUGIN_NAME"
KIRO_SKILLS_DIR="$KIRO_DIR/skills"
TARGET_MCP="$PROJECT_ROOT/.mcp.json"
SOURCE_MCP="$SCRIPT_DIR/.mcp.json"
Expand All @@ -16,14 +16,24 @@ DRY_RUN=false

usage() {
cat <<'USAGE'
Usage: bash install.sh [--dry-run]
Usage: bash install.sh [--project PATH] [--dry-run]

Install this MCP plugin into the current project's Kiro settings.
USAGE
}

while [ "$#" -gt 0 ]; do
case "$1" in
--project)
[ "$#" -ge 2 ] || { echo "ERROR: --project requires a path" >&2; exit 2; }
PROJECT_ROOT="$(cd "$2" && pwd)"
KIRO_DIR="$PROJECT_ROOT/.kiro"
KIRO_AGENT_FILE="$KIRO_DIR/agents/default.json"
KIRO_PLUGIN_LINK="$KIRO_DIR/mcp_runtime/$PLUGIN_NAME"
KIRO_SKILLS_DIR="$KIRO_DIR/skills"
TARGET_MCP="$PROJECT_ROOT/.mcp.json"
shift
;;
--dry-run) DRY_RUN=true ;;
-h|--help) usage; exit 0 ;;
*) echo "Unknown option: $1" >&2; usage >&2; exit 2 ;;
Expand All @@ -48,12 +58,12 @@ if [ "$DRY_RUN" = true ]; then
exit 0
fi

mkdir -p "$KIRO_DIR/plugins" "$KIRO_SKILLS_DIR" "$(dirname "$KIRO_AGENT_FILE")"
mkdir -p "$KIRO_DIR/mcp_runtime" "$KIRO_SKILLS_DIR" "$(dirname "$KIRO_AGENT_FILE")"
if [ -e "$KIRO_PLUGIN_LINK" ] && [ ! -L "$KIRO_PLUGIN_LINK" ]; then
echo "ERROR: $KIRO_PLUGIN_LINK already exists and is not a symlink" >&2
exit 1
fi
ln -sfn "../../plugins/mcp/kiro/$PLUGIN_NAME" "$KIRO_PLUGIN_LINK"
ln -sfn "$SCRIPT_DIR" "$KIRO_PLUGIN_LINK"

if [ -d "$SOURCE_SKILLS" ]; then
find "$SOURCE_SKILLS" -mindepth 1 -maxdepth 1 -type d | sort | while IFS= read -r skill_dir; do
Expand All @@ -64,7 +74,7 @@ if [ -d "$SOURCE_SKILLS" ]; then
echo "ERROR: $skill_link already exists and is not a symlink" >&2
exit 1
fi
ln -sfn "../plugins/$PLUGIN_NAME/skills/$skill_name" "$skill_link"
ln -sfn "$skill_dir" "$skill_link"
echo "Linked Kiro skill: $skill_name"
done
fi
Expand Down
20 changes: 15 additions & 5 deletions plugins/mcp/kiro/mcp-chrome-devtools/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ PLUGIN_NAME="$(basename "$SCRIPT_DIR")"
PROJECT_ROOT="$(pwd)"
KIRO_DIR="$PROJECT_ROOT/.kiro"
KIRO_AGENT_FILE="$KIRO_DIR/agents/default.json"
KIRO_PLUGIN_LINK="$KIRO_DIR/plugins/$PLUGIN_NAME"
KIRO_PLUGIN_LINK="$KIRO_DIR/mcp_runtime/$PLUGIN_NAME"
KIRO_SKILLS_DIR="$KIRO_DIR/skills"
TARGET_MCP="$PROJECT_ROOT/.mcp.json"
SOURCE_MCP="$SCRIPT_DIR/.mcp.json"
Expand All @@ -16,14 +16,24 @@ DRY_RUN=false

usage() {
cat <<'USAGE'
Usage: bash install.sh [--dry-run]
Usage: bash install.sh [--project PATH] [--dry-run]

Install this MCP plugin into the current project's Kiro settings.
USAGE
}

while [ "$#" -gt 0 ]; do
case "$1" in
--project)
[ "$#" -ge 2 ] || { echo "ERROR: --project requires a path" >&2; exit 2; }
PROJECT_ROOT="$(cd "$2" && pwd)"
KIRO_DIR="$PROJECT_ROOT/.kiro"
KIRO_AGENT_FILE="$KIRO_DIR/agents/default.json"
KIRO_PLUGIN_LINK="$KIRO_DIR/mcp_runtime/$PLUGIN_NAME"
KIRO_SKILLS_DIR="$KIRO_DIR/skills"
TARGET_MCP="$PROJECT_ROOT/.mcp.json"
shift
;;
--dry-run) DRY_RUN=true ;;
-h|--help) usage; exit 0 ;;
*) echo "Unknown option: $1" >&2; usage >&2; exit 2 ;;
Expand All @@ -48,12 +58,12 @@ if [ "$DRY_RUN" = true ]; then
exit 0
fi

mkdir -p "$KIRO_DIR/plugins" "$KIRO_SKILLS_DIR" "$(dirname "$KIRO_AGENT_FILE")"
mkdir -p "$KIRO_DIR/mcp_runtime" "$KIRO_SKILLS_DIR" "$(dirname "$KIRO_AGENT_FILE")"
if [ -e "$KIRO_PLUGIN_LINK" ] && [ ! -L "$KIRO_PLUGIN_LINK" ]; then
echo "ERROR: $KIRO_PLUGIN_LINK already exists and is not a symlink" >&2
exit 1
fi
ln -sfn "../../plugins/mcp/kiro/$PLUGIN_NAME" "$KIRO_PLUGIN_LINK"
ln -sfn "$SCRIPT_DIR" "$KIRO_PLUGIN_LINK"

if [ -d "$SOURCE_SKILLS" ]; then
find "$SOURCE_SKILLS" -mindepth 1 -maxdepth 1 -type d | sort | while IFS= read -r skill_dir; do
Expand All @@ -64,7 +74,7 @@ if [ -d "$SOURCE_SKILLS" ]; then
echo "ERROR: $skill_link already exists and is not a symlink" >&2
exit 1
fi
ln -sfn "../plugins/$PLUGIN_NAME/skills/$skill_name" "$skill_link"
ln -sfn "$skill_dir" "$skill_link"
echo "Linked Kiro skill: $skill_name"
done
fi
Expand Down
Loading
Loading