Skip to content

Commit 678ee46

Browse files
authored
Add default/preview skill distribution (#23)
1 parent 20b8ba9 commit 678ee46

File tree

35 files changed

+3483
-119
lines changed

35 files changed

+3483
-119
lines changed

.claude-plugin/marketplace.json

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,26 @@
99
"plugins": [
1010
{
1111
"name": "asta",
12-
"source": "./",
13-
"description": "Paper search, citations, literature reports, and Semantic Scholar API tools",
12+
"source": "./plugins/asta",
13+
"description": "Paper search, metadata, and document management for scientific research",
14+
"version": "0.8.0",
15+
"author": {
16+
"name": "AI2 Asta Team"
17+
},
18+
"repository": "https://github.com/allenai/asta-plugins",
19+
"license": "Apache-2.0",
20+
"keywords": [
21+
"academic",
22+
"papers",
23+
"citations",
24+
"semantic-scholar",
25+
"literature"
26+
]
27+
},
28+
{
29+
"name": "asta-preview",
30+
"source": "./plugins/asta-preview",
31+
"description": "Paper search, metadata, document management, literature reports, and experiments for scientific research",
1432
"version": "0.8.0",
1533
"author": {
1634
"name": "AI2 Asta Team"

.claude-plugin/plugin.json

Lines changed: 0 additions & 12 deletions
This file was deleted.

.github/workflows/ci.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@ jobs:
2424
- name: Lint shell scripts with shellcheck
2525
uses: ludeeus/action-shellcheck@master
2626
with:
27-
scandir: './servers ./hooks'
27+
scandir: './scripts ./hooks'
28+
29+
- name: Verify generated plugins are up to date
30+
run: |
31+
./scripts/build-plugins.sh
32+
git diff --exit-code plugins/ || { echo "plugins/ is out of date. Run 'make build-plugins' and commit."; exit 1; }
2833
2934
test:
3035
runs-on: ubuntu-latest
@@ -35,6 +40,13 @@ jobs:
3540
steps:
3641
- uses: actions/checkout@v4
3742

43+
- uses: actions/setup-node@v4
44+
with:
45+
node-version: "20"
46+
47+
- name: Install Claude Code CLI
48+
run: npm install -g @anthropic-ai/claude-code
49+
3850
- name: Install uv
3951
uses: astral-sh/setup-uv@v4
4052

@@ -43,4 +55,3 @@ jobs:
4355

4456
- name: Run tests
4557
run: make test
46-

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ __pycache__/
88
.claude/settings.local.json
99
CLAUDE.local.md
1010

11+
# Test artifacts
12+
.goose/
13+
skills-lock.json
14+
.agents/
15+
1116
# IDEs
1217
.idea/
1318
*.iml

.mcp.json

Lines changed: 0 additions & 11 deletions
This file was deleted.

DEVELOPER.md

Lines changed: 103 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,14 @@ src/asta/ # Main CLI package
3535
├── citations.py # `asta papers citations` command
3636
└── author.py # `asta papers author` commands
3737
38-
skills/ # Claude Code skill definitions
38+
skills/ # Canonical skill definitions (edit here)
3939
hooks/ # Claude Code permission hooks
40-
.claude-plugin/plugin.json # Claude Code plugin manifest
40+
scripts/ # Build and maintenance scripts
41+
42+
# Claude Code marketplace distribution:
43+
plugins/ # Generated plugin packages (do not edit)
44+
.claude-plugin/
45+
marketplace.json # Marketplace listing (asta + asta-preview plugins)
4146
```
4247

4348
### Design Principles
@@ -65,6 +70,7 @@ hooks/ # Claude Code permission hooks
6570
- Python 3.11+
6671
- `uv` (for running commands)
6772
- `make` (for development tasks)
73+
- Node.js 20+ / `npx` (for skill discovery tests — `make test` skips these if missing)
6874

6975
### Quick Start
7076

@@ -77,9 +83,11 @@ make test # Run all tests
7783
make lint # Check code style
7884
make format # Auto-fix formatting
7985
make check # Quick pre-commit check (format + lint + unit tests)
80-
make ci # Full CI check (format + lint + all tests)
81-
make build # Build distribution packages
82-
make clean # Remove build artifacts
86+
make ci # Full CI check (format + lint + all tests + plugins check)
87+
88+
# Claude Code marketplace (run after editing skills/)
89+
make build-plugins # Regenerate plugins/ from skills/
90+
make check-plugins # Verify plugins/ is up to date
8391
```
8492

8593
### Install for Development
@@ -114,7 +122,7 @@ For coding agents like Claude that invoke bare `asta` from arbitrary working dir
114122
add to `~/.zshrc`:
115123

116124
```bash
117-
alias claude-asta='PATH="/path/to/asta-plugins/.venv/bin:$PATH" claude --plugin-dir /path/to/asta-plugins'
125+
alias claude-asta='PATH="/path/to/asta-plugins/.venv/bin:$PATH" claude --plugin-dir /path/to/asta-plugins/plugins/asta-preview'
118126
```
119127

120128
The PATH prepend ensures skills resolve `asta` to your local source for that session,
@@ -128,7 +136,7 @@ twice alongside `--plugin-dir`.
128136
|---|---|
129137
| Python files (`src/asta/`) | None — editable install |
130138
| `pyproject.toml` (new deps/scripts) | `make install` |
131-
| Skills, hooks, `plugin.json` | Restart `claude-asta` session |
139+
| Skills (`skills/`) or hooks (`hooks/`) | `make build-plugins`, then restart `claude-asta` session |
132140

133141
### Run Tests
134142

@@ -283,6 +291,67 @@ allowed-tools:
283291
Instructions and examples...
284292
```
285293

294+
#### Skill distribution design
295+
296+
All skills live in `skills/` — this is the **single source of truth**. Whether a skill is included in the default install or requires opt-in is determined by its SKILL.md frontmatter:
297+
298+
```yaml
299+
# Default skill — no metadata.internal field
300+
---
301+
name: Semantic Scholar Lookup
302+
---
303+
304+
# Preview skill — add metadata.internal: true
305+
---
306+
name: Find Literature
307+
metadata:
308+
internal: true
309+
---
310+
```
311+
312+
This one flag drives all distribution behavior — no lists to maintain elsewhere.
313+
314+
**Two distribution channels, same source:**
315+
316+
| Channel | Default install | All skills |
317+
|---------|----------------|------------|
318+
| npx skills CLI | `npx skills add allenai/asta-plugins` (default only) | `--all` or `--skill "Name"` |
319+
| Claude Code plugin | `/plugin install asta` (default only) | `/plugin install asta-preview` |
320+
| Local dev | `claude --plugin-dir plugins/asta-preview` (all skills) ||
321+
322+
**Why `plugins/` exists:**
323+
324+
The npx skills CLI reads `metadata.internal` directly from SKILL.md, so filtering works automatically. Claude Code plugins, however, auto-discover every skill in the `skills/` directory — they have no per-skill filtering mechanism. The only way to ship a subset of skills via Claude Code is to package separate plugin directories with different skill sets.
325+
326+
`plugins/` contains these generated packages:
327+
- `plugins/asta/` — default skills only
328+
- `plugins/asta-preview/` — all skills (default + preview)
329+
330+
**Never edit `plugins/` directly.** It's generated from `skills/` by `scripts/build-plugins.sh`.
331+
332+
**Workflow for changing skills:**
333+
334+
```bash
335+
# Edit the canonical source
336+
vim skills/my-skill/SKILL.md
337+
338+
# Regenerate plugin packages
339+
make build-plugins
340+
341+
# Commit both
342+
git add skills/ plugins/
343+
git commit -m "Update my-skill"
344+
```
345+
346+
CI enforces that `plugins/` stays in sync — PRs fail if someone edits a skill without rebuilding.
347+
348+
**Adding a new skill:**
349+
350+
1. Create `skills/<name>/SKILL.md`
351+
2. Add `metadata.internal: true` if it shouldn't be in the default install yet
352+
3. Run `make build-plugins`
353+
4. To promote to default later: remove the `metadata.internal` block and rebuild
354+
286355
### Hooks
287356

288357
Hooks in `hooks/` are bash scripts that can auto-approve tool usage:
@@ -316,7 +385,7 @@ Register hooks in `hooks/hooks.json`:
316385

317386
```bash
318387
# Run Claude Code with local plugin
319-
claude --plugin-dir . --debug
388+
claude --plugin-dir plugins/asta-preview --debug
320389

321390
# In Claude, test skills naturally
322391
# Skills activate automatically based on what you ask
@@ -353,57 +422,62 @@ packages = ["src/asta"]
353422

354423
## Release Process
355424

356-
The version number is stored in four locations and must be kept in sync:
425+
The version number is stored in three source locations:
357426
- `src/asta/__init__.py` - `__version__` variable (Python package version)
358427
- `pyproject.toml` - `version` field (Build system version)
359-
- `.claude-plugin/plugin.json` - `version` field (Plugin manifest for Claude Code)
360-
- `.claude-plugin/marketplace.json` - `plugins[0].version` field (Marketplace listing for `/plugin marketplace add`)
428+
- `.claude-plugin/marketplace.json` - `plugins[].version` fields (Claude Code auto-updates)
361429

362-
**Note:** Both `.claude-plugin/plugin.json` (individual plugin manifest) and `.claude-plugin/marketplace.json` (marketplace repository listing) are required. The marketplace file allows users to install via `/plugin marketplace add allenai/asta-plugins` in Claude Code.
430+
`make set-version` updates all three.
363431

364432
### Complete Release Workflow
365433

366-
1. **Update version in all files:**
434+
1. **Update version in all source files:**
367435
```bash
368436
make set-version VERSION=0.3.0
369437
```
370-
This updates all three version locations atomically.
438+
Updates `src/asta/__init__.py`, `pyproject.toml`, and `.claude-plugin/marketplace.json`.
371439

372440
2. **Review changes:**
373441
```bash
374442
git diff
375443
```
376-
Verify that all three files were updated correctly.
444+
Verify the version updated correctly.
445+
446+
3. **Rebuild generated plugin packages:**
447+
```bash
448+
make build-plugins
449+
```
450+
Rebuilds `plugins/` from `skills/`, `hooks/`, and `marketplace.json`.
377451

378-
3. **Run full test suite:**
452+
4. **Run full test suite:**
379453
```bash
380454
make ci
381455
```
382-
Ensures all tests pass, code is formatted, and linting is clean.
456+
Ensures all tests pass, linting is clean, code is formatted, and generated files are in sync.
383457

384-
4. **Commit version bump:**
458+
5. **Commit version bump:**
385459
```bash
386460
git add -A
387461
git commit -m "chore: bump version to 0.3.0"
388462
git push
389463
```
390464

391-
5. **Create and push version tag:**
465+
6. **Create and push version tag:**
392466
```bash
393467
make push-version-tag
394468
```
395469
This command will:
396-
- Verify all three version files are in sync (fails if they differ)
470+
- Verify all version files are in sync (fails if they differ)
397471
- Check that the git tag doesn't already exist
398472
- Create and push the git tag (e.g., `0.3.0`)
399473
- Provide a URL to create the GitHub release
400474

401-
6. **Create GitHub release notes:**
475+
7. **Create GitHub release notes:**
402476
- Visit the URL provided by `make push-version-tag`
403477
- Add release notes describing changes
404478
- Publish the release
405479

406-
7. **Publish to PyPI (optional):**
480+
8. **Publish to PyPI (optional):**
407481
```bash
408482
make publish # Production PyPI
409483
make publish-test # TestPyPI for testing
@@ -420,17 +494,17 @@ make version
420494
```bash
421495
make set-version VERSION=x.y.z
422496
```
423-
- Updates all four version locations atomically
497+
- Updates `__init__.py`, `pyproject.toml`, and `marketplace.json`
498+
- Run `make build-plugins` after to regenerate plugin packages
424499
- Fails with error if VERSION parameter is not provided
425500
- Provides suggested commit command after success
426501

427502
**Push version tag:**
428503
```bash
429504
make push-version-tag
430505
```
431-
- Checks version consistency across all four files
432-
- Fails with clear error if versions don't match
433-
- Shows current versions in each file when there's a mismatch
506+
- Checks that `__init__.py`, `pyproject.toml`, and `marketplace.json` versions match
507+
- Fails with clear error if they differ
434508
- Creates and pushes git tag if all checks pass
435509
- Fails if git tag already exists (prevents accidental overwrites)
436510

@@ -442,10 +516,9 @@ If you try to push a version tag with mismatched versions:
442516
$ make push-version-tag
443517
Checking version consistency...
444518
Error: Version mismatch detected:
445-
src/asta/__init__.py: 0.3.0
446-
pyproject.toml: 0.2.0
447-
.claude-plugin/plugin.json: 0.2.0
448-
.claude-plugin/marketplace.json: 0.2.0
519+
src/asta/__init__.py: 0.3.0
520+
pyproject.toml: 0.2.0
521+
.claude-plugin/marketplace.json: 0.2.0
449522

450523
Run 'make set-version VERSION=x.y.z' to sync versions
451524
```

0 commit comments

Comments
 (0)