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
73 changes: 12 additions & 61 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,78 +31,29 @@ flowchart TD

## 1. Set up

Needs **Node 20+** and **pnpm**, plus **jq**, **python3**, and **pipx** for the pre-commit hooks (`gh` optional). Then:
Needs **Node 20+**, **pnpm**, **jq**, **python3**, and **pipx** (`gh` and the Claude/Codex CLI optional). Then:

```bash
pnpm install
pnpm exec lefthook install
make setup
```

Every commit then runs the framework checks (json/yaml validity, schema validation, SKILL.md frontmatter, CATALOG regeneration, commitlint). Check your environment anytime with `./scripts/doctor.sh`.
- installs deps + git hooks
- registers this checkout as a local marketplace
- installs the plugins into Claude + Codex (`y/N` confirm, since it writes your global config; `YES=1` skips)

### Test your changes locally

Before opening a PR, exercise the skills you touched in a real session. Clone the framework, then point your assistant at the checkout instead of a published release:

```bash
git clone https://github.com/ai-driven-dev/framework ~/projects/framework
```

#### Claude Code
`make` lists every target; `make doctor` / `make check` verify the environment and run the pre-commit checks.

Register the checkout as a local marketplace, then install the plugins:

```text
/plugin marketplace add ~/projects/framework
/plugin install aidd-context@aidd-framework
/plugin install aidd-dev@aidd-framework
/plugin install aidd-vcs@aidd-framework
/plugin install aidd-pm@aidd-framework
/plugin install aidd-orchestrator@aidd-framework
/plugin install aidd-refine@aidd-framework
```

After editing a `SKILL.md`, an agent, or any action, run `/reload-plugins` in the same session to pick up the change - no reinstall needed.

To load the plugins into a personal project, point its `.claude/settings.local.json` at the checkout:

```json
{
"extraKnownMarketplaces": {
"aidd-framework": {
"source": {
"source": "directory",
"path": "~/projects/framework"
}
}
},
"enabledPlugins": {
"aidd-context@aidd-framework": true,
"aidd-dev@aidd-framework": true,
"aidd-vcs@aidd-framework": true,
"aidd-pm@aidd-framework": true,
"aidd-orchestrator@aidd-framework": true,
"aidd-refine@aidd-framework": true
}
}
```

#### Codex
### Test your changes locally

Register the checkout (pass an absolute path; `./` is rejected), then install the plugins:
Exercise the skills you touched before opening a PR. Neither tool hot-reloads the checkout (both serve a copied cache), so after editing:

```bash
codex plugin marketplace add ~/projects/framework
codex plugin add aidd-context@aidd-framework
codex plugin add aidd-dev@aidd-framework
codex plugin add aidd-vcs@aidd-framework
codex plugin add aidd-pm@aidd-framework
codex plugin add aidd-orchestrator@aidd-framework
codex plugin add aidd-refine@aidd-framework
codex plugin list --marketplace aidd-framework # confirm every plugin is `installed, enabled`
make reload # all plugins; or PLUGIN="aidd-refine aidd-pm" for a subset
```

No live reload - run `codex plugin marketplace upgrade` after each change to refresh.
- reinstalls each plugin from the checkout (current versions, no bump - nothing to revert)
- purges + refreshes the cache in Claude + Codex
- restart the session to load it (`/reload-plugins` covers a Claude-only edit to an existing skill)

## 2. Commit

Expand Down
21 changes: 21 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
PLUGIN ?= all

.DEFAULT_GOAL := help
.PHONY: help setup doctor check reload

help: ## List targets
@grep -hE '^[a-z-]+:.*##' $(MAKEFILE_LIST) | sed 's/:.*## /\t/' | sort

setup: ## Install deps, git hooks, and register+install the plugins in Claude/Codex
pnpm install
pnpm exec lefthook install
scripts/dev-setup.sh

doctor: ## Check the local toolchain
./scripts/doctor.sh

check: ## Run the pre-commit checks
pnpm exec lefthook run pre-commit

reload: ## Dev: reinstall plugins into Claude+Codex from the checkout (PLUGIN="aidd-refine aidd-pm", default all)
scripts/dev-sync.sh $(PLUGIN)
38 changes: 38 additions & 0 deletions scripts/dev-setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env bash
# dev-setup.sh - register this checkout as a local marketplace, then install every plugin
# into Claude and Codex (delegates the install to dev-sync.sh, current versions, no bump).
# This mutates your GLOBAL (user-scope) config, so it asks to confirm first. Bypass with
# `-y` / `--yes` / `YES=1`; a non-interactive shell skips rather than hangs. Called by
# `make setup`. For iterating after edits use `make reload`.
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
FW="${FW:-$(dirname "$SCRIPT_DIR")}" # repo root = parent of scripts/
MKT="${MKT:-aidd-framework}"

HAVE_CODEX=0; command -v codex >/dev/null 2>&1 && HAVE_CODEX=1
HAVE_CLAUDE=0; command -v claude >/dev/null 2>&1 && HAVE_CLAUDE=1
[ "$HAVE_CODEX" = 1 ] || echo "codex CLI not found - skipping Codex"
[ "$HAVE_CLAUDE" = 1 ] || echo "claude CLI not found - skipping Claude"
if [ "$HAVE_CODEX" = 0 ] && [ "$HAVE_CLAUDE" = 0 ]; then
echo "Neither CLI found - nothing to install."; exit 0
fi

# Confirm before touching the global config (skip with -y / --yes / YES=1).
if [ "${YES:-}" != "1" ] && [ "${1:-}" != "-y" ] && [ "${1:-}" != "--yes" ]; then
echo "About to register '$MKT' and install its plugins into your GLOBAL Claude/Codex config (user scope)."
if [ -t 0 ]; then
printf "Continue? [y/N] "; read -r ans
case "$ans" in
y | Y | yes | YES) ;;
*) echo "Skipped. (deps + git hooks are already done; re-run with: YES=1 make setup)"; exit 0 ;;
esac
else
echo "Non-interactive shell - skipped. Re-run with: YES=1 make setup"; exit 0
fi
fi

# Register the marketplace (no-op if already registered), then install via dev-sync.
[ "$HAVE_CODEX" = 1 ] && codex plugin marketplace add "$FW" >/dev/null 2>&1 || true
[ "$HAVE_CLAUDE" = 1 ] && claude plugin marketplace add "$FW" >/dev/null 2>&1 || true
exec "$SCRIPT_DIR/dev-sync.sh" all
51 changes: 51 additions & 0 deletions scripts/dev-sync.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
# dev-sync.sh - reinstall plugins into Claude and Codex from the live checkout, at their
# CURRENT versions (no bump). Purges each plugin's cache dir first so the copy is always
# fresh and a single version dir survives (no sprawl, no stale broken versions).
# Idempotent; each tool is skipped if its CLI is absent.
#
# scripts/dev-sync.sh aidd-refine # one plugin
# scripts/dev-sync.sh aidd-refine aidd-pm # several
# scripts/dev-sync.sh all # every plugin (default)
#
# Why purge: `codex plugin remove` does not delete the cached version dir, and
# `claude plugin install` skips the copy when that version is already cached - so without
# the purge an edit would not reach the cache. Restart the session afterwards to load it.
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
FW="${FW:-$(dirname "$SCRIPT_DIR")}" # repo root = parent of scripts/
MKT="${MKT:-aidd-framework}"
CODEX_CACHE="${CODEX_CACHE:-$HOME/.codex/plugins/cache}"
CLAUDE_CACHE="${CLAUDE_CACHE:-$HOME/.claude/plugins/cache}"

HAVE_CODEX=0; command -v codex >/dev/null 2>&1 && HAVE_CODEX=1
HAVE_CLAUDE=0; command -v claude >/dev/null 2>&1 && HAVE_CLAUDE=1

sync_one() {
local name="$1" dir
dir="$FW/plugins/$name"
[ -f "$dir/.claude-plugin/plugin.json" ] || { echo "skip $name (no plugin.json)"; return; }
printf '%-22s' "$name"

if [ "$HAVE_CODEX" = 1 ]; then
codex plugin remove "$name" >/dev/null 2>&1 || true
rm -rf "$CODEX_CACHE/$MKT/$name"
codex plugin add "$name@$MKT" >/dev/null 2>&1 && printf ' codex:ok' || printf ' codex:FAIL'
fi
if [ "$HAVE_CLAUDE" = 1 ]; then
rm -rf "$CLAUDE_CACHE/$MKT/$name"
claude plugin install "$name@$MKT" --scope user >/dev/null 2>&1 && printf ' claude:ok' || printf ' claude:FAIL'
fi
echo
}

targets=()
if [ $# -eq 0 ] || [ "${1:-}" = "all" ]; then
for d in "$FW"/plugins/*/; do targets+=("$(basename "$d")"); done
else
targets=("$@")
fi
for t in "${targets[@]}"; do sync_one "$t"; done

echo "Done. Restart the Claude/Codex session to load the refreshed files."