Integration Testing
thedaviddias/Front-End-Checklist
A skill your agent uses when reviewing CI coverage, automated checks, or test strategy related to Write integration tests for key workflows.
Agent skill
by datadrivenconstruction in datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction
Integrate open construction datasets. An agent skill from datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction.
$ npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill open-data-integrator -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction open-data-integrator --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction.git skills-src && mkdir -p .claude/skills && cp -r skills-src/2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator .claude/skills/open-data-integrator && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "open-data-integrator" agent skill from https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction/tree/main/2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator into .claude/skills/open-data-integrator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "open-data-integrator", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction/tree/main/2_DDC_Book/2.2-Open-Data-Standards/open-data-integratorType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill open-data-integrator -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction open-data-integrator --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction.git skills-src && mkdir -p .agents/skills && cp -r skills-src/2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator .agents/skills/open-data-integrator && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "open-data-integrator" agent skill from https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction/tree/main/2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator into .agents/skills/open-data-integrator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "open-data-integrator", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill open-data-integrator -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction open-data-integrator --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator .cursor/skills/open-data-integrator && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "open-data-integrator" agent skill from https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction/tree/main/2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator into .cursor/skills/open-data-integrator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "open-data-integrator", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction.git --path 2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill open-data-integrator -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction open-data-integrator --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator .gemini/skills/open-data-integrator && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "open-data-integrator" agent skill from https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction/tree/main/2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator into .gemini/skills/open-data-integrator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "open-data-integrator", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction open-data-integratorInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill open-data-integrator -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction.git skills-src && mkdir -p .github/skills && cp -r skills-src/2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator .github/skills/open-data-integrator && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "open-data-integrator" agent skill from https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction/tree/main/2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator into .github/skills/open-data-integrator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "open-data-integrator", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill open-data-integrator -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction open-data-integrator --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator .opencode/skills/open-data-integrator && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "open-data-integrator" agent skill from https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction/tree/main/2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator into .opencode/skills/open-data-integrator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "open-data-integrator", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
open-data-integratorIntegrate open construction datasets. An agent skill from datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction.
Open Data Integrator is an agent skill from datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction. Integrate open construction datasets. Combine open data sources for enhanced analysis
Its SKILL.md is about 5k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files (for example `claw.json` and `instructions.md`).
The repository describes itself as: 221 AI skills for construction: BIM analysis, cost estimation, scheduling, document control, and automation with Claude Code. The licence is MIT.
Read from SKILL.md and the folder at commit ce45bbf. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are python).
From the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
api.openweathermap.orgAlso links to:
datadrivenconstruction.ioFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Open Data Integrator loads about 5k tokens when it runs. Until then it costs about 27 tokens; SKILL.md has 105 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction at commit ce45bbf, republished under its MIT licence (© datadrivenconstruction). 105 words, ~5,003 tokens.
.claude/skills/open-data-integrator/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.Based on DDC methodology (Chapter 2.2), this skill integrates open construction datasets from various sources like government databases, industry benchmarks, weather services, and geospatial data.
Book Reference: "Доминирование открытых данных" / "Open Data Dominance"
from dataclasses import dataclass, field
from enum import Enum
from typing import List, Dict, Optional, Any, Callable
from datetime import datetime, date
import json
import requests
from abc import ABC, abstractmethod
class DataSourceType(Enum):
"""Types of open data sources"""
GOVERNMENT = "government" # Government statistics
INDUSTRY_BENCHMARK = "benchmark" # Industry benchmarks
WEATHER = "weather" # Weather data
GEOSPATIAL = "geospatial" # Geographic data
MATERIAL_PRICES = "material_prices" # Material cost indices
LABOR_RATES = "labor_rates" # Labor cost data
BUILDING_PERMITS = "permits" # Permit data
ENERGY = "energy" # Energy prices/data
ECONOMIC = "economic" # Economic indicators
class UpdateFrequency(Enum):
"""Data update frequency"""
REALTIME = "realtime"
HOURLY = "hourly"
DAILY = "daily"
WEEKLY = "weekly"
MONTHLY = "monthly"
QUARTERLY = "quarterly"
ANNUAL = "annual"
@dataclass
class OpenDataSource:
"""Definition of an open data source"""
id: str
name: str
source_type: DataSourceType
url: str
api_key_required: bool = False
update_frequency: UpdateFrequency = UpdateFrequency.DAILY
format: str = "json"
license: str = "open"
description: Optional[str] = None
fields: List[str] = field(default_factory=list)
@dataclass
class DataRecord:
"""A single data record from a source"""
source_id: str
timestamp: datetime
data: Dict[str, Any]
metadata: Dict[str, Any] = field(default_factory=dict)
@dataclass
class IntegrationResult:
"""Result of data integration"""
source: str
records_fetched: int
records_processed: int
errors: List[str]
last_updated: datetime
sample_data: List[Dict]
@dataclass
class EnrichedData:
"""Data enriched with open data"""
original_data: Dict[str, Any]
enrichments: Dict[str, Any]
sources_used: List[str]
confidence: float
class OpenDataConnector(ABC):
"""Base class for open data connectors"""
@abstractmethod
def fetch(self, params: Dict) -> List[DataRecord]:
pass
@abstractmethod
def get_metadata(self) -> Dict:
pass
class WeatherDataConnector(OpenDataConnector):
"""Connector for weather data (e.g., OpenWeatherMap)"""
def __init__(self, api_key: Optional[str] = None):
self.api_key = api_key
self.base_url = "https://api.openweathermap.org/data/2.5"
def fetch(
self,
params: Dict
) -> List[DataRecord]:
"""Fetch weather data for location"""
lat = params.get("lat")
lon = params.get("lon")
start_date = params.get("start_date")
end_date = params.get("end_date")
# Simulate API call (in production, use actual API)
records = []
# Generate sample historical data
current = start_date
while current <= end_date:
records.append(DataRecord(
source_id="openweathermap",
timestamp=datetime.combine(current, datetime.min.time()),
data={
"date": current.isoformat(),
"temp_max": 25.0,
"temp_min": 15.0,
"precipitation": 0.0,
"wind_speed": 10.0,
"weather_code": "clear"
},
metadata={"lat": lat, "lon": lon}
))
current = date(current.year, current.month, current.day + 1) if current.day < 28 else date(current.year, current.month + 1 if current.month < 12 else 1, 1)
return records[:30] # Limit for demo
def get_metadata(self) -> Dict:
return {
"source": "OpenWeatherMap",
"type": DataSourceType.WEATHER.value,
"frequency": UpdateFrequency.HOURLY.value,
"fields": ["temp_max", "temp_min", "precipitation", "wind_speed"]
}
class MaterialPriceConnector(OpenDataConnector):
"""Connector for material price indices"""
def __init__(self, region: str = "US"):
self.region = region
self.price_indices = self._load_indices()
def _load_indices(self) -> Dict[str, Dict]:
"""Load material price indices"""
return {
"concrete": {"base": 100, "current": 125, "trend": "up"},
"steel": {"base": 100, "current": 145, "trend": "up"},
"lumber": {"base": 100, "current": 180, "trend": "stable"},
"copper": {"base": 100, "current": 135, "trend": "up"},
"asphalt": {"base": 100, "current": 115, "trend": "stable"},
"gypsum": {"base": 100, "current": 110, "trend": "stable"},
"glass": {"base": 100, "current": 105, "trend": "down"},
"cement": {"base": 100, "current": 120, "trend": "up"},
}
def fetch(self, params: Dict) -> List[DataRecord]:
"""Fetch material price data"""
materials = params.get("materials", list(self.price_indices.keys()))
records = []
for material in materials:
if material in self.price_indices:
records.append(DataRecord(
source_id="material_prices",
timestamp=datetime.now(),
data={
"material": material,
"region": self.region,
**self.price_indices[material]
}
))
return records
def get_metadata(self) -> Dict:
return {
"source": "Material Price Index",
"type": DataSourceType.MATERIAL_PRICES.value,
"frequency": UpdateFrequency.MONTHLY.value,
"materials": list(self.price_indices.keys())
}
class LaborRateConnector(OpenDataConnector):
"""Connector for labor rate data"""
def __init__(self, region: str = "US"):
self.region = region
self.labor_rates = self._load_rates()
def _load_rates(self) -> Dict[str, Dict]:
"""Load labor rates by trade"""
return {
"carpenter": {"hourly": 45.00, "burden_rate": 1.35},
"electrician": {"hourly": 55.00, "burden_rate": 1.40},
"plumber": {"hourly": 52.00, "burden_rate": 1.38},
"ironworker": {"hourly": 58.00, "burden_rate": 1.42},
"laborer": {"hourly": 32.00, "burden_rate": 1.30},
"operator": {"hourly": 48.00, "burden_rate": 1.35},
"mason": {"hourly": 50.00, "burden_rate": 1.36},
"painter": {"hourly": 38.00, "burden_rate": 1.32},
"hvac_tech": {"hourly": 54.00, "burden_rate": 1.38},
"welder": {"hourly": 52.00, "burden_rate": 1.40},
}
def fetch(self, params: Dict) -> List[DataRecord]:
"""Fetch labor rate data"""
trades = params.get("trades", list(self.labor_rates.keys()))
records = []
for trade in trades:
if trade in self.labor_rates:
rate_data = self.labor_rates[trade]
records.append(DataRecord(
source_id="labor_rates",
timestamp=datetime.now(),
data={
"trade": trade,
"region": self.region,
"hourly_rate": rate_data["hourly"],
"burden_rate": rate_data["burden_rate"],
"fully_loaded": rate_data["hourly"] * rate_data["burden_rate"]
}
))
return records
def get_metadata(self) -> Dict:
return {
"source": "Labor Rate Database",
"type": DataSourceType.LABOR_RATES.value,
"frequency": UpdateFrequency.QUARTERLY.value,
"trades": list(self.labor_rates.keys())
}
class BuildingPermitConnector(OpenDataConnector):
"""Connector for building permit data"""
def __init__(self, jurisdiction: str = "default"):
self.jurisdiction = jurisdiction
def fetch(self, params: Dict) -> List[DataRecord]:
"""Fetch permit data"""
# Simulate permit data
permit_types = ["new_construction", "renovation", "addition", "demolition"]
records = []
for ptype in permit_types:
records.append(DataRecord(
source_id="building_permits",
timestamp=datetime.now(),
data={
"permit_type": ptype,
"jurisdiction": self.jurisdiction,
"count_ytd": 150,
"total_value": 25000000,
"avg_processing_days": 21
}
))
return records
def get_metadata(self) -> Dict:
return {
"source": "Building Permit Database",
"type": DataSourceType.BUILDING_PERMITS.value,
"frequency": UpdateFrequency.DAILY.value
}
class OpenDataIntegrator:
"""
Integrate open construction datasets.
Based on DDC methodology Chapter 2.2.
"""
def __init__(self, region: str = "US"):
self.region = region
self.connectors: Dict[str, OpenDataConnector] = {}
self.cache: Dict[str, List[DataRecord]] = {}
self.cache_expiry: Dict[str, datetime] = {}
self._register_default_connectors()
def _register_default_connectors(self):
"""Register default data connectors"""
self.register_connector("weather", WeatherDataConnector())
self.register_connector("material_prices", MaterialPriceConnector(self.region))
self.register_connector("labor_rates", LaborRateConnector(self.region))
self.register_connector("permits", BuildingPermitConnector())
def register_connector(
self,
name: str,
connector: OpenDataConnector
):
"""Register a data connector"""
self.connectors[name] = connector
def fetch_data(
self,
source: str,
params: Optional[Dict] = None,
use_cache: bool = True
) -> IntegrationResult:
"""
Fetch data from a source.
Args:
source: Name of the data source
params: Query parameters
use_cache: Whether to use cached data
Returns:
Integration result with fetched data
"""
if source not in self.connectors:
return IntegrationResult(
source=source,
records_fetched=0,
records_processed=0,
errors=[f"Unknown source: {source}"],
last_updated=datetime.now(),
sample_data=[]
)
# Check cache
cache_key = f"{source}_{json.dumps(params or {}, sort_keys=True)}"
if use_cache and cache_key in self.cache:
expiry = self.cache_expiry.get(cache_key)
if expiry and expiry > datetime.now():
cached = self.cache[cache_key]
return IntegrationResult(
source=source,
records_fetched=len(cached),
records_processed=len(cached),
errors=[],
last_updated=expiry,
sample_data=[r.data for r in cached[:5]]
)
# Fetch fresh data
connector = self.connectors[source]
errors = []
try:
records = connector.fetch(params or {})
# Cache the results
self.cache[cache_key] = records
self.cache_expiry[cache_key] = datetime.now()
return IntegrationResult(
source=source,
records_fetched=len(records),
records_processed=len(records),
errors=errors,
last_updated=datetime.now(),
sample_data=[r.data for r in records[:5]]
)
except Exception as e:
errors.append(str(e))
return IntegrationResult(
source=source,
records_fetched=0,
records_processed=0,
errors=errors,
last_updated=datetime.now(),
sample_data=[]
)
def enrich_project_data(
self,
project_data: Dict[str, Any],
enrichment_sources: Optional[List[str]] = None
) -> EnrichedData:
"""
Enrich project data with open data.
Args:
project_data: Original project data
enrichment_sources: Sources to use for enrichment
Returns:
Enriched data
"""
sources = enrichment_sources or ["material_prices", "labor_rates", "weather"]
enrichments = {}
sources_used = []
# Material price enrichment
if "material_prices" in sources and "materials" in project_data:
materials = project_data["materials"]
result = self.fetch_data("material_prices", {"materials": materials})
if result.records_fetched > 0:
enrichments["material_price_indices"] = result.sample_data
sources_used.append("material_prices")
# Labor rate enrichment
if "labor_rates" in sources and "trades" in project_data:
trades = project_data["trades"]
result = self.fetch_data("labor_rates", {"trades": trades})
if result.records_fetched > 0:
enrichments["labor_rates"] = result.sample_data
sources_used.append("labor_rates")
# Weather enrichment
if "weather" in sources and "location" in project_data:
loc = project_data["location"]
params = {
"lat": loc.get("lat"),
"lon": loc.get("lon"),
"start_date": project_data.get("start_date", date.today()),
"end_date": project_data.get("end_date", date.today())
}
result = self.fetch_data("weather", params)
if result.records_fetched > 0:
enrichments["weather_forecast"] = result.sample_data
sources_used.append("weather")
# Calculate confidence based on enrichment success
confidence = len(sources_used) / len(sources) if sources else 0
return EnrichedData(
original_data=project_data,
enrichments=enrichments,
sources_used=sources_used,
confidence=confidence
)
def get_cost_indices(
self,
materials: Optional[List[str]] = None,
trades: Optional[List[str]] = None
) -> Dict:
"""Get current cost indices"""
indices = {
"timestamp": datetime.now().isoformat(),
"region": self.region
}
if materials:
result = self.fetch_data("material_prices", {"materials": materials})
indices["materials"] = result.sample_data
if trades:
result = self.fetch_data("labor_rates", {"trades": trades})
indices["labor"] = result.sample_data
return indices
def get_weather_risk(
self,
lat: float,
lon: float,
start_date: date,
end_date: date
) -> Dict:
"""Assess weather risk for project period"""
result = self.fetch_data("weather", {
"lat": lat,
"lon": lon,
"start_date": start_date,
"end_date": end_date
})
if result.records_fetched == 0:
return {"error": "No weather data available"}
# Calculate risk metrics
rain_days = sum(1 for d in result.sample_data
if d.get("precipitation", 0) > 5)
extreme_temp_days = sum(1 for d in result.sample_data
if d.get("temp_max", 0) > 35 or d.get("temp_min", 0) < 0)
total_days = len(result.sample_data)
risk_score = (rain_days + extreme_temp_days) / total_days if total_days > 0 else 0
return {
"total_days": total_days,
"rain_days": rain_days,
"extreme_temperature_days": extreme_temp_days,
"risk_score": risk_score,
"risk_level": "high" if risk_score > 0.3 else "medium" if risk_score > 0.1 else "low"
}
def list_sources(self) -> List[Dict]:
"""List all available data sources"""
sources = []
for name, connector in self.connectors.items():
meta = connector.get_metadata()
sources.append({
"name": name,
**meta
})
return sources
def generate_report(self) -> str:
"""Generate data availability report"""
output = """
# Open Data Integration Report
## Available Sources
"""
for source in self.list_sources():
output += f"""
### {source['name'].title()}
- **Type:** {source['type']}
- **Update Frequency:** {source['frequency']}
"""
output += """
## Cache Status
"""
for key, expiry in self.cache_expiry.items():
status = "valid" if expiry > datetime.now() else "expired"
output += f"- {key}: {status}\n"
return outputintegrator = OpenDataIntegrator(region="US")
# Get material price indices
result = integrator.fetch_data("material_prices", {
"materials": ["concrete", "steel", "lumber"]
})
print(f"Fetched: {result.records_fetched} records")
for record in result.sample_data:
print(f" {record['material']}: index={record['current']}, trend={record['trend']}")project = {
"name": "Office Building",
"materials": ["concrete", "steel", "glass"],
"trades": ["carpenter", "electrician", "plumber"],
"location": {"lat": 40.7128, "lon": -74.0060},
"start_date": date(2024, 6, 1),
"end_date": date(2024, 12, 31)
}
enriched = integrator.enrich_project_data(project)
print(f"Sources used: {enriched.sources_used}")
print(f"Confidence: {enriched.confidence:.0%}")
print(f"Material indices: {enriched.enrichments.get('material_price_indices')}")risk = integrator.get_weather_risk(
lat=40.7128,
lon=-74.0060,
start_date=date(2024, 6, 1),
end_date=date(2024, 8, 31)
)
print(f"Risk Level: {risk['risk_level']}")
print(f"Rain Days: {risk['rain_days']}")| Component | Purpose |
|---|---|
OpenDataIntegrator | Main integration engine |
OpenDataConnector | Base connector class |
WeatherDataConnector | Weather API connector |
MaterialPriceConnector | Material price indices |
LaborRateConnector | Labor rate data |
EnrichedData | Enriched data result |
© datadrivenconstruction, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 2 other files in 2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator of datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction.
Open the folder on GitHubat commit ce45bbf
We found 1 copy of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction, which our catalogue first saw on October 7, 2026.
Open Data Integrator next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Open Data Integrator this skilldatadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction | 344 | 1 repos | ~5k | Automated safety check: Pass | MIT | |
| Integration Testingthedaviddias/Front-End-Checklist | 74k | — | ~514 | Automated safety check: Pass | MIT | |
| API Integrationsickn33/agentic-awesome-skills | 47k | 1 repos | ~1.3k | Automated safety check: Pass | MIT | |
| Integrations Lifecyclenetdata/netdata | 81k | — | ~1.3k | Automated safety check: Pass | GPL-3.0 | |
| Labarchive Integrationdavila7/claude-code-templates | 32k | 10 repos | ~2.3k | Automated safety check: Pass | MIT | |
| Mem0 Integration Pipelinemem0ai/mem0 | 67k | — | ~3.3k | Automated safety check: Pass | Apache-2.0 |
thedaviddias/Front-End-Checklist
A skill your agent uses when reviewing CI coverage, automated checks, or test strategy related to Write integration tests for key workflows.
sickn33/agentic-awesome-skills
Designs event-driven architectures, webhook systems, API chaining flows, ETL pipelines, and integration patterns between services.
netdata/netdata
Change or review the Netdata integrations pipeline, collector artifact consistency, metadata validation, generated docs/catalogs and source-versus-runtime delivery.
davila7/claude-code-templates
Electronic lab notebook API integration. An agent skill from davila7/claude-code-templates.
mem0ai/mem0
Adds Mem0 memory to an existing repository with a test-first pipeline that detects the language, lets you choose Platform or open source, and leaves a local feature branch.
Arize-ai/phoenix
Understand what a Phoenix dataset is and reason well about its examples, outputs, splits, and how it feeds evaluators and experiments.
datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction
Orchestrate multiple AI agents for construction workflows: estimator, scheduler, document, QA and safety agents coordinated by a supervisor agent, with human checkpoints.
datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction
Estimate embodied carbon and produce ESG/climate reporting for construction: LCA per work item, material-based carbon factors, EU taxonomy and CSRD alignment.
datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction
Material passports and circular construction: generate per-element material inventories from BOQ/BIM, mark reuse potential and recycled content, and prepare deconstruction data.
datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction
Browse and search the OpenConstructionERP cost database: classification tree, SQL and semantic search, autocomplete, certainty badges, and the resource catalog.
datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction
Create bills of quantities and estimates in OpenConstructionERP: search cost items, build BOQ sections, link BIM elements in bulk, validate the BOQ, and export GAEB/XLSX/JSON.
datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction
Field operations in OpenConstructionERP: punch list, daily diary, HSE observations and task tracking on site.
Integrate open construction datasets. An agent skill from datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction. Open Data Integrator is an agent skill from datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction. Integrate open construction datasets.
Run `npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill open-data-integrator -a claude-code`. Or copy the skill folder (2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator in datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction) into .claude/skills/open-data-integrator in your project. Claude Code loads it when a task matches its description.
Run `npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill open-data-integrator -a codex`. Or copy the skill folder (2_DDC_Book/2.2-Open-Data-Standards/open-data-integrator in datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction) into .agents/skills/open-data-integrator in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill open-data-integrator -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/open-data-integrator, .gemini/skills/open-data-integrator, .github/skills/open-data-integrator and .opencode/skills/open-data-integrator in your project.
SKILL.md names no scripts, command-line tools or credentials: Open Data Integrator is instructions for the agent only. Our summary lists: Python 3.
SKILL.md names 2 domains. In commands or code: api.openweathermap.org; the agent is likely to contact it when it follows the instructions. As links in the text: datadrivenconstruction.io. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Open Data Integrator is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 5k tokens (SKILL.md is roughly 20k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Open Data Integrator: Integration Testing (thedaviddias/Front-End-Checklist, 74k stars), API Integration (sickn33/agentic-awesome-skills, 47k stars), Integrations Lifecycle (netdata/netdata, 81k stars) and Labarchive Integration (davila7/claude-code-templates, 32k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
datadrivenconstruction (a GitHub user) maintains it in datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction, which has 344 GitHub stars. The repository holds 43 skills in this directory. The repository was last updated on August 22, 2026.
Source: datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.