Skip to content

Conversation

@xiaomizhou2
Copy link
Contributor

@xiaomizhou2 xiaomizhou2 commented Jan 3, 2026

User description

#264 Implement a complete configuration export and import system to enable seamless config migration across devices and platforms.

Key Features:

  • Export configurations to .zip packages with metadata manifest
  • Import configurations with cross-platform path adaptation
  • Intelligent sensitive data sanitization (API keys redacted by default)
  • Three merge strategies: replace, merge, skip-existing
  • Automatic backup creation before import operations
  • Support for selective export/import scopes (all, workflows, mcp, settings)
  • Both Claude Code and Codex environment support

Technical Implementation:

  • Use adm-zip library for better cross-platform zip compatibility
  • Comprehensive TypeScript type system for export-import operations
  • Full i18n support (zh-CN and en) across all user-facing messages
  • Cross-platform path adapter for Windows ↔ Unix conversions
  • Config merger with conflict detection and resolution
  • Package validator with version compatibility checks

File Changes:

  • Add src/commands/export.ts and import.ts with CLI integration
  • Add src/utils/export-import/ module with 9 core utilities
  • Add src/types/export-import.ts for type definitions
  • Add comprehensive test suites for export-import functionality
  • Update i18n translations with new export/import namespaces
  • Integrate into main menu and CLI setup

Breaking Changes: None

Migration Guide: Added in .claude/plan/config-export-import.md

Description

Brief description of changes

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Testing

  • Tests added/updated
  • All tests pass
  • Coverage maintained

Checklist

  • Code follows style guidelines
  • Self-review completed
  • Documentation updated
  • No new warnings introduced

PR Type

Enhancement, Tests


Description

  • Implement comprehensive configuration export and import system enabling seamless config migration across devices and platforms

  • Export functionality: Create .zip packages with metadata manifest, support selective scopes (all, workflows, mcp, settings), and intelligent sensitive data sanitization

  • Import functionality: Extract and apply configurations with three merge strategies (replace, merge, skip-existing), automatic backup creation, and rollback on failure

  • Cross-platform support: Implement path adaptation for Windows ↔ Unix conversions, support both Claude Code and Codex environments

  • Core utilities: Use adm-zip library for ZIP operations, implement checksum verification, sensitive data detection/redaction, and conflict resolution

  • CLI integration: Add export and import commands with interactive prompts and direct execution modes, integrate into main menu

  • Internationalization: Full i18n support (zh-CN and en) for all user-facing messages across export, import, CLI, and menu

  • Comprehensive testing: Add test suites for all modules covering validation, file collection, sanitization, manifest management, and command execution

  • Type safety: Define comprehensive TypeScript types for export/import operations, options, results, and validation


Diagram Walkthrough

flowchart LR
  A["User Input<br/>Export/Import"] --> B["Command Handler<br/>export.ts/import.ts"]
  B --> C["Collector<br/>Gather configs"]
  C --> D["Sanitizer<br/>Redact secrets"]
  D --> E["Exporter<br/>Create ZIP"]
  E --> F["Package<br/>with Manifest"]
  
  G["Import Package"] --> H["Validator<br/>Check integrity"]
  H --> I["Path Adapter<br/>Cross-platform"]
  I --> J["Merger<br/>Resolve conflicts"]
  J --> K["Importer<br/>Apply configs"]
  K --> L["Backup/Rollback<br/>on failure"]
Loading

File Walkthrough

Relevant files
Enhancement
16 files
import.ts
Import command implementation with interactive prompts     

src/commands/import.ts

  • Implements complete import command handler with interactive and direct
    execution modes
  • Provides comprehensive user prompts for package selection, merge
    strategy, sensitive data handling, and backup creation
  • Displays package information and validation results with detailed
    error/warning messages
  • Handles import execution with progress tracking and result reporting
    including rollback availability
+503/-0 
merger.ts
Configuration merge strategies and conflict resolution     

src/utils/export-import/merger.ts

  • Implements three merge strategies: replace, merge, and skip-existing
    for configuration merging
  • Provides specialized merging for MCP services, workflows, and profiles
    with conflict detection
  • Includes conflict resolution logic with user choice support
    (use-existing, use-incoming, merge, rename)
  • Generates conflict summaries grouped by configuration type
+539/-0 
importer.ts
Main import orchestration and execution logic                       

src/utils/export-import/importer.ts

  • Orchestrates complete import workflow: validation, backup creation,
    extraction, path adaptation, conflict detection, and configuration
    application
  • Implements automatic rollback on failure with backup restoration
  • Handles cross-platform path adaptation for imported configurations
  • Provides progress callbacks and comprehensive import result reporting
+499/-0 
core.ts
Core export-import utilities and zip operations                   

