# Publishing the job-carousel Skill to npm

Claude Code skills are distributed as npm packages. When a user installs your package, Claude Code detects the `.claude/skills/` directory and makes the skill available as `/job-carousel`.

---

## Prerequisites

- Node.js 18+
- An npm account — create one at [npmjs.com](https://www.npmjs.com/signup)
- You are logged in: `npm login`

---

## Step 1 — Choose a Package Name

Skill packages follow the convention:

```
@<your-npm-username>/claude-skill-<skill-name>
```

Examples:
- `@shawn/claude-skill-job-carousel`
- `claude-skill-job-carousel` (if you want a public unscoped name)

Pick a name and keep it consistent through the rest of this guide.

---

## Step 2 — Restructure for Publishing

The current repo has `private: true` and bundles everything together. For npm publishing, create a dedicated package for just the skill.

### 2a. Create a new folder

```bash
mkdir ../claude-skill-job-carousel
cd ../claude-skill-job-carousel
```

### 2b. Copy the skill and source files

```bash
# Skill definition (required — this is what Claude Code reads)
cp -r ../shawn-agent-skills/.claude ./

# Pipeline source code
cp -r ../shawn-agent-skills/src ./

# Docs
cp -r ../shawn-agent-skills/docs ./
```

### 2c. Create a fresh `package.json`

```json
{
  "name": "@shawn/claude-skill-job-carousel",
  "version": "1.0.0",
  "description": "Claude Code skill: transform a resume + job description into a LinkedIn career carousel",
  "keywords": [
    "claude",
    "claude-code",
    "claude-skill",
    "resume",
    "linkedin",
    "carousel",
    "job-search"
  ],
  "author": "Your Name <you@email.com>",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/your-username/claude-skill-job-carousel"
  },
  "files": [
    ".claude/",
    "src/",
    "docs/"
  ],
  "scripts": {
    "carousel": "ts-node src/job-carousel/index.ts",
    "build": "tsc",
    "typecheck": "tsc --noEmit"
  },
  "dependencies": {
    "@types/node": "^20.11.0",
    "@types/react": "^18.2.0",
    "@types/react-dom": "^18.2.0",
    "pdf-lib": "^1.17.1",
    "puppeteer": "^22.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.3.3",
    "zod": "^3.22.4"
  },
  "devDependencies": {
    "tailwindcss": "^3.4.1"
  },
  "engines": {
    "node": ">=18.0.0"
  }
}
```

> **Key fields:**
> - `"files"` — controls what gets included in the published package. Must include `.claude/` so Claude Code can find the skill.
> - `"keywords"` — include `"claude-skill"` so the package is discoverable.
> - Remove `"private": true` — private packages cannot be published.

---

## Step 3 — Verify the `files` Field

Before publishing, check exactly what will be included:

```bash
npx npm-packlist
```

Confirm you see:
```
.claude/skills/job-carousel/SKILL.md
.claude/skills/job-carousel/examples.md
.claude/skills/job-carousel/rubric.md
src/job-carousel/index.ts
src/job-carousel/...
docs/job-carousel.md
docs/publish-to-npm.md
package.json
README.md
```

If `.claude/` is missing, double-check your `files` array. npm ignores dotfiles by default — the explicit `files` entry overrides this.

---

## Step 4 — Add a `.npmignore` (optional but recommended)

If there are files you want to exclude from the package (e.g., test inputs, output artifacts):

```
output/
inputs/
*.local.*
.env
```

---

## Step 5 — Dry Run

Do a dry run to see what would be published without actually publishing:

```bash
npm publish --dry-run
```

Review the output. Make sure `.claude/skills/job-carousel/SKILL.md` is listed.

---

## Step 6 — Publish

### Public (unscoped) package:
```bash
npm publish
```

### Scoped package (e.g. `@shawn/...`), published publicly:
```bash
npm publish --access public
```

> Scoped packages default to private. `--access public` is required for free accounts.

---

## Step 7 — Verify on npmjs.com

Visit:
```
https://www.npmjs.com/package/@shawn/claude-skill-job-carousel
```

Confirm the package exists and the version is correct.

---

## How Users Install and Use the Skill

Once published, any Claude Code user can install your skill:

```bash
# Install into their project
npm install @shawn/claude-skill-job-carousel

# Or install globally
npm install -g @shawn/claude-skill-job-carousel
```

After installation, Claude Code detects `.claude/skills/job-carousel/SKILL.md` in `node_modules` and the skill becomes available as:

```
/job-carousel
```

---

## Updating the Package

When you make changes:

1. Bump the version in `package.json`:
   ```bash
   npm version patch   # 1.0.0 → 1.0.1  (bug fixes)
   npm version minor   # 1.0.0 → 1.1.0  (new features)
   npm version major   # 1.0.0 → 2.0.0  (breaking changes)
   ```

2. Publish again:
   ```bash
   npm publish --access public
   ```

---

## Checklist Before Publishing

- [ ] `package.json` has no `"private": true`
- [ ] `"files"` includes `.claude/`
- [ ] `SKILL.md` has valid YAML frontmatter (`name`, `description`)
- [ ] Package name is unique on npmjs.com
- [ ] Version follows semver
- [ ] `npm publish --dry-run` shows `.claude/skills/job-carousel/SKILL.md`
- [ ] You are logged in with `npm login`
- [ ] For scoped packages: `--access public` flag is included
