Kanban Board
Interactive task board with drag-and-drop. Create, organize, and share your boards via URL.
Ideas
5Draft plans and attach them, then move to To Do
To Do
0Planned tasks ready to start
In Progress
0In Review
0Change Log
77restore prerendered deploys for indexed routes
restore prerendered deploys for indexed routes
migrate to lucide-react 1.x
* deps(deps): bump lucide-react from 0.563.0 to 1.8.0 Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 0.563.0 to 1.8.0. - [Release notes](https://github.com/lucide-icons/lucide/releases) - [Commits](https://github.com/lucide-icons/lucide/commits/1.8.0/packages/lucide-react) --- updated-dependencies: - dependency-name: lucide-react dependency-version: 1.8.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> * fix(deps): migrate to lucide-react 1.x Lucide 1.x dropped brand icons (no Linkedin) and made LucideIcon type-only. This bundles the major bump with the source-side fixes so the dependabot PR #292 can be replaced cleanly. - Add src/components/icons/LinkedinIcon.tsx as a small inline-SVG component matching the GitHubMark pattern. Uses currentColor so it inherits text color the same way the lucide icon did. - Switch HeroSection and ContactSection to import LinkedinIcon instead of Linkedin from lucide-react. - Fix the value-import of LucideIcon in MetricCard.tsx — it's a type now, not a runtime export. All 215 tests pass; typecheck clean. Closes #292 Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
Blog: Two Supply Chain Attacks in One Day (and a Setting I Used to Argue Against)
Lightning on PyPI and intercom-client on npm got compromised the same morning by what looks like the same attacker. We weren't exposed, but the threat shape changed enough that I walked back a position I took a month ago.
refactor Search Console fetch and add summary-only mode
- Split Search Console query into two calls: an authoritative no-dimension summary and a dimensional rows fetch. Previously the summary was derived by summing rows, which under-counted clicks/ impressions because the row response is capped and aggregated by (query, page) — a single page can split across many rows. - Replace ad-hoc reductions with summarizeRows / aggregateRows / weightedAveragePosition helpers; impression-weighted positions replace simple averages. - Make the daily history write idempotent (update existing date entry instead of appending a duplicate). - Add --update-summary-only mode that re-reads the latest history entry and rewrites docs/metrics/latest.json, preserving the original timestamp. The daily workflow now invokes this after fetch-ga4-data.js so the GA4 step's latest.json overwrite doesn't drop fresh Search Console numbers. - updateMetricsSummary now takes a lastCheck override so the summary- only path doesn't bump the timestamp to "now". Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
make Blog the first and default tab
Reorders ANALYTICS_TABS so Blog is first and sets it as the initial activeTab. Also fixes the Search CTR display (averageCTR is already a percentage; the extra *100 was double-scaling it). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
add preinstall guard section
Documents the npm install blocker that forces npm ci usage, closing the gap between having a lockfile and actually using it. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
fix quarantine section — min-release-age not enforced in npm 11
npm warns "Unknown user config" for min-release-age, so it's not actually protecting anything. Kept uv exclude-newer (which works) and noted npm doesn't have an equivalent yet. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>