src/utils/export-import/core.ts

  • Provides core utilities for zip package creation and extraction using
    adm-zip
  • Implements sensitive data detection and sanitization for API keys and
    tokens
  • Includes cross-platform path conversion (Windows ↔ Unix) with
    environment variable handling
  • Calculates SHA-256 checksums for file integrity verification
+490/-0 
collector.ts
Configuration file collection and filtering logic               

src/utils/export-import/collector.ts

  • Collects configuration files from Claude Code and Codex installations
    based on code type and scope
  • Filters out ZCF standard workflows to avoid duplication in exports
  • Supports selective collection by scope (all, workflows, mcp, settings)
    and custom file selection
  • Provides collection summary with file counts grouped by configuration
    type
+447/-0 
path-adapter.ts
Cross-platform path adaptation for imports                             

src/utils/export-import/path-adapter.ts

  • Adapts configuration paths for cross-platform compatibility during
    import
  • Provides specialized MCP command path adaptation with validation and
    warnings
  • Handles environment variable expansion ($HOME, %USERPROFILE%, etc.)
  • Generates path adaptation summaries and identifies critical paths
    requiring manual review
+475/-0 
validator.ts
Package validation and compatibility checking                       

src/utils/export-import/validator.ts

  • Validates import packages comprehensively: zip format, manifest
    structure, file integrity via checksums
  • Checks version and platform compatibility with appropriate warnings
  • Validates import options before execution
  • Provides detailed validation errors and warnings with severity levels
+450/-0 
export.ts
Export command implementation with interactive UI               

src/commands/export.ts

  • Implements export command with interactive and direct execution modes
  • Provides user prompts for code type, export scope, sensitive data
    inclusion, and output path selection
  • Shows file collection preview grouped by configuration type before
    confirmation
  • Displays export results with package path, file count, and size
    information
+396/-0 
cli-setup.ts
CLI integration for export and import commands                     

src/cli-setup.ts

  • Registers export and import commands with CLI framework
  • Adds command aliases (e for export) and positional arguments for
    import
  • Integrates help text, examples, and option descriptions for both
    commands
  • Updates help menu with export/import command documentation and usage
    examples
+41/-0   
index.ts
Export-import module index and exports                                     

src/utils/export-import/index.ts

  • Creates centralized module index for export-import functionality
  • Exports all public functions from collector, core, exporter, importer,
    manifest, merger, path-adapter, sanitizer, and validator modules
+15/-0   
index.ts
I18n namespace registration for export-import                       

src/i18n/index.ts

  • Adds export and import namespaces to i18n configuration
  • Enables internationalization support for export-import user-facing
    messages
+2/-0     
exporter.ts
Core export functionality with file collection and packaging

src/utils/export-import/exporter.ts

  • Main exporter module implementing executeExport function with progress
    callbacks and multi-step export workflow
  • Collects configuration files, processes/sanitizes content, creates
    manifest, and packages into ZIP with verification
  • Provides getExportSummary for preview and validateExportOptions for
    input validation
  • Handles file collection based on code type and scope with proper error
    handling and progress reporting
+423/-0 
export-import.ts
Type definitions for export-import functionality                 

src/types/export-import.ts

  • Comprehensive TypeScript type definitions for export/import system
    with 273 lines
  • Defines types for CodeType, ExportScope, MergeStrategy, ExportOptions,
    ExportMetadata, and ImportOptions
  • Includes validation types (ValidationError, ValidationResult),
    conflict handling, and progress tracking
  • Provides interfaces for sensitive field definitions, path mappings,
    and operation results
+273/-0 
manifest.ts
Manifest creation and validation utilities                             

src/utils/export-import/manifest.ts

  • Manifest management module with 268 lines for creating, validating,
    and analyzing export package metadata
  • Implements createManifest, validateManifest, and file integrity
    validation functions
  • Provides version comparison utilities and manifest summary generation
    for display
  • Detects platform and version compatibility issues with appropriate
    warnings
+268/-0 
sanitizer.ts
Sensitive data sanitization utilities                                       

src/utils/export-import/sanitizer.ts

  • Sensitive data sanitizer module with 190 lines for redacting API keys
    and tokens from configurations
  • Implements JSON and TOML content sanitization with pattern-based field
    detection
  • Provides batch sanitization, sanitization summary generation, and
    sanitized field detection
  • Includes utilities to identify redacted placeholders and check for
    sanitized data presence
+190/-0 
menu.ts
Menu integration for export-import commands                           

src/commands/menu.ts

  • Integrates export and import commands into main menu with new menu
    options 'E' and 'I'
  • Adds waitForKeyPress helper function for user interaction after
    command execution
  • Updates menu validation to accept new export/import choice characters
    in both Claude Code and Codex menus
  • Adds menu descriptions and options for export/import functionality
