{"id":"94d01e3e-c1c6-498f-a0f9-8bc472aeabfa","entityType":"agent","slug":"clawhub-datadrivenconstruction-batch-cad-converter","name":"Batch Cad Converter","canonicalUrl":"https://www.xpersona.co/agent/clawhub-datadrivenconstruction-batch-cad-converter","canonicalPath":"/agent/clawhub-datadrivenconstruction-batch-cad-converter","generatedAt":"2026-10-10T17:34:50.372Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-10T14:38:53.967Z","emptyReason":null},"description":"Batch convert multiple CAD/BIM files (Revit, IFC, DWG, DGN) with progress tracking, error handling, and consolidated reporting. Skill: Batch Cad Converter Owner: datadrivenconstruction Summary: Batch convert multiple CAD/BIM files (Revit, IFC, DWG, DGN) with progress tracking, error handling, and consolidated reporting. Tags: latest:2.0.0 Version history: v2.0.0 | 2026-02-13T16:40:05.967Z | auto Batch CAD Converter 2.0.0 — Major Update - Adds unified batch conversion for Revit, IFC, DWG, and DGN files. - Enables robust progress tracking and r","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.4K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s1774mv3t1cm8r1kgs9hccdnmn8852nb:batch-cad-converter","sourceUrl":"https://clawhub.ai/datadrivenconstruction/batch-cad-converter","homepage":"https://clawhub.ai/datadrivenconstruction/skills/batch-cad-converter","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/datadrivenconstruction/batch-cad-converter","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/datadrivenconstruction/skills/batch-cad-converter","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":63,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Batch convert multiple CAD/BIM files (Revit, IFC, DWG, DGN) with progress tracking, error handling, and consolidated reporting. Skill: Batch Cad Converter Owner"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T14:38:53.967Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T14:38:53.967Z","emptyReason":null},"stars":null,"forks":null,"downloads":1382,"packageName":null,"latestVersion":"2.0.0","tractionLabel":"1.4K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T14:38:53.967Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T14:38:53.967Z","lastCrawledAt":"2026-10-10T14:38:53.967Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T14:38:53.967Z","lastVerifiedAt":null,"highlights":[{"version":"2.0.0","createdAt":"2026-02-13T16:40:05.967Z","changelog":"Batch CAD Converter 2.0.0 — Major Update - Adds unified batch conversion for Revit, IFC, DWG, and DGN files. - Enables robust progress tracking and reporting for large conversion batches. - Provides error recovery and continues batch operations on individual file failures. - Produces consolidated results, including per-file and batch summary data. - Introduces extensible architecture supporting additional CAD/BIM formats and custom converter paths.","fileCount":4,"zipByteSize":5587},{"version":"1.0.0","createdAt":"2026-02-07T14:33:32.467Z","changelog":"Initial release of Batch CAD Converter. - Batch converts multiple CAD/BIM files (Revit, IFC, DWG, DGN) in one workflow. - Supports progress tracking for large conversion jobs. - Error handling and recovery: skips unsupported/failed files without interrupting batch. - Outputs consolidated conversion report for the entire batch. - Flexible configuration for converter paths and output locations.","fileCount":2,"zipByteSize":4192}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s1774mv3t1cm8r1kgs9hccdnmn8852nb:batch-cad-converter","setupComplexity":"low","setupSteps":["Setup complexity is LOW. This package is likely designed for quick installation with minimal external side-effects.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-datadrivenconstruction-batch-cad-converter/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-datadrivenconstruction-batch-cad-converter/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-datadrivenconstruction-batch-cad-converter/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-datadrivenconstruction-batch-cad-converter/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-datadrivenconstruction-batch-cad-converter/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-datadrivenconstruction-batch-cad-converter/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T17:34:50.371Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-datadrivenconstruction-batch-cad-converter/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-datadrivenconstruction-batch-cad-converter/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-datadrivenconstruction-batch-cad-converter/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-datadrivenconstruction-batch-cad-converter/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-10T14:38:53.967Z","emptyReason":null},"readme":"Skill: Batch Cad Converter\n\nOwner: datadrivenconstruction\n\nSummary: Batch convert multiple CAD/BIM files (Revit, IFC, DWG, DGN) with progress tracking, error handling, and consolidated reporting.\n\nTags: latest:2.0.0\n\nVersion history:\n\nv2.0.0 | 2026-02-13T16:40:05.967Z | auto\n\nBatch CAD Converter 2.0.0 — Major Update\n\n- Adds unified batch conversion for Revit, IFC, DWG, and DGN files.\n- Enables robust progress tracking and reporting for large conversion batches.\n- Provides error recovery and continues batch operations on individual file failures.\n- Produces consolidated results, including per-file and batch summary data.\n- Introduces extensible architecture supporting additional CAD/BIM formats and custom converter paths.\n\nv1.0.0 | 2026-02-07T14:33:32.467Z | auto\n\nInitial release of Batch CAD Converter.\n\n- Batch converts multiple CAD/BIM files (Revit, IFC, DWG, DGN) in one workflow.\n- Supports progress tracking for large conversion jobs.\n- Error handling and recovery: skips unsupported/failed files without interrupting batch.\n- Outputs consolidated conversion report for the entire batch.\n- Flexible configuration for converter paths and output locations.\n\nArchive index:\n\nArchive v2.0.0: 4 files, 5587 bytes\n\nFiles: claw.json (490b), instructions.md (1782b), SKILL.md (14277b), _meta.json (138b)\n\nFile v2.0.0:SKILL.md\n\n---\r\nname: \"batch-cad-converter\"\r\ndescription: \"Batch convert multiple CAD/BIM files (Revit, IFC, DWG, DGN) with progress tracking, error handling, and consolidated reporting.\"\r\n---\r\n\r\n# Batch CAD/BIM Converter\r\n\r\n## Business Case\r\n\r\n### Problem Statement\r\nLarge projects and archives contain hundreds or thousands of CAD/BIM files:\r\n- Manual conversion is tedious and error-prone\r\n- Different formats require different converters\r\n- Progress tracking is needed for long operations\r\n- Error handling is critical for large batches\r\n\r\n### Solution\r\nUnified batch converter handling all supported formats with progress tracking, error recovery, and consolidated reporting.\r\n\r\n### Business Value\r\n- **Multi-format** - Revit, IFC, DWG, DGN in one workflow\r\n- **Error recovery** - Continue on failures\r\n- **Progress tracking** - Monitor large batches\r\n- **Reporting** - Consolidated conversion results\r\n\r\n## Python Implementation\r\n\r\n```python\r\nimport subprocess\r\nfrom pathlib import Path\r\nfrom typing import List, Optional, Dict, Any, Callable\r\nfrom dataclasses import dataclass, field\r\nfrom datetime import datetime\r\nimport time\r\nimport json\r\nfrom enum import Enum\r\nfrom concurrent.futures import ThreadPoolExecutor, as_completed\r\n\r\n\r\nclass CADFormat(Enum):\r\n    \"\"\"Supported CAD/BIM formats.\"\"\"\r\n    REVIT = (\".rvt\", \".rfa\")\r\n    IFC = (\".ifc\",)\r\n    DWG = (\".dwg\",)\r\n    DGN = (\".dgn\",)\r\n\r\n\r\nclass ConversionStatus(Enum):\r\n    \"\"\"Status of conversion operation.\"\"\"\r\n    PENDING = \"pending\"\r\n    CONVERTING = \"converting\"\r\n    SUCCESS = \"success\"\r\n    FAILED = \"failed\"\r\n    SKIPPED = \"skipped\"\r\n\r\n\r\n@dataclass\r\nclass ConversionResult:\r\n    \"\"\"Result of single file conversion.\"\"\"\r\n    input_file: str\r\n    output_file: Optional[str]\r\n    format: str\r\n    status: ConversionStatus\r\n    start_time: datetime\r\n    end_time: Optional[datetime]\r\n    duration_seconds: float\r\n    error_message: Optional[str] = None\r\n    file_size_kb: float = 0\r\n\r\n\r\n@dataclass\r\nclass BatchResult:\r\n    \"\"\"Result of batch conversion.\"\"\"\r\n    total_files: int\r\n    successful: int\r\n    failed: int\r\n    skipped: int\r\n    total_duration: float\r\n    results: List[ConversionResult]\r\n    start_time: datetime\r\n    end_time: datetime\r\n\r\n\r\nclass BatchCADConverter:\r\n    \"\"\"Batch convert multiple CAD/BIM files.\"\"\"\r\n\r\n    # Default converter paths\r\n    DEFAULT_CONVERTERS = {\r\n        'revit': 'RvtExporter.exe',\r\n        'ifc': 'IfcExporter.exe',\r\n        'dwg': 'DwgExporter.exe',\r\n        'dgn': 'DgnExporter.exe'\r\n    }\r\n\r\n    def __init__(self, converter_dir: str = \".\",\r\n                 converters: Dict[str, str] = None):\r\n        self.converter_dir = Path(converter_dir)\r\n        self.converters = converters or self.DEFAULT_CONVERTERS\r\n        self.results: List[ConversionResult] = []\r\n        self.progress_callback: Optional[Callable] = None\r\n\r\n    def set_progress_callback(self, callback: Callable[[int, int, str], None]):\r\n        \"\"\"Set callback for progress updates.\"\"\"\r\n        self.progress_callback = callback\r\n\r\n    def _get_format(self, file_path: Path) -> Optional[str]:\r\n        \"\"\"Detect CAD format from extension.\"\"\"\r\n        ext = file_path.suffix.lower()\r\n\r\n        for format_name, extensions in [\r\n            ('revit', ('.rvt', '.rfa')),\r\n            ('ifc', ('.ifc',)),\r\n            ('dwg', ('.dwg',)),\r\n            ('dgn', ('.dgn',))\r\n        ]:\r\n            if ext in extensions:\r\n                return format_name\r\n\r\n        return None\r\n\r\n    def _get_converter(self, format_name: str) -> Optional[Path]:\r\n        \"\"\"Get converter path for format.\"\"\"\r\n        if format_name not in self.converters:\r\n            return None\r\n\r\n        converter = self.converter_dir / self.converters[format_name]\r\n        if converter.exists():\r\n            return converter\r\n\r\n        # Try in system PATH\r\n        return Path(self.converters[format_name])\r\n\r\n    def convert_file(self, input_file: str,\r\n                     output_dir: Optional[str] = None,\r\n                     options: List[str] = None) -> ConversionResult:\r\n        \"\"\"Convert single file.\"\"\"\r\n\r\n        input_path = Path(input_file)\r\n        start_time = datetime.now()\r\n\r\n        # Detect format\r\n        format_name = self._get_format(input_path)\r\n        if not format_name:\r\n            return ConversionResult(\r\n                input_file=input_file,\r\n                output_file=None,\r\n                format='unknown',\r\n                status=ConversionStatus.SKIPPED,\r\n                start_time=start_time,\r\n                end_time=datetime.now(),\r\n                duration_seconds=0,\r\n                error_message=\"Unsupported format\"\r\n            )\r\n\r\n        # Get converter\r\n        converter = self._get_converter(format_name)\r\n        if not converter:\r\n            return ConversionResult(\r\n                input_file=input_file,\r\n                output_file=None,\r\n                format=format_name,\r\n                status=ConversionStatus.FAILED,\r\n                start_time=start_time,\r\n                end_time=datetime.now(),\r\n                duration_seconds=0,\r\n                error_message=f\"Converter not found for {format_name}\"\r\n            )\r\n\r\n        # Build command\r\n        cmd = [str(converter), str(input_path)]\r\n        if options:\r\n            cmd.extend(options)\r\n\r\n        # Execute\r\n        try:\r\n            result = subprocess.run(cmd, capture_output=True, text=True, timeout=3600)\r\n            end_time = datetime.now()\r\n            duration = (end_time - start_time).total_seconds()\r\n\r\n            # Determine output file\r\n            output_file = input_path.with_suffix('.xlsx')\r\n            if output_dir:\r\n                output_file = Path(output_dir) / output_file.name\r\n\r\n            if result.returncode == 0 and output_file.exists():\r\n                return ConversionResult(\r\n                    input_file=input_file,\r\n                    output_file=str(output_file),\r\n                    format=format_name,\r\n                    status=ConversionStatus.SUCCESS,\r\n                    start_time=start_time,\r\n                    end_time=end_time,\r\n                    duration_seconds=duration,\r\n                    file_size_kb=output_file.stat().st_size / 1024\r\n                )\r\n            else:\r\n                return ConversionResult(\r\n                    input_file=input_file,\r\n                    output_file=None,\r\n                    format=format_name,\r\n                    status=ConversionStatus.FAILED,\r\n                    start_time=start_time,\r\n                    end_time=end_time,\r\n                    duration_seconds=duration,\r\n                    error_message=result.stderr or \"Conversion failed\"\r\n                )\r\n\r\n        except subprocess.TimeoutExpired:\r\n            return ConversionResult(\r\n                input_file=input_file,\r\n                output_file=None,\r\n                format=format_name,\r\n                status=ConversionStatus.FAILED,\r\n                start_time=start_time,\r\n                end_time=datetime.now(),\r\n                duration_seconds=3600,\r\n                error_message=\"Timeout exceeded (1 hour)\"\r\n            )\r\n\r\n        except Exception as e:\r\n            return ConversionResult(\r\n                input_file=input_file,\r\n                output_file=None,\r\n                format=format_name,\r\n                status=ConversionStatus.FAILED,\r\n                start_time=start_time,\r\n                end_time=datetime.now(),\r\n                duration_seconds=0,\r\n                error_message=str(e)\r\n            )\r\n\r\n    def batch_convert(self, input_folder: str,\r\n                      output_folder: Optional[str] = None,\r\n                      include_subfolders: bool = True,\r\n                      formats: List[str] = None,\r\n                      options: Dict[str, List[str]] = None,\r\n                      parallel: bool = False,\r\n                      max_workers: int = 4) -> BatchResult:\r\n        \"\"\"Convert all files in folder.\"\"\"\r\n\r\n        start_time = datetime.now()\r\n        input_path = Path(input_folder)\r\n\r\n        # Find all supported files\r\n        files = []\r\n        pattern = \"**/*\" if include_subfolders else \"*\"\r\n\r\n        for ext in ['.rvt', '.rfa', '.ifc', '.dwg', '.dgn']:\r\n            files.extend(input_path.glob(f\"{pattern}{ext}\"))\r\n\r\n        # Filter by format if specified\r\n        if formats:\r\n            files = [f for f in files if self._get_format(f) in formats]\r\n\r\n        total_files = len(files)\r\n        self.results = []\r\n\r\n        # Create output directory\r\n        if output_folder:\r\n            Path(output_folder).mkdir(parents=True, exist_ok=True)\r\n\r\n        # Process files\r\n        if parallel and total_files > 1:\r\n            self._convert_parallel(files, output_folder, options, max_workers)\r\n        else:\r\n            self._convert_sequential(files, output_folder, options)\r\n\r\n        end_time = datetime.now()\r\n\r\n        # Calculate statistics\r\n        successful = sum(1 for r in self.results if r.status == ConversionStatus.SUCCESS)\r\n        failed = sum(1 for r in self.results if r.status == ConversionStatus.FAILED)\r\n        skipped = sum(1 for r in self.results if r.status == ConversionStatus.SKIPPED)\r\n\r\n        return BatchResult(\r\n            total_files=total_files,\r\n            successful=successful,\r\n            failed=failed,\r\n            skipped=skipped,\r\n            total_duration=(end_time - start_time).total_seconds(),\r\n            results=self.results,\r\n            start_time=start_time,\r\n            end_time=end_time\r\n        )\r\n\r\n    def _convert_sequential(self, files: List[Path],\r\n                            output_folder: Optional[str],\r\n                            options: Dict[str, List[str]]):\r\n        \"\"\"Convert files sequentially.\"\"\"\r\n\r\n        total = len(files)\r\n        for i, file_path in enumerate(files, 1):\r\n            if self.progress_callback:\r\n                self.progress_callback(i, total, str(file_path))\r\n\r\n            format_name = self._get_format(file_path)\r\n            format_options = options.get(format_name, []) if options else []\r\n\r\n            result = self.convert_file(str(file_path), output_folder, format_options)\r\n            self.results.append(result)\r\n\r\n            status_symbol = \"✓\" if result.status == ConversionStatus.SUCCESS else \"✗\"\r\n            print(f\"[{i}/{total}] {status_symbol} {file_path.name}\")\r\n\r\n    def _convert_parallel(self, files: List[Path],\r\n                          output_folder: Optional[str],\r\n                          options: Dict[str, List[str]],\r\n                          max_workers: int):\r\n        \"\"\"Convert files in parallel.\"\"\"\r\n\r\n        total = len(files)\r\n\r\n        with ThreadPoolExecutor(max_workers=max_workers) as executor:\r\n            futures = {}\r\n\r\n            for file_path in files:\r\n                format_name = self._get_format(file_path)\r\n                format_options = options.get(format_name, []) if options else []\r\n                future = executor.submit(self.convert_file, str(file_path), output_folder, format_options)\r\n                futures[future] = file_path\r\n\r\n            completed = 0\r\n            for future in as_completed(futures):\r\n                completed += 1\r\n                result = future.result()\r\n                self.results.append(result)\r\n\r\n                if self.progress_callback:\r\n                    self.progress_callback(completed, total, str(futures[future]))\r\n\r\n    def generate_report(self, batch_result: BatchResult,\r\n                        output_path: str = None) -> str:\r\n        \"\"\"Generate conversion report.\"\"\"\r\n\r\n        report = {\r\n            'summary': {\r\n                'total_files': batch_result.total_files,\r\n                'successful': batch_result.successful,\r\n                'failed': batch_result.failed,\r\n                'skipped': batch_result.skipped,\r\n                'success_rate': round(batch_result.successful / batch_result.total_files * 100, 1) if batch_result.total_files > 0 else 0,\r\n                'total_duration_seconds': round(batch_result.total_duration, 2),\r\n                'start_time': batch_result.start_time.isoformat(),\r\n                'end_time': batch_result.end_time.isoformat()\r\n            },\r\n            'results': [\r\n                {\r\n                    'input': r.input_file,\r\n                    'output': r.output_file,\r\n                    'format': r.format,\r\n                    'status': r.status.value,\r\n                    'duration': round(r.duration_seconds, 2),\r\n                    'error': r.error_message\r\n                }\r\n                for r in batch_result.results\r\n            ]\r\n        }\r\n\r\n        report_json = json.dumps(report, indent=2)\r\n\r\n        if output_path:\r\n            with open(output_path, 'w') as f:\r\n                f.write(report_json)\r\n\r\n        return report_json\r\n\r\n\r\n# Progress callback example\r\ndef print_progress(current: int, total: int, file_name: str):\r\n    \"\"\"Print progress to console.\"\"\"\r\n    percent = current / total * 100\r\n    print(f\"Progress: {current}/{total} ({percent:.1f}%) - {file_name}\")\r\n```\r\n\r\n## Quick Start\r\n\r\n```python\r\n# Initialize batch converter\r\nconverter = BatchCADConverter(converter_dir=\"C:/DDC/\")\r\n\r\n# Set progress callback\r\nconverter.set_progress_callback(print_progress)\r\n\r\n# Convert all files\r\nresult = converter.batch_convert(\r\n    input_folder=\"C:/Projects\",\r\n    output_folder=\"C:/Converted\",\r\n    include_subfolders=True\r\n)\r\n\r\nprint(f\"Success: {result.successful}/{result.total_files}\")\r\n```\r\n\r\n## Common Use Cases\r\n\r\n### 1. Convert Specific Formats Only\r\n```python\r\nresult = converter.batch_convert(\r\n    input_folder=\"C:/Archive\",\r\n    formats=['revit', 'ifc'],  # Only Revit and IFC\r\n    parallel=True,\r\n    max_workers=4\r\n)\r\n```\r\n\r\n### 2. With Format-Specific Options\r\n```python\r\noptions = {\r\n    'revit': ['complete', 'bbox', 'rooms'],\r\n    'ifc': ['bbox'],\r\n    'dwg': []\r\n}\r\nresult = converter.batch_convert(\r\n    input_folder=\"C:/Projects\",\r\n    options=options\r\n)\r\n```\r\n\r\n### 3. Generate Report\r\n```python\r\nresult = converter.batch_convert(\"C:/Projects\")\r\nreport = converter.generate_report(result, \"conversion_report.json\")\r\n```\r\n\r\n## Resources\r\n- **GitHub**: [cad2data Pipeline](https://github.com/datadrivenconstruction/cad2data-Revit-IFC-DWG-DGN-pipeline-with-conversion-validation-qto)\n\nFile v2.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn75fhjxn1jz5xbgd9ggj0nrtd80q1dz\",\n  \"slug\": \"batch-cad-converter\",\n  \"version\": \"2.0.0\",\n  \"publishedAt\": 1771000805967\n}\n\nFile v2.0.0:instructions.md\n\nYou are a batch CAD/BIM conversion assistant. You help users convert multiple files across formats (Revit, IFC, DWG, DGN) in a single automated run with progress tracking and error handling.\n\nWhen the user asks to batch convert files:\n1. Scan input directory for supported files (.rvt, .ifc, .dwg, .dgn)\n2. Auto-detect format and select appropriate converter\n3. Process each file with progress tracking (X of N completed)\n4. Handle errors gracefully — skip failed files, continue processing\n5. Generate consolidated report: successes, failures, output paths\n\nWhen the user asks to set up batch conversion:\n1. Help define input/output directory structure\n2. Configure per-format settings (IFC schema, DWG version, export mode)\n3. Set up file naming conventions for outputs\n4. Estimate processing time based on file count and sizes\n\n## Input Format\n- Input directory path containing CAD/BIM files\n- Output directory path for converted files\n- Optional: file format filter (e.g., only .rvt files)\n- Optional: per-format conversion settings\n\n## Output Format\n- Converted files in output directory (one Excel per input file)\n- Batch report: total files, successful, failed, processing time\n- Error log with specific failure reasons per file\n- Consolidated summary Excel combining data from all files\n\n## Supported Formats\n| Format | Extension | Converter |\n|--------|-----------|-----------|\n| Revit | .rvt, .rfa | RvtExporter |\n| IFC | .ifc | IfcExporter / IfcOpenShell |\n| AutoCAD | .dwg | DwgExporter |\n| MicroStation | .dgn | DgnExporter |\n\n## Constraints\n- Filesystem permission required for reading/writing files\n- subprocess.run() is used for invoking format-specific CLI converters\n- Each converter must be installed locally\n- Failed files are logged but do not stop the batch\n\nFile v2.0.0:claw.json\n\n{\n  \"name\": \"batch-cad-converter\",\n  \"version\": \"2.0.0\",\n  \"description\": \"Batch convert multiple CAD/BIM files (Revit, IFC, DWG, DGN) with progress tracking, error handling, and consolidated reporting.\",\n  \"author\": \"datadrivenconstruction\",\n  \"license\": \"MIT\",\n  \"permissions\": [\"filesystem\"],\n  \"entry\": \"instructions.md\",\n  \"tags\": [\"construction\", \"CAD\", \"BIM\", \"batch-processing\", \"data-conversion\", \"automation\"],\n  \"models\": [\"claude-*\", \"gpt-*\"],\n  \"minOpenClawVersion\": \"0.8.0\"\n}\n\nArchive v1.0.0: 2 files, 4192 bytes\n\nFiles: SKILL.md (14314b), _meta.json (138b)\n\nFile v1.0.0:SKILL.md\n\n---\r\nslug: \"batch-cad-converter\"\r\ndisplay_name: \"Batch CAD Converter\"\r\ndescription: \"Batch convert multiple CAD/BIM files (Revit, IFC, DWG, DGN) with progress tracking, error handling, and consolidated reporting.\"\r\n---\r\n\r\n# Batch CAD/BIM Converter\r\n\r\n## Business Case\r\n\r\n### Problem Statement\r\nLarge projects and archives contain hundreds or thousands of CAD/BIM files:\r\n- Manual conversion is tedious and error-prone\r\n- Different formats require different converters\r\n- Progress tracking is needed for long operations\r\n- Error handling is critical for large batches\r\n\r\n### Solution\r\nUnified batch converter handling all supported formats with progress tracking, error recovery, and consolidated reporting.\r\n\r\n### Business Value\r\n- **Multi-format** - Revit, IFC, DWG, DGN in one workflow\r\n- **Error recovery** - Continue on failures\r\n- **Progress tracking** - Monitor large batches\r\n- **Reporting** - Consolidated conversion results\r\n\r\n## Python Implementation\r\n\r\n```python\r\nimport subprocess\r\nfrom pathlib import Path\r\nfrom typing import List, Optional, Dict, Any, Callable\r\nfrom dataclasses import dataclass, field\r\nfrom datetime import datetime\r\nimport time\r\nimport json\r\nfrom enum import Enum\r\nfrom concurrent.futures import ThreadPoolExecutor, as_completed\r\n\r\n\r\nclass CADFormat(Enum):\r\n    \"\"\"Supported CAD/BIM formats.\"\"\"\r\n    REVIT = (\".rvt\", \".rfa\")\r\n    IFC = (\".ifc\",)\r\n    DWG = (\".dwg\",)\r\n    DGN = (\".dgn\",)\r\n\r\n\r\nclass ConversionStatus(Enum):\r\n    \"\"\"Status of conversion operation.\"\"\"\r\n    PENDING = \"pending\"\r\n    CONVERTING = \"converting\"\r\n    SUCCESS = \"success\"\r\n    FAILED = \"failed\"\r\n    SKIPPED = \"skipped\"\r\n\r\n\r\n@dataclass\r\nclass ConversionResult:\r\n    \"\"\"Result of single file conversion.\"\"\"\r\n    input_file: str\r\n    output_file: Optional[str]\r\n    format: str\r\n    status: ConversionStatus\r\n    start_time: datetime\r\n    end_time: Optional[datetime]\r\n    duration_seconds: float\r\n    error_message: Optional[str] = None\r\n    file_size_kb: float = 0\r\n\r\n\r\n@dataclass\r\nclass BatchResult:\r\n    \"\"\"Result of batch conversion.\"\"\"\r\n    total_files: int\r\n    successful: int\r\n    failed: int\r\n    skipped: int\r\n    total_duration: float\r\n    results: List[ConversionResult]\r\n    start_time: datetime\r\n    end_time: datetime\r\n\r\n\r\nclass BatchCADConverter:\r\n    \"\"\"Batch convert multiple CAD/BIM files.\"\"\"\r\n\r\n    # Default converter paths\r\n    DEFAULT_CONVERTERS = {\r\n        'revit': 'RvtExporter.exe',\r\n        'ifc': 'IfcExporter.exe',\r\n        'dwg': 'DwgExporter.exe',\r\n        'dgn': 'DgnExporter.exe'\r\n    }\r\n\r\n    def __init__(self, converter_dir: str = \".\",\r\n                 converters: Dict[str, str] = None):\r\n        self.converter_dir = Path(converter_dir)\r\n        self.converters = converters or self.DEFAULT_CONVERTERS\r\n        self.results: List[ConversionResult] = []\r\n        self.progress_callback: Optional[Callable] = None\r\n\r\n    def set_progress_callback(self, callback: Callable[[int, int, str], None]):\r\n        \"\"\"Set callback for progress updates.\"\"\"\r\n        self.progress_callback = callback\r\n\r\n    def _get_format(self, file_path: Path) -> Optional[str]:\r\n        \"\"\"Detect CAD format from extension.\"\"\"\r\n        ext = file_path.suffix.lower()\r\n\r\n        for format_name, extensions in [\r\n            ('revit', ('.rvt', '.rfa')),\r\n            ('ifc', ('.ifc',)),\r\n            ('dwg', ('.dwg',)),\r\n            ('dgn', ('.dgn',))\r\n        ]:\r\n            if ext in extensions:\r\n                return format_name\r\n\r\n        return None\r\n\r\n    def _get_converter(self, format_name: str) -> Optional[Path]:\r\n        \"\"\"Get converter path for format.\"\"\"\r\n        if format_name not in self.converters:\r\n            return None\r\n\r\n        converter = self.converter_dir / self.converters[format_name]\r\n        if converter.exists():\r\n            return converter\r\n\r\n        # Try in system PATH\r\n        return Path(self.converters[format_name])\r\n\r\n    def convert_file(self, input_file: str,\r\n                     output_dir: Optional[str] = None,\r\n                     options: List[str] = None) -> ConversionResult:\r\n        \"\"\"Convert single file.\"\"\"\r\n\r\n        input_path = Path(input_file)\r\n        start_time = datetime.now()\r\n\r\n        # Detect format\r\n        format_name = self._get_format(input_path)\r\n        if not format_name:\r\n            return ConversionResult(\r\n                input_file=input_file,\r\n                output_file=None,\r\n                format='unknown',\r\n                status=ConversionStatus.SKIPPED,\r\n                start_time=start_time,\r\n                end_time=datetime.now(),\r\n                duration_seconds=0,\r\n                error_message=\"Unsupported format\"\r\n            )\r\n\r\n        # Get converter\r\n        converter = self._get_converter(format_name)\r\n        if not converter:\r\n            return ConversionResult(\r\n                input_file=input_file,\r\n                output_file=None,\r\n                format=format_name,\r\n                status=ConversionStatus.FAILED,\r\n                start_time=start_time,\r\n                end_time=datetime.now(),\r\n                duration_seconds=0,\r\n                error_message=f\"Converter not found for {format_name}\"\r\n            )\r\n\r\n        # Build command\r\n        cmd = [str(converter), str(input_path)]\r\n        if options:\r\n            cmd.extend(options)\r\n\r\n        # Execute\r\n        try:\r\n            result = subprocess.run(cmd, capture_output=True, text=True, timeout=3600)\r\n            end_time = datetime.now()\r\n            duration = (end_time - start_time).total_seconds()\r\n\r\n            # Determine output file\r\n            output_file = input_path.with_suffix('.xlsx')\r\n            if output_dir:\r\n                output_file = Path(output_dir) / output_file.name\r\n\r\n            if result.returncode == 0 and output_file.exists():\r\n                return ConversionResult(\r\n                    input_file=input_file,\r\n                    output_file=str(output_file),\r\n                    format=format_name,\r\n                    status=ConversionStatus.SUCCESS,\r\n                    start_time=start_time,\r\n                    end_time=end_time,\r\n                    duration_seconds=duration,\r\n                    file_size_kb=output_file.stat().st_size / 1024\r\n                )\r\n            else:\r\n                return ConversionResult(\r\n                    input_file=input_file,\r\n                    output_file=None,\r\n                    format=format_name,\r\n                    status=ConversionStatus.FAILED,\r\n                    start_time=start_time,\r\n                    end_time=end_time,\r\n                    duration_seconds=duration,\r\n                    error_message=result.stderr or \"Conversion failed\"\r\n                )\r\n\r\n        except subprocess.TimeoutExpired:\r\n            return ConversionResult(\r\n                input_file=input_file,\r\n                output_file=None,\r\n                format=format_name,\r\n                status=ConversionStatus.FAILED,\r\n                start_time=start_time,\r\n                end_time=datetime.now(),\r\n                duration_seconds=3600,\r\n                error_message=\"Timeout exceeded (1 hour)\"\r\n            )\r\n\r\n        except Exception as e:\r\n            return ConversionResult(\r\n                input_file=input_file,\r\n                output_file=None,\r\n                format=format_name,\r\n                status=ConversionStatus.FAILED,\r\n                start_time=start_time,\r\n                end_time=datetime.now(),\r\n                duration_seconds=0,\r\n                error_message=str(e)\r\n            )\r\n\r\n    def batch_convert(self, input_folder: str,\r\n                      output_folder: Optional[str] = None,\r\n                      include_subfolders: bool = True,\r\n                      formats: List[str] = None,\r\n                      options: Dict[str, List[str]] = None,\r\n                      parallel: bool = False,\r\n                      max_workers: int = 4) -> BatchResult:\r\n        \"\"\"Convert all files in folder.\"\"\"\r\n\r\n        start_time = datetime.now()\r\n        input_path = Path(input_folder)\r\n\r\n        # Find all supported files\r\n        files = []\r\n        pattern = \"**/*\" if include_subfolders else \"*\"\r\n\r\n        for ext in ['.rvt', '.rfa', '.ifc', '.dwg', '.dgn']:\r\n            files.extend(input_path.glob(f\"{pattern}{ext}\"))\r\n\r\n        # Filter by format if specified\r\n        if formats:\r\n            files = [f for f in files if self._get_format(f) in formats]\r\n\r\n        total_files = len(files)\r\n        self.results = []\r\n\r\n        # Create output directory\r\n        if output_folder:\r\n            Path(output_folder).mkdir(parents=True, exist_ok=True)\r\n\r\n        # Process files\r\n        if parallel and total_files > 1:\r\n            self._convert_parallel(files, output_folder, options, max_workers)\r\n        else:\r\n            self._convert_sequential(files, output_folder, options)\r\n\r\n        end_time = datetime.now()\r\n\r\n        # Calculate statistics\r\n        successful = sum(1 for r in self.results if r.status == ConversionStatus.SUCCESS)\r\n        failed = sum(1 for r in self.results if r.status == ConversionStatus.FAILED)\r\n        skipped = sum(1 for r in self.results if r.status == ConversionStatus.SKIPPED)\r\n\r\n        return BatchResult(\r\n            total_files=total_files,\r\n            successful=successful,\r\n            failed=failed,\r\n            skipped=skipped,\r\n            total_duration=(end_time - start_time).total_seconds(),\r\n            results=self.results,\r\n            start_time=start_time,\r\n            end_time=end_time\r\n        )\r\n\r\n    def _convert_sequential(self, files: List[Path],\r\n                            output_folder: Optional[str],\r\n                            options: Dict[str, List[str]]):\r\n        \"\"\"Convert files sequentially.\"\"\"\r\n\r\n        total = len(files)\r\n        for i, file_path in enumerate(files, 1):\r\n            if self.progress_callback:\r\n                self.progress_callback(i, total, str(file_path))\r\n\r\n            format_name = self._get_format(file_path)\r\n            format_options = options.get(format_name, []) if options else []\r\n\r\n            result = self.convert_file(str(file_path), output_folder, format_options)\r\n            self.results.append(result)\r\n\r\n            status_symbol = \"✓\" if result.status == ConversionStatus.SUCCESS else \"✗\"\r\n            print(f\"[{i}/{total}] {status_symbol} {file_path.name}\")\r\n\r\n    def _convert_parallel(self, files: List[Path],\r\n                          output_folder: Optional[str],\r\n                          options: Dict[str, List[str]],\r\n                          max_workers: int):\r\n        \"\"\"Convert files in parallel.\"\"\"\r\n\r\n        total = len(files)\r\n\r\n        with ThreadPoolExecutor(max_workers=max_workers) as executor:\r\n            futures = {}\r\n\r\n            for file_path in files:\r\n                format_name = self._get_format(file_path)\r\n                format_options = options.get(format_name, []) if options else []\r\n                future = executor.submit(self.convert_file, str(file_path), output_folder, format_options)\r\n                futures[future] = file_path\r\n\r\n            completed = 0\r\n            for future in as_completed(futures):\r\n                completed += 1\r\n                result = future.result()\r\n                self.results.append(result)\r\n\r\n                if self.progress_callback:\r\n                    self.progress_callback(completed, total, str(futures[future]))\r\n\r\n    def generate_report(self, batch_result: BatchResult,\r\n                        output_path: str = None) -> str:\r\n        \"\"\"Generate conversion report.\"\"\"\r\n\r\n        report = {\r\n            'summary': {\r\n                'total_files': batch_result.total_files,\r\n                'successful': batch_result.successful,\r\n                'failed': batch_result.failed,\r\n                'skipped': batch_result.skipped,\r\n                'success_rate': round(batch_result.successful / batch_result.total_files * 100, 1) if batch_result.total_files > 0 else 0,\r\n                'total_duration_seconds': round(batch_result.total_duration, 2),\r\n                'start_time': batch_result.start_time.isoformat(),\r\n                'end_time': batch_result.end_time.isoformat()\r\n            },\r\n            'results': [\r\n                {\r\n                    'input': r.input_file,\r\n                    'output': r.output_file,\r\n                    'format': r.format,\r\n                    'status': r.status.value,\r\n                    'duration': round(r.duration_seconds, 2),\r\n                    'error': r.error_message\r\n                }\r\n                for r in batch_result.results\r\n            ]\r\n        }\r\n\r\n        report_json = json.dumps(report, indent=2)\r\n\r\n        if output_path:\r\n            with open(output_path, 'w') as f:\r\n                f.write(report_json)\r\n\r\n        return report_json\r\n\r\n\r\n# Progress callback example\r\ndef print_progress(current: int, total: int, file_name: str):\r\n    \"\"\"Print progress to console.\"\"\"\r\n    percent = current / total * 100\r\n    print(f\"Progress: {current}/{total} ({percent:.1f}%) - {file_name}\")\r\n```\r\n\r\n## Quick Start\r\n\r\n```python\r\n# Initialize batch converter\r\nconverter = BatchCADConverter(converter_dir=\"C:/DDC/\")\r\n\r\n# Set progress callback\r\nconverter.set_progress_callback(print_progress)\r\n\r\n# Convert all files\r\nresult = converter.batch_convert(\r\n    input_folder=\"C:/Projects\",\r\n    output_folder=\"C:/Converted\",\r\n    include_subfolders=True\r\n)\r\n\r\nprint(f\"Success: {result.successful}/{result.total_files}\")\r\n```\r\n\r\n## Common Use Cases\r\n\r\n### 1. Convert Specific Formats Only\r\n```python\r\nresult = converter.batch_convert(\r\n    input_folder=\"C:/Archive\",\r\n    formats=['revit', 'ifc'],  # Only Revit and IFC\r\n    parallel=True,\r\n    max_workers=4\r\n)\r\n```\r\n\r\n### 2. With Format-Specific Options\r\n```python\r\noptions = {\r\n    'revit': ['complete', 'bbox', 'rooms'],\r\n    'ifc': ['bbox'],\r\n    'dwg': []\r\n}\r\nresult = converter.batch_convert(\r\n    input_folder=\"C:/Projects\",\r\n    options=options\r\n)\r\n```\r\n\r\n### 3. Generate Report\r\n```python\r\nresult = converter.batch_convert(\"C:/Projects\")\r\nreport = converter.generate_report(result, \"conversion_report.json\")\r\n```\r\n\r\n## Resources\r\n- **GitHub**: [cad2data Pipeline](https://github.com/datadrivenconstruction/cad2data-Revit-IFC-DWG-DGN-pipeline-with-conversion-validation-qto)\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn75fhjxn1jz5xbgd9ggj0nrtd80q1dz\",\n  \"slug\": \"batch-cad-converter\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1770474812467\n}","readmeExcerpt":"Skill: Batch Cad Converter Owner: datadrivenconstruction Summary: Batch convert multiple CAD/BIM files (Revit, IFC, DWG, DGN) with progress tracking, error handling, and consolidated reporting. Tags: latest:2.0.0 Version history: v2.0.0 | 2026-02-13T16:40:05.967Z | auto Batch CAD Converter 2.0.0 — Major Update - Adds unified batch conversion for Revit, IFC, DWG, and DGN files. - Enables robust progress tracking and r","codeSnippets":[],"executableExamples":[],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\r\nname: \"batch-cad-converter\"\r\ndescription: \"Batch convert multiple CAD/BIM files (Revit, IFC, DWG, DGN) with progress tracking, error handling, and consolidated reporting.\"\r\n---\r\n\r\n# Batch CAD/BIM Converter\r\n\r\n## Business Case\r\n\r\n### Problem Statement\r\nLarge projects and archives contain hundreds or thousands of CAD/BIM files:\r\n- Manual conversion is tedious and error-prone\r\n- Different formats require different converters\r\n- Progress tracking is needed for long operations\r\n- Error handling is critical for large batches\r\n\r\n### Solution\r\nUnified batch converter handling all supported formats with progress tracking, error recovery, and consolidated reporting.\r\n\r\n### Business Value\r\n- **Multi-format** - Revit, IFC, DWG, DGN in one workflow\r\n- **Error recovery** - Continue on failures\r\n- **Progress tracking** - Monitor large batches\r\n- **Reporting** - Consolidated conversion results\r\n\r\n## Python Implementation\r\n\r\n```python\r\nimport subprocess\r\nfrom pathlib import Path\r\nfrom typing import List, Optional, Dict, Any, Callable\r\nfrom dataclasses import dataclass, field\r\nfrom datetime import datetime\r\nimport time\r\nimport json\r\nfrom enum import Enum\r\nfrom concurrent.futures import ThreadPoolExecutor, as_completed\r\n\r\n\r\nclass CADFormat(Enum):\r\n    \"\"\"Supported CAD/BIM formats.\"\"\"\r\n    REVIT = (\".rvt\", \".rfa\")\r\n    IFC = (\".ifc\",)\r\n    DWG = (\".dwg\",)\r\n    DGN = (\".dgn\",)\r\n\r\n\r\nclass ConversionStatus(Enum):\r\n    \"\"\"Status of conversion operation.\"\"\"\r\n    PENDING = \"pending\"\r\n    CONVERTING = \"converting\"\r\n    SUCCESS = \"success\"\r\n    FAILED = \"failed\"\r\n    SKIPPED = \"skipped\"\r\n\r\n\r\n@dataclass\r\nclass ConversionResult:\r\n    \"\"\"Result of single file conversion.\"\"\"\r\n    input_file: str\r\n    output_file: Optional[str]\r\n    format: str\r\n    status: ConversionStatus\r\n    start_time: datetime\r\n    end_time: Optional[datetime]\r\n    duration_seconds: float\r\n    error_message: Optional[str] = None\r\n    file_size_kb: float = 0\r\n\r\n\r\n@dataclass\r\nclass BatchResult:\r\n    \"\"\"Result of batch conversion.\"\"\"\r\n    total_files: int\r\n    successful: int\r\n    failed: int\r\n    skipped: int\r\n    total_duration: float\r\n    results: List[ConversionResult]\r\n    start_time: datetime\r\n    end_time: datetime\r\n\r\n\r\nclass BatchCADConverter:\r\n    \"\"\"Batch convert multiple CAD/BIM files.\"\"\"\r\n\r\n    # Default converter paths\r\n    DEFAULT_CONVERTERS = {\r\n        'revit': 'RvtExporter.exe',\r\n        'ifc': 'IfcExporter.exe',\r\n        'dwg': 'DwgExporter.exe',\r\n        'dgn': 'DgnExporter.exe'\r\n    }\r\n\r\n    def __init__(self, converter_dir: str = \".\",\r\n                 converters: Dict[str, str] = None):\r\n        self.converter_dir = Path(converter_dir)\r\n        self.converters = converters or self.DEFAULT_CONVERTERS\r\n        self.results: List[ConversionResult] = []\r\n        self.progress_callback: Optional[Callable] = None\r\n\r\n    def set_progress_callback(self, callback: Callable[[int, int, str], None]):\r\n        \"\"\"Set callback for progress updates.\"\"\"\r\n        self.progress_callback = callback\r\n\r"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn75fhjxn1jz5xbgd9ggj0nrtd80q1dz\",\n  \"slug\": \"batch-cad-converter\",\n  \"version\": \"2.0.0\",\n  \"publishedAt\": 1771000805967\n}"},{"path":"instructions.md","content":"You are a batch CAD/BIM conversion assistant. You help users convert multiple files across formats (Revit, IFC, DWG, DGN) in a single automated run with progress tracking and error handling.\n\nWhen the user asks to batch convert files:\n1. Scan input directory for supported files (.rvt, .ifc, .dwg, .dgn)\n2. Auto-detect format and select appropriate converter\n3. Process each file with progress tracking (X of N completed)\n4. Handle errors gracefully — skip failed files, continue processing\n5. Generate consolidated report: successes, failures, output paths\n\nWhen the user asks to set up batch conversion:\n1. Help define input/output directory structure\n2. Configure per-format settings (IFC schema, DWG version, export mode)\n3. Set up file naming conventions for outputs\n4. Estimate processing time based on file count and sizes\n\n## Input Format\n- Input directory path containing CAD/BIM files\n- Output directory path for converted files\n- Optional: file format filter (e.g., only .rvt files)\n- Optional: per-format conversion settings\n\n## Output Format\n- Converted files in output directory (one Excel per input file)\n- Batch report: total files, successful, failed, processing time\n- Error log with specific failure reasons per file\n- Consolidated summary Excel combining data from all files\n\n## Supported Formats\n| Format | Extension | Converter |\n|--------|-----------|-----------|\n| Revit | .rvt, .rfa | RvtExporter |\n| IFC | .ifc | IfcExporter / IfcOpenShell |\n| AutoCAD | .dwg | DwgExporter |\n| MicroStation | .dgn | DgnExporter |\n\n## Constraints\n- Filesystem permission required for reading/writing files\n- subprocess.run() is used for invoking format-specific CLI converters\n- Each converter must be installed locally\n- Failed files are logged but do not stop the batch"},{"path":"claw.json","content":"{\n  \"name\": \"batch-cad-converter\",\n  \"version\": \"2.0.0\",\n  \"description\": \"Batch convert multiple CAD/BIM files (Revit, IFC, DWG, DGN) with progress tracking, error handling, and consolidated reporting.\",\n  \"author\": \"datadrivenconstruction\",\n  \"license\": \"MIT\",\n  \"permissions\": [\"filesystem\"],\n  \"entry\": \"instructions.md\",\n  \"tags\": [\"construction\", \"CAD\", \"BIM\", \"batch-processing\", \"data-conversion\", \"automation\"],\n  \"models\": [\"claude-*\", \"gpt-*\"],\n  \"minOpenClawVersion\": \"0.8.0\"\n}"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Batch convert multiple CAD/BIM files (Revit, IFC, DWG, DGN) with progress tracking, error handling, and consolidated reporting. Skill: Batch Cad Converter Owner: datadrivenconstruction Summary: Batch convert multiple CAD/BIM files (Revit, IFC, DWG, DGN) with progress tracking, error handling, and consolidated reporting. Tags: latest:2.0.0 Version history: v2.0.0 | 2026-02-13T16:40:05.967Z | auto Batch CAD Converter 2.0.0 — Major Update - Adds unified batch conversion for Revit, IFC, DWG, and DGN files. - Enables robust progress tracking and r","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1121,"uniquenessScore":45,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T14:38:53.967Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T14:38:53.967Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T17:34:50.372Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}