con un clic
add-source
Step-by-step guide for adding a new data source to the Federal Website Index
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Menú
Step-by-step guide for adding a new data source to the Federal Website Index
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Basado en la clasificación ocupacional SOC
| name | add-source |
| description | Step-by-step guide for adding a new data source to the Federal Website Index |
| trigger | Use when user wants to add a new source list, integrate a new dataset, or expand coverage with additional data sources |
Guide for adding a new data source to the Federal Website Index.
Add a new source list when:
A valid source must:
Edit builder/src/types/config.ts:
export enum SourceList {
// ... existing entries ...
MY_NEW_SOURCE = "MY_NEW_SOURCE",
}
Use SCREAMING_SNAKE_CASE for the enum name.
Edit builder/src/config/source-list.config.ts:
export const sourceListConfig: SourceListConfigMap = {
// ... existing entries ...
[SourceList.MY_NEW_SOURCE]: {
shortName: "my_source", // Used for snapshot filename
sourceUrl: "https://example.gov/data.csv", // Or local path
sourceColumnName: "source_list_my_source", // Column in final output
hasHeaders: true, // Does CSV have header row?
},
};
Notes:
shortName: lowercase, underscores, no spacessourceColumnName: prefix with source_list_ for consistencysourceUrl: Can be HTTP URL or local path using path.join(__dirname, '...')hasHeaders: Set to false if CSV has no header rowCreate builder/src/services/source-lists/MyNewSourceList.ts:
import { DataFrame } from "dataframe-js";
import { sourceListConfig } from "../../config/source-list.config";
import { SourceList } from "../../types/config";
export class MyNewSourceList {
static async loadData(): Promise<DataFrame> {
const config = sourceListConfig[SourceList.MY_NEW_SOURCE];
// Load CSV from URL or file
const df = await DataFrame.fromCSV(config.sourceUrl);
// Transform to standard format with 'initial_url' column
// Example: if source has 'domain' column, rename it
let processedDf = df.select("domain").rename("domain", "initial_url");
// Add source tracking column
processedDf = processedDf.withColumn(
config.sourceColumnName,
() => "TRUE"
);
// Clean URLs (remove protocols, www., paths)
processedDf = processedDf.withColumn("initial_url", (row) => {
let url = row.get("initial_url");
url = url.replace(/^https?:\/\//, ""); // Remove protocol
url = url.replace(/^www\./, ""); // Remove www.
url = url.split("/")[0]; // Remove paths
return url;
});
// Write snapshot for debugging
const snapshotPath = path.join(
__dirname,
`../../../data/source-list-snapshots/${config.shortName}.csv`
);
await processedDf.toCSV(true, snapshotPath);
return processedDf;
}
}
Key patterns:
static async loadData() method returning Promise<DataFrame>initial_url column (normalized URL)source_list_my_source)data/source-list-snapshots/Edit builder/src/main.ts:
Add import at top:
import { MyNewSourceList } from './services/source-lists/MyNewSourceList';
Add to fetchAllSourceListData() function:
async function fetchAllSourceListData(): Promise<DataFrame[]> {
return Promise.all([
// ... existing sources ...
MyNewSourceList.loadData(),
// [SOURCE-ADD-POINT]
// Add new source list configuration here
]);
}
Add column default in setSourceListColumnDefaults():
function setSourceListColumnDefaults(allSites: DataFrame) {
return allSites.replace("", "FALSE", [
// ... existing columns ...
sourceListConfig[SourceList.MY_NEW_SOURCE].sourceColumnName,
]);
}
Run the builder:
cd builder
bun src/main.ts
Check outputs:
Source snapshot: data/source-list-snapshots/my_source.csv
initial_url and source_list_my_source columnsAfter union: data/process-snapshots/after-union.csv
Final output: data/site-scanning-target-url-list.csv
source_list_my_source = TRUEAnalysis report: data/site-scanning-target-url-list-analysis.csv
Possible reasons:
criteria/ignore-list-*.csvcriteria/suspected-dead-sites.csvCheck data/process-snapshots/after-dead-sites-filter-removed.csv to see what was removed.
curl <url>sourceColumnName is uniquesource_list_<name>sourceUrl: "https://example.gov/data.csv"
sourceUrl: path.join(__dirname, "../../../data/source-lists/my-data.csv")
hasHeaders: false
Then in class, manually add column names:
let df = await DataFrame.fromCSV(config.sourceUrl, false);
df = df.rename("0", "initial_url"); // Rename first column
After adding a source, update:
README.md - Add to list of datasetsdata/source-descriptions/ - Create markdown file describing the source