+42/-2   
Documentation
9 files
menu.json
Chinese language translations for export-import menu         

src/i18n/locales/zh-CN/menu.json

  • Adds Chinese translations for export and import menu options and
    descriptions
  • Includes menu option labels and descriptive text for configuration
    export/import functionality
  • Adds translation for "press any key to return" prompt
+6/-1     
import.json
Chinese translations for import functionality                       

src/i18n/locales/zh-CN/import.json

  • New Chinese (zh-CN) translation file with 82 entries for import
    functionality
  • Covers package validation, conflict detection, path adaptation, and
    merge strategies
  • Includes user prompts, status messages, and error/warning descriptions
  • Provides translations for backup creation, rollback, and import
    summary
+82/-0   
import.json
English translations for import functionality                       

src/i18n/locales/en/import.json

  • New English translation file with 82 entries for import functionality
  • Covers package validation, conflict detection, path adaptation, and
    merge strategies
  • Includes user prompts, status messages, and error/warning descriptions
  • Provides translations for backup creation, rollback, and import
    summary
+82/-0   
cli.json
Chinese CLI help text for export-import                                   

src/i18n/locales/zh-CN/cli.json

  • Adds Chinese translations for export and import command descriptions
    and help text
  • Includes command descriptions, shortcut descriptions, example
    descriptions, and default behavior labels
  • Adds entries for interactive export/import menus and quick export
    functionality
+8/-0     
cli.json
English CLI help text for export-import                                   

src/i18n/locales/en/cli.json

  • Adds English translations for export and import command descriptions
    and help text
  • Includes command descriptions, shortcut descriptions, example
    descriptions, and default behavior labels
  • Adds entries for interactive export/import menus and quick export
    functionality
+8/-0     
menu.json
English menu translations for export-import                           

src/i18n/locales/en/menu.json

  • Adds English menu options and descriptions for export/import
    functionality
  • Includes menu option labels ('Export config', 'Import config') and
    detailed descriptions
  • Adds "Press any key to return to main menu..." prompt message
+6/-1     
export.json
Chinese translations for export functionality                       

src/i18n/locales/zh-CN/export.json

  • New Chinese translation file with 45 entries for export functionality
  • Covers code type selection, scope options, sensitive data warnings,
    and output path configuration
  • Includes progress messages, file collection status, and export
    completion notifications
  • Provides translations for sanitization, packaging, and optional
    metadata (description, tags)
+45/-0   
export.json
English translations for export functionality                       

src/i18n/locales/en/export.json

  • New English translation file with 45 entries for export functionality
  • Covers code type selection, scope options, sensitive data warnings,
    and output path configuration
  • Includes progress messages, file collection status, and export
    completion notifications
  • Provides translations for sanitization, packaging, and optional
    metadata (description, tags)
+45/-0   
config-export-import.md
Add comprehensive config export-import feature planning document

.claude/plan/config-export-import.md

  • Comprehensive planning document for config export/import feature with
    965 lines of detailed specifications
  • Documents decision to use .zip format instead of tar.gz for better
    cross-platform compatibility
  • Defines complete task breakdown across 4 phases: architecture design,
    export implementation, import implementation, and integration
  • Includes type definitions, core utilities, CLI commands, testing
    strategy, and documentation requirements
  • Addresses potential risks and provides mitigation strategies for
    cross-platform path conversion, performance, security, and version
    compatibility
+965/-0 
Tests
6 files
export.test.ts
Export command test suite with interactive and direct modes

tests/commands/export.test.ts

  • Comprehensive test suite for exportCommand with 365 lines covering
    direct export, interactive flow, and option normalization
  • Tests validate export with command-line options, error handling, and
    user cancellation scenarios
  • Includes tests for code type and scope alias normalization (e.g., 'cc'
    → 'claude-code', 'wf' → 'workflows')
  • Mocks inquirer, i18n, and exporter modules with proper i18n
    translation handling
+365/-0 
collector.test.ts
Configuration collector test suite with scope filtering   

tests/utils/export-import/collector.test.ts

  • Test suite for configuration collector with 281 lines covering Claude
    Code and Codex config collection
  • Tests file collection by scope (all, workflows, settings, mcp) and
    validates collection summaries
  • Includes tests for ZCF standard workflow filtering (excluding zcf
    directory while including custom workflows)
  • Mocks file system operations and validates proper file type detection
+281/-0 
manifest.test.ts
Manifest creation and validation test suite                           

tests/utils/export-import/manifest.test.ts

  • Test suite for manifest management with 291 lines covering creation,
    validation, and version comparison
  • Tests manifest structure validation, sensitive data detection, and
    platform/version compatibility checks
  • Includes version parsing and comparison utilities for semantic
    versioning
  • Validates file integrity checks and manifest summary generation
+291/-0 
sanitizer.test.ts
Sensitive data sanitizer test suite                                           

