@raypx-kit/drizzle-kit 0.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,97 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/index.ts
3
+ /**
4
+ * **You are currently using version 0.21.0+ of drizzle-kit. If you have just upgraded to this version, please make sure to read the changelog to understand what changes have been made and what
5
+ * adjustments may be necessary for you. See https://orm.drizzle.team/kit-docs/upgrade-21#how-to-migrate-to-0210**
6
+ *
7
+ * **Config** usage:
8
+ *
9
+ * `dialect` - mandatory and is responsible for explicitly providing a databse dialect you are using for all the commands
10
+ * *Possible values*: `postgresql`, `mysql`, `sqlite`, `singlestore`, `gel`
11
+ *
12
+ * See https://orm.drizzle.team/kit-docs/config-reference#dialect
13
+ *
14
+ * ---
15
+ * `schema` - param lets you define where your schema file/files live.
16
+ * You can have as many separate schema files as you want and define paths to them using glob or array of globs syntax.
17
+ *
18
+ * See https://orm.drizzle.team/kit-docs/config-reference#schema
19
+ *
20
+ * ---
21
+ * `out` - allows you to define the folder for your migrations and a folder, where drizzle will introspect the schema and relations
22
+ *
23
+ * See https://orm.drizzle.team/kit-docs/config-reference#out
24
+ *
25
+ * ---
26
+ * `driver` - optional param that is responsible for explicitly providing a driver to use when accessing a database
27
+ * *Possible values*: `aws-data-api`, `d1-http`, `expo`, `turso`, `pglite`
28
+ * If you don't use AWS Data API, D1, Turso or Expo - ypu don't need this driver. You can check a driver strategy choice here: https://orm.drizzle.team/kit-docs/upgrade-21
29
+ *
30
+ * See https://orm.drizzle.team/kit-docs/config-reference#driver
31
+ *
32
+ * ---
33
+ *
34
+ * `dbCredentials` - an object to define your connection to the database. For more info please check the docs
35
+ *
36
+ * See https://orm.drizzle.team/kit-docs/config-reference#dbcredentials
37
+ *
38
+ * ---
39
+ *
40
+ * `migrations` - param let’s you specify a custom table and schema(PostgreSQL only) for migrations.
41
+ * By default, all information about executed migrations will be stored in the database inside
42
+ * the `__drizzle_migrations` table, and for PostgreSQL, inside the drizzle schema.
43
+ * However, you can configure where to store those records.
44
+ *
45
+ * See https://orm.drizzle.team/kit-docs/config-reference#migrations
46
+ *
47
+ * ---
48
+ *
49
+ * `breakpoints` - param lets you enable/disable SQL statement breakpoints in generated migrations.
50
+ * It’s optional and true by default, it’s necessary to properly apply migrations on databases,
51
+ * that do not support multiple DDL alternation statements in one transaction(MySQL, SQLite, SingleStore) and
52
+ * Drizzle ORM has to apply them sequentially one by one.
53
+ *
54
+ * See https://orm.drizzle.team/kit-docs/config-reference#breakpoints
55
+ *
56
+ * ---
57
+ *
58
+ * `tablesFilters` - param lets you filter tables with glob syntax for db push command.
59
+ * It’s useful when you have only one database avaialable for several separate projects with separate sql schemas.
60
+ *
61
+ * How to define multi-project tables with Drizzle ORM — see https://orm.drizzle.team/docs/goodies#multi-project-schema
62
+ *
63
+ * See https://orm.drizzle.team/kit-docs/config-reference#tablesfilters
64
+ *
65
+ * ---
66
+ *
67
+ * `schemaFilter` - parameter allows you to define which schema in PostgreSQL should be used for either introspect or push commands.
68
+ * This parameter accepts a single schema as a string or an array of schemas as strings.
69
+ * No glob pattern is supported here. By default, drizzle will use the public schema for both commands,
70
+ * but you can add any schema you need.
71
+ *
72
+ * For example, having schemaFilter: ["my_schema"] will only look for tables in both the database and
73
+ * drizzle schema that are a part of the my_schema schema.
74
+ *
75
+ * See https://orm.drizzle.team/kit-docs/config-reference#schemafilter
76
+ *
77
+ * ---
78
+ *
79
+ * `verbose` - command is used for drizzle-kit push commands and prints all statements that will be executed.
80
+ *
81
+ * > Note: This command will only print the statements that should be executed.
82
+ * To approve them before applying, please refer to the `strict` command.
83
+ *
84
+ * See https://orm.drizzle.team/kit-docs/config-reference#verbose
85
+ *
86
+ * ---
87
+ *
88
+ * `strict` - command is used for drizzle-kit push commands and will always ask for your confirmation,
89
+ * either to execute all statements needed to sync your schema with the database or not.
90
+ *
91
+ * See https://orm.drizzle.team/kit-docs/config-reference#strict
92
+ */
93
+ function defineConfig(config) {
94
+ return config;
95
+ }
96
+ //#endregion
97
+ exports.defineConfig = defineConfig;
package/dist/index.mjs ADDED
@@ -0,0 +1,96 @@
1
+ //#region src/index.ts
2
+ /**
3
+ * **You are currently using version 0.21.0+ of drizzle-kit. If you have just upgraded to this version, please make sure to read the changelog to understand what changes have been made and what
4
+ * adjustments may be necessary for you. See https://orm.drizzle.team/kit-docs/upgrade-21#how-to-migrate-to-0210**
5
+ *
6
+ * **Config** usage:
7
+ *
8
+ * `dialect` - mandatory and is responsible for explicitly providing a databse dialect you are using for all the commands
9
+ * *Possible values*: `postgresql`, `mysql`, `sqlite`, `singlestore`, `gel`
10
+ *
11
+ * See https://orm.drizzle.team/kit-docs/config-reference#dialect
12
+ *
13
+ * ---
14
+ * `schema` - param lets you define where your schema file/files live.
15
+ * You can have as many separate schema files as you want and define paths to them using glob or array of globs syntax.
16
+ *
17
+ * See https://orm.drizzle.team/kit-docs/config-reference#schema
18
+ *
19
+ * ---
20
+ * `out` - allows you to define the folder for your migrations and a folder, where drizzle will introspect the schema and relations
21
+ *
22
+ * See https://orm.drizzle.team/kit-docs/config-reference#out
23
+ *
24
+ * ---
25
+ * `driver` - optional param that is responsible for explicitly providing a driver to use when accessing a database
26
+ * *Possible values*: `aws-data-api`, `d1-http`, `expo`, `turso`, `pglite`
27
+ * If you don't use AWS Data API, D1, Turso or Expo - ypu don't need this driver. You can check a driver strategy choice here: https://orm.drizzle.team/kit-docs/upgrade-21
28
+ *
29
+ * See https://orm.drizzle.team/kit-docs/config-reference#driver
30
+ *
31
+ * ---
32
+ *
33
+ * `dbCredentials` - an object to define your connection to the database. For more info please check the docs
34
+ *
35
+ * See https://orm.drizzle.team/kit-docs/config-reference#dbcredentials
36
+ *
37
+ * ---
38
+ *
39
+ * `migrations` - param let’s you specify a custom table and schema(PostgreSQL only) for migrations.
40
+ * By default, all information about executed migrations will be stored in the database inside
41
+ * the `__drizzle_migrations` table, and for PostgreSQL, inside the drizzle schema.
42
+ * However, you can configure where to store those records.
43
+ *
44
+ * See https://orm.drizzle.team/kit-docs/config-reference#migrations
45
+ *
46
+ * ---
47
+ *
48
+ * `breakpoints` - param lets you enable/disable SQL statement breakpoints in generated migrations.
49
+ * It’s optional and true by default, it’s necessary to properly apply migrations on databases,
50
+ * that do not support multiple DDL alternation statements in one transaction(MySQL, SQLite, SingleStore) and
51
+ * Drizzle ORM has to apply them sequentially one by one.
52
+ *
53
+ * See https://orm.drizzle.team/kit-docs/config-reference#breakpoints
54
+ *
55
+ * ---
56
+ *
57
+ * `tablesFilters` - param lets you filter tables with glob syntax for db push command.
58
+ * It’s useful when you have only one database avaialable for several separate projects with separate sql schemas.
59
+ *
60
+ * How to define multi-project tables with Drizzle ORM — see https://orm.drizzle.team/docs/goodies#multi-project-schema
61
+ *
62
+ * See https://orm.drizzle.team/kit-docs/config-reference#tablesfilters
63
+ *
64
+ * ---
65
+ *
66
+ * `schemaFilter` - parameter allows you to define which schema in PostgreSQL should be used for either introspect or push commands.
67
+ * This parameter accepts a single schema as a string or an array of schemas as strings.
68
+ * No glob pattern is supported here. By default, drizzle will use the public schema for both commands,
69
+ * but you can add any schema you need.
70
+ *
71
+ * For example, having schemaFilter: ["my_schema"] will only look for tables in both the database and
72
+ * drizzle schema that are a part of the my_schema schema.
73
+ *
74
+ * See https://orm.drizzle.team/kit-docs/config-reference#schemafilter
75
+ *
76
+ * ---
77
+ *
78
+ * `verbose` - command is used for drizzle-kit push commands and prints all statements that will be executed.
79
+ *
80
+ * > Note: This command will only print the statements that should be executed.
81
+ * To approve them before applying, please refer to the `strict` command.
82
+ *
83
+ * See https://orm.drizzle.team/kit-docs/config-reference#verbose
84
+ *
85
+ * ---
86
+ *
87
+ * `strict` - command is used for drizzle-kit push commands and will always ask for your confirmation,
88
+ * either to execute all statements needed to sync your schema with the database or not.
89
+ *
90
+ * See https://orm.drizzle.team/kit-docs/config-reference#strict
91
+ */
92
+ function defineConfig(config) {
93
+ return config;
94
+ }
95
+ //#endregion
96
+ export { defineConfig };
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,5 @@
1
+ //#region src/utils/schemaValidator.d.ts
2
+ declare const dialects: readonly ["postgresql", "mysql", "sqlite", "turso", "singlestore", "mssql", "cockroach", "duckdb"];
3
+ type Dialect = (typeof dialects)[number];
4
+ //#endregion
5
+ export { Dialect as t };
@@ -0,0 +1,5 @@
1
+ //#region src/utils/schemaValidator.d.ts
2
+ declare const dialects: readonly ["postgresql", "mysql", "sqlite", "turso", "singlestore", "mssql", "cockroach", "duckdb"];
3
+ type Dialect = (typeof dialects)[number];
4
+ //#endregion
5
+ export { Dialect as t };
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: drizzle
3
+ description: Run a one-time staleness check against the installed `drizzle-kit` and notify the user if it ships a newer agent-skills bundle than what's embedded here. Load before reading or editing any Drizzle file (anything importing from `drizzle-orm/*`), touching `drizzle.config.ts`, invoking `drizzle-kit <command>` or using the Drizzle SDK, or handling drizzle-kit output.
4
+ metadata:
5
+ revision: 12
6
+ ---
7
+
8
+ # Drizzle
9
+
10
+ This skill runs a one-time staleness check against the installed `drizzle-kit` binary. If `drizzle-kit` ships a newer agent-skills bundle than the revision embedded in this file (the skills currently in use), surface a single user-facing notice with the refresh command.
11
+
12
+ ## Staleness check
13
+
14
+ Run once per session when this skill is loaded — cache the result for the rest of the conversation and do not re-run on subsequent drizzle work.
15
+
16
+ Locate the working directory where `drizzle-kit` is meant to run. This is the package that owns `drizzle-kit`, which in a monorepo is often a workspace package rather than the repo root — not a bare binary on `PATH`. Use your judgment to find it. Signals you may draw on, none of them binding and none of them a fixed precedence: the current working directory, the Drizzle file being worked on, the nearest `drizzle.config.ts`, and the nearest `package.json` that declares `drizzle-kit`.
17
+
18
+ Invoke `drizzle-kit` through whatever package manager the project already uses, determined at your discretion (read the lockfile, the `packageManager` field, or the running agent's environment — no fixed ordering). Use that package manager's mechanism for running an already-installed binary (for example `pnpm exec`, `yarn`, `bun x`, or `npx` without the yes flag), or run the local `node_modules/.bin/drizzle-kit` directly.
19
+
20
+ The check must run the project-INSTALLED `drizzle-kit` and must NEVER use a download-latest form — not `pnpm dlx`, not `bunx`, not `npx -y`, not `yarn dlx`. Downloading latest always reports the newest revision, which would make this check structurally incapable of ever detecting staleness. This invariant overrides the discretion above: the discretion is only about HOW to locate and invoke the installed binary, never about installed-versus-latest.
21
+
22
+ Run the resolved `drizzle-kit skills version` in the resolved directory, then compare. The trimmed stdout is the revision the installed `drizzle-kit` ships; this skill's own `metadata.revision` (read from this file's frontmatter when it loads) is the revision of the skills currently in use. Parse both as integers. If the revision `drizzle-kit` ships is strictly greater than this skill's own revision, the skills in use are outdated — surface this message verbatim to the user:
23
+
24
+ ```
25
+ drizzle-kit ships a newer agent-skills bundle (revision X) than what's installed (revision Y). Run `drizzle-kit skills` to refresh.
26
+ ```
27
+
28
+ Substitute X with the revision the installed `drizzle-kit` ships (the `drizzle-kit skills version` value) and Y with this skill's own `metadata.revision`. Do not auto-update, do not prompt, do not write anything to the project — the recovery action is identical to first-install (re-run `drizzle-kit skills`). If the revision `drizzle-kit` ships is less than or equal to this skill's own revision, stop silently.
29
+
30
+ If no project-installed `drizzle-kit` can be found or run AND the pending operation actually requires it — running a `drizzle-kit` command, using the Drizzle SDK, performing a migration verb (`generate` / `push` / `pull` / `up` / `check` / `export`), or handling drizzle-kit output — tell the user in one short line that `drizzle-kit` is required for that operation and to install it with the project's package manager. For example: "`drizzle-kit` is required to run `push` — install it with the project's package manager." If `drizzle-kit` is absent but the pending operation does not require it (just reading or editing a `drizzle-orm/*` source file), stay silent — do not nag.
31
+
32
+ If `drizzle-kit` is found and runs but the call errors — non-zero exit, stdout that does not parse as a positive integer, or any other failure — stop silently as before. The "required" notice is only for the not-found case above.
33
+
34
+ ## Surface selection
35
+
36
+ drizzle-kit exposes the same migration verbs (`generate`, `push`, `pull`, `up`, `check`, `export`) over three surfaces — CLI, SDK, and an MCP server — that all return the identical JSON envelope and consume the same `hints` array. The procedural skills (`drizzle-hints`, `drizzle-responses-and-errors`) apply unchanged regardless of surface; only the invocation differs. Pick the surface per verb:
37
+
38
+ 1. If a `mcp__drizzle__<verb>` tool is available in the session, prefer it over shelling out. Its `structuredContent` is the same envelope; resolve a `missing_hints` result with the same `hints` array and re-call the tool.
39
+ 2. Otherwise fall back to the CLI: `drizzle-kit <verb> --output json`.
40
+
41
+ Two cases where the CLI is the better surface even when the MCP tool exists:
42
+
43
+ - **Monorepos.** The target package is often a workspace package, not the repo root, and the MCP server resolves config from its own process cwd, not the client's. If the server was launched outside the target package, pass an explicit `config` to the tool, or run the CLI from that package through the package manager the project uses.
44
+ - **Path overrides.** MCP tools take only `config` / `hints` / etc. — there is no `schema` / `out` / `dialect` override. When a task needs those, use the CLI flags.
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: drizzle-generate
3
+ description: Create a new drizzle migration SQL file by diffing the schema against the latest snapshot. Load before running `drizzle-kit generate` or calling the `generate(...)` SDK, after any Drizzle schema edit when the next step is producing migration SQL, or when the task is to generate, scaffold, or make a new migration.
4
+ metadata:
5
+ version: "1.0.0"
6
+ ---
7
+
8
+ # Drizzle generate
9
+
10
+ If the `drizzle` skill has not been loaded yet this session, load it first — it carries the staleness check and the MCP-vs-CLI surface-selection rule that govern every drizzle-kit invocation.
11
+
12
+ The CLI flag `--output json` and the SDK `generate(...)` function emit the same discriminated-union envelope, and the envelope (not the stdout text) is what the agent decodes. Output format and interactivity are separate axes: `--output json` selects the machine-readable envelope and is always non-interactive, so pass it whenever an agent calls the CLI. Under the default `--output text` the CLI prompts only when stdin is a TTY; in a non-TTY it prints the missing-decisions report and exits 2 (it never hangs prompting). See the `drizzle-output-modes` skill for the two modes and the interactivity rule. The SDK runs in JSON mode internally with no flag needed at the call site. This skill assumes a working Drizzle schema and a `drizzle.config.ts` already exist; it does not author schemas.
13
+
14
+ ## CLI form
15
+
16
+ ```bash
17
+ drizzle-kit generate --output json [--config drizzle.config.ts] [--dialect <d>] [--schema <path>] [--out <dir>] [--explain] [--hints '<json>' | --hints-file ./hints.json]
18
+ ```
19
+
20
+ Flag surface:
21
+
22
+ - `--config` — path to `drizzle.config.ts` (default: `drizzle.config.ts` at CWD).
23
+ - `--dialect`, `--schema`, `--out` — override the corresponding `defineConfig` fields.
24
+ - `--output json` — switches stdout to one JSON line carrying the envelope and is always non-interactive. Use it for agent / CI / scripted contexts. Under the default `--output text` the CLI prompts only on a TTY and otherwise prints the missing-decisions report (exit 2).
25
+ - `--explain` — dry-run mode. Returns planned SQL statements and computed hints instead of writing a migration file.
26
+ - `--hints` — inline JSON array of hint resolutions (see the `drizzle-hints` skill).
27
+ - `--hints-file` — same payload as `--hints`, read from a JSON file. Use for long hint sets.
28
+
29
+ Minimal example:
30
+
31
+ ```bash
32
+ drizzle-kit generate --output json --config drizzle.config.ts
33
+ # → {"status":"ok","dialect":"postgresql","migration_path":"drizzle/0001_name/migration.sql"}
34
+ ```
35
+
36
+ The process exits with the code that matches `status` (see Response envelope below). Agents read both stdout (the envelope) and the exit code.
37
+
38
+ ## SDK form
39
+
40
+ ```typescript
41
+ import { generate } from 'drizzle-kit';
42
+
43
+ const response = await generate({
44
+ dialect: 'postgresql',
45
+ schema: './src/db/schema.ts',
46
+ out: './drizzle',
47
+ });
48
+
49
+ if (response.status === 'ok') {
50
+ // response.migration_path is the path to the new SQL file
51
+ } else if (response.status === 'no_changes') {
52
+ // schema matches the most recent migration — nothing was written
53
+ } else if (response.status === 'missing_hints') {
54
+ // response.unresolved lists ambiguities — see the drizzle-hints skill
55
+ } else if (response.status === 'error') {
56
+ // response.error.code identifies the failure — see drizzle-responses-and-errors
57
+ }
58
+ ```
59
+
60
+ The SDK is the public-surface entry point. It always runs in JSON mode internally — no `--output json` flag needed at the call site — and returns the same envelope the CLI prints. Narrow on `response.status` to extract typed branches:
61
+
62
+ - `'ok'` → `response.dialect`, `response.migration_path` (or `response.statements`, `response.hints` in explain mode).
63
+ - `'no_changes'` → `response.dialect`.
64
+ - `'missing_hints'` → `response.unresolved` (array of items).
65
+ - `'error'` → `response.error.code` plus per-code metadata.
66
+
67
+ The SDK does not throw on user-level failures — every outcome flows through the envelope. Unexpected runtime exceptions are wrapped as `status: 'error'` with `code: 'internal_error'`.
68
+
69
+ ## Response shape
70
+
71
+ `'ok'` (write mode) carries `{ status, dialect, migration_path }`; `'ok'` (explain mode) carries `{ status, dialect, statements, hints }`. `'no_changes'`, `'missing_hints'`, and `'error'` are shared across operations. Full envelope shapes, exit-code mapping, and per-code error metadata live in the `drizzle-responses-and-errors` skill's response-envelope section.
72
+
73
+ `'missing_hints'` (exit 2) means the diff is ambiguous or unsafe — the resolution loop lives in the `drizzle-hints` skill. The most common error codes for `generate` are `config_validation_error`, `config_file_not_found_error`, `schema_files_not_found_error`, `orm_version_error`, `invalid_hints`, `unsupported_schema_change`, `internal_error`.
74
+
75
+ ## Dialect notes
76
+
77
+ Per-dialect quirks (postgresql, mysql, sqlite, mssql, cockroach, singlestore) — the same diff engine and dialect surface drives both `generate` and `push`, so the notes are shared. See the `drizzle-migrations` skill's dialect-notes section.
78
+
79
+ ## Examples
80
+
81
+ ```bash
82
+ # Happy path
83
+ drizzle-kit generate --output json --config drizzle.config.ts
84
+ # → {"status":"ok","dialect":"postgresql","migration_path":"drizzle/0001_init/migration.sql"}
85
+
86
+ # Idempotent re-run on an up-to-date schema
87
+ drizzle-kit generate --output json --config drizzle.config.ts
88
+ # → {"status":"no_changes","dialect":"postgresql"}
89
+
90
+ # Ambiguous diff — caller must supply hints and retry
91
+ drizzle-kit generate --output json --config drizzle.config.ts
92
+ # → {"status":"missing_hints","unresolved":[{"type":"rename_or_create","kind":"column","entity":["public","users","email_v2"]}]}
93
+ # (resolution loop: see the drizzle-hints skill)
94
+
95
+ # Hard error
96
+ drizzle-kit generate --output json --config missing.ts
97
+ # → {"status":"error","error":{"code":"config_file_not_found_error","path":"missing.ts"}}
98
+ ```
99
+
100
+ SDK equivalent of the happy path:
101
+
102
+ ```typescript
103
+ import { generate } from 'drizzle-kit';
104
+
105
+ const r = await generate({ dialect: 'postgresql', schema: './src/db/schema.ts', out: './drizzle' });
106
+ if (r.status === 'ok') console.log(r.migration_path);
107
+ ```
@@ -0,0 +1,181 @@
1
+ ---
2
+ name: drizzle-hints
3
+ description: Resolve `missing_hints` responses from drizzle-kit `generate` or `push` — covers rename-vs-create disambiguation, `confirm_data_loss` approvals, and the `Hint` reply array shape for the retry. Load whenever drizzle-kit output shows `missing_hints` status, prompts to confirm a rename or destructive change, or the next step is constructing a `hints` array for a retry call.
4
+ metadata:
5
+ version: "1.0.0"
6
+ ---
7
+
8
+ # Drizzle hints
9
+
10
+ If the `drizzle` skill has not been loaded yet this session, load it first — it carries the staleness check and the MCP-vs-CLI surface-selection rule that govern every drizzle-kit invocation.
11
+
12
+ `status: 'missing_hints'` means the diff is ambiguous (a rename could also be a drop + create) or unsafe (would drop a non-empty entity, or would recreate a SQLite table and wipe its rows). Until hints are supplied the operation cannot proceed — the CLI exits `2`, the SDK returns the envelope without writing or applying anything.
13
+
14
+ Under `--output text` + non-TTY the same unresolved decisions surface as the human-readable missing-decisions report on stdout (also exit code 2) rather than this envelope — the `drizzle-output-modes` skill covers the text-report shape.
15
+
16
+ Resolution is one round trip: read each item in `unresolved`, build one reply `Hint` per item, re-invoke the same command with the array. Both the missing-hints request shape and the reply shape are typed and validated by the runtime — wrong arity, wrong spelling, or wrong reply discriminator returns `status: 'error'` with `error.code: 'invalid_hints'`. See the `drizzle-responses-and-errors` skill for that branch.
17
+
18
+ ## Reply types
19
+
20
+ A reply is an array of `Hint`. Each `Hint` is one of these three shapes:
21
+
22
+ ```typescript
23
+ { type: 'rename', kind: K, from: <entity-tuple>, to: <entity-tuple> } // resolves a rename_or_create AS a rename
24
+ { type: 'create', kind: K, entity: <entity-tuple> } // resolves a rename_or_create AS a create
25
+ { type: 'confirm_data_loss', kind: K, entity: <entity-tuple> } // approves a destructive change
26
+ ```
27
+
28
+ The `confirm_data_loss` reply omits the `reason` and `reason_details` keys that the request carries — those are runtime-only metadata used to explain why the prompt fired. The reply only needs `type`, `kind`, and `entity`.
29
+
30
+ Each unresolved item maps to exactly one reply:
31
+
32
+ | unresolved item type | reply type |
33
+ |----------------------|------------|
34
+ | `'rename_or_create'` | `'rename'` (pick a deleted entity of the same kind to be the `from`) OR `'create'` |
35
+ | `'confirm_data_loss'` | `'confirm_data_loss'` (same `kind` + `entity`) |
36
+
37
+ ## Rename-vs-create kinds
38
+
39
+ The `kind` literal in the reply must match the literal in the unresolved item exactly. Note that `foreign key` carries a single space — it is the one remaining non-snake_case literal in the union.
40
+
41
+ | kind | entity-tuple arity | dialect availability |
42
+ |---|---|---|
43
+ | `schema` | `[name]` | postgresql, cockroach, mssql |
44
+ | `role` | `[name]` | postgresql, cockroach |
45
+ | `table` | `[schema, name]` | all |
46
+ | `enum` | `[schema, name]` | postgresql, cockroach |
47
+ | `sequence` | `[schema, name]` | postgresql, cockroach |
48
+ | `view` | `[schema, name]` | all |
49
+ | `column` | `[schema, table, name]` | all |
50
+ | `default` | `[schema, table, name]` | all |
51
+ | `policy` | `[schema, table, name]` | postgresql, cockroach |
52
+ | `check` | `[schema, table, name]` | all |
53
+ | `index` | `[schema, table, name]` | all |
54
+ | `unique` | `[schema, table, name]` | all |
55
+ | `primary_key` | `[schema, table, name]` | all |
56
+ | `foreign key` | `[schema, table, name]` | all |
57
+ | `privilege` | `[grantor, grantee, schema, table, type]` | postgresql, cockroach |
58
+
59
+ The runtime only emits unresolved items for kinds that exist on the target dialect, so the dialect-availability column is informational — an agent that just echoes whatever shows up in `unresolved` never sees a kind that doesn't apply. For `rename`, both `from` and `to` are entity tuples of the same arity (the `from` is a deleted entity of the same kind that the new one is being matched against). For `create`, only `entity` is set.
60
+
61
+ ## Confirm-data-loss kinds
62
+
63
+ Confirm-data-loss replies carry `type`, `kind`, and `entity` only — the `reason` and `reason_details` fields the request carries are runtime-only metadata and are dropped from the reply.
64
+
65
+ | kind | entity-tuple arity | dialect availability |
66
+ |---|---|---|
67
+ | `schema` | `[name]` | postgresql, cockroach, mssql |
68
+ | `table` | `[schema, name]` | all |
69
+ | `view` | `[schema, name]` | postgresql, cockroach (materialized views only) |
70
+ | `column` | `[schema, table, name]` | all |
71
+ | `primary_key` | `[schema, table, name]` | all except sqlite / turso |
72
+ | `add_not_null` | `[schema, table, name]` | sqlite / turso only |
73
+
74
+ `add_not_null` is the only confirmation-triggering constraint addition, and it fires only on sqlite / turso. The server dialects (postgresql, mysql, mssql, cockroach, singlestore) add `NOT NULL` / `UNIQUE` constraints without triggering a confirmation request — the `ALTER` runs and the database enforces the constraint, rejecting a genuine violation cleanly — so neither `add_not_null` nor `add_unique` surfaces as a `confirm_data_loss` on those dialects.
75
+
76
+ ## Reasons
77
+
78
+ The unresolved item for a `confirm_data_loss` carries a `reason` (and, for `type_change`, a `reason_details`). The reply does not carry the reason — it carries only `type`, `kind`, `entity`.
79
+
80
+ | reason | applicable kinds | meaning | reason_details |
81
+ |--------|------------------|---------|----------------|
82
+ | `non_empty` | `table`, `column`, `schema`, `view`, `primary_key` | Target entity has ≥1 row; drop will lose data | — |
83
+ | `table_recreate` | `add_not_null` (sqlite / turso only) | Adding the `NOT NULL` column has no in-place path on SQLite, so confirming wipes all rows and recreates the table | — |
84
+ | `type_change` | `column` | Existing column SQL type changes (e.g. mysql / singlestore `ALTER COLUMN`) | `{ from: string, to: string }` |
85
+
86
+ ## Resolution loop
87
+
88
+ 1. **Invoke.** Run `drizzle-kit generate --output json` / `push --output json` (CLI) or `await generate(...)` / `await push(...)` (SDK).
89
+ 2. **Read the envelope.** If `status === 'missing_hints'`, the response carries `unresolved: MissingHint[]`. Each item has a `type` of `'rename_or_create'` or `'confirm_data_loss'`.
90
+ 3. **Build the reply.** For every `unresolved[i]`, append exactly one `Hint` to the reply array:
91
+ - `rename_or_create` → pick `rename` (provide `from` as a deleted entity of the same `kind`) OR `create` (just echo `entity`).
92
+ - `confirm_data_loss` → echo the same `kind` and `entity`; drop `reason` and `reason_details`.
93
+ 4. **Re-invoke** the same command, passing the reply array via the CLI flag or the SDK option (see below). Repeat from step 2 if more hints surface.
94
+
95
+ The reply must cover every item in `unresolved` — partial replies that still leave ambiguities return `missing_hints` again with the still-unresolved items.
96
+
97
+ ## CLI form
98
+
99
+ Pass the reply array as JSON via one of two flags on `generate` or `push`:
100
+
101
+ - `--hints '<json>'` — inline JSON array of `Hint` objects. Watch shell quoting; the JSON has to survive your shell intact.
102
+ - `--hints-file ./hints.json` — same JSON array read from a file. Preferred for arrays of more than one or two items.
103
+
104
+ ```bash
105
+ drizzle-kit push --output json --config drizzle.config.ts --hints-file ./hints.json
106
+ ```
107
+
108
+ `--hints` and `--hints-file` are mutually exclusive at the source level — pass one or the other, not both. A malformed JSON file or a hint that fails shape validation returns `status: 'error'` with `error.code: 'invalid_hints'` and `meta.source: 'file' | 'inline'`.
109
+
110
+ ## SDK form
111
+
112
+ Pass the reply array as a raw `Hint[]` via the `hints` option to `generate` / `push` (or use `hintsFile` with a file path instead):
113
+
114
+ ```typescript
115
+ import { generate, push } from 'drizzle-kit';
116
+
117
+ const r1 = await generate({
118
+ dialect: 'postgresql',
119
+ schema: './src/db/schema.ts',
120
+ out: './drizzle',
121
+ hints: [
122
+ { type: 'rename', kind: 'column', from: ['public', 'users', 'email'], to: ['public', 'users', 'email_v2'] },
123
+ ],
124
+ });
125
+
126
+ const r2 = await push({
127
+ dialect: 'postgresql',
128
+ schema: './src/db/schema.ts',
129
+ url: process.env.DATABASE_URL!,
130
+ hints: [
131
+ { type: 'confirm_data_loss', kind: 'column', entity: ['public', 'users', 'legacy_id'] },
132
+ ],
133
+ });
134
+ ```
135
+
136
+ The SDK and CLI consume the exact same `Hint` shape — anything that validates against `--hints-file` validates against `hints:` and vice versa.
137
+
138
+ ## Worked example
139
+
140
+ A first invocation against a SQLite database returns two ambiguities — one rename-or-create, one confirm-data-loss:
141
+
142
+ ```json
143
+ {
144
+ "status": "missing_hints",
145
+ "unresolved": [
146
+ { "type": "rename_or_create", "kind": "column",
147
+ "entity": ["public", "users", "email_v2"] },
148
+ { "type": "confirm_data_loss", "kind": "add_not_null",
149
+ "entity": ["public", "users", "handle"],
150
+ "reason": "table_recreate" }
151
+ ]
152
+ }
153
+ ```
154
+
155
+ The `table_recreate` reason fires because SQLite has no in-place way to add a `NOT NULL` column — confirming it recreates the `users` table and wipes its rows. The reply resolves the rename-or-create as a rename of `email` → `email_v2`, and approves the `NOT NULL` addition:
156
+
157
+ ```json
158
+ [
159
+ { "type": "rename", "kind": "column",
160
+ "from": ["public", "users", "email"],
161
+ "to": ["public", "users", "email_v2"] },
162
+ { "type": "confirm_data_loss", "kind": "add_not_null",
163
+ "entity": ["public", "users", "handle"] }
164
+ ]
165
+ ```
166
+
167
+ Re-invoke with this array via `--hints-file ./hints.json` (CLI) or `hints: [...]` (SDK). The successful retry returns `status: 'ok'` (with `migration_path` for `generate`, or just `dialect` for `push`).
168
+
169
+ ### Privilege 5-tuple rename
170
+
171
+ `privilege` is the only kind whose entity tuple has five slots: `[grantor, grantee, schema, table, type]`. Renaming the underlying table renames each privilege grant against it:
172
+
173
+ ```json
174
+ { "type": "rename", "kind": "privilege",
175
+ "from": ["app_owner", "analytics_role", "public", "orders", "SELECT"],
176
+ "to": ["app_owner", "analytics_role", "public", "orders_v2", "SELECT"] }
177
+ ```
178
+
179
+ ## Schema-namespace placeholder
180
+
181
+ Every entity tuple leads with a namespace segment so its arity is uniform across dialects, but only postgresql, cockroach, and mssql have a real schema namespace — the `schema` entity kind is wired for those three dialects only. On the schemaless dialects (mysql, sqlite, singlestore) that leading segment is a synthesized `'public'` placeholder, not a real schema. Echo whatever the unresolved item carries in that slot verbatim; on a schemaless dialect it is filler — never build a separate `schema` rename or create from it.
@@ -0,0 +1,88 @@
1
+ ---
2
+ name: drizzle-migrations
3
+ description: Orient to the drizzle-kit migration workflow — `defineConfig`, `generate` vs `push`, and per-dialect quirks across postgresql, mysql, sqlite, mssql, cockroach, and singlestore. Load whenever drizzle migrations are being set up or modified, `drizzle.config.ts` is being read or edited, the generate-vs-push choice is being made, or any Drizzle schema file has just been edited.
4
+ metadata:
5
+ version: "1.0.0"
6
+ ---
7
+
8
+ # Drizzle migrations
9
+
10
+ If the `drizzle` skill has not been loaded yet this session, load it first — it carries the staleness check and the MCP-vs-CLI surface-selection rule that govern every drizzle-kit invocation.
11
+
12
+ Entry-point skill for the drizzle-kit migration workflow. Three responsibilities live here: the `defineConfig` reference, the `generate` vs `push` comparison, and the per-dialect quirks catalog. Invocation details (CLI form, SDK form, response shapes) live in the operation skills.
13
+
14
+ ## Configuration
15
+
16
+ `defineConfig` is the type-safe entry point. The same object shape is used by both the CLI (loaded automatically from `drizzle.config.ts`) and the SDK (passed inline to `generate` / `push`).
17
+
18
+ Required fields:
19
+
20
+ - **`dialect`** — one of `postgresql`, `mysql`, `sqlite`, `turso`, `mssql`, `cockroach`, `singlestore`. For Turso / libsql set `dialect: 'turso'` (with the `@libsql/client` or `@tursodatabase/serverless` driver) — it is a first-class dialect value, not a `sqlite` alias.
21
+ - **`schema`** — path or path-glob to the schema file(s). Examples: `'./src/db/schema.ts'`, `['./src/db/**/*.ts']`.
22
+ - **`out`** — directory where `generate` writes `.sql` migration files. Conventional: `'./drizzle'`.
23
+ - **`dbCredentials`** — per-dialect credential shape. Required for `push` (which connects to a live database) and for the introspect side of some `generate` codepaths. Either a `url` field or a structured object (`{ host, port, user, password, database }`-style); the exact shape varies by dialect. Use environment variables — never hard-code secrets.
24
+
25
+ Minimal example (postgresql):
26
+
27
+ ```typescript
28
+ import { defineConfig } from 'drizzle-kit';
29
+
30
+ export default defineConfig({
31
+ dialect: 'postgresql',
32
+ schema: './src/db/schema.ts',
33
+ out: './drizzle',
34
+ dbCredentials: {
35
+ url: process.env.DATABASE_URL!,
36
+ },
37
+ });
38
+ ```
39
+
40
+ ## Generate vs push
41
+
42
+ - **`generate`** — file-based. Computes the diff, writes a `.sql` file under `out`, and exits. The agent (or a human, or CI) reviews the SQL and applies it later via the driver's migrate runner. Safest for production. Pairs naturally with code-review workflows. Load the `drizzle-generate` skill for invocation details.
43
+ - **`push`** — direct application. Computes the diff and executes the DDL against the live database immediately. No migration file. Fastest feedback loop during development. In production, destructive changes (dropping a non-empty entity, changing a column's SQL type, or recreating a SQLite table to add a `NOT NULL` column) return `status: 'missing_hints'` and require explicit approval via the `drizzle-hints` resolution loop before they apply. Load the `drizzle-push` skill for invocation details.
44
+
45
+ Choose `generate` for production releases and review workflows; choose `push` for rapid local iteration. Both operations share one JSON envelope (decoded by the `drizzle-responses-and-errors` skill) and one hint vocabulary.
46
+
47
+ To go the other direction — introspect an existing database into a Drizzle schema instead of driving the database from a schema — see the `drizzle-pull` skill.
48
+
49
+ ## Dialect notes
50
+
51
+ The diff engine and dialect surface are shared by `generate` and `push`, so the per-dialect quirks below apply uniformly to both operations.
52
+
53
+ - `postgresql` — full surface: schemas, enums, sequences, views, policies, roles, privileges. `confirm_data_loss` on `view` fires only for materialized views (regular views drop silently). `serial` / `bigserial` columns auto-create their sequences with no `confirm_data_loss` prompt.
54
+ - `mysql` — `confirm_data_loss` with `reason: 'type_change'` fires on any `ALTER COLUMN` whose dialect-native type would change; `reason_details` carries `{ from, to }` with dialect-native spellings. `unsupported_schema_change/drop_pk_dependency` blocks `DROP PRIMARY KEY` when foreign keys reference the dropped columns and no covering UNIQUE exists. `unsupported_schema_change/fk_target_not_unique` blocks `CREATE FOREIGN KEY` when the referenced columns are not unique. No `schema` / `enum` / `sequence` / `policy` / `role` / `privilege` kinds.
55
+ - `sqlite` — table-rebuild semantics: most ALTERs emit `recreate_table` statements (copy-into-new-table, swap, drop-old). `confirm_data_loss/add_not_null` issues a `DELETE` to truncate nulls before the rebuild — approve only when row loss is acceptable. No `primary_key` / `add_unique` `confirm_data_loss` kinds. `turso` (libsql) shares the sqlite handler over the libsql driver.
56
+ - `mssql` — `unsupported_schema_change/rename_blocked_by_check_constraint` fires when `sp_rename` would fail because the column is referenced by a `CHECK` constraint; the agent must drop the constraint, rename, then recreate. `unsupported_schema_change/rename_schema_unsupported` is unconditional — MSSQL has no schema rename. `schema` kind is available for create / drop.
57
+ - `cockroach` — postgres-family; surface largely mirrors `postgresql`. Materialized-view drops are the only `confirm_data_loss/view` trigger. Distributed-schema notes surface in `--explain` mode.
58
+ - `singlestore` — inherits the MySQL handler shape. Same `unsupported_schema_change` variants apply (`drop_pk_dependency`, `fk_target_not_unique`). No `schema` / `enum` / `sequence` / `policy` / `role` / `privilege` kinds.
59
+
60
+ ## Collapsing snapshot diffs in code review
61
+
62
+ Every migration `generate` writes carries a machine-generated `meta/<n>_snapshot.json` alongside the `.sql` — the full schema state, regenerated wholesale on each migration. Reviewers want to read the SQL, not the snapshot churn, so keep these generated files out of code-review noise through `.gitattributes`. This is PR-review hygiene, not a drizzle-kit command.
63
+
64
+ Target only the snapshot glob `drizzle/**/meta/*_snapshot.json`. It mirrors the configured `out` dir: the default is `drizzle/`, so an `out: 'migrations'` project uses `migrations/**/meta/*_snapshot.json` instead — adjust the leading directory to match `out`. Scope the glob to `*_snapshot.json` only; do not broaden to `meta/*`, because the sibling `meta/_journal.json` is small and human-meaningful and is intentionally not a collapse target.
65
+
66
+ Per platform:
67
+
68
+ - **GitHub** — mark the snapshots as generated so Linguist collapses them by default (reviewers can still expand):
69
+
70
+ ```gitattributes
71
+ drizzle/**/meta/*_snapshot.json linguist-generated=true
72
+ ```
73
+
74
+ Linguist auto-detects many generated files by filename and content heuristics, but `*_snapshot.json` is not on that list, so the explicit attribute is required.
75
+
76
+ - **GitLab** — collapse via the `gitlab-generated` attribute (GA on 16.11+, no feature flag):
77
+
78
+ ```gitattributes
79
+ drizzle/**/meta/*_snapshot.json gitlab-generated
80
+ ```
81
+
82
+ - **Bitbucket and Gerrit** — neither has a native generated-file collapse mechanism, and neither honors `linguist-generated` or `gitlab-generated`; there is no path-based auto-collapse in their web review UIs. The closest git-native lever is the `-diff` attribute:
83
+
84
+ ```gitattributes
85
+ drizzle/**/meta/*_snapshot.json -diff
86
+ ```
87
+
88
+ Be honest about what `-diff` does: it tells git to treat the path as non-text, so `git diff` prints "Binary files differ" instead of the textual hunk (and renders as a suppressed/binary diff on GitHub and GitLab too). But it does NOT collapse the file in the Bitbucket or Gerrit web review UIs — the snapshot still appears in the changed-files list, just without a readable diff — and it removes a diff that is locally useful, since the snapshot is real JSON. Treat `-diff` as a deliberate tradeoff for those platforms, not a blanket recommendation.