Skip to content

fix(bins): every npx bin was a silent no-op + add Astro integration (0.5.0) - #29

Merged
RelayStack merged 1 commit into
mainfrom
feat/integration-and-bin-fix
Oct 16, 2026
Merged

RelayStack merged 1 commit into
mainfrom
feat/integration-and-bin-fix

Conversation

@RelayStack

Copy link
Copy Markdown
Owner

The bug this fixes

Every bin in the published package was a silent no-op.

const isCli = process.argv[1] && import.meta.url.endsWith(process.argv[1].split("/").pop());

npm installs bins as node_modules/.bin/* symlinks. When npm (or npx, or npm run) executes one, process.argv[1] is the link (astro-seo-llms) while import.meta.url is the real file (llms-txt.mjs). The comparison is therefore always false, the CLI block never runs, and the process exits 0 having written nothing.

Reproduced on 0.4.0:

$ npx astro-seo-sitemap --dir src/content --site https://example.com
exit=0        # no output, no file

That means the README's advertised paths — npx astro-seo-llms …, build-script hooks, the github: shorthand — all did nothing for anyone who tried them. Fixed by resolving the path:

import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href

Covered by a new test (bins run when invoked through a .bin-style symlink) that executes a bin through a symlink exactly as npm does.

What else is here

  • astro-seo-toolkit/integration — a real Astro integration. Writes llms.txt, llms-full.txt, sitemap.xml, robots.txt during astro:build:done, from one or more content dirs (deduped by URL). Exports generate / writeFiles / normalizeOptions for build scripts.
  • New bins: astro-seo-toolkit (all files at once) and astro-seo-check.
  • Usage hints now print the npx astro-seo-* form instead of node <file>.mjs.
  • scripts/sync-skill.mjs generates the skill's vendored copies and restores the executable bit; npm run check:skill fails on drift.
  • README rewritten — who it's for, the integration, a comparison table, and install paths that were actually tested.
  • One documented path removed: npm 12 defaults allow-git=none, so npx -y github:RelayStack/astro-seo-toolkit … errors out (EALLOWGIT), and even with --allow-git=all the bin isn't exposed. Replaced with a git clone snippet that works.
  • CODE_OF_CONDUCT.md, CHANGELOG/CITATION 0.5.0, examples/astro on the integration, social card redesigned (docs/social-preview.png).

Verification

$ npm test          → 33/33 pass
$ npm run check:skill → in sync
$ npm pack && install tarball, then:
$ npx astro-seo-toolkit --dir content --site https://example.com --out dist
llms.txt, llms-full.txt, sitemap.xml, robots.txt written to dist (1 pages).
$ npx astro-seo-check --dir dist --site https://example.com
{ "ok": true, "issues": [] }

Held back

.github/workflows/test.yml (adds the check:skill step and a packaging smoke test that installs the tarball and invokes each bin) and a new .github/workflows/release.yml are not in this PR: the token used to push lacks the workflow scope, so GitHub rejects them. Run gh auth refresh -h github.com -s workflow and they can go in a follow-up.

Follow-up (not in this PR)

Publish 0.5.0 to npm so npx astro-seo-toolkit resolves from the registry. Requires npm login.

…gration (0.5.0)

The CLI guard compared import.meta.url against the basename of
process.argv[1]. npm installs bins as node_modules/.bin symlinks, so
argv[1] is the link (astro-seo-llms) while import.meta.url is the real
file (llms-txt.mjs) — the comparison never matched, so every bin and
`npm run` build hook exited 0 and generated nothing. Resolve argv[1]
with realpathSync + pathToFileURL instead, and cover it with a
regression test that executes a bin through a symlink, the way npm does.

Integration:
- astro-seo-toolkit/integration writes llms.txt, llms-full.txt,
  sitemap.xml and robots.txt during astro:build:done, from one or more
  content dirs (deduped by URL). Exposes generate/writeFiles/normalizeOptions.
- new bins: astro-seo-toolkit (every file at once), astro-seo-check.
- usage hints print the npx form.

Repo:
- scripts/sync-skill.mjs generates the skill's vendored copies and
  restores the executable bit; `npm run check:skill` fails on drift.
- README: who-it's-for, the integration section, a comparison table.
  Documents that npm 12 blocks `github:` specs (allow-git=none), so the
  old `npx -y github:RelayStack/...` snippet is replaced with a clone
  that actually runs.
- CHANGELOG/CITATION 0.5.0, CODE_OF_CONDUCT, CONTRIBUTING bin rule,
  SKILL.md integration flow, examples/astro on the integration,
  social card redesigned and exported to PNG.

tests: 33 (was 27)
Copilot AI balanced review requested due to automatic review settings October 16, 2026 12:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@RelayStack
RelayStack merged commit 08253e6 into main Oct 16, 2026
6 checks passed
@RelayStack
RelayStack deleted the feat/integration-and-bin-fix branch October 16, 2026 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants