From kinoa-dashboard
Reads a CSV's headers and sample rows and infers a Kinoa **feature-schema**:
How this skill is triggered — by the user, by Claude, or both
Slash command
/kinoa-dashboard:kinoa-csv-schema-inferThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Reads a CSV's headers and sample rows and infers a Kinoa **feature-schema**:
Reads a CSV's headers and sample rows and infers a Kinoa feature-schema:
which column is an integer, which is a version, which is a date, and so on.
It is a deterministic parser — no HTTP, no session.env — so it's safe to run
on any file and its output is reproducible.
It exists so the "I have a CSV, make a schema" path stays one clean step: infer →
pipe into kinoa-dashboard-feature-settings create-schema.
python "${CLAUDE_SKILL_DIR}/kinoa_csv_schema_infer.py" infer --csv PATH --name NAME [options]
Per column, over its non-empty cells, first match wins:
| Type | Rule |
|---|---|
boolean | every cell ∈ {true, false, yes, no} (case-insensitive) |
integer | every cell a whole number within signed 32-bit range |
long | every cell a whole number, some beyond 32-bit |
version | every cell like 1.0.0 (two or more dots) |
number | every cell numeric with a fractional part |
date | every cell an ISO date/datetime (YYYY-MM-DD…) |
object | every cell a JSON object/array ({…} / […]) |
long_string | text whose longest cell exceeds 255 chars |
string | fallback |
Why "first match wins" and not something cleverer: the order encodes specificity.
1.0.0 is a version, not a number; a pure integer column is integer, not the
broader number. The thresholds (32-bit cutoff, 255-char long-string, the
date/version regexes) mirror how the backend's SchemaColumnType actually
coerces values, so what you infer is what the dashboard will accept.
Low-cardinality text columns are surfaced as enumeration candidates in the
review but kept as string — a schema field row carries no allowed-value list, so
forcing enumeration only changes the label. If the developer wants it, override
explicitly with --type col=enumeration.
| Flag | Meaning |
|---|---|
--csv PATH | the CSV, or - for stdin |
--name NAME | schema name (default ImportedSchema) |
--delimiter , | field delimiter |
--sample N | max data rows sampled for inference (0 = all; default 200) |
--required all|none|nonempty | isRequired policy. nonempty (default): a column is required iff it has no blank cells |
--type COL=TYPE | override one column's type (repeatable) — for the cases inference can't see, e.g. --type sku=bundle_key |
--emit full|body|fields | full (default) = review object; body = bare SchemaDto to pipe into create-schema; fields = bare tableFields array |
--emit full → { name, csv, row_count, column_count, fields[], schema_body{}, review[] }.
Show review[] to the developer — one row per column with inferred_type,
chosen_type, distinct, samples, and any note — so they can sanity-check
and correct before anything hits the API.--emit body → just the SchemaDto. This is the create-schema contract:
python .../kinoa_csv_schema_infer.py infer --csv boosters.csv --name BoostersConfig --emit body \
| python ../kinoa-dashboard-feature-settings/kinoa_dashboard_feature_settings.py create-schema
--emit fields → just the tableFields array, for
create-schema --fields-json "$(…)".--emit full and present the review table to the developer.--type COL=TYPE overrides (and
--name). Inference is a starting point, not a verdict — the developer owns
the final types.--emit body. That JSON is this skill's deliverable. If the
developer also wants the schema created + published on the dashboard, hand
off to the schema-from-csv scoped run of
kinoa-sync-feature-settings-integration (which drives the
create-schema / publish-schema admin calls) — don't drive them from here.npx claudepluginhub kinoa-labs-ltd/integration-skills --plugin kinoa-dashboardGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.