@gerdloos/npm-trusts-github-skill 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,22 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ permissions:
9
+ id-token: write
10
+ contents: read
11
+
12
+ jobs:
13
+ publish:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-node@v4
18
+ with:
19
+ node-version: '22'
20
+ registry-url: 'https://registry.npmjs.org'
21
+ - run: npm install -g npm@latest
22
+ - run: npm publish --access public
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # setup-npm-trusts-github-skill
2
+
3
+ A skill that teaches an LLM how to set up npm trusted publishing (OIDC) with GitHub Actions.
4
+
5
+ ## Install on Pi
6
+
7
+ ```bash
8
+ pi install npm:@gerdloos/npm-trusts-github-skill
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ In Pi: `/skill:npm-trusts-github`
14
+
15
+ The agent will guide you through setting up automated npm publishing — no tokens, no 2FA prompts, just git tags → GitHub Actions → npm.
package/package.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "@gerdloos/npm-trusts-github-skill",
3
+ "version": "1.0.0",
4
+ "description": "A skill that teaches an LLM how to set up npm trusted publishing with GitHub Actions",
5
+ "keywords": ["pi-package", "npm", "publish", "workflow"],
6
+ "license": "MIT",
7
+ "pi": {
8
+ "skills": ["./skills"]
9
+ }
10
+ }
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: npm-trusts-github
3
+ description: >
4
+ Set up npm trusted publishing (OIDC) with GitHub Actions — no tokens, no 2FA
5
+ prompts. Teaches the agent how to create package.json, write publish.yml,
6
+ configure trusted publisher on npmjs.com, wire git-tag-driven releases, and
7
+ troubleshoot common failures. Trigger when a user asks to publish an npm
8
+ package automatically from GitHub, set up CI/CD for npm, use OIDC to avoid
9
+ npm tokens, or wire a GitHub repo to auto-publish on every git tag.
10
+ ---
11
+
12
+ # npm trusts GitHub — Trusted Publishing Setup
13
+
14
+ Wires a GitHub repo to auto-publish to npm on every git tag via OIDC trusted
15
+ publishing. No long-lived tokens, no 2FA prompts, no manual rotation.
16
+
17
+ ## Before starting
18
+
19
+ Read `defaults.json` in this skill directory. It contains the user's preferred
20
+ npm scope, npm org, and GitHub account. If a field is empty or contains a
21
+ placeholder (`<Fill default here ... or leave empty>`), ask the user for that
22
+ value. The user can edit `defaults.json` at any time.
23
+
24
+ - **npmScope**: your npm username with `@` (e.g. `@alice`). Scope and org are
25
+ alternatives — fill one, leave the other empty. If both are empty, packages
26
+ are unscoped.
27
+ - **npmOrg**: an optional npm organization name (e.g. `mycompany`). Creates
28
+ packages under `@mycompany/` instead of `@yourname/`.
29
+ - **githubAccount**: your GitHub username for repo URLs and trusted publisher.
30
+
31
+ Prefer values the user provides in conversation over the config file.
32
+
33
+ ## Reference documents
34
+
35
+ All in `references/` relative to this SKILL.md. Load on demand.
36
+
37
+ | File | When to load |
38
+ |---|---|
39
+ | `references/quick-start.md` | User wants the full step-by-step with placeholders filled in |
40
+ | `references/publish.yml` | User needs the GitHub Actions workflow template |
41
+ | `references/setup-guide.md` | User needs detailed explanations of each step |
42
+ | `references/troubleshooting.md` | User hits an error |
43
+ | `references/example-hello.md` | User wants a worked example (the hello-world package) |
44
+
45
+ ## Core concept
46
+
47
+ The pipeline:
48
+
49
+ ```
50
+ git push --follow-tags → GitHub Action detects v* tag → npm publish via OIDC
51
+ ```
52
+
53
+ No npm login, no token secrets, no 2FA codes. The GitHub Action exchanges a
54
+ short-lived OIDC identity token for publish rights. Provenance is signed
55
+ automatically.
56
+
57
+ ## Troubleshooting quick reference
58
+
59
+ | Error | Cause | Fix |
60
+ |---|---|---|
61
+ | `ENEEDAUTH` | npm too old (< 11.5.1) | `npm install -g npm@latest` in workflow |
62
+ | `E404` | Trusted publisher config typo OR package never manually published | Re-check fields on npmjs.com; do one manual publish |
63
+ | `EOTP` | Token-based path is being used instead of OIDC | Remove `NODE_AUTH_TOKEN` and `--provenance` |
64
+
65
+ Full guide: `references/troubleshooting.md`.
@@ -0,0 +1,17 @@
1
+ {
2
+ "_comment": "==========================================================\n DEFAULTS CONFIG — setup-npm-publish skill\n Fill in your values below. Leave a field empty (empty string)\n or keep its placeholder, and the LLM will ask you for it\n when needed.\n==========================================================",
3
+
4
+ "npmScope": "<Fill default here like @your-username or leave empty>",
5
+
6
+ "_npmScope_explanation": "Your npm scope is just the @account part — not the full\n package name. Example: in @alice/utils, the scope is @alice,\n and 'utils' is the project name (chosen at npm init time).\n Every npm account automatically gets a scope matching its\n username.\n\n When you publish with a scope, your package name only needs\n to be unique within that scope — @alice/utils and @bob/utils\n can both exist without conflict.\n\n If you also fill in npmOrg, leave this empty. The org name\n becomes the scope instead.\n\n If both are empty, packages are unscoped (global namespace,\n e.g. 'utils' instead of '@alice/utils'). Unscoped names\n must be globally unique — first come, first served.\n\n Fill in like: @your-username",
7
+
8
+ "_scopeOrOrg_note": "npmScope and npmOrg are alternatives, not layers. If you fill in npmOrg, leave npmScope empty (and vice versa). The org name becomes the scope. If both are empty, packages are unscoped (global namespace).",
9
+
10
+ "npmOrg": "<Fill default here like org-name without @ or leave empty>",
11
+
12
+ "_npmOrg_explanation": "An npm organization is a shared namespace you create at\n npmjs.com/org/create. It's free. The org gets its own scope\n (e.g. @mycompany). Multiple people can publish under it.\n\n This field is OPTIONAL. Leave empty if you don't have an org\n or don't want to publish under one.\n\n When to use an org:\n - You want packages under @mycompany/ instead of @yourname/\n - Multiple maintainers need publish access\n - You want organizational branding separate from your\n personal account\n\n If you set this, the LLM uses @<npmOrg>/ as the scope\n instead of your personal scope. Your personal account must\n own or be a member of the org.\n\n Fill in like: mycompany (no @ prefix — just the name)",
13
+
14
+ "githubAccount": "<Fill default here like account-name or leave empty>",
15
+
16
+ "_githubAccount_explanation": "Your GitHub username. Used for:\n - Repo URLs: git@github.com:<account>/<repo>.git\n - Trusted publisher config on npmjs.com\n\n Fill in like: alice"
17
+ }
@@ -0,0 +1,78 @@
1
+ # Worked Example — @gerdloos/pi-skill-hello
2
+
3
+ This is the real package that this skill's setup was battle-tested against.
4
+ Follow this walkthrough to see the full flow in action.
5
+
6
+ ## Final state
7
+
8
+ | Piece | Value |
9
+ |---|---|
10
+ | npm package | `@gerdloos/pi-skill-hello` ([view](https://www.npmjs.com/package/@gerdloos/pi-skill-hello)) |
11
+ | GitHub repo | `<github-account>/pi-skill-hello` (private) |
12
+ | Workflow | `.github/workflows/publish.yml` |
13
+ | Trusted publisher | Configured on npm package settings |
14
+ | npm org (available) | `<org-name>` under your npm account |
15
+
16
+ ## Package contents
17
+
18
+ ```
19
+ pi-skill-hello/
20
+ ├── package.json # name: @gerdloos/pi-skill-hello
21
+ ├── README.md
22
+ ├── .github/workflows/
23
+ │ └── publish.yml # triggers on v* tags, id-token: write
24
+ ├── skills/
25
+ │ └── hello/
26
+ │ ├── SKILL.md # Agent Skills spec — says "Hello npm! 🎉"
27
+ │ └── scripts/
28
+ │ └── hello.sh
29
+ ```
30
+
31
+ ## Errors we hit and how we fixed them
32
+
33
+ ### 1. `EOTP` — one-time password required
34
+ **When:** First attempt with a "Publish" type granular token.
35
+ **Why:** The token required 2FA for every publish. GitHub Actions can't enter OTPs.
36
+ **Fix:** Switched to trusted publishing (OIDC). Deleted the token entirely.
37
+
38
+ ### 2. `E404` — package not in registry (after trusted publisher config)
39
+ **When:** After configuring the trusted publisher on npmjs.com.
40
+ **Why:** Had `--provenance` flag and `NODE_AUTH_TOKEN` in the workflow.
41
+ These triggered the old token-based code path, which overrode the OIDC flow.
42
+ **Fix:** Removed `--provenance` flag and `NODE_AUTH_TOKEN` env var.
43
+
44
+ ### 3. `ENEEDAUTH` — need auth
45
+ **When:** After removing token and flags.
46
+ **Why:** npm version on the runner was too old (< 11.5.1). OIDC wasn't recognized.
47
+ **Fix:** Added `npm install -g npm@latest` step before `npm publish`.
48
+
49
+ ### 4. `E404` again — trusted publisher mismatch
50
+ **When:** After all workflow fixes.
51
+ **Why:** The `registry-url` in `setup-node` was creating an `.npmrc` with an
52
+ empty `_authToken` line, which blocked the OIDC flow.
53
+ **Fix:** Moved to passing `--registry https://registry.npmjs.org` in the
54
+ publish command instead of relying on `setup-node`'s `registry-url`.
55
+ (Later re-added `registry-url` once we understood that the issue was npm version,
56
+ not the registry config.)
57
+
58
+ ### 5. Final working state
59
+ - `registry-url` in setup-node (creates registry config)
60
+ - No `NODE_AUTH_TOKEN` env var (OIDC handles auth)
61
+ - No `--provenance` flag (automatic with trusted publishing)
62
+ - `npm install -g npm@latest` (ensures npm ≥ 11.5.1)
63
+ - `id-token: write` at root permissions level
64
+ - Bare `npm publish --access public`
65
+
66
+ ## The exact publish.yml that works
67
+
68
+ See `references/publish.yml` in this skill directory.
69
+
70
+ ## How to replicate for your own project
71
+
72
+ 1. Copy the `publish.yml` into your project
73
+ 2. Replace `@gerdloos` with your scope in `package.json`
74
+ 3. Create the GitHub repo, push code
75
+ 4. Manually publish once: `npm login && npm publish --access public`
76
+ 5. Configure trusted publisher on npmjs.com
77
+ 6. `npm version patch && git push --follow-tags`
78
+ 7. Watch `github.com/your-username/your-repo/actions`
@@ -0,0 +1,22 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ permissions:
9
+ id-token: write
10
+ contents: read
11
+
12
+ jobs:
13
+ publish:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-node@v4
18
+ with:
19
+ node-version: '22'
20
+ registry-url: 'https://registry.npmjs.org'
21
+ - run: npm install -g npm@latest
22
+ - run: npm publish --access public
@@ -0,0 +1,102 @@
1
+ # Quick Start
2
+
3
+ Follow these steps to wire up your first package. Replace `<npmScope>`,
4
+ `<githubAccount>`, and `<my-pkg>` with values from `defaults.json` or user
5
+ answers.
6
+
7
+ ## 1. Create the package
8
+
9
+ ```bash
10
+ mkdir <my-pkg> && cd <my-pkg>
11
+ npm init --scope=<npmScope>
12
+ ```
13
+
14
+ ## 2. Write code
15
+
16
+ Add your source files. Create a README.
17
+
18
+ ## 3. Add the GitHub Actions workflow
19
+
20
+ ```bash
21
+ mkdir -p .github/workflows
22
+ ```
23
+
24
+ Copy the workflow template from `references/publish.yml` into
25
+ `.github/workflows/publish.yml`. The template is ready to use — it includes
26
+ the correct permissions, npm upgrade step, and bare publish command.
27
+
28
+ ## 4. Commit and push to GitHub
29
+
30
+ Create a repo on GitHub (public or private — Actions works on both).
31
+
32
+ ```bash
33
+ git init
34
+ git add -A
35
+ git commit -m "Initial commit"
36
+ git remote add origin git@github.com:<githubAccount>/<my-pkg>.git
37
+ git branch -M main
38
+ git push -u origin main
39
+ ```
40
+
41
+ ## 5. Publish manually once
42
+
43
+ This establishes the package on npm. The trusted publisher can publish new
44
+ versions of an existing package, but cannot create a brand-new one.
45
+
46
+ ```bash
47
+ npm login
48
+ npm publish --access public
49
+ ```
50
+
51
+ Verify: `https://www.npmjs.com/package/<npmScope>/<my-pkg>`
52
+
53
+ ## 6. Configure trusted publisher on npm
54
+
55
+ 1. Go to `https://www.npmjs.com/package/<npmScope>/<my-pkg>/access`
56
+ 2. Scroll to **Trusted Publisher** → click **GitHub Actions**
57
+ 3. Fill in:
58
+
59
+ | Field | Value |
60
+ |---|---|
61
+ | Organization or user | `<githubAccount>` |
62
+ | Repository | `<my-pkg>` |
63
+ | Workflow filename | `publish.yml` |
64
+ | Environment name | leave empty |
65
+ | Allowed actions | `npm publish` |
66
+
67
+ **Warning:** npm does NOT validate this form on save. Triple-check every field.
68
+
69
+ 4. Click **Save**
70
+
71
+ ## 7. Restrict token access (recommended)
72
+
73
+ On the same page, under **Publishing access**, select:
74
+ **"Require two-factor authentication and disallow tokens"**.
75
+
76
+ Trusted publishers bypass this restriction. This blocks any leaked API tokens
77
+ from publishing to your package.
78
+
79
+ ## 8. Push a tag and publish
80
+
81
+ ```bash
82
+ npm version patch
83
+ git push --follow-tags
84
+ ```
85
+
86
+ Watch the workflow run: `https://github.com/<githubAccount>/<my-pkg>/actions`
87
+
88
+ Once green, the package is live on npm with cryptographic provenance.
89
+
90
+ ## Releasing future versions
91
+
92
+ ```bash
93
+ # Make changes, commit, push
94
+ git add -A && git commit -m "changes"
95
+ git push
96
+
97
+ # When ready to release:
98
+ npm version patch # or minor, or major
99
+ git push --follow-tags
100
+ ```
101
+
102
+ No login. No tokens. No npm CLI on release day. The Action handles everything.
@@ -0,0 +1,137 @@
1
+ # Setup Guide — npm Trusted Publishing with GitHub Actions
2
+
3
+ ## What you're building
4
+
5
+ A pipeline where `git push --follow-tags` on your machine triggers a GitHub
6
+ Action that publishes your package to npm — with cryptographic provenance,
7
+ no long-lived tokens, no 2FA prompts.
8
+
9
+ ## Prerequisites
10
+
11
+ - npm account (creates personal scope `@your-username`)
12
+ - GitHub account
13
+ - Node.js ≥ 22 and npm ≥ 11.5.1 on your local machine
14
+
15
+ ## Step 1: Create the npm package locally
16
+
17
+ ```bash
18
+ mkdir my-package && cd my-package
19
+
20
+ # With personal scope:
21
+ npm init --scope=@your-username
22
+
23
+ # Or with org scope (if you created an org on npmjs.com):
24
+ npm init --scope=@your-org
25
+
26
+ # Or unscoped:
27
+ npm init
28
+ ```
29
+
30
+ The `name` field in `package.json` now reads `@your-username/my-package`.
31
+ This is what users will `npm install`.
32
+
33
+ Write your code. Add a README.
34
+
35
+ ## Step 2: Add the GitHub Actions workflow
36
+
37
+ Create `.github/workflows/publish.yml`. The template is in `references/publish.yml`
38
+ in this skill directory. Copy it verbatim — it has the correct permissions,
39
+ npm upgrade step, and a bare `npm publish` command (no `--provenance`, no auth token).
40
+
41
+ Key requirements in the workflow:
42
+ - `permissions: id-token: write` at root level (not per-job)
43
+ - `npm install -g npm@latest` before publish (trusted publishing needs ≥ 11.5.1)
44
+ - `npm publish --access public` — bare, no extra flags
45
+ - Triggers on tags matching `v*`
46
+
47
+ ## Step 3: Create the GitHub repo and push
48
+
49
+ Create a repo on GitHub (public or private — Actions works on both, 2,000 free
50
+ minutes/month for private repos).
51
+
52
+ ```bash
53
+ git init
54
+ git add -A
55
+ git commit -m "Initial commit"
56
+ git remote add origin git@github.com:your-username/my-package.git
57
+ git branch -M main
58
+ git push -u origin main
59
+ ```
60
+
61
+ ## Step 4: Publish the package manually ONCE
62
+
63
+ This establishes the package on npm. The trusted publisher needs a package to
64
+ publish *to* — it can't create a new package from scratch.
65
+
66
+ ```bash
67
+ npm login # prompts for username, password, 2FA if enabled
68
+ npm publish --access public
69
+ ```
70
+
71
+ Verify: `https://www.npmjs.com/package/@your-username/my-package`
72
+
73
+ ## Step 5: Configure the trusted publisher on npm
74
+
75
+ 1. Go to `https://www.npmjs.com/package/@your-username/my-package/access`
76
+ 2. Scroll to **Trusted Publisher**
77
+ 3. Click **GitHub Actions**
78
+ 4. Fill in:
79
+
80
+ | Field | Value |
81
+ |---|---|
82
+ | Organization or user | Your GitHub username (case-sensitive) |
83
+ | Repository | Your repo name (case-sensitive) |
84
+ | Workflow filename | `publish.yml` (filename only, no path) |
85
+ | Environment name | Leave empty |
86
+ | Allowed actions | `npm publish` |
87
+
88
+ **Critical:** npm does NOT validate this form on save. Every field must match
89
+ exactly — a single typo produces an opaque `E404` error later.
90
+
91
+ 5. Click **Save**
92
+
93
+ ## Step 6: Restrict token access (optional, recommended)
94
+
95
+ On the same page, under **Publishing access**, select:
96
+ **"Require two-factor authentication and disallow tokens"**
97
+
98
+ Trusted publishers bypass this check. It blocks any leaked API tokens from
99
+ publishing to your package.
100
+
101
+ ## Step 7: Push a tag and watch it publish
102
+
103
+ ```bash
104
+ npm version patch # bumps version, creates git tag v1.x.x
105
+ git push --follow-tags # pushes code + tag, triggers the Action
106
+ ```
107
+
108
+ Watch the workflow run: `https://github.com/your-username/my-package/actions`
109
+
110
+ Once green, your package is live on npm with provenance.
111
+
112
+ ## Releasing future versions
113
+
114
+ ```bash
115
+ # Make changes, commit, push as usual
116
+ git add -A && git commit -m "changes"
117
+ git push
118
+
119
+ # When ready to release:
120
+ npm version patch # or minor, or major
121
+ git push --follow-tags
122
+ ```
123
+
124
+ That's it. No login, no tokens, no npm CLI on release day. The Action handles
125
+ everything.
126
+
127
+ ## Organization-scoped packages
128
+
129
+ If publishing under an org (`@myorg/pkg`):
130
+
131
+ 1. Create the org at `npmjs.com/org/create` (free)
132
+ 2. Publish the first version manually as org owner
133
+ 3. Configure trusted publisher on the org package's settings page
134
+ 4. The GitHub repo can be under your personal account or the org — no coupling
135
+
136
+ Multiple maintainers: add them as org members on npm, and as repo collaborators
137
+ on GitHub. Anyone who pushes a tag can trigger a publish.
@@ -0,0 +1,109 @@
1
+ # Troubleshooting — npm Trusted Publishing
2
+
3
+ ## Error: `ENEEDAUTH` — "need auth"
4
+
5
+ **Full message:**
6
+ ```
7
+ npm error code ENEEDAUTH
8
+ npm error need auth This command requires you to be logged in
9
+ ```
10
+
11
+ **Cause:** npm version too old for OIDC trusted publishing, or OIDC environment
12
+ not detected.
13
+
14
+ **Fix:** Add a step BEFORE `npm publish`:
15
+ ```yaml
16
+ - run: npm install -g npm@latest
17
+ ```
18
+
19
+ Trusted publishing requires npm ≥ 11.5.1. The default npm on `ubuntu-latest`
20
+ runners is older and doesn't support OIDC.
21
+
22
+ ---
23
+
24
+ ## Error: `E404` — "not in this registry"
25
+
26
+ **Full message:**
27
+ ```
28
+ npm error code E404
29
+ npm error 404 Not Found - PUT https://registry.npmjs.org/@scope%2fpackage
30
+ npm error 404 '@scope/package@x.y.z' is not in this registry.
31
+ ```
32
+
33
+ **Causes (check both):**
34
+
35
+ 1. **Typo in trusted publisher config.** The GitHub owner, repo name, or workflow
36
+ filename on npmjs.com doesn't match exactly (case-sensitive). npm doesn't
37
+ validate this form on save — it only fails at publish time.
38
+
39
+ Fix: go to npmjs.com → package → Settings → Access → Trusted Publisher.
40
+ Re-enter all fields carefully. Check:
41
+ - GitHub username case (e.g., `my-github-user` not `My-Github-User`)
42
+ - Repo name exactly as on GitHub
43
+ - Workflow filename is just `publish.yml`, not `.github/workflows/publish.yml`
44
+
45
+ 2. **Package never manually published.** The trusted publisher can publish new
46
+ versions of an existing package, but can't create a brand-new package.
47
+
48
+ Fix: `npm login && npm publish --access public` from your laptop once.
49
+
50
+ ---
51
+
52
+ ## Error: `EOTP` — "one-time password required"
53
+
54
+ **Full message:**
55
+ ```
56
+ npm error code EOTP
57
+ npm error This operation requires a one-time password from your authenticator.
58
+ ```
59
+
60
+ **Cause:** The workflow is using an old token-based publish path instead of
61
+ OIDC trusted publishing. This happens when `NODE_AUTH_TOKEN` is set or when
62
+ `--provenance` is passed as a flag.
63
+
64
+ **Fix:**
65
+ - Remove `NODE_AUTH_TOKEN` env var from the workflow
66
+ - Remove `--provenance` flag from `npm publish` (provenance is automatic with OIDC)
67
+ - The workflow's `npm publish` line should be bare: `npm publish --access public`
68
+
69
+ Background: `--provenance` triggers the old provenance code path which expects
70
+ a token. With trusted publishers, provenance signing is automatic — the flag
71
+ is not only unnecessary but harmful.
72
+
73
+ ---
74
+
75
+ ## Symptom: Provenance signed successfully but package not published
76
+
77
+ **What you see:** The workflow log shows "Provenance statement published to
78
+ transparency log" followed by a publish error.
79
+
80
+ **Cause:** Same as EOTP above — `--provenance` flag was passed, which signs the
81
+ provenance but then routes publish auth through the token path. The token isn't
82
+ set (or is wrong), so the publish fails even though provenance worked.
83
+
84
+ **Fix:** Remove `--provenance` from the `npm publish` command.
85
+
86
+ ---
87
+
88
+ ## Symptom: Workflow never triggers
89
+
90
+ **Check:**
91
+ - Tag format: must match `v*` (e.g., `v1.0.0`, `v1.0.1`). `npm version patch`
92
+ creates these automatically.
93
+ - Did you push with `--follow-tags`? `git push` alone doesn't push tags.
94
+ - Run `git tag -l` to see local tags. Run `git ls-remote --tags origin` to see
95
+ remote tags.
96
+
97
+ ## Symptom: Actions tab shows no workflow at all
98
+
99
+ The workflow file must be exactly at `.github/workflows/publish.yml` (not
100
+ `.github/workflows/publish.yaml`, not `.github/publish.yml`).
101
+
102
+ ## General debugging
103
+
104
+ 1. Go to `github.com/you/repo/actions` → click the failing run → expand the
105
+ `publish` step → read the full log
106
+ 2. Check the trusted publisher config on npmjs.com for typos
107
+ 3. Verify `npm --version` in the workflow log is ≥ 11.5.1
108
+ 4. Try a manual publish from your laptop to confirm the package is healthy:
109
+ `npm publish --access public`