Skip to content

refactor: extract duplicate string literals to constants#301

Merged
sjnims merged 3 commits intomainfrom
refactor/299-extract-duplicate-string-literals
Jan 19, 2026
Merged

refactor: extract duplicate string literals to constants#301
sjnims merged 3 commits intomainfrom
refactor/299-extract-duplicate-string-literals

Conversation

@sjnims
Copy link
Copy Markdown
Owner

@sjnims sjnims commented Jan 19, 2026

Description

Extract duplicated string literals to named constants to improve maintainability and enable single-source-of-truth updates. This resolves all 5 sonarjs/no-duplicate-string ESLint warnings reported in the issue.

Type of Change

  • Refactoring (code change that neither fixes a bug nor adds a feature)

Component(s) Affected

Pipeline Stages

  • Stage 3: Execution (src/stages/3-execution/)

Core Infrastructure

  • CLI (src/cli/)
  • Configuration (src/config/)

Other

  • Tests (tests/)
  • Documentation (CLAUDE.md, README.md)
  • Configuration files (config.yaml, eslint.config.js, tsconfig.json, etc.)
  • GitHub templates/workflows (.github/)
  • Other (please specify):

Motivation and Context

ESLint reported 5 warnings for duplicate string literals that should be extracted to constants. This improves:

  • Maintainability: Single source of truth for repeated values
  • Refactoring safety: Change in one place affects all usages
  • Code clarity: Named constants are self-documenting

Fixes #299

Changes Made

File Change
src/cli/commands/resume.ts Extract "Resume complete!" to RESUME_COMPLETE_MESSAGE constant
src/config/models.ts Export MODEL_OPUS_4_5, MODEL_SONNET_4_5, MODEL_HAIKU_4_5 constants for default model IDs
src/config/defaults.ts Use exported model constants from models.ts
src/config/schema.ts Use exported model constants from models.ts
src/stages/3-execution/plugin-loader.ts Extract "needs-auth" to MCP_STATUS_NEEDS_AUTH constant

How Has This Been Tested?

Test Configuration:

  • Node.js version: v25.3.0
  • OS: macOS Darwin 25.2.0

Test Steps:

  1. npm run lint - Verified all 5 duplicate string warnings are resolved ✅
  2. npm run typecheck - TypeScript compilation passes ✅
  3. npm run format - Code formatting is consistent ✅
  4. npm run knip - No dead code detected ✅
  5. npm run madge - No circular dependencies ✅
  6. npm test - All 1556 tests pass ✅

Checklist

General

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings or errors

TypeScript / Code Quality

  • All functions have explicit return types
  • Strict TypeScript checks pass (npm run typecheck)
  • ESM import/export patterns used correctly
  • Unused parameters prefixed with _
  • No any types without justification

Documentation

  • I have updated CLAUDE.md if behavior or commands changed (N/A - no behavior change)
  • I have updated inline JSDoc comments where applicable
  • I have verified all links work correctly

Linting

  • I have run npm run lint and fixed all issues
  • I have run npm run format:check
  • I have run markdownlint "*.md" on Markdown files (N/A - no markdown changes)
  • I have run uvx yamllint -c .yamllint.yml on YAML files (N/A - no YAML changes)
  • I have run actionlint on workflow files (N/A - no workflow changes)

Testing

  • I have run npm test and all tests pass
  • I have added tests for new functionality (N/A - refactoring only)
  • Test coverage meets thresholds (78% lines, 75% functions, 65% branches)
  • I have tested with a sample plugin (N/A - no execution behavior change)

Reviewer Notes

Areas that need special attention:

  • The model ID constants are now exported from models.ts and imported by defaults.ts and schema.ts. This creates a single source of truth for default model versions.

Known limitations or trade-offs:

  • pricing.ts and batch-calculator.ts still use raw model ID strings as object keys. The sonarjs/no-duplicate-string rule only flagged duplicates within the same file, so these were not modified.

🤖 Generated with Claude Code

sjnims and others added 2 commits January 19, 2026 05:19
- Add SDK Integration section explaining the two Anthropic SDKs
- Document detection confidence levels for programmatic detection
- Add jscpd, madge, and clean commands to command reference
- Fix type guards file path reference (now in detection/ directory)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Extract duplicated string literals to named constants to improve
maintainability and enable single-source-of-truth updates.

Changes:
- resume.ts: Extract "Resume complete!" to RESUME_COMPLETE_MESSAGE
- models.ts: Export MODEL_OPUS_4_5, MODEL_SONNET_4_5, MODEL_HAIKU_4_5
  constants for default model IDs
- defaults.ts: Use exported model constants from models.ts
- schema.ts: Use exported model constants from models.ts
- plugin-loader.ts: Extract "needs-auth" to MCP_STATUS_NEEDS_AUTH

This resolves all 5 sonarjs/no-duplicate-string ESLint warnings and
establishes model ID constants as the single source of truth for
default model versions across the codebase.

Fixes #299

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@claude
Copy link
Copy Markdown
Contributor

claude bot commented Jan 19, 2026

Claude finished @sjnims's task in 1m 42s —— View job


Code Review Complete ✅

Quality Checks

All quality checks pass successfully:

  • TypeScript: No type errors
  • ESLint: All 5 duplicate string warnings resolved
  • Prettier: Code formatting is consistent
  • Knip: No dead code detected

Verdict: ✅ Looks Good

This refactoring successfully addresses issue #299 by extracting duplicate string literals to named constants. The changes improve maintainability by creating single sources of truth for repeated values.


What's Good

  1. Well-structured constants: The new constants are properly documented with JSDoc comments and grouped in clear sections
  2. Single source of truth: Model IDs are now exported from models.ts and imported by defaults.ts and schema.ts, eliminating duplication
  3. Type safety: Constants like MCP_STATUS_NEEDS_AUTH maintain proper typing (McpServerStatus["status"])
  4. Comprehensive resolution: All 5 ESLint warnings mentioned in [Feature]: Extract duplicate string literals to constants #299 are resolved
  5. Documentation updates: CLAUDE.md updated with relevant SDK integration and detection confidence information
  6. Clean implementation: The refactoring follows existing code patterns (constant sections, JSDoc, naming conventions)

Suggestions

1. Consider consolidating the "needs-auth" constant location

The MCP_STATUS_NEEDS_AUTH constant is defined in src/stages/3-execution/plugin-loader.ts, but the same string literal "needs-auth" is still used in src/stages/1-analysis/index.ts:151:

status: m.authRequired ? "needs-auth" : "pending",

Recommendation: Move MCP_STATUS_NEEDS_AUTH to src/types/plugin.ts alongside the McpServerStatus type definition, then import it in both Stage 1 and Stage 3. This would:

  • Avoid a circular dependency (Stage 1 depending on Stage 3)
  • Co-locate the constant with its type definition
  • Create a consistent pattern for status value constants

This is a minor improvement and not a blocker for this PR.

2. Test coverage consideration

The PR description mentions "N/A - refactoring only" for adding tests. While this refactoring doesn't require new tests, it might be worth verifying that existing tests cover the affected code paths to ensure the constant substitutions work correctly. The test suite passes, which is a good sign.


Technical Notes

  • The refactoring correctly maintains ESM import patterns with .js extensions
  • No runtime behavior changes - purely a code quality improvement
  • The model constants pattern is extensible for future model version updates
  • CLAUDE.md updates are appropriate and add useful reference information

Overall: This is a clean, well-executed refactoring that improves code maintainability. The extracted constants follow TypeScript best practices and the changes are minimal and focused. Approved! 🚀

@sjnims sjnims self-assigned this Jan 19, 2026
@claude claude bot added refactor Code restructuring without behavior change effort:small < 1 hour component:cli CLI entry point and pipeline orchestration (src/index.ts) component:config Configuration loading (src/config/) stage:execution Stage 3: Agent SDK execution with tool capture labels Jan 19, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Jan 19, 2026

Codecov Report

❌ Patch coverage is 50.00000% with 5 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/cli/commands/resume.ts 0.00% 5 Missing ⚠️

📢 Thoughts on this report? Let us know!

Per PR review suggestion, consolidate the "needs-auth" constant by:
- Moving MCP_STATUS_NEEDS_AUTH to src/types/plugin.ts alongside the
  McpServerStatus type definition (single source of truth)
- Exporting via src/types/index.ts for consistent access
- Updating Stage 1 (analysis) and Stage 3 (execution) to use the
  shared constant instead of raw string literals

This avoids potential circular dependencies and co-locates the constant
with its type definition.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@sjnims
Copy link
Copy Markdown
Owner Author

sjnims commented Jan 19, 2026

Addressed the review suggestion in commit 51801e7:

Changes:

  • Moved MCP_STATUS_NEEDS_AUTH constant to src/types/plugin.ts alongside the McpServerStatus type definition
  • Exported via src/types/index.ts for consistent access
  • Updated src/stages/1-analysis/index.ts to import and use the shared constant (eliminating the raw "needs-auth" string there as well)
  • Updated src/stages/3-execution/plugin-loader.ts to import from types instead of defining locally

This creates a single source of truth for the MCP auth status value, co-located with its type definition, and avoids potential circular dependency issues.

All tests passing (1556/1556) ✅

@claude
Copy link
Copy Markdown
Contributor

claude bot commented Jan 19, 2026

Claude finished @sjnims's task in 2m 26s —— View job


Code Review Complete ✅

Todo List

  • Run quality checks (typecheck, lint, format:check, knip)
  • Review the PR diff
  • Verify the latest commit addresses review feedback correctly
  • Check for any new issues introduced
  • Post final review verdict

Quality Checks

All quality checks pass successfully:

  • TypeScript: No type errors
  • ESLint: All 5 duplicate string warnings resolved (no new issues)
  • Prettier: Code formatting is consistent
  • Knip: No dead code detected
  • Tests: All 1556 tests pass

Verdict: ✅ Excellent Update

The latest commit (51801e7) successfully addresses the review feedback by moving MCP_STATUS_NEEDS_AUTH to src/types/plugin.ts. This is a significant improvement that creates a proper single source of truth for the MCP auth status value.


What's Good

  1. Perfect constant location: Moving MCP_STATUS_NEEDS_AUTH to src/types/plugin.ts is exactly right - it's now co-located with the McpServerStatus type definition it references
  2. Proper typing: The constant uses McpServerStatus["status"] for type safety, ensuring it's always a valid status value
  3. Clean exports: The constant is properly exported via src/types/index.ts alongside the type exports
  4. Consistent usage: Both Stage 1 (src/stages/1-analysis/index.ts:151) and Stage 3 (src/stages/3-execution/plugin-loader.ts) now import and use the shared constant
  5. No circular dependencies: The solution avoids any circular dependency issues that would have existed if Stage 1 imported from Stage 3
  6. Complete elimination: All raw "needs-auth" string literals have been replaced (only remaining in the type definition and constant declaration itself)
  7. Documentation updates: CLAUDE.md has been enhanced with SDK integration and detection confidence information

Technical Notes

Constant Usage Pattern: The refactoring establishes an excellent pattern:

// Define in src/types/plugin.ts (alongside the type)
export const MCP_STATUS_NEEDS_AUTH: McpServerStatus["status"] = "needs-auth";

// Export via src/types/index.ts
export { MCP_STATUS_NEEDS_AUTH } from "./plugin.js";

// Import and use everywhere
import { MCP_STATUS_NEEDS_AUTH } from "../../types/index.js";
status: m.authRequired ? MCP_STATUS_NEEDS_AUTH : "pending"

This pattern:

  • Co-locates the constant with its type definition
  • Ensures type safety through TypeScript's literal type inference
  • Makes future changes trivial (one place to update)
  • Follows the project's existing patterns for type exports

Model Constants: The model ID constants (MODEL_OPUS_4_5, MODEL_SONNET_4_5, MODEL_HAIKU_4_5) in src/config/models.ts follow a similar pattern and will make future model version updates straightforward.

Resume Message Constant: The RESUME_COMPLETE_MESSAGE constant in src/cli/commands/resume.ts is well-documented and properly scoped to the file where it's used.


Summary

This PR successfully extracts all 5 duplicate string literals flagged by ESLint into well-named, properly-typed constants. The latest commit perfectly addresses the review feedback by moving the MCP status constant to the types file, creating a maintainable architecture that avoids circular dependencies and establishes a single source of truth for each value.

All quality checks pass, tests are green, and the code follows TypeScript best practices. This is a clean, focused refactoring that improves code maintainability without changing any behavior. Approved! 🚀


@claude claude bot added the documentation Improvements or additions to documentation label Jan 19, 2026
@sjnims sjnims merged commit e3d360c into main Jan 19, 2026
14 of 15 checks passed
@sjnims sjnims deleted the refactor/299-extract-duplicate-string-literals branch January 19, 2026 10:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component:cli CLI entry point and pipeline orchestration (src/index.ts) component:config Configuration loading (src/config/) documentation Improvements or additions to documentation effort:small < 1 hour refactor Code restructuring without behavior change stage:execution Stage 3: Agent SDK execution with tool capture

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Extract duplicate string literals to constants

1 participant