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 .plaited/rules/accuracy.md → .agents/rules/accuracy.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@
- Code review: Read files before commenting
- Patterns: Confirm examples reflect actual usage

See .plaited/rules/testing.md for verification in test contexts.
See .agents/rules/testing.md for verification in test contexts.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion .plaited/rules/testing.md → .agents/rules/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

**Use real dependencies** - Prefer installed packages over mocks when testing module resolution
*Verify:* Review test imports for fake paths
*Fix:* Use actual package like `@modelcontextprotocol/sdk/client`
*Fix:* Use actual package like `typescript`

**Organize with describe** - Group related tests in `describe('feature', () => {...})`
*Verify:* Check for flat test structure
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ bunx @plaited/development-skills scaffold-rules
```

This will:
1. Copy rules to `.plaited/rules/` (canonical location)
1. Copy rules to `.agents/rules/` (canonical location)
2. Create symlinks in `.claude/rules` and `.cursor/rules` (if those directories exist)
3. Fallback: append links to `AGENTS.md` if no agent directories found

Expand All @@ -52,23 +52,23 @@ Tell the user what was created based on the `actions` output.
## How It Works

```
.plaited/rules/ ← Canonical location (files copied here)
.agents/rules/ ← Canonical location (files copied here)
├── testing.md
├── bun.md
└── ...

.claude/rules -> ../.plaited/rules ← Symlink (if .claude/ exists)
.cursor/rules -> ../.plaited/rules ← Symlink (if .cursor/ exists)
.claude/rules -> ../.agents/rules ← Symlink (if .claude/ exists)
.cursor/rules -> ../.agents/rules ← Symlink (if .cursor/ exists)
```

| Project has... | Copy | Symlinks | AGENTS.md |
|----------------|------|----------|-----------|
| `.plaited/` only | ✓ | None | No |
| `.agents/` only | ✓ | None | No |
| `.claude/` only | ✓ | `.claude/rules` | No |
| `.cursor/` only | ✓ | `.cursor/rules` | No |
| `.plaited/` + `.claude/` | ✓ | `.claude/rules` | No |
| `.plaited/` + `.cursor/` | ✓ | `.cursor/rules` | No |
| `.plaited/` + `.claude/` + `.cursor/` | ✓ | Both | No |
| `.agents/` + `.claude/` | ✓ | `.claude/rules` | No |
| `.agents/` + `.cursor/` | ✓ | `.cursor/rules` | No |
| `.agents/` + `.claude/` + `.cursor/` | ✓ | Both | No |
| None of the above | ✓ | None | ✓ Append links |

## Related Skills
Expand Down
2 changes: 1 addition & 1 deletion .claude/rules
2 changes: 1 addition & 1 deletion .claude/skills
2 changes: 1 addition & 1 deletion .cursor/rules
2 changes: 1 addition & 1 deletion .cursor/skills
10 changes: 10 additions & 0 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ jobs:

steps:
- name: Check author permission
id: author-permission
env:
GH_TOKEN: ${{ github.token }}
run: |
Expand All @@ -26,26 +27,32 @@ jobs:
if [[ "$PERMISSION" != "admin" && "$PERMISSION" != "maintain" && "$PERMISSION" != "write" ]]; then
echo "Skipping review: Only users with admin, maintain, or write permissions can trigger Claude Code Review"
echo "Current permission level: $PERMISSION"
echo "authorized=false" >> "$GITHUB_OUTPUT"
exit 0
fi

echo "Author is authorized, proceeding with review"
echo "authorized=true" >> "$GITHUB_OUTPUT"

- name: Checkout repository
if: steps.author-permission.outputs.authorized == 'true'
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Setup Bun
if: steps.author-permission.outputs.authorized == 'true'
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Install dependencies
if: steps.author-permission.outputs.authorized == 'true'
run: |
bun install

- name: Run Claude Code Review
if: steps.author-permission.outputs.authorized == 'true'
id: claude-review
uses: anthropics/claude-code-action@v1
with:
Expand All @@ -54,6 +61,9 @@ jobs:
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}

Before reviewing, gather existing PR feedback:
- `gh pr view ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --json comments,reviews,reviewThreads`

Please review this pull request and provide feedback on:
- Code quality and best practices
- Potential bugs or issues
Expand Down
126 changes: 56 additions & 70 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,19 @@ name: Publish
on:
workflow_dispatch:
inputs:
version:
description: "New version tag (e.g., 1.0.0)"
bump:
description: "Version bump type"
required: true
next:
description: "Next prerelease number (optional, will create a version like x.y.z-next.N)"
type: choice
options:
- patch
- minor
- major
prerelease:
description: "Prerelease number (optional, creates x.y.z-next.N)"
required: false
type: string

jobs:
publish:
runs-on: ubuntu-22.04
Expand All @@ -17,69 +24,6 @@ jobs:
id-token: write

steps:
- name: Validate inputs
env:
INPUT_VERSION: ${{ github.event.inputs.version }}
INPUT_NEXT: ${{ github.event.inputs.next }}
run: |
# SECURITY: Validate all inputs before use to prevent injection
# Using env vars instead of direct interpolation to prevent shell injection

# Validate version format (semver)
if ! echo "$INPUT_VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "::error::Invalid version format: $INPUT_VERSION"
echo "::error::Expected: X.Y.Z (e.g., 1.0.0)"
exit 1
fi

# Validate next is a number if provided
if [[ -n "$INPUT_NEXT" ]] && ! echo "$INPUT_NEXT" | grep -qE '^[0-9]+$'; then
echo "::error::Invalid next value: $INPUT_NEXT"
echo "::error::Expected: number (e.g., 1, 2, 3)"
exit 1
fi

echo "✓ Input validation passed"

- name: Set version
id: set_version
env:
INPUT_VERSION: ${{ github.event.inputs.version }}
INPUT_NEXT: ${{ github.event.inputs.next }}
run: |
base_version="$INPUT_VERSION"
next="$INPUT_NEXT"

if [[ -n "$next" ]]; then
echo "version=${base_version}-next.${next}" >> $GITHUB_OUTPUT
echo "is_prerelease=true" >> $GITHUB_OUTPUT
else
echo "version=${base_version}" >> $GITHUB_OUTPUT
echo "is_prerelease=false" >> $GITHUB_OUTPUT
fi

- name: Validate version format
env:
VERSION: ${{ steps.set_version.outputs.version }}
run: |
version="$VERSION"

# Check for 'v' prefix (common mistake)
if [[ "$version" =~ ^v ]]; then
echo "::error::Version should not include 'v' prefix"
echo "::error::Enter '1.3.4' not 'v1.3.4'"
echo "::error::The workflow will automatically add 'v' for Git tags"
exit 1
fi

# Validate semver format (allows dots in prerelease suffix for formats like 1.0.0-next.1)
if [[ ! "$version" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)(-([a-zA-Z0-9._-]+))?$ ]]; then
echo "::error::Version must have the format 'x.y.z' or 'x.y.z-<string>', where x, y, and z are numbers."
exit 1
fi

echo "✅ Version format validated: $version"

- name: Checkout repository
uses: actions/checkout@v4
with:
Expand All @@ -98,6 +42,48 @@ jobs:
run: |
bun install

- name: Validate inputs
env:
INPUT_PRERELEASE: ${{ github.event.inputs.prerelease }}
run: |
# Validate prerelease is a number if provided
if [[ -n "$INPUT_PRERELEASE" ]] && ! echo "$INPUT_PRERELEASE" | grep -qE '^[0-9]+$'; then
echo "::error::Invalid prerelease value: $INPUT_PRERELEASE"
echo "::error::Expected: number (e.g., 1, 2, 3)"
exit 1
fi
echo "✓ Input validation passed"

- name: Compute version
id: compute_version
env:
INPUT_BUMP: ${{ github.event.inputs.bump }}
INPUT_PRERELEASE: ${{ github.event.inputs.prerelease }}
run: |
# Read current version from package.json
CURRENT=$(node -p "require('./package.json').version")
echo "Current version: $CURRENT"

# Strip any existing prerelease suffix to get base semver
BASE=$(echo "$CURRENT" | grep -oE '^[0-9]+\.[0-9]+\.[0-9]+')
IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE"

case "$INPUT_BUMP" in
major) NEW_VERSION="$((MAJOR + 1)).0.0" ;;
minor) NEW_VERSION="${MAJOR}.$((MINOR + 1)).0" ;;
patch) NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))" ;;
esac

if [[ -n "$INPUT_PRERELEASE" ]]; then
echo "version=${NEW_VERSION}-next.${INPUT_PRERELEASE}" >> "$GITHUB_OUTPUT"
echo "is_prerelease=true" >> "$GITHUB_OUTPUT"
else
echo "version=${NEW_VERSION}" >> "$GITHUB_OUTPUT"
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
fi

echo "✅ Computed version: $(grep 'version=' "$GITHUB_OUTPUT" | head -1)"

- name: Configure Git
env:
GIT_AUTHOR_NAME: ${{ github.actor }}
Expand All @@ -109,8 +95,8 @@ jobs:
- name: Version
env:
GH_TOKEN: ${{ secrets.GH_PAT }}
VERSION: ${{ steps.set_version.outputs.version }}
IS_PRERELEASE: ${{ steps.set_version.outputs.is_prerelease }}
VERSION: ${{ steps.compute_version.outputs.version }}
IS_PRERELEASE: ${{ steps.compute_version.outputs.is_prerelease }}
run: |
npm version --no-git-tag-version "$VERSION"

Expand All @@ -127,7 +113,7 @@ jobs:

- name: Publish to NPM (Trusted Publishing)
env:
IS_PRERELEASE: ${{ steps.set_version.outputs.is_prerelease }}
IS_PRERELEASE: ${{ steps.compute_version.outputs.is_prerelease }}
run: |
# NPM trusted publishing uses OIDC token automatically
# Provenance attestations are generated automatically (npm >=11.5.1)
Expand Down
22 changes: 11 additions & 11 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
```
bin/cli.ts # CLI entry point
src/ # TypeScript source
.plaited/skills/ # Agent skills
.plaited/rules/ # Shared rules (bundled)
.agents/skills/ # Agent skills
.agents/rules/ # Shared rules (bundled)
```

**Test CLI:** `bun bin/cli.ts <command>`
**Install skills:** `curl -fsSL https://raw.githubusercontent.com/plaited/skills-installer/main/install.sh | bash -s -- --agent <agent> --project development-skills`
**Install skills:** `npx skills add plaited/development-skills` or `bunx skills add plaited/development-skills`

