Release @tpmjs/createblogpost v0.2.0 with initial features:
- Creates structured blog posts with frontmatter and metadata
- Supports both Markdown and MDX output formats
- Automatic slug generation, word count, and reading time calculation
- Rich TPMJS metadata for NPM registry discovery
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add test tool package to verify sync system can discover and process tools:
Package Features:
- Creates structured blog posts with frontmatter and metadata
- Supports both Markdown and MDX output formats
- Automatic slug generation from title
- Word count and reading time calculation
- SEO-friendly metadata generation
TPMJS Integration:
- Rich-tier tpmjs field with all optional metadata
- Tagged with 'tpmjs-tool' keyword for NPM discovery
- Complete parameter and return type documentation
- AI agent guidance for optimal LLM usage
- Pricing, authentication, and framework metadata
Implementation:
- Full TypeScript implementation with exported types
- Proper tsconfig and tsup build configuration
- Comprehensive README with usage examples
- Changeset for publishing workflow
- Added packages/tools/* to pnpm workspace
This package serves as an end-to-end test of the sync workers to verify:
1. NPM keyword search discovers the package
2. Changes feed picks up updates
3. tpmjs field validation works correctly
4. Rich-tier metadata is properly extracted
5. Quality score calculation functions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add complete sync worker system for NPM package discovery and metrics:
**Sync Workers:**
- Changes Feed Sync (/api/sync/changes) - Polls NPM changes every 2 min
- Keyword Search Sync (/api/sync/keyword) - Searches tpmjs-tool keyword every 15 min
- Metrics Sync (/api/sync/metrics) - Updates downloads & quality scores hourly
**Features:**
- Secure CRON_SECRET authentication for all sync endpoints
- Comprehensive error handling with sync logs and checkpoints
- Smart package validation and filtering (skip invalid tpmjs fields)
- Automatic tool upsert with discovery method tracking
- Quality score calculation based on tier, downloads, and GitHub stars
- 5-minute timeout support for long-running sync operations
**Dependencies:**
- Add @tpmjs/npm-client to web app for NPM API integration
- Use barrel exports from npm-client package (no subpath imports)
- Add CRON_SECRET env variable validation
- Add ~/src path alias to tsconfig
**Infrastructure:**
- Configure Vercel Cron jobs in vercel.json for automated syncing
- Add publishedAt field to PackageVersion schema
- Fix Prisma JSON field handling (use undefined instead of null)
- Proper null checks for fetchLatestPackageVersion return values
**Type Safety:**
- Cast TpmjsField union type to access optional rich-tier properties
- Handle searchByKeyword array return type correctly
- Fix fetchDownloadStats to return number directly
All API routes follow Next.js 16 conventions with proper type checking.
Type-check and full build successful.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Implement changes feed client for real-time package discovery
- Implement keyword search with auto-pagination support
- Implement package metadata fetcher with tpmjs field extraction
- Implement download statistics client for quality scoring
- Implement rate limiter with configurable concurrency and delays
- Implement retry logic with exponential backoff for 429 errors
All API responses validated with Zod schemas for type safety.
Rate limiter defaults: max 10 concurrent, 100ms minimum delay.
Handles scoped packages (@scope/name) correctly.
Graceful 404 handling returns null instead of throwing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add @tpmjs/db package with Prisma ORM setup
- Define Tool model with NPM metadata and TPMJS fields
- Define SyncCheckpoint model for tracking sync worker progress
- Define SyncLog model for audit trail of sync operations
- Add Prisma client singleton with dev logging
- Add seed script for initializing sync checkpoints
- Include comprehensive README with setup instructions
Package includes:
- Complete Prisma schema matching NPM_MIRROR.md spec
- Three models: Tool, SyncCheckpoint, SyncLog
- Indexes for performance on key fields
- TypeScript support via @tpmjs/tsconfig
- Scripts for db:migrate, db:push, db:studio, db:seed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Convert all SVG fill/stroke from Tailwind classes to direct attributes
- Use hsl(var(--css-custom-property)) for theme compatibility
- Add explicit fontSize, fontFamily, fontWeight instead of text-* classes
- Fixes text visibility issue where labels appeared as black rectangles
Resolves rendering bug where SVG text elements weren't displaying properly
due to improper CSS class application on SVG elements.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove SSR check from useRadioGroup hook that caused hydration mismatch
- Always return default values when context is null (SSR + hydration)
- Add useEffect in Radio component to validate context after hydration
- Dev-only warning instead of runtime error during hydration
Fixes "Radio must be used within a RadioGroup" error on playground page
during React hydration. The issue was that during hydration, the context
wasn't available yet even though components were properly wrapped.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fixed SSR detection: only return defaults when `window === undefined` (SSR)
- Previous version had inverted logic that threw errors in browser
- Maintains runtime validation in browser while allowing SSR builds
- Fixes Next.js build failures and browser errors on playground page
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove SSR workaround from useRadioGroup hook
- Context error was throwing in browser even when Radio was inside RadioGroup
- The playground page already uses dynamic rendering, so SSR workaround not needed
- All 58 Radio tests still pass
Fixes "Radio must be used within a RadioGroup" error on playground page.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Format 18 files with Biome
- Fix array formatting and line breaks in variants and test files
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update useRadioGroup hook to return default values during SSR/prerendering
- Still throws error in browser and test environments when Radio is outside RadioGroup
- Add dynamic='force-dynamic' export to playground page
- Fixes Next.js build error: "Radio must be used within a RadioGroup"
All tests pass (58 Radio tests), including the test that validates the error is thrown.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add RadioGroup.tsx to tsup entry points (was missing from build)
- Fix HTMLTextareaElement casing in Textarea tests (should be HTMLTextAreaElement)
- Remove unused variables in test files (user, container)
Fixes CI type-check and build failures.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Set NODE_OPTIONS='--max-old-space-size=4096' in build script
- Prevents "JS heap out of memory" during TypeScript declaration generation
- CI was failing when building 20+ components simultaneously
- Also simplified tsup DTS config (removed composite false workaround)
Fixes GitHub Actions build failures for @tpmjs/ui package.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented 8 production-ready form components with full accessibility:
Components Added:
- Textarea: Multi-line text input with character counter
- Checkbox: Custom styled with indeterminate state support
- Radio & RadioGroup: Context-based radio button groups
- Switch: Toggle with animated thumb and loading state
- Select: Native select with custom styling and option groups
- Slider: Range input with marks, value display, cross-browser support
- FormField: Wrapper component with label, error, and helper text
Features:
- Full accessibility (ARIA attributes, semantic HTML)
- Controlled/uncontrolled patterns via useControlled hook
- Dark mode support with semantic tokens
- Design tokens and shared variant system
- Comprehensive test coverage (856 tests passing)
- Form-specific design tokens (formTokens)
- Shared form variant base classes (formVariants)
Playground Updates:
- Added comprehensive Forms section showcasing all components
- Interactive examples with state management
- Complete form composition example
- All components fully functional and themed
Test Coverage:
- 10+ describe blocks per component
- All edge cases covered
- Accessibility testing
- Cross-browser compatibility
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add **/next-env.d.ts to Biome ignore list
- Next.js generates this file with double quotes, conflicts with single quote config
- This is an auto-generated file that should not be manually formatted
Fixes format-check CI failures.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add root biome.json that extends packages/config/biome.json
- Add explicit ignore patterns for dist/, build/, .next/, .turbo/, etc.
- Make a11y lints warnings instead of errors (non-blocking)
- Remove invalid biome-ignore comment from Section.tsx
- Apply formatting to all source files (155 files checked, 129 fixed)
This fixes the CI format check that was failing with 2064+ errors
because Biome was checking generated files in dist/ and .turbo/.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove root biome.json (conflicted with packages/config/biome.json)
- Format all files with correct config (spaces, not tabs)
- Restore non-null assertions (ref!) in test files where refs are guaranteed
- Biome's optional chaining conversion broke TypeScript inference in tests
Fixes type-check and format-check CI failures.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added biome-ignore and eslint-disable-next-line comments inline on the
ref prop to properly suppress the any type warnings. Polymorphic component
requires any for proper ref forwarding across dynamic component types.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Packages/apps that run `eslint .` need eslint installed as a
devDependency. While eslint is in @tpmjs/eslint-config, it needs to
be available in the local node_modules/.bin for the lint script to run.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add type-coverage, knip, and dependency-cruiser for code quality
- Set up Node 22 (LTS) with .nvmrc file
- Configure knip for dead code detection across monorepo
- Configure dependency-cruiser with sensible architecture rules
- Add ts-reset for better TypeScript built-in types
- Fix Tabs component type exports for Storybook
- Recreate eslint react.js config that was missing
- Add quality gates documentation
All quality checks pass with 0 errors (only informational warnings).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add "type": "module" to @tpmjs/eslint-config package.json for ES module support
- Rename eslint.config.js to eslint.config.mjs in apps/web and packages/ui
- Update ESLint configs to ignore build directories (.next, dist, .turbo)
- Extend import/no-internal-modules allowlist for Next.js, testing libs, and React
- Fix unescaped quotes in playground page code elements
- Convert CardDescriptionProps from empty interface to type alias
- Disable jsx-a11y/no-autofocus rule in test files
- Change web app lint script from 'next lint' to 'eslint .'
- Fix TypeScript ref type inference errors in UI package tests by using non-null assertions
- Disable Biome noNonNullAssertion rule for test files
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace Geist fonts with Space Grotesk + Space Mono via next/font/google
- Make dotted borders default for all card variants (default, elevated, outline)
- Add blueprint grid backgrounds to homepage sections and playground
- Create Section layout component with flexible semantic elements and spacing variants
- Create GridContainer component with auto-fit/auto-fill responsive grid support
- Add blueprint variants to Tabs and Button components (dotted borders)
- Add editorial typography tokens (line-heights, letter-spacing) to Tailwind config
- Add spacing tokens for airy editorial layouts
- Add shadow utilities for blueprint aesthetic (shadow-blueprint, shadow-blueprint-hover)
- Update 59 component tests for new variants and styling
- All 429 tests passing, zero hardcoded colors, fully themeable
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Convert Button, Card, CodeBlock, Container, Input, Label, ProgressBar, Tabs, and Header components to JSX
- Convert all test files to JSX syntax with direct element rendering
- Replace createElement calls with cleaner JSX syntax for better readability
- Update tsup config to handle .tsx files
- Maintain all functionality, accessibility, and TypeScript types
- All 370 tests passing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Convert Icon component from createElement to JSX (Icon.tsx)
- Convert Icon tests to JSX (24 tests passing)
- Convert Icon stories to JSX (Icon.stories.tsx)
- Convert Badge component from createElement to JSX (Badge.tsx)
- Convert Badge tests to JSX (34 tests passing)
- Rename files from .ts to .tsx
- Remove createElement imports, use native JSX syntax
- All tests passing (58/58)
Part of broader effort to convert entire codebase from createElement to JSX.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add @testing-library/jest-dom as dev dependency
- Create test-setup.ts to import jest-dom matchers
- Configure Vitest to use setup file
- All UI package tests now passing
Fixes test failures with toHaveTextContent and other DOM matchers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>