feat(core): add configurable tagging scope for HTML vs React Components#24
feat(core): add configurable tagging scope for HTML vs React Components#24konard wants to merge 9 commits intoProverCoderAI:mainfrom
Conversation
Adding CLAUDE.md with task information for AI processing. This file will be removed when the task is complete. Issue: ProverCoderAI#23
Implement tagComponents option to control whether React Components (PascalCase)
are tagged in addition to HTML elements (lowercase).
Core changes:
- Add isHtmlTag() pure function to classify HTML vs Component elements
- Add shouldTagElement() predicate for configurable tagging logic
- Update processJsxElement() to respect tagComponents configuration
- Add JsxTaggerOptions type with tagComponents?: boolean | undefined
Shell changes:
- Extend Babel plugin options with tagComponents parameter
- Extend Vite plugin to accept tagComponents configuration
- Propagate options through context to core tagging logic
Tests:
- Add comprehensive unit tests for isHtmlTag() classification
- Add unit tests for shouldTagElement() with various configurations
- Add unit tests for processJsxElement() with tagComponents variations
- Update E2E tests (Vite + Next.js) to verify both HTML and Component tagging
- Add CustomComponent to test apps for integration testing
Documentation:
- Update README with configuration examples and formal specification
- Add mathematical theorems for tagging predicates
- Document invariants: HTML always tagged, Components configurable
- Add usage examples for both tagComponents: true/false modes
Default behavior: tagComponents = true (tag everything)
Mathematical model: ∀ html ∈ HTML: shouldTag(html, _) = true
∀ comp ∈ Component: shouldTag(comp, opts) = opts.tagComponents ?? true
Closes ProverCoderAI#23
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
CI Status ReportSummary: Implementation is complete and functionally correct. One non-blocking warning exists in test linting. ✅ Passing Checks
|
This reverts commit 3d6031c.
🤖 Solution Draft LogThis log file contains the complete execution trace of the AI solution draft process. 💰 Cost estimation:
Now working session is ended, feel free to review and add any feedback on the solution draft. |
|
Исправь конфликты |
|
🤖 AI Work Session Started Starting automated work session at 2026-02-05T09:26:06.898Z The PR has been converted to draft mode while work is in progress. This comment marks the beginning of an AI work session. Please wait for the session to finish, and provide your feedback. |
Integrate both attributeName (issue-14) and tagComponents (issue-23) features. Main branch changes integrated: - Renamed attribute from "path" to "data-path" (breaking change) - Added attributeName option to customize attribute name - Added normalizeModuleId() function for query parameter stripping - Updated all tests to use "data-path" attribute Issue-23 changes preserved: - Added tagComponents option to control tagging scope - Added isHtmlTag() function to classify HTML vs React Components - Added shouldTagElement() predicate for configurable tagging - Default behavior: tag everything (tagComponents: true) - HTML elements always tagged regardless of tagComponents setting Architecture: - JsxTaggerContext now includes: relativeFilename, attributeName, options - ComponentTaggerOptions (Vite) includes: attributeName, tagComponents - ComponentTaggerBabelPluginOptions includes: rootDir, attributeName, tagComponents - Both options extend JsxTaggerOptions for consistency Tests updated: - All integration tests now check for "data-path" attribute - Added unit tests for isHtmlTag() classification - Added unit tests for normalizeModuleId() - E2E tests verify both HTML and Component tagging Documentation updated: - README includes both features with examples - Clear usage guide for attributeName and tagComponents options - Behavior guarantees documented Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
All processJsxElement tests now include attributeName property in JsxTaggerContext. Updated expected attribute name from 'path' to 'data-path' to match new default. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
🤖 Solution Draft LogThis log file contains the complete execution trace of the AI solution draft process. 💰 Cost estimation:
Now working session is ended, feel free to review and add any feedback on the solution draft. |
|
Исправь все линтеры и тесты |
|
🤖 AI Work Session Started Starting automated work session at 2026-02-05T09:44:31.541Z The PR has been converted to draft mode while work is in progress. This comment marks the beginning of an AI work session. Please wait for the session to finish, and provide your feedback. |
- Extract getRootDir() and extractOptions() helpers to reduce cyclomatic complexity in babel-plugin.ts from 9 to under 8 - Add test helper functions (createTestComponents, createNamespacedElement, createTestContext, assertProcessResult) to eliminate code duplication in test files - Fix ESLint complexity error: babel-plugin.ts:62:74 - Fix jscpd duplicate code detection in jsx-tagger.test.ts WHY: ESLint enforces maximum complexity of 8 for maintainability. Test code duplication was flagged by jscpd linter. REF: PR ProverCoderAI#24 CI failures (Lint and Test jobs) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
✅ CI Fixes AppliedAll linter and test failures have been resolved: 🔧 Lint Error FixedIssue: Arrow function complexity of 9 exceeded maximum allowed (8) in Solution: Extracted helper functions to reduce cyclomatic complexity:
Files: 🧪 Test Duplicates FixedIssue: 6 duplicate code blocks detected in test file by jscpd linter Solution: Created reusable test helper functions:
Files: ✅ VerificationLocal Tests: ✅ All 30 tests passing CI Status: ✅ All 8 checks passing
Commit: 53520af The pull request is now ready for final review and merge. 🤖 Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com |
🤖 Solution Draft LogThis log file contains the complete execution trace of the AI solution draft process. 💰 Cost estimation:
Now working session is ended, feel free to review and add any feedback on the solution draft. |
🔄 Auto-restart 1/3Detected uncommitted changes from previous run. Starting new session to review and commit them. Uncommitted files: Auto-restart will stop after changes are committed or after 2 more iterations. Please wait until working session will end and give your feedback. |
✅ Auto-restart CompleteAll uncommitted changes have been cleaned up. The PR is ready for review. 📊 Final StatusWorking Tree: ✅ Clean (all temporary log files removed) Local CI Checks: ✅ Passing
GitHub CI Checks: ✅ All 8 checks passing
Branch Status: ✅ Up-to-date with main (no conflicts) Latest Commit: 53520af - "fix(lint): reduce complexity and eliminate test duplicates" 🎯 Implementation Summary✅ Configurable tagging scope implemented ( The pull request is ready for final review and merge. 🤖 Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com |
|
Исправь конфликты |
🔄 Auto-restart 1/3 LogThis log file contains the complete execution trace of the AI solution draft process. 💰 Cost estimation:
Now working session is ended, feel free to review and add any feedback on the solution draft. |
|
🤖 AI Work Session Started Starting automated work session at 2026-02-05T09:57:27.151Z The PR has been converted to draft mode while work is in progress. This comment marks the beginning of an AI work session. Please wait for the session to finish, and provide your feedback. |
Resolve conflicts from main branch updates: - Import babelPluginName constant from component-path.ts - Merge test files to include both base tests and new shouldTagElement tests - Keep JsxTaggerOptions type in imports for configurable tagging - Preserve options parameter in makeBabelTagger function Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Split jsx-tagger.test.ts into two files to stay under 300-line limit: - jsx-tagger.test.ts: Core tests for attrExists, createPathAttribute, processJsxElement - jsx-tagger-scoping.test.ts: Tests for configurable tagging scope (issue ProverCoderAI#23) Move shared test helpers to jsx-test-fixtures.ts to eliminate duplication. Note: Minor test setup duplicates (5-6 lines) are acceptable test patterns. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
✅ Merge Conflicts ResolvedSuccessfully merged Changes Made
CI StatusRunning checks for merge commit
The small test duplicates (5-6 lines of fixture setup) are standard testing patterns and do not affect code quality. 🤖 Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com |
Move test helper functions to module scope and consolidate similar test cases using parametrized helpers: - `testComponentTagging`: Tests component tagging with different options - `testProcessing`: Tests processJsxElement integration This eliminates all code duplication detected by jscpd linter. Test Results: - ✅ 64 tests passing (7 test files) - ✅ 0 code duplicates found - ✅ 0 lint errors Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
✅ All CI Checks PassingSuccessfully resolved all issues and CI is now passing for commit Final StatusCI Checks: ✅ All 3 workflows passing
Local Validation:
Changes Summary
The PR is ready for final review and merge. 🤖 Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com |
🤖 Solution Draft LogThis log file contains the complete execution trace of the AI solution draft process. 💰 Cost estimation:
Now working session is ended, feel free to review and add any feedback on the solution draft. |
🎯 Issue Reference
Fixes #23
📋 Summary
Implements configurable JSX tagging scope through the
tagComponentsoption, allowing users to control whether React Components (PascalCase elements) are tagged in addition to HTML elements (lowercase tags).Default Behavior: Tag everything (both HTML and Components), as requested in issue comments.
🔬 Mathematical Specification
Formal Model
Mathematical Guarantees
Invariants
∀ html ∈ HTML: shouldTag(html, _) = true
All HTML elements are always tagged, regardless of configuration
∀ comp ∈ Component: shouldTag(comp, {tagComponents: false}) = false
React Components are skipped when tagComponents is false
∀ comp ∈ Component: shouldTag(comp, {tagComponents: true}) = true
React Components are tagged when tagComponents is true
∀ comp ∈ Component: shouldTag(comp, undefined) = true
React Components are tagged by default (no configuration)
∀ elem ∈ JSX: processElement(elem, ctx) → idempotent
Processing an element twice produces the same result (no duplicate attributes)
Preconditions
elementName.length > 0(non-empty element names)node.loc !== null(elements must have location info)options.tagComponents ∈ {true, false, undefined}(valid configuration)Postconditions
∀ tagged_element: hasAttribute(tagged_element, "path")path_format = relativeFilename:line:columnwhereline ≥ 1 ∧ column ≥ 0∀ element: |{attr ∈ element.attributes | attr.name = "path"}| ≤ 1(at most one path attribute)Complexity Analysis
O(1)time,O(1)spaceO(1)time,O(1)spaceO(n)time wheren = |existing attributes|,O(1)space🏗️ Implementation Architecture
CORE (Pure Functions)
isHtmlTag(name: string): booleanPurity: ✅ Pure
Effect: None
Theorem:
∀ name: isHtmlTag(name) ↔ name[0] ∈ [a-z]Complexity:
O(1)/O(1)Classifies JSX element names as HTML tags (lowercase) vs React Components (PascalCase).
shouldTagElement(node, options, types): booleanPurity: ✅ Pure
Effect: None
Theorem:
∀ elem, opts: shouldTag(elem, opts) = isHtml(elem) ∨ (opts.tagComponents ≠ false)Complexity:
O(1)/O(1)Determines whether an element should be tagged based on configuration.
processJsxElement(node, context, types): booleanPurity: ❌ Impure (mutates AST)
Effect: AST mutation
Theorem:
∀ elem: processElement(elem, ctx) → tagged(elem) ∨ skipped(elem)Complexity:
O(n)/O(1)wheren = |attributes|Applies path attribute to eligible JSX elements, respecting configuration.
SHELL (Effectful Layer)
Babel Plugin
Propagates configuration through Babel state to core logic.
Vite Plugin
Accepts configuration and passes it through transform pipeline.
✅ Testing Coverage
Unit Tests (23 tests, all passing)
isHtmlTagClassificationdiv,h1,span)MyComponent,Route)shouldTagElementPredicatetagComponents: truetagComponents: falseFoo.Bar)svg:path)processJsxElementIntegrationtagComponents: truetagComponents: falseIntegration Tests (E2E with Playwright)
Vite Plugin (
packages/frontend)<h1>,<p>,<main>)<CustomComponent>) by defaultBabel Plugin (
packages/frontend-nextjs)📁 Files Changed
Core Logic
src/core/component-path.ts: AddisHtmlTag()pure functionsrc/core/jsx-tagger.ts: AddJsxTaggerOptions,shouldTagElement(), updateprocessJsxElement()src/index.ts: Export new types and functionsShell Layer
src/shell/babel-plugin.ts: AddtagComponentsto options, propagate through contextsrc/shell/component-tagger.ts: AccepttagComponentsoption in Vite pluginTests
tests/core/component-path.test.ts: Add 6 tests forisHtmlTag()tests/core/jsx-tagger.test.ts: Add 14 new tests for configurable taggingtests/packaging/entrypoints.test.ts: Unchanged (validates exports)Integration Tests
packages/frontend/src/App.tsx: AddCustomComponentfor testingpackages/frontend/tests/component-path.spec.ts: Add Component tagging testspackages/frontend-nextjs/app/page.tsx: AddCustomComponentfor testingpackages/frontend-nextjs/tests/component-path.spec.ts: Add Component tagging testsDocumentation
README.md: Add comprehensive documentation with mathematical specs, configuration examples, and usage guide🔄 Migration Guide
Breaking Changes
None. Default behavior tags everything, maintaining backward compatibility.
Configuration Examples
Tag Everything (Default)
Tag HTML Only
🧪 Verification Steps
🤖 AI Implementation Notes
This solution was implemented following strict functional programming principles:
exactOptionalPropertyTypes🤖 Generated with Claude Sonnet 4.5
Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com