tests/utils/export-import/sanitizer.test.ts

  • Test suite for sensitive data sanitization with 288 lines covering
    JSON and TOML content sanitization
  • Tests API key and auth token redaction, file-based sanitization, and
    batch processing
  • Includes detection of sanitized fields and verification of
    sanitization effectiveness
  • Validates that non-config files are skipped and sensitive data
    placeholders are properly handled
+288/-0 
core.test.ts
Core utilities test suite with path and checksum handling

tests/utils/export-import/core.test.ts

  • Test suite for core utilities with 263 lines covering checksum
    calculation, platform detection, and path adaptation
  • Tests sensitive data detection in nested configs and config
    sanitization with deep object traversal
  • Includes cross-platform path conversion (Windows ↔ Unix) and path
    mapping for configuration adaptation
  • Validates platform-specific path handling with environment variable
    substitution
+263/-0 
exporter.test.ts
Exporter module test suite                                                             

tests/utils/export-import/exporter.test.ts

  • Test suite for exporter functionality with 217 lines covering
    validation, summary generation, and execution
  • Tests validateExportOptions with various option combinations and error
    scenarios
  • Includes tests for getExportSummary with file counting and
    executeExport with progress callbacks
  • Validates proper handling of missing files and progress reporting
    during export
+217/-0 
Dependencies
2 files
pnpm-lock.yaml
Dependency updates for ZIP functionality                                 

pnpm-lock.yaml

  • Adds [email protected] dependency for cross-platform ZIP file creation
  • Adds @types/[email protected] type definitions for TypeScript support
  • Updates lock file with resolved versions and dependency tree
+25/-0   
package.json
Package dependencies for ZIP support                                         

package.json

  • Adds adm-zip to dependencies for ZIP file creation functionality
  • Adds @types/adm-zip to devDependencies for TypeScript type support
+2/-0     
Configuration changes
1 files
pnpm-workspace.yaml
Workspace catalog updates for ZIP dependencies                     

pnpm-workspace.yaml

  • Adds adm-zip@^0.5.16 to tooling catalog
  • Adds @types/adm-zip@^0.5.7 to types catalog
+2/-0     

Implement a complete configuration export and import system to enable seamless config migration across devices and platforms.

Key Features:
- Export configurations to .zip packages with metadata manifest
- Import configurations with cross-platform path adaptation
- Intelligent sensitive data sanitization (API keys redacted by default)
- Three merge strategies: replace, merge, skip-existing
- Automatic backup creation before import operations
- Support for selective export/import scopes (all, workflows, mcp, settings)
- Both Claude Code and Codex environment support

Technical Implementation:
- Use adm-zip library for better cross-platform zip compatibility
- Comprehensive TypeScript type system for export-import operations
- Full i18n support (zh-CN and en) across all user-facing messages
- Cross-platform path adapter for Windows ↔ Unix conversions
- Config merger with conflict detection and resolution
- Package validator with version compatibility checks

File Changes:
- Add src/commands/export.ts and import.ts with CLI integration
- Add src/utils/export-import/ module with 9 core utilities
- Add src/types/export-import.ts for type definitions
- Add comprehensive test suites for export-import functionality
- Update i18n translations with new export/import namespaces
- Integrate into main menu and CLI setup

Breaking Changes: None

Migration Guide: Added in .claude/plan/config-export-import.md
@qodo-free-for-open-source-projects
Copy link

qodo-free-for-open-source-projects bot commented Jan 3, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🔴
Zip path traversal

Description: Extracting zip files with extractAllTo without validating entry paths can lead to path
traversal vulnerabilities (zip slip attack) where malicious archives extract files outside
the intended directory.
core.ts [274-277]

Referred Code
const zip = new AdmZip(packagePath)

// Extract all files
zip.extractAllTo(targetDir, true)
Test error exposure

Description: Error re-throwing in test environment bypasses proper error handling and may expose
sensitive stack traces or internal implementation details to test outputs that could be
logged or captured.
import.ts [54-56]

Referred Code
if (process.env.NODE_ENV === 'test' || process.env.VITEST) {
  throw error
}
Dynamic import risk

Description: Using dynamic import with fs-extra without proper validation could allow arbitrary module
loading if the backup path or related variables are controllable, though this is mitigated
by the controlled context.
importer.ts [457-457]

Referred Code
const backupFiles = await import('fs-extra').then(fs => fs.readdirSync(backupPath, { recursive: true }))
Environment variable exposure

Description: Environment variable replacement using regex without validation could be exploited if
user-controlled paths contain crafted variable patterns, potentially exposing sensitive
environment variables.
core.ts [327-333]

Referred Code
converted = converted.replace(/%([^%]+)%/g, (_, varName) => {
  if (varName.toUpperCase() === 'USERPROFILE') {
    return '$HOME'
  }
  return `$${varName}`
})
Path filter bypass

Description: Path filtering logic for ZCF standard workflows relies on string prefix matching which
could be bypassed with path traversal sequences like '../zcf' or URL-encoded characters,
allowing unauthorized file inclusion.
collector.ts [62-67]

Referred Code
function isZcfStandardWorkflow(relativePath: string): boolean {
  // Normalize path separators to forward slash
  const normalizedPath = relativePath.replace(/\\/g, '/')

  // Check if the path starts with 'zcf/' or is exactly 'zcf'
  return normalizedPath === 'zcf' || normalizedPath.startsWith('zcf/')
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Missing audit logging: Critical import operations (backup creation, configuration merging, file restoration) lack
audit logging with user context, timestamps, and operation outcomes.

Referred Code
export async function executeImport(
  options: ImportOptions,
  progressCallback?: ProgressCallback,
): Promise<ImportResult> {
  let tempDir: string | null = null
  let backupPath: string | null = null

  try {
    // Merge with default options
    const opts: ImportOptions = {
      ...DEFAULT_IMPORT_OPTIONS,
      ...options,
    }

    // Step 1: Validate package
    progressCallback?.({
      step: 'Validating package',
      progress: 10,
    })

    const validation = validatePackage(opts.packagePath)


 ... (clipped 130 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Sensitive data logging: Package metadata including file paths and potentially sensitive configuration details are
logged to console without sanitization at lines 218-232.

Referred Code
console.log(`  ${ansis.bold(i18n.t('import:zcfVersion'))}:         ${ansis.cyan(metadata.version)}`)
console.log(`  ${ansis.bold(i18n.t('import:exportDate'))}:        ${ansis.cyan(dayjs(metadata.exportDate).format('YYYY-MM-DD HH:mm:ss'))}`)
console.log(`  ${ansis.bold(i18n.t('import:sourcePlatform'))}:    ${ansis.cyan(metadata.platform)}`)
console.log(`  ${ansis.bold(i18n.t('import:codeType'))}:          ${ansis.cyan(metadata.codeType)}`)
console.log(`  ${ansis.bold(i18n.t('import:scope'))}:             ${ansis.cyan(metadata.scope.join(', '))}`)
console.log(`  ${ansis.bold(i18n.t('import:filesCount'))}:        ${ansis.cyan(metadata.files.length)}`)
console.log(`  ${ansis.bold(i18n.t('import:hasSensitiveData'))}: ${metadata.hasSensitiveData ? ansis.red(i18n.t('common:yes')) : ansis.green(i18n.t('common:no'))}`)

if (metadata.description) {
  console.log(`  ${ansis.bold(i18n.t('import:description'))}:      ${ansis.gray(metadata.description)}`)
}

if (metadata.tags && metadata.tags.length > 0) {
  console.log(`  ${ansis.bold(i18n.t('import:tags'))}:             ${ansis.gray(metadata.tags.join(', '))}`)
}

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Path traversal vulnerability: ZIP extraction at line 277 lacks validation to prevent path traversal attacks where
malicious archives could write files outside the target directory.

Referred Code
export function extractZipPackage(packagePath: string, targetDir: string): ExportMetadata {
  if (!exists(packagePath)) {
    throw new Error(`Package file does not exist: ${packagePath}`)
  }

  const zip = new AdmZip(packagePath)

  // Extract all files
  zip.extractAllTo(targetDir, true)

  // Read and parse manifest
  const manifestPath = join(targetDir, 'manifest.json')
  if (!exists(manifestPath)) {
    throw new Error('Invalid package: manifest.json not found')
  }

  const manifestContent = readFile(manifestPath, 'utf-8')
  const metadata: ExportMetadata = JSON.parse(manifestContent)

  return metadata
}

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Silent cleanup failure: Temporary directory cleanup errors are silently ignored in the finally block without
logging, which may hide disk space or permission issues.

Referred Code
// Cleanup temporary directory
if (tempDir) {
  try {
    rmSync(tempDir, { recursive: true, force: true })
  }
  catch {
    // Ignore cleanup errors
  }
}

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status:
Detailed error exposure: Error messages at lines 82-83 and 452 may expose internal file paths and system details to
end users during validation failures.

Referred Code
console.error(ansis.red(i18n.t('import:importFailed')))
for (const error of validation.errors) {
  console.error(ansis.red(`  - ${error}`))
}
process.exit(1)

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@codecov
Copy link

codecov bot commented Jan 3, 2026

@qodo-free-for-open-source-projects
Copy link

qodo-free-for-open-source-projects bot commented Jan 3, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Fix infinite loop in recursion

To prevent an infinite loop, pass a new empty array for conflicts in the
recursive call to skipExistingStrategy instead of the parent's conflicts array.

src/utils/export-import/merger.ts [131-136]

 else if (isPlainObject(value) && isPlainObject(merged[key])) {
   // Recursively skip existing for nested objects
-  const result = skipExistingStrategy(merged[key], value, conflicts)
+  const result = skipExistingStrategy(merged[key], value, [])
   merged[key] = result.merged
   conflicts.push(...result.conflicts)
 }
  • Apply / Chat
Suggestion importance[1-10]: 10

__

Why: The suggestion correctly identifies a critical bug where passing the conflicts array by reference to a recursive call and then spreading its result back into itself would cause an infinite loop and a fatal error.

High
Implement robust multi-tool configuration rollback

Improve the rollbackFromBackup function to correctly restore configurations for
both .claude and .codex directories by cleaning existing directories and copying
the entire backup, preventing a corrupted state.

src/utils/export-import/importer.ts [447-473]

 async function rollbackFromBackup(backupPath: string): Promise<void> {
   if (!exists(backupPath)) {
     throw new Error(`Backup not found: ${backupPath}`)
   }
 
+  const fs = await import('fs-extra')
   const homeDir = homedir()
   const claudeDir = join(homeDir, '.claude')
+  const codexDir = join(homeDir, '.codex')
 
-  // Restore from backup
-  // This is a simplified rollback - in production, you'd want more sophisticated logic
-  const backupFiles = await import('fs-extra').then(fs => fs.readdirSync(backupPath, { recursive: true }))
+  // Clean up existing config directories before restoring
+  if (exists(claudeDir)) {
+    fs.rmSync(claudeDir, { recursive: true, force: true })
+  }
+  if (exists(codexDir)) {
+    fs.rmSync(codexDir, { recursive: true, force: true })
+  }
 
-  for (const file of backupFiles) {
-    if (typeof file !== 'string') {
-      continue
-    }
-
-    const sourcePath = join(backupPath, file)
-    const targetPath = join(claudeDir, file)
-
-    if (exists(sourcePath) && !sourcePath.endsWith('/')) {
-      const targetDir = join(targetPath, '..')
-      mkdirSync(targetDir, { recursive: true })
-      copyFile(sourcePath, targetPath)
-    }
-  }
+  // Copy the entire backup content to the home directory, restoring original structure
+  await fs.copy(backupPath, homeDir, { overwrite: true })
 }
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a critical flaw in the rollback logic, which only handles the .claude directory and would lead to a corrupted state if .codex files were modified. The proposed fix is robust and correctly handles the multi-tool architecture.

High
Halt import when conflicts are detected

In executeImport, halt the import process if detectImportConflicts finds any
conflicts to prevent potential data loss or configuration corruption, as there
is no conflict resolution step implemented.

src/utils/export-import/importer.ts [137-153]

-// Step 7: Complete
-progressCallback?.({
-  step: 'Import complete',
-  progress: 100,
-})
-
-return {
-  success: true,
-  fileCount: metadata.files.length,
-  backupPath: backupPath || undefined,
-  resolvedConflicts: conflicts,
-  warnings: [
-    ...validation.warnings.map(w => w.message),
-    ...warnings,
-  ],
-  rollbackAvailable: backupPath !== null,
+// Step 5.5: Abort if there are conflicts to resolve
+if (conflicts.length > 0) {
+  // In a future implementation, this is where interactive conflict resolution would happen.
+  // For now, we treat conflicts as an error to prevent data loss.
+  throw new Error(
+    `Import aborted due to ${conflicts.length} configuration conflicts. Please use a different merge strategy or manually resolve conflicts in the package.`,
+  )
 }
 
+// Step 6: Apply configurations
+progressCallback?.({
+  step: 'Applying configurations',
+  progress: 75,
+})
+...
+

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a major logical flaw where detected configuration conflicts are ignored, potentially leading to data loss or a corrupted state. Halting the import on conflict is a crucial safety measure.

Medium
Fix incomplete TOML sanitization logic

Fix a bug in sanitizeTOMLContent where using .test() with a global regex caused
.replace() to skip the first match, leading to incomplete sanitization.

src/utils/export-import/sanitizer.ts [52-75]

 function sanitizeTOMLContent(content: string): { sanitized: string, hadSensitiveData: boolean } {
-  let hadSensitiveData = false
   let sanitized = content
 
   // Sanitize TOML key-value pairs
   // Pattern: apiKey = "value" or APIKEY = 'value'
   const apiKeyPattern = /^(\s*(?:api[Kk]ey|APIKEY|API_KEY)\s*=\s*)["']([^"']+)["']/gm
-  if (apiKeyPattern.test(content)) {
-    hadSensitiveData = true
-    sanitized = sanitized.replace(apiKeyPattern, '$1"***REDACTED_API_KEY***"')
-  }
+  sanitized = sanitized.replace(apiKeyPattern, '$1"***REDACTED_API_KEY***"')
 
   // Pattern: authToken = "value" or AUTH_TOKEN = "value"
   const authTokenPattern = /^(\s*(?:auth[Tt]oken|AUTH_TOKEN|ANTHROPIC_AUTH_TOKEN)\s*=\s*)["']([^"']+)["']/gm
-  if (authTokenPattern.test(content)) {
-    hadSensitiveData = true
-    sanitized = sanitized.replace(authTokenPattern, '$1"***REDACTED_AUTH_TOKEN***"')
-  }
+  sanitized = sanitized.replace(authTokenPattern, '$1"***REDACTED_AUTH_TOKEN***"')
+
+  const hadSensitiveData = content !== sanitized
 
   return {
     sanitized,
     hadSensitiveData,
   }
 }
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a critical bug in the TOML sanitization logic that could lead to incomplete redaction of sensitive data. The proposed fix is correct and essential for the security of the export feature.

Medium
Handle user-provided full file paths

Update the createPackage function to correctly handle outputPath when it is a
full file path ending in .zip, preventing a runtime error.

src/utils/export-import/exporter.ts [256-270]

 async function createPackage(
   files: Array<{ fileInfo: ExportFileInfo, content: string }>,
   manifest: ExportMetadata,
   outputPath?: string,
 ): Promise<string> {
   // Determine output path
   const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5)
   const defaultFileName = `zcf-export-${timestamp}.zip`
-  const packagePath = outputPath
-    ? join(outputPath, defaultFileName)
-    : join(homedir(), defaultFileName)
+  let packagePath: string
+
+  if (outputPath) {
+    if (outputPath.endsWith('.zip')) {
+      packagePath = outputPath
+    }
+    else {
+      packagePath = join(outputPath, defaultFileName)
+    }
+  }
+  else {
+    packagePath = join(homedir(), defaultFileName)
+  }
 
   // Create temporary directory for staging
   const tempDir = join(homedir(), '.zcf-temp', `export-${Date.now()}`)
   mkdirSync(tempDir, { recursive: true })
   ...
 }

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 7

__

Why: This suggestion correctly identifies a bug where providing a full file path as an output argument would cause an error, and the proposed fix makes the command-line interface more robust and user-friendly.

Medium
Use file extension for sanitization

Refactor sanitizeContent to use the file's path extension to determine whether
to apply JSON or TOML sanitization, rather than relying on a try-catch fallback.

src/utils/export-import/sanitizer.ts [18-44]

 export function sanitizeContent(
   content: string,
-  _filePath: string,
+  filePath: string,
 ): { sanitized: string, hadSensitiveData: boolean } {
-  try {
-    // Attempt to parse as JSON
-    const parsed = JSON.parse(content)
-    const hadSensitiveData = hasSensitiveData(parsed)
+  if (filePath.endsWith('.json')) {
+    try {
+      const parsed = JSON.parse(content)
+      const hadSensitiveData = hasSensitiveData(parsed)
 
-    if (hadSensitiveData) {
-      const sanitized = sanitizeConfig(parsed)
-      return {
-        sanitized: JSON.stringify(sanitized, null, 2),
-        hadSensitiveData: true,
+      if (hadSensitiveData) {
+        const sanitized = sanitizeConfig(parsed)
+        return {
+          sanitized: JSON.stringify(sanitized, null, 2),
+          hadSensitiveData: true,
+        }
       }
     }
-
-    return {
-      sanitized: content,
-      hadSensitiveData: false,
+    catch {
+      // Not a valid JSON file, return as is.
+      return { sanitized: content, hadSensitiveData: false }
     }
   }
-  catch {
-    // If not JSON, try TOML or treat as plain text
+  else if (filePath.endsWith('.toml')) {
     return sanitizeTOMLContent(content)
+  }
+
+  return {
+    sanitized: content,
+    hadSensitiveData: false,
   }
 }
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies that relying on a try-catch block for file type detection is not robust and proposes a more reliable method using file extensions, which improves the correctness and predictability of the sanitization logic.

Low
Security
Add path traversal validation check

Update the import validation plan to include a security check against path
traversal attacks (Zip Slip). This involves verifying that all file paths within
the ZIP archive resolve to a location inside the intended extraction directory.

.claude/plan/config-export-import.md [379-397]

 #### 任务 3.1: 实现导入包验证器 **[已修改]**
 
 - **目标**: 在导入前验证配置包的完整性和兼容性
 - **输入**:
   - 导入的 zip 配置包路径 **[已修改]**
 - **输出**:
   - `src/utils/export-import/validator.ts` 实现:
-    - `validatePackageStructure()` - 验证包结构
+    - `validatePackageStructure()` - 验证包结构和路径安全性
     - `validateManifest()` - 验证元数据
     - `validateFileIntegrity()` - 验证文件完整性 (checksum)
     - `checkVersionCompatibility()` - 检查版本兼容性
     - `validateZipFormat()` - 验证 zip 文件格式 **[新增]**
   - 验证规则:
     - zip 文件格式有效且未损坏 **[新增]**
     - 包结构完整 (manifest.json 存在)
+    - **所有文件路径均在目标目录内 (防止路径遍历攻击) [新增]**
     - 所有清单中列出的文件都存在
     - 文件校验和匹配
     - ZCF 版本兼容 (主版本号一致)
     - 目标平台支持
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a critical security vulnerability (path traversal/Zip Slip) in the design plan for the import feature, which is crucial to address before implementation.

High
High-level
Refactor the core.ts god module

The src/utils/export-import/core.ts module centralizes too many distinct
responsibilities. It should be split into smaller, more focused modules (e.g.,
for zip operations, path handling, checksums) to improve modularity and reduce
coupling.

Examples:

src/utils/export-import/core.ts [1-490]
/**
 * Core utilities for ZCF configuration export and import
 *
 * This module provides fundamental functionality for:
 * - Collecting configuration files from the system
 * - Sanitizing sensitive data (API keys, tokens)
 * - Creating and extracting zip packages
 * - Validating package integrity
 * - Adapting paths for cross-platform compatibility
 */

 ... (clipped 480 lines)
src/utils/export-import/sanitizer.ts [9]
import { hasSensitiveData, sanitizeConfig, SENSITIVE_FIELDS } from './core'

Solution Walkthrough:

Before:

// src/utils/export-import/core.ts
export function calculateChecksum(...) { ... }
export function createZipPackage(...) { ... }
export function extractZipPackage(...) { ... }
export function windowsToUnixPath(...) { ... }
export const SENSITIVE_FIELDS = [...]
export function sanitizeConfig(...) { ... }
// ... and many other functions for different concerns

// src/utils/export-import/sanitizer.ts
import { sanitizeConfig, hasSensitiveData } from './core';
export function sanitizeFile(...) {
  // ... uses sanitizeConfig from core.ts
}

// src/utils/export-import/path-adapter.ts
import { adaptPlatformPaths } from './core';
export function adaptConfigPaths(...) {
  // ... calls adaptPlatformPaths from core.ts
}

After:

// src/utils/export-import/checksum.ts (new file)
export function calculateChecksum(...) { ... }

// src/utils/export-import/zip.ts (new file)
export function createZipPackage(...) { ... }
export function extractZipPackage(...) { ... }

// src/utils/export-import/sanitizer.ts (refactored)
export const SENSITIVE_FIELDS = [...]
export function sanitizeConfig(...) { ... }
export function sanitizeFile(...) {
  // ... uses local sanitization logic
}

// src/utils/export-import/path.ts (new or refactored path-adapter.ts)
export function windowsToUnixPath(...) { ... }
export function adaptPlatformPaths(...) { ... }

// src/utils/export-import/core.ts (removed or greatly reduced)
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies that src/utils/export-import/core.ts is a "god module" with multiple unrelated responsibilities, creating high coupling across the new feature, which is a significant architectural issue.

Medium
  • Update

…ystem

Add complete test coverage for the new export-import functionality:

- collector.test.ts: Config collection with ZCF filtering (550 lines)
- core.test.ts: Core utilities including checksum and zip operations (708 lines)
- manifest.test.ts: Manifest validation and metadata handling (420 lines)
- merger.test.ts: Intelligent config merging with conflict resolution (580 lines)
- path-adapter.test.ts: Cross-platform path adaptation (485 lines)
- validator.test.ts: Package validation and security checks (522 lines)

Test coverage includes:
- Unit tests for all core functions with extensive mocking
- Edge case testing for error scenarios and boundary conditions
- Cross-platform compatibility tests (Windows/macOS/Linux/Termux)
- Security validation for sensitive data handling
- Integration scenarios for complete workflows

Follows ZCF testing standards with 80% coverage target and comprehensive test organization.
- Added tests for collecting skills, hooks, and prompts in collector.test.ts.
- Expanded test cases for collectWorkflows and collectAllConfig functions.
- Introduced tests for collectCustomFiles to validate handling of custom paths.
- Enhanced getCollectionSummary tests to cover scenarios with only Claude Code or Codex files.
- Improved core.test.ts with additional cases for adaptPlatformPaths, calculateChecksum, and file handling.
- Added tests for createZipPackage and extractZipPackage to ensure proper zip file handling.
- Implemented validation tests in manifest.test.ts for missing file types, invalid sizes, and checksum warnings.
- Introduced validateFileIntegrity tests to check file integrity against checksums.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant