Target design

This example uses the planned manifest and Host API (Writing an Extension Part B), which are not built. A working example of today’s API is Part A of the same page.

A static extension (native driver ⇒ desktop/server) adding a hypothetical “CSV directory” source. Shows the source contribution point (Contribution Points) and the lifting rules (Data Sources).

[[contributes.source]]
family = "sql"
dialect = "csvdir"
form = [{ name = "path", kind = "directory", label = "Folder of CSV files" }]
platforms = ["desktop", "server"]
struct CsvDirFactory;
impl SourceFactory for CsvDirFactory {
    fn connect(&self, params: ConnectParams) -> Result<Box<dyn Source>, SourceError> {
        // open DuckDB in-memory, `CREATE VIEW <file> AS SELECT * FROM read_csv_auto(...)` per file
    }
}
 
impl Source for CsvDirSource {
    fn descriptor(&self) -> SourceDescriptor {
        // family Sql, dialect csvdir, capabilities READ | TEXT_QUERY(Sql) | FULLTEXT
        // schema graph: one Table node per file, Column nodes with Contains edges
    }
    async fn query(&self, q: Query) -> Result<QueryResult, SourceError> {
        // structured → SQL via moonkale_sources_sql::structured; rows → Row nodes
        // ids: derive(source_id, table, row_number) — flagged unstable (no PK)
    }
    async fn fetch(&self, id: NodeId) -> Result<Content, SourceError> { /* one row as props */ }
    async fn apply(&self, _tx: Transaction) -> Result<Applied, SourceError> {
        Ok(Applied::all_unsupported("csvdir is read-only"))
    }
    fn subscribe(&self) -> BoxStream<'static, SourceEvent> { /* watch dir via project-fs::watch */ }
}
 
moonkale_ext_api::export!(CsvDirExt);   // registers the factory in activate()

What the user gets for free: the explorer shows tables, the Table Editor pages rows, the Graph View shows the schema graph, [[sales.csv]] resolves from a wiki page, and the agent can run SELECT against it (policy: read-only source ⇒ writes impossible).

Web users see the same source if the server has the extension installed — the shell routes through RemoteSource (ADR-0005 Server functions as the remote backend).