Skip to content

🙈 chore(build): untrack dist/, keep publishing it - #52

Merged
vtempest merged 3 commits into
masterfrom
claude/serene-clarke-ibj8nc
Sep 11, 2026
Merged

🙈 chore(build): untrack dist/, keep publishing it#52
vtempest merged 3 commits into
masterfrom
claude/serene-clarke-ibj8nc

Conversation

@vtempest

Copy link
Copy Markdown
Collaborator

Hides dist/ from git while keeping it in every npm tarball.

The problem

dist was already listed in .gitignore, but 130 build artifacts were tracked anyway.gitignore has no effect on files git already follows. Worse, the committed bundle had gone stale: it predated a package reshuffle, so its .d.ts tree (dist/grab-api/*.d.ts) no longer matched the current source layout (dist/grab-api/src/*.d.ts). That stale bundle was masking the fact that npm run build has been failing on master.

What changed

Untracked (files stay on disk; only git stops following them):

Path Why
dist/ 87 root build artifacts
packages/archiver-web/dist/ 35 stale copies of the root build — contains grab-api, grab-url-cli, log, icons, nothing of archiver-web's
packages/quantum-sphere-loading-animation/dist/ 8 tsup outputs

Kept tracked: packages/native-app-wrapper/dist/index.html. It is not build output — it is the hand-written UI Tauri serves as frontendDist (src-tauri/tauri.conf.json), and its own comment says "no build step and no npm dependency". .gitignore re-includes that one directory.

Build fix (separate commit, required to make the above safe): packages/grab-url-cli/src/index.ts carried a duplicate export { … } from './transfer/ytdlp-transfer.js' block whose names were either already exported a few lines above or never existed at all. page/archive-page.ts imported that same never-written pair, so the --page video step could not have run. Implemented probeYtDlp(url) and runYtDlpDownload(url, opts) in ytdlp-transfer.ts under the names archive-page.ts and test/page-archive.test.ts already expect.

Why publishing still works

A files entry cannot be excluded by .gitignore or .npmignore — so npm pack still carries dist, and prepublishOnly rebuilds it beforehand. Also adds the missing prepublishOnly to quantum-sphere-loading-icon so a manual npm publish cannot ship without one.

Verification

  • rm -rf dist && npm run build → rebuilds clean; all 18 paths named by package.json's main/types/module/bin/exports resolve.
  • npm pack --dry-run91 files, identical to before (125 dist entries after the rebuild, up from the stale 87).
  • git status clean after a build — no dist noise.
  • npx vitest run343 passed / 11 failed, byte-identical to the master baseline (verified via a git worktree of HEAD). Those 11 failures are pre-existing and untouched here.

Left for a follow-up

master is red on npm test independently of this PR: test/page-archive.test.ts is written against a different yt-dlp module design than the one on disk — it expects parseYtDlpSize, parseYtDlpEta, a percent-bearing parseYtDlpProgress that parses yt-dlp's human console line, and buildYtDlpArgs({ filename }), whereas the module implements a --progress-template sentinel design with output. Reconciling those two is a design decision, not a build fix, so it is deliberately out of scope.

Worth noting: CI (tests.yml) runs only npm run test:coverage, never npm run build — which is how a broken build reached master unnoticed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01R3wkKQsRoi6k3DTvBRQhHd


Generated by Claude Code

`npm run build` has been failing on master. `packages/grab-url-cli/src/index.ts`
carried a second `export { … } from './transfer/ytdlp-transfer.js'` block whose
names were either already exported a few lines above or never existed at all
(`parseYtDlpSize`, `parseYtDlpEta`, `runYtDlpDownload`, `YtDlpMetadata`), so
esbuild rejected the duplicates and rollup then rejected the missing ones.

`page/archive-page.ts` imported that same never-written pair, so the `--page`
video step could not have run. Implement both in `ytdlp-transfer.ts` under the
names archive-page and `test/page-archive.test.ts` already expect:

- `probeYtDlp(url)` — a `--dump-single-json --skip-download` probe returning
  `YtDlpMetadata` or null, so an ordinary article skips the video step quietly.
- `runYtDlpDownload(url, opts)` — the quiet counterpart to `runYtDlpTransfer`,
  reporting saved paths from yt-dlp's own `after_move:filepath` print.

`findYtDlp` and `ytDlpInstallHint` are re-exported from `ytdlp-transfer` so
archive-page takes its whole yt-dlp surface from one module. The barrel keeps
exporting `ytdlp-binary`'s `probeYtDlp`, so the public API is unchanged.

CI runs only `test:coverage`, never `build`, which is how this reached master.

Test suite is unchanged at 343 passed / 11 failed — those 11 are a separate
pre-existing conflict between two yt-dlp progress-parsing designs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3wkKQsRoi6k3DTvBRQhHd
`dist` was already listed in .gitignore, but 130 build artifacts were tracked
anyway — gitignore does not apply to files git already follows. The committed
bundle had also gone stale: it predated a package reshuffle, so its `.d.ts`
tree no longer matched the source it claimed to come from, and it masked the
fact that `npm run build` was failing.

Untracks root `dist/`, `packages/archiver-web/dist/` (35 stale copies of the
root build, unrelated to that package) and
`packages/quantum-sphere-loading-animation/dist/`. The files stay on disk;
only git stops following them.

`packages/native-app-wrapper/dist/index.html` stays tracked — it is not build
output but the hand-written UI Tauri serves as `frontendDist`, so .gitignore
re-includes that one directory.

Publishing is unaffected: a `files` entry cannot be excluded by .gitignore, so
`npm pack` still carries dist, and `prepublishOnly` rebuilds it first. Verified
with `npm pack --dry-run` — the root tarball packs the same 91 files as before,
and all 18 paths named by package.json's main/types/module/bin/exports resolve
in a from-scratch build. Adds the missing `prepublishOnly` to
quantum-sphere-loading-icon so a manual publish cannot ship without one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R3wkKQsRoi6k3DTvBRQhHd
@vercel

vercel Bot commented Sep 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
grab-url Error Error Sep 11, 2026 2:22pm UTC

@codecov

codecov Bot commented Sep 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Collaborator Author

CI: Tests is red here, and it is red on master too

Not standing down quietly — here is the evidence and a proposed patch.

The check is failing on the base branch independently of this PR. Tests run #175 on master (18201a0, the merge of #50) is a failure, as is #173 on the merge of #49. I also ran the suite locally against a git worktree of the base commit and against this branch:

Tests
master baseline 343 passed / 11 failed
this branch 343 passed / 11 failed

Same 11, same names. This PR neither causes nor worsens them.

What the 11 failures actually are. test/page-archive.test.ts is written against a different generation of packages/grab-url-cli/src/transfer/ytdlp-transfer.ts than the one on disk — the --page feature (#49) landed with tests for one design while the module implements another:

The test expects The module implements
parseYtDlpSize('1.00KiB')1024 (does not exist)
parseYtDlpEta('01:02:03')3723 (does not exist)
parseYtDlpProgress() parses yt-dlp's human console line ([download] 23.4% of ~12.00MiB at 1.00MiB/s ETA 00:42) and returns a percent parses the @GRAB@ --progress-template sentinel and returns status / estimated / fragmentIndex
buildYtDlpArgs(url, { filename })'My Video.%(ext)s' takes output, used verbatim
describeYtDlpExit(1) === 'download failed' 'download failed — the media may be private, region-locked or removed'

Why I am not fixing it here. Nine of the eleven are additive and safe (parseYtDlpSize, parseYtDlpEta, accepting filename alongside output, shortening the exit string). The remaining two are not: parseYtDlpProgress cannot satisfy both designs at once, and the sentinel version is the one runYtDlpTransfer feeds its live progress bar from. Fixing nine leaves CI red anyway, so it buys nothing and widens a .gitignore PR into a rewrite of the downloader's progress path. Which design is canonical is a call for the repo owner, not something to decide inside this PR.

Proposed patch, for whoever picks it up. Keep the sentinel design — it is what production uses, and it is strictly more informative. Then:

  1. Add parseYtDlpSize / parseYtDlpEta as pure helpers (the tests fully specify them).
  2. Accept filename in YtDlpOptions as filename + '.%(ext)s', keeping output for the verbatim case.
  3. Update the parseYtDlpProgress tests to the sentinel format rather than the console format — the console-parsing API they describe is not reachable from any caller.
  4. Decide on the describeYtDlpExit(1) wording and align test and module.

This is not a flake, so I have not spent a re-run on it: a re-run would fail identically.

One thing this PR does fix: npm run build was also broken on master (duplicate and non-existent re-exports in grab-url-cli/src/index.ts, plus archive-page.ts importing a runYtDlpDownload that was never written). That is repaired in 596d7b1 and the build is green. It went unnoticed because tests.yml runs only npm run test:coverage and never npm run build — worth adding a build step to CI in a follow-up.

Vercel is a separate known issue: the project's Root Directory is still docs, a folder #47 deleted, so every deployment fails at clone. That is a dashboard setting, already documented in .claude/architecture/documentation.md by #51 — nothing in this diff affects it.


Generated by Claude Code

@vtempest
vtempest merged commit 0217a98 into master Sep 11, 2026
2 of 4 checks passed
@vtempest
vtempest deleted the claude/serene-clarke-ibj8nc branch September 11, 2026 14:45
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