## Commands

Expand All @@ -38,7 +38,7 @@ After code changes:
1. `bun run check` - Must pass
2. `bun test` - Must pass
3. `bun bin/cli.ts <cmd>` - Test CLI changes
4. For skills: `bunx @plaited/development-skills validate-skill .plaited/skills`
4. For skills: `bunx @plaited/development-skills validate-skill .agents/skills`

**Rule compliance:** Read rules below, use verification patterns to self-check

Expand All @@ -59,13 +59,13 @@ After code changes:

Compressed rules with embedded verification patterns:

- @.plaited/rules/core.md - TypeScript conventions (type>interface, no any, arrow fns)
- @.plaited/rules/testing.md - Test patterns (test>it, no conditional assertions)
- @.plaited/rules/modules.md - Module organization (no index.ts, explicit .ts)
- @.plaited/rules/workflow.md - Git + GitHub CLI patterns
- @.plaited/rules/bun.md - Bun APIs over Node.js
- @.plaited/rules/accuracy.md - 95% confidence, verify before stating
- @.plaited/rules/documentation.md - TSDoc standards
- @.agents/rules/core.md - TypeScript conventions (type>interface, no any, arrow fns)
- @.agents/rules/testing.md - Test patterns (test>it, no conditional assertions)
- @.agents/rules/modules.md - Module organization (no index.ts, explicit .ts)
- @.agents/rules/workflow.md - Git + GitHub CLI patterns
- @.agents/rules/bun.md - Bun APIs over Node.js
- @.agents/rules/accuracy.md - 95% confidence, verify before stating
- @.agents/rules/documentation.md - TSDoc standards

<!-- PLAITED-RULES-END -->

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ LSP understands re-exports, aliases, and type relationships.
## Install for AI Agents

```bash
curl -fsSL https://raw.githubusercontent.com/plaited/skills-installer/main/install.sh | bash -s -- --agents <agent-name> --project development-skills
npx skills add plaited/development-skills
# or
bunx skills add plaited/development-skills
```

**Agents:** `claude` · `cursor` · `copilot` · `codex` · `gemini` · `windsurf` · `opencode` · `amp` · `goose` · `factory`

## Commands

| Command | What it does |
Expand Down
Loading
Loading