The 43-case mock smoke duplicated tests/cli.rs, which already runs the
real binary against fixture providers. Replace the flake's smoke-mock
check with a small packaged-cli check (version JSON, bash completions,
one mock quote), and cut scripts/live-smoke.sh from 672 to ~170 lines:
it now only runs shipped commands against live MSN/Yahoo/IDX and
validates output shape. Rewrite docs/SMOKE.md around the Nix gate and
the drift check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Run deterministic installer and publisher checks in Nix, align dev and release dependency artifacts, narrow derivation inputs, and use content-aware CI cache keys. Replace duplicate Cargo gates with a Nix pre-push gate; validate JSON streams and cache data in representative packaged-binary smoke cases.
Move fmt, clippy, tests, cargo package verification and the offline mock
smoke into flake checks built with crane, so the crate dependency build is
its own derivation that is reused until Cargo.lock changes. CI runs a single
nix flake check and restores /nix/store from the GitHub Actions cache via
nix-community/cache-nix-action, replacing the rustup + cargo test job.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013cfWL2GVg97oLfkNvPLaci
Addresses review on #29:
- drop errtrace: a failure inside $(...) printed two RESULT lines
- explicit failures go through fail(), which always prints
RESULT: FAILED stage=...; idx check gets its own `preflight` stage;
the never-failing published-manifest read is no longer a stage
- validate the built latest_as_of_date (`// empty` + date regex) so a
corrupt manifest cannot compare as "newer"
- freshness: validate --now (exit 2) and latest_as_of_date (exit 3)
before calling date
- flake: package an explicit script list instead of scripts/*.sh
- docs: GH_TOKEN prerequisite for the packaged publisher
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017a5Cv5Z1NzdYKgKnTiAF4E
The self-hosted publish timer has not produced an upload since it was
enabled (manifest last updated 2026-07-14, a manual run), and failures
were invisible. Make the job safe to run daily and easy to deploy:
- publish-ownership-snapshot.sh: skip the upload when the published
manifest already has the latest as-of date (pre-check via discover
for XLSX sources, post-build check for legacy PDF); --force to
override. Always ends with one line: RESULT: published|up-to-date
<as-of> or RESULT: FAILED stage=<stage> (exit N). gh release create
no longer requires a git checkout.
- check-ownership-snapshot-freshness.sh: exit 1 when the published
latest_as_of_date is older than --max-age-days (default 40).
- flake: packages.ownership-publisher bundles the scripts with a
pinned idx (curl-impersonate + mupdf) and jq/gh/sqlite/curl as
bin/idx-ownership-publish and bin/idx-ownership-freshness, so hosts
need no checkout, nix develop or cargo build at run time. Built in CI.
- contrib/systemd + docs: daily 06:00 UTC timer, run semantics table,
freshness alarm, packaged usage.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017a5Cv5Z1NzdYKgKnTiAF4E
Add an npm wrapper (package.json + postinstall downloader) so the Rust
binary can be installed via npm/npx. Include a local smoke test, a GitHub
Release cross-compile workflow, and nodejs in the dev shell.
- package.json: idx-cli v0.2.3, bin idx, engines node>=16
- scripts/install.js: dependency-free postinstall that downloads the
platform-specific GitHub Release asset (or IDX_BINARY_URL override)
- scripts/idx.js: binary launcher preserving exit codes/signals
- scripts/npm-smoke.sh: npm pack -> install tarball -> run idx --help
and idx config --help, locale, no publish required
- .github/workflows/release.yml: cross-compile linux-x64/arm64 and
darwin-arm64 releases and attach binaries to the version tag
- flake.nix: add nodejs_22 to the dev shell
- docs/NPM_DISTRIBUTION.md: usage, local test, and release flow
Yahoo Finance blocks standard ureq/rustls via TLS fingerprinting (JA3/JA4).
Reverse-engineered from yfinance source: they use curl_cffi with Chrome impersonation.
Fix:
- Fetch cookie via curl-impersonate from fc.yahoo.com
- Fetch crumb via curl-impersonate from query1.finance.yahoo.com/v1/test/getcrumb
(correct URL: getcrumb, not getCrumb or csrfToken)
- Parse Netscape cookie jar format, send cookies as header to quoteSummary
- 401 retry: clear crumb + cookie jar, re-auth on next attempt
- Crumb validation: reject HTML, empty, rate-limit responses
- Add curl-impersonate-chrome to flake.nix devShell
- rust-overlay for stable toolchain + rust-src + rust-analyzer
- pkg-config, openssl, sqlite for reqwest + ownership DB
- cargo-watch, cargo-nextest for dev workflow
- direnv integration via .envrc