dataframe / dataframe-jdbc
AGENTS.md1.1k starsChanged 26 days agoApache-2.0View on GitHub
Guidance for this module. See the root AGENTS.md for repo-wide build/style/KoDEx rules; only module-specific details are here. dataframe-jdbc (artifact dataframe-jdbc, "JDBC support for Kotlin DataFrame"). Reads SQL tables, queries, ResultSets, DataSources, and whole schemas from any JDBC database into a DataFrame, mapping SQL types to Kotlin types. Depends only on core. No JDBC driver is shipped for any database — users always bring their own driver on the runtime classpath (this applies equally to H2, MySQL, MariaDB, MSSQL, PostgreSQL, SQLite,…
Trending
Less talk lately.about the whole repository
Who's talking about Kotlin/dataframe
- Kotlin/kandy“Support compose multiplatform”GitHub · Dec 14, 2023 · 45 reactions
- Kotlin/kotlin-agent-skills“Add a Skill for working with Kotlin DataFrame”GitHub · May 19, 2026 · 6 reactions
- deephaven/deephaven-csv“Read files with different encodings”GitHub · Nov 11, 2025 · 2 reactions
- Velkonost/sssss“deps(gradle): bump org.jetbrains.kotlinx:dataframe from 0.13.1 to 0.15.0”GitHub · Oct 15, 2025 · 2 reactions
- jeremymailen/kotlinter-gradle“Wired issues when Upgrading to Kotlin 1.8.20 ”GitHub · Apr 12, 2023 · 2 reactions
The biggest 5 of 51 mentions linking to the repository that our crawl found. Each line is their own headline.
See all 51
Talked about on GitHub and Bluesky (51 times).
On GitHub · 50
- Dec 14, 2023Support compose multiplatform — Kotlin/kandy45 reactions · 7 comments
- May 19, 2026Add a Skill for working with Kotlin DataFrame — Kotlin/kotlin-agent-skills6 reactions
- Nov 11, 2025Read files with different encodings — deephaven/deephaven-csv2 reactions · 2 comments
- Oct 15, 2025deps(gradle): bump org.jetbrains.kotlinx:dataframe from 0.13.1 to 0.15.0 — Velkonost/sssss2 reactions · 1 comment
- Apr 12, 2023Wired issues when Upgrading to Kotlin 1.8.20 — jeremymailen/kotlinter-gradle2 reactions · 9 comments
45 more on GitHub
- Sep 25, 2026fix(deps): update all dependencies — salesforce-misc/ReVoman1 reaction · 1 comment
- Dec 9, 2024chore(deps): update dependency org.jetbrains.kotlinx:dataframe to v0.15.0 — Kotlin/kotlin-jupyter-libraries1 reaction
- May 27, 2024Remove `concatFixed()` — Kotlin/kandy1 reaction
- Nov 1, 2026build(deps): bump kotlinx-dataframe from 1.0.0-rc02 to 1.0.0-rc02n — sureshg/native-image-playground0 reactions · 2 comments
- Oct 30, 2026[KDF] Support columnOf(vararg DataFrame) FrameColumn creation — JetBrains/kotlin0 reactions · 18 comments
- Oct 29, 2026Move `@sample` after the removal of escape characters — Jolanrensen/KoDEx0 reactions · 2 comments
- Oct 26, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-rc02 to 1.0.0-rc02n — sureshg/build-commons0 reactions
- Oct 19, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-rc01 to 1.0.0-rc02n — sureshg/kotlin-mpp-playground0 reactions · 2 comments
- Oct 19, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-rc02 to 1.0.0-rc02n — sureshg/build-commons0 reactions
- Oct 16, 2026Fix generated jars and support publishing KoDEx-processed artifacts — Jolanrensen/KoDEx0 reactions
- Oct 15, 2026chore(deps): update dependency org.jetbrains.kotlinx:dataframe-geo to v1.0.0-rc02n - autoclosed — Kotlin/kotlin-jupyter-libraries0 reactions
- Oct 12, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-rc01 to 1.0.0-rc01n — sureshg/build-commons0 reactions
- Oct 7, 2026[KDF] (Attempt 2) Fixed return type mismatch report, like when using `add {}` — JetBrains/kotlin0 reactions · 12 comments
- Oct 5, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-rc01 to 1.0.0-rc01n — sureshg/build-commons0 reactions
- Oct 2, 2026[KDF] Fixed return type mismatch report, like when using `add {}` — JetBrains/kotlin0 reactions · 8 comments
- Oct 1, 2026build(deps): bump kotlinx-dataframe from 1.0.0-rc01 to 1.0.0-rc01n — sureshg/native-image-playground0 reactions · 2 comments
- Sep 28, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-rc01 to 1.0.0-rc01n — sureshg/build-commons0 reactions
- Sep 21, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-rc01 to 1.0.0-rc01n — sureshg/build-commons0 reactions
- Sep 14, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-rc01 to 1.0.0-rc01n — sureshg/build-commons0 reactions
- Sep 11, 2026Bump org.jetbrains.kotlinx:dataframe from 1.0.0-rc01 to 1.0.0-rc01n — linde9821/epa-visualizer0 reactions
- Sep 7, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-rc01 to 1.0.0-rc01n — sureshg/build-commons0 reactions
- Aug 31, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-rc01 to 1.0.0-rc01n — sureshg/build-commons0 reactions
- Aug 24, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-rc01 to 1.0.0-rc01n — sureshg/build-commons0 reactions
- Aug 21, 2026[Feature] Create a preprocessor that adds/creates reference aliases with codespans — Jolanrensen/KoDEx0 reactions
- Aug 10, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-rc01 to 1.0.0-rc01n — sureshg/build-commons0 reactions
- Aug 3, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-rc01 to 1.0.0-rc01n — sureshg/build-commons0 reactions
- Aug 1, 2026build(deps): bump kotlinx-dataframe from 1.0.0-rc01 to 1.0.0-rc01n — sureshg/native-image-playground0 reactions · 2 comments
- Jul 27, 2026Bumped built-in dataframe version to 1.0.0-rc01 — JetBrains/kotlin-toolchain0 reactions · 3 comments
- Jul 27, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-rc01 to 1.0.0-rc01n — sureshg/build-commons0 reactions
- Jul 20, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-Beta5 to 1.0.0-rc01n — sureshg/kotlin-mpp-playground0 reactions · 2 comments
- Jul 20, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-Beta5 to 1.0.0-Beta5n — sureshg/build-commons0 reactions
- Jul 13, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-Beta5 to 1.0.0-Beta5n — sureshg/build-commons0 reactions
- Jul 6, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-Beta5 to 1.0.0-Beta5n — sureshg/build-commons0 reactions
- Jul 1, 2026build(deps): bump kotlinx-dataframe from 1.0.0-Beta5 to 1.0.0-Beta5n — sureshg/native-image-playground0 reactions · 2 comments
- Jun 25, 2026Kotlin SWE benchmark contribution — multi-swe-bench/multi-swe-benchsays it tested it0 reactions
- Jun 22, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-Beta5 to 1.0.0-Beta5n — sureshg/build-commons0 reactions
- Jun 15, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-Beta5 to 1.0.0-Beta5n — sureshg/kotlin-mpp-playground0 reactions · 2 comments
- Jun 15, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-Beta5 to 1.0.0-Beta5n — sureshg/build-commons0 reactions
- Jun 8, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-Beta5 to 1.0.0-dev-10584 — sureshg/kotlin-mpp-playground0 reactions · 2 comments
- Jun 8, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-Beta5 to 1.0.0-dev-10535 — sureshg/build-commons0 reactions
- Jun 2, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-Beta5 to 1.0.0-dev-10508 — sureshg/build-commons0 reactions
- Jun 1, 2026build(deps): bump kotlinx-dataframe from 1.0.0-Beta5 to 1.0.0-dev-10508 — sureshg/native-image-playground0 reactions · 2 comments
- May 25, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-Beta5 to 1.0.0-dev-10485 — sureshg/build-commons0 reactions
- May 18, 2026chore(deps): bump kotlinx-dataframe from 1.0.0-Beta5 to 1.0.0-dev-10438 — sureshg/build-commons0 reactions
- Oct 29, 2025[K2] TranslatorError: from STATUS to IMPLICIT_TYPES_BODY_RESOLVE — Kotlin/dokka0 reactions · 3 comments
On Bluesky · 1
- May 19, 2025Kotlin DataFrame aims to reconcile Kotlin's static typing with the dynamic nature of data by utilizing both the full power of the Kotlin… — @ytroncal.bsky.social1 likes and repost
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,542 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository24 other files it gives its agents.
- AGENTS.mdAGENTS.md
- core/AGENTS.mdAGENTS.md
- dataframe-arrow/AGENTS.mdAGENTS.md
- dataframe-compiler-plugin-core/AGENTS.mdAGENTS.md
- dataframe-csv/AGENTS.mdAGENTS.md
- dataframe-excel/AGENTS.mdAGENTS.md
- dataframe-geo/AGENTS.mdAGENTS.md
- dataframe-json/AGENTS.mdAGENTS.md
- examples/AGENTS.mdAGENTS.md
- plugins/AGENTS.mdAGENTS.md
- samples/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- core/CLAUDE.mdCLAUDE.md
- dataframe-arrow/CLAUDE.mdCLAUDE.md
- dataframe-compiler-plugin-core/CLAUDE.mdCLAUDE.md
- dataframe-csv/CLAUDE.mdCLAUDE.md
- dataframe-excel/CLAUDE.mdCLAUDE.md
- dataframe-geo/CLAUDE.mdCLAUDE.md
- dataframe-jdbc/CLAUDE.mdCLAUDE.md
- dataframe-json/CLAUDE.mdCLAUDE.md
- examples/CLAUDE.mdCLAUDE.md
- plugins/CLAUDE.mdCLAUDE.md
- samples/CLAUDE.mdCLAUDE.md
- operation-website-documentationSkill
The file
We split this AGENTS.md into the rules it gives an agent
4 rules. About 0 are common, 0 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 49
A metadata fallback must not guess a column's nullability: When isNullable is unsupported, getTableColumnsMetadata looks the column up with …
- Very specific: line 103
Every read* function accepts an optional DbType argument.
- Very specific: line 121
Test layout under src/test/kotlin/.../io/ splits by how the DB is provided:
- Very specific: line 165
Test-only driver dependencies (MariaDB, MySQL, MSSQL, H2, SQLite, PostgreSQL, DuckDB, plus HikariCP and kotest-assertions) are declared …
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md — dataframe-jdbc
Guidance for this module. See the root AGENTS.md for repo-wide build/style/KoDEx rules; only module-specific
details are here.
What this module is
dataframe-jdbc (artifact dataframe-jdbc, "JDBC support for Kotlin DataFrame"). Reads SQL tables, queries,
ResultSets, DataSources, and whole schemas from any JDBC database into a DataFrame, mapping SQL types to
Kotlin types. Depends only on core.
No JDBC driver is shipped for any database — users always bring their own driver on the runtime classpath
(this applies equally to H2, MySQL, MariaDB, MSSQL, PostgreSQL, SQLite, DuckDB). DuckDB, SQLite, and PostgreSQL are
declared compileOnly for a different reason: the module's own code compiles against those drivers' specific API
classes (DuckDb.kt → org.duckdb.DuckDBColumnType.*; PostgreSql.kt → org.postgresql.geometric.PG*, PGobject;
Sqlite.kt → org.sqlite.SQLiteConfig), so their classes must be on the compile classpath but are deliberately
kept off the runtime classpath. The other DbTypes reference their driver only by class-name string
(e.g. "org.h2.Driver", "com.mysql.jdbc.Driver"), so they need no compile-time dependency at all.
Public API surface (src/main/kotlin/.../io/)
readJdbc.kt— the entry points, all asDataFrame.Companion/ receiver extensions:readSqlTable,readSqlQuery,readResultSet,readAllSqlTables, andreadDataFrameonDbConnectionConfig/Connection/DataSource/ResultSet. Each has overloads taking aDbConnectionConfig, an existingConnection, or aDataSource.DbConnectionConfig.kt— URL/user/password/readOnly config for library-managed connections.jdbcSchema.kt,readDataFrameSchema.kt— schema inference (for codegen /@DataSchema).
The DbType abstraction — the core of this module
io/db/DbType.kt is an abstract class keyed by dbTypeInJdbcUrl. Each supported database is a subclass:
H2, MariaDb, MySql, Sqlite, PostgreSql, MsSql, DuckDb (all in io/db/). extractDBTypeFromUrl(url)
in io/db/util.kt matches the JDBC URL substring to pick the instance (H2 additionally resolves its MODE —
MySQL/PostgreSQL/MSSQLServer/MariaDB/Regular — from the URL or a live connection).
The value-reading pipeline is a sequence of overridable open functions on DbType, applied per column. Understand
this chain before changing type mapping — the type variables J → D → P flow through it:
getTableColumnsMetadata(resultSet)→TableColumnMetadatalist (with defensive fallbacks for drivers like Hive that throwSQLFeatureNotSupportedException).- Type J (what the driver returns):
getExpectedJdbcType(...)givestypeOf<J>()— the typeResultSet.getObjectactually returns — andgetValueFromResultSet(...)extracts the actual value of type J (which must match that type exactly). - Type D:
getPreprocessedValueType(...)/preprocessValue(...)— Java→Kotlin conversions (e.g.Timestamp→kotlin.time.Instant,java.util.UUID→kotlin.uuid.Uuid). - Type P:
getTargetColumnSchema(...)→ColumnSchemaandbuildDataColumn(...)→ the finalDataColumn<P>(post-processesjava.sql.Array→Kotlin arrays).
A metadata fallback must not guess a column's nullability. When isNullable is unsupported,
getTableColumnsMetadata looks the column up with DatabaseMetaData.getColumns, whose name arguments are
patterns: H2, like other drivers, reads a null table or column pattern as "any", so a lookup with an unknown
name returns the IS_NULLABLE of some other column. A known name is a pattern too: _ and % are LIKE
wildcards, so is_active also matches an earlier isXactive. Look up only when both names are known, take only
the row whose TABLE_NAME and COLUMN_NAME equal them, and otherwise assume nullable. The two errors are not equal: a column wrongly read as nullable only gains a ?, while one
wrongly read as non-null fails to read with inferNullability = false.
H2 in a compatibility mode delegates type mapping to the emulated database's DbType (H2(Mode.MySql)
→ MySql, Mode.MsSqlServer → MsSql, and so on), but it reports its own metadata and returns its own
value classes. It delegates only getExpectedJdbcType: getValueFromResultSet, getPreprocessedValueType
and preprocessValue stay H2's own, so a delegated branch that fires for H2 declares a type that H2 then never
returns. So every condition in an overridden getExpectedJdbcType has to be chosen so that it excludes
H2, and which field does that differs per case: MariaDb keys its blob branch on jdbcType != Types.BLOB,
because H2 in MariaDB mode reports Types.BLOB and does return a real java.sql.Blob; MsSql keys its
Short branch on javaClassName, because H2 in MSSQL mode reports Types.SMALLINT too but returns an
Integer. Neither field is the right discriminator in general — io/h2/*H2Test.kt is the oracle that
decides, so run it before believing either.
SQLite is the case where neither field describes the column at all. The Xerial driver reports both
javaClassName and jdbcType from the storage class of the first row: a BIGINT column is reported as
Types.VARCHAR / String when its first row holds text, and as Types.FLOAT / Double when it holds a
real number. Only sqlTypeName — the declared type, verbatim from CREATE TABLE — stays the same whatever
the rows hold, so Sqlite keys its mappings on it (EmbeddedColumnTypeAuditTest pins this driver
behaviour). Before choosing a discriminator for any driver, probe it with a first row of every storage
class — NULL, a small and a large integer, a real number, text — not only with a representative value.
Other overridable behavior: quoteIdentifier (per-DB identifier quoting), buildSqlQueryWithLimit/
buildSelectTableQueryWithLimit, configureReadStatement (fetch size/direction, query timeout), createConnection
(SQLite needs read-only set at connect time), isSystemTable, buildTableMetadata, tableTypes.
Adding a new database or fixing type handling: subclass DbType, override only the functions that deviate from
the defaults, register it in extractDBTypeFromUrl, and copy the KDoc structure from a sibling like PostgreSql.kt.
For databases with structured/composite types, subclass AdvancedDbType instead (see next section).
AdvancedDbType — for structured types / heavy per-type mapping (experimental)
io/db/AdvancedDbType.kt is an alternative base class (abstract class AdvancedDbType : DbType, experimental,
API subject to change). Instead of overriding the individual open pipeline functions, it final-overrides the
whole J → D → P chain and routes every column through a single per-column JdbcToDataFrameConverter
(io/db/JdbcToDataFrameConverter.kt). A subclass implements just one method —
protected abstract fun generateConverter(tableColumnMetadata): AnyJdbcToDataFrameConverter — and the returned
converter supplies the expected JDBC type, preprocessed type, target schema, value extraction, and column building.
Converters are cached per CacheKey(sqlTypeName, jdbcType, size, javaClassName, isNullable).
When to use which: extend plain DbType for ordinary relational databases where you only tweak a few functions
(type mapping, quoting, limits, system-table filtering). Extend AdvancedDbType when a database has
structured/composite types (arrays, STRUCT/MAP/LIST nesting) or needs a lot of per-JDBC-type mapping and a
single caching converter per column type is cleaner than many overrides. The only built-in subclass today is
DuckDb (io/db/DuckDb.kt) — use it as the reference implementation. (This is the piece agents have missed in
the past, e.g. while extending SQLite handling — check whether AdvancedDbType fits before overriding DbType.)
Custom DbType (extensibility for users)
Every read* function accepts an optional DbType argument. When it's omitted, the library resolves the built-in
type from the JDBC URL via extractDBTypeFromUrl; when it's supplied, that instance is used directly and URL
detection is skipped. A user can therefore pass their own DbType subclass without touching this module or
registering anything — it lives entirely in the user's own code.
This is the intended escape hatch for cases the built-ins don't cover, for example:
- a database the library doesn't ship a
DbTypefor (Oracle, DB2, Snowflake, ClickHouse, Hive, …); - a driver whose SQL→Kotlin type mapping or
ResultSetbehavior deviates and needsgetExpectedJdbcType/preprocessValue/getValueFromResultSetoverridden; - per-DB tuning: custom
quoteIdentifier,defaultFetchSize/defaultQueryTimeout,tableTypes, orisSystemTablefiltering.
Because the user's subclass overrides the same open pipeline described above, custom types get the full
metadata → JDBC type → preprocess → column-build flow for free and only override what differs.
Tests
Test layout under src/test/kotlin/.../io/ splits by how the DB is provided:
io/h2/— run entirely on embedded H2 in the various compatibility modes (h2Test,mysqlH2Test,postgresH2Test,mssqlH2Test,mariadbH2Test). These need no external DB and run in normaltest.io/local/— integration tests against a real DBMS (postgresTest,mysqlTest,mariadbTest,mssqlTest,duckDbTest,imdbTest). They connect to either a Dockerized or a locally installed server; don't point them at a production database.io/db/jdbcTypesTest.kt— SQL-type-to-KType mapping, asserted against syntheticTableColumnMetadatarather than a live driver. Its metadata is only as true as its source: copyjdbcTypeandjavaClassNamefrom a probe of the real driver, and do not cite such a test as evidence of what a driver returns.io/db/tableColumnsMetadataTest.kt— the fallbacks ofgetTableColumnsMetadata, on a proxy over an H2ResultSetthat makes chosenResultSetMetaDatamethods throw. No bundled driver reaches these branches on its own (H2, SQLite and DuckDB all answerisNullable), so a new fallback is tested the same way.- SQLite tests at the top level use bundled
.sqlitefiles insrc/test/resources/. commonTestScenarios.ktholds the shared assertions reused across databases.
@DataSchema interfaces in these tests are only checked by cast<T>(verify = true) — write the
argument out: a bare cast<T>() resolves to the overload that checks nothing. The check needs the
exact column type, nullability included, and the nullability is inferred from the rows read
(inferNullability), so the same table can read as String with a limit and as String? without
one. It stops at the first mismatch, and a nullable field with no matching column is filled with
nulls instead of reported — a wrong name on a nullable field never fails.
The column-type audit is the second half of that mapping coverage and lives in its own two files
rather than in commonTestScenarios.kt, because it carries a large per-database SQL fixture with it:
columnTypeAudit.kt— two assertions, both driven by a probe table with one column per SQL type.assertColumnTypesMatchValueschecks the invariant behind #2087, that the type the library declares accepts the value the driver returns;assertColumnTypespins the type each column is actually read as, which is the claim thereadSqlTypeMapping_*.mdpages publish.columnTypeAuditTables.kt— the probe tables and expected-type maps for the containerized databases; the embedded ones live next to their test inembeddedColumnTypeAuditTest.kt.
Both assertions are called from every *TestBase and from EmbeddedColumnTypeAuditTest, so all seven
databases are covered. The expected types must come from a real run: read them off the failure message
of a run with an incomplete map rather than deriving them by hand. Only the H2/SQLite/DuckDB half runs
in the ordinary test task — the rest needs testcontainersTest and a working Docker.
The probe row is a type fixture, not an example: some of its literals print degenerate values
(to_tsvector('a') is an empty string, a being a stop word). Take a documented example value from a test
that asserts that value. A timestamptz/tstzrange literal is parsed and printed in the session time zone,
so a test that asserts its text sets TIME ZONE before the INSERT and resets it in finally.
Test-only driver dependencies (MariaDB, MySQL, MSSQL, H2, SQLite, PostgreSQL, DuckDB, plus HikariCP and
kotest-assertions) are declared testImplementation in build.gradle.kts. Run just this module with
./gradlew dataframe-jdbc:test (add -Pkotlin.dataframe.debug=true to match CI checks).
Note
The module uses KoDEx + BuildConfig generation (processKDocsMain depends on generateBuildConfigClasses);
generated sources are build output — see the root AGENTS.md for the generated-sources and KDoc rules.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

