@assemora/cli 0.1.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.
Files changed (76) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +272 -0
  3. package/bin.mjs +31 -0
  4. package/dist/args.d.ts +35 -0
  5. package/dist/args.d.ts.map +1 -0
  6. package/dist/args.js +104 -0
  7. package/dist/args.js.map +1 -0
  8. package/dist/bin.d.ts +3 -0
  9. package/dist/bin.d.ts.map +1 -0
  10. package/dist/bin.js +11 -0
  11. package/dist/bin.js.map +1 -0
  12. package/dist/commands/agents.d.ts +50 -0
  13. package/dist/commands/agents.d.ts.map +1 -0
  14. package/dist/commands/agents.js +169 -0
  15. package/dist/commands/agents.js.map +1 -0
  16. package/dist/commands/artifacts.d.ts +5 -0
  17. package/dist/commands/artifacts.d.ts.map +1 -0
  18. package/dist/commands/artifacts.js +126 -0
  19. package/dist/commands/artifacts.js.map +1 -0
  20. package/dist/commands/console.d.ts +25 -0
  21. package/dist/commands/console.d.ts.map +1 -0
  22. package/dist/commands/console.js +99 -0
  23. package/dist/commands/console.js.map +1 -0
  24. package/dist/commands/db.d.ts +48 -0
  25. package/dist/commands/db.d.ts.map +1 -0
  26. package/dist/commands/db.js +585 -0
  27. package/dist/commands/db.js.map +1 -0
  28. package/dist/commands/index.d.ts +21 -0
  29. package/dist/commands/index.d.ts.map +1 -0
  30. package/dist/commands/index.js +21 -0
  31. package/dist/commands/index.js.map +1 -0
  32. package/dist/commands/inspect.d.ts +8 -0
  33. package/dist/commands/inspect.d.ts.map +1 -0
  34. package/dist/commands/inspect.js +280 -0
  35. package/dist/commands/inspect.js.map +1 -0
  36. package/dist/commands/make.d.ts +29 -0
  37. package/dist/commands/make.d.ts.map +1 -0
  38. package/dist/commands/make.js +393 -0
  39. package/dist/commands/make.js.map +1 -0
  40. package/dist/commands/mcp.d.ts +19 -0
  41. package/dist/commands/mcp.d.ts.map +1 -0
  42. package/dist/commands/mcp.js +116 -0
  43. package/dist/commands/mcp.js.map +1 -0
  44. package/dist/commands/new.d.ts +20 -0
  45. package/dist/commands/new.d.ts.map +1 -0
  46. package/dist/commands/new.js +83 -0
  47. package/dist/commands/new.js.map +1 -0
  48. package/dist/commands/run.d.ts +20 -0
  49. package/dist/commands/run.d.ts.map +1 -0
  50. package/dist/commands/run.js +355 -0
  51. package/dist/commands/run.js.map +1 -0
  52. package/dist/commands/watchdog.d.ts +2 -0
  53. package/dist/commands/watchdog.d.ts.map +1 -0
  54. package/dist/commands/watchdog.js +74 -0
  55. package/dist/commands/watchdog.js.map +1 -0
  56. package/dist/config.d.ts +89 -0
  57. package/dist/config.d.ts.map +1 -0
  58. package/dist/config.js +156 -0
  59. package/dist/config.js.map +1 -0
  60. package/dist/index.d.ts +19 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +133 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/output.d.ts +96 -0
  65. package/dist/output.d.ts.map +1 -0
  66. package/dist/output.js +181 -0
  67. package/dist/output.js.map +1 -0
  68. package/dist/project.d.ts +44 -0
  69. package/dist/project.d.ts.map +1 -0
  70. package/dist/project.js +102 -0
  71. package/dist/project.js.map +1 -0
  72. package/dist/registry.d.ts +48 -0
  73. package/dist/registry.d.ts.map +1 -0
  74. package/dist/registry.js +74 -0
  75. package/dist/registry.js.map +1 -0
  76. package/package.json +49 -0
@@ -0,0 +1,585 @@
1
+ /**
2
+ * `db:generate`, `db:migrate`, `db:rollback`, `db:status` (SPEC.md §34).
3
+ *
4
+ * The CLI orchestrates and owns neither the SQL nor the runner. `diffSchema` says
5
+ * what changed between two schemas, `migrationSql` turns that into statements and
6
+ * `applyMigrations` applies them (ADR-0021). What lives here is the part in between:
7
+ * the file a migration is, the number it gets, the snapshot a diff is taken against,
8
+ * and the refusals that stand between a destructive statement and a live database.
9
+ *
10
+ * A migration is a plain `.sql` file, because the whole point of generating one is
11
+ * that a person reads it in a pull request before it ever reaches a database.
12
+ */
13
+ import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
14
+ import { join } from 'node:path';
15
+ import { ConfigurationError } from '@assemora/core';
16
+ import { currentAdapter, registeredModels } from '@assemora/data';
17
+ import { diffSchema } from '@assemora/database';
18
+ import { bool } from '../args.js';
19
+ import { loadConfig } from '../config.js';
20
+ import { detail, fail, json, line, ok, table, warn } from '../output.js';
21
+ import { loadApplication } from '../project.js';
22
+ import { defineCommand, register } from '../registry.js';
23
+ const isRecord = (value) => typeof value === 'object' && value !== null;
24
+ const count = (amount, noun) => `${amount} ${noun}${amount === 1 ? '' : 's'}`;
25
+ /**
26
+ * Where a migration's SQL comes from — the one function in this file that knows.
27
+ *
28
+ * The work splits along the dialect line (ADR-0021): `diffSchema` in
29
+ * `@assemora/database` says what changed and knows no dialect, and `migrationSql` in
30
+ * `@assemora/database-postgres` turns that into PostgreSQL. The CLI orchestrates and
31
+ * writes neither half.
32
+ *
33
+ * The list of changes is carried straight from one to the other and never read here,
34
+ * so what a schema change looks like can move without the CLI moving with it.
35
+ */
36
+ const generateMigration = async (before, after, defaultLocale) => {
37
+ // Loaded here rather than at the top of the module: `assemora --help` must not pay
38
+ // for a database driver it is never going to use.
39
+ const { migrationSql } = await import('@assemora/database-postgres');
40
+ /**
41
+ * The default language reaches the writer because a table becoming translatable is
42
+ * the one case where a not-null column *can* be added to a populated table: what the
43
+ * rows already there are written in is a fact the application configured, not a guess
44
+ * about the data (SPEC.md §131).
45
+ */
46
+ return migrationSql(diffSchema(before, after).changes, defaultLocale === undefined ? {} : { defaultLocale });
47
+ };
48
+ /**
49
+ * The schema the models describe right now, in a stable order.
50
+ *
51
+ * Sorted by name so that reordering a module's imports does not rewrite the snapshot
52
+ * and produce a diff nobody made.
53
+ */
54
+ const declaredTables = () => Object.values(registeredModels()).sort((left, right) => left.name.localeCompare(right.name));
55
+ /** A tag is empty or starts with a letter, so `$1$2` in a statement is not one. */
56
+ const DOLLAR_TAG = /\$(?:[A-Za-z_][A-Za-z_0-9]*)?\$/y;
57
+ const dollarTag = (text, index) => {
58
+ DOLLAR_TAG.lastIndex = index;
59
+ return DOLLAR_TAG.exec(text)?.[0];
60
+ };
61
+ /** The index just past the closing quote. A doubled quote is the character itself. */
62
+ const endOfQuoted = (text, start, quote, file) => {
63
+ let index = start + 1;
64
+ while (index < text.length) {
65
+ if (text.charAt(index) !== quote) {
66
+ index += 1;
67
+ continue;
68
+ }
69
+ if (text.charAt(index + 1) === quote) {
70
+ index += 2;
71
+ continue;
72
+ }
73
+ return index + 1;
74
+ }
75
+ throw new ConfigurationError(`${file}: a ${quote === "'" ? 'string' : 'quoted name'} is opened and never closed.`);
76
+ };
77
+ const endOfDollarQuoted = (text, from, tag, file) => {
78
+ const end = text.indexOf(tag, from);
79
+ if (end === -1)
80
+ throw new ConfigurationError(`${file}: a ${tag} quoted block is never closed.`);
81
+ return end + tag.length;
82
+ };
83
+ /** PostgreSQL nests block comments, so counting depth is the only correct way out. */
84
+ const endOfBlockComment = (text, start, file) => {
85
+ let depth = 0;
86
+ let index = start;
87
+ while (index < text.length) {
88
+ if (text.startsWith('/*', index)) {
89
+ depth += 1;
90
+ index += 2;
91
+ continue;
92
+ }
93
+ if (text.startsWith('*/', index)) {
94
+ depth -= 1;
95
+ index += 2;
96
+ if (depth === 0)
97
+ return index;
98
+ continue;
99
+ }
100
+ index += 1;
101
+ }
102
+ throw new ConfigurationError(`${file}: a /* block comment is opened and never closed.`);
103
+ };
104
+ /**
105
+ * Reads a migration file back into the statements it holds.
106
+ *
107
+ * A file with no `-- +migration` marker at all is read as an `up` migration, which is
108
+ * what somebody who dropped a plain `.sql` file into the directory meant. `file` is
109
+ * only ever used to name the file in a complaint.
110
+ */
111
+ export const parseMigration = (text, file) => {
112
+ const statements = { up: [], down: [] };
113
+ const destructive = [];
114
+ let section = 'up';
115
+ let buffer = '';
116
+ let index = 0;
117
+ const flush = () => {
118
+ const statement = buffer.trim();
119
+ buffer = '';
120
+ if (statement !== '')
121
+ statements[section].push(statement);
122
+ };
123
+ const directive = (body) => {
124
+ const parts = body.split(/\s+/);
125
+ const name = parts[0] ?? '';
126
+ const argument = parts.slice(1).join(' ');
127
+ if (name === '+migration') {
128
+ if (argument !== 'up' && argument !== 'down') {
129
+ throw new ConfigurationError(`${file}: "-- ${body}" names no section — it is either "up" or "down".`);
130
+ }
131
+ flush();
132
+ section = argument;
133
+ return;
134
+ }
135
+ if (name === '+destructive') {
136
+ destructive.push(argument);
137
+ return;
138
+ }
139
+ throw new ConfigurationError(`${file}: "-- ${body}" is not a directive. A comment meant for a reader must not begin ` +
140
+ 'with `+`.');
141
+ };
142
+ while (index < text.length) {
143
+ if (text.startsWith('--', index)) {
144
+ const newline = text.indexOf('\n', index);
145
+ const stop = newline === -1 ? text.length : newline;
146
+ const body = text.slice(index + 2, stop).trim();
147
+ if (body.startsWith('+'))
148
+ directive(body);
149
+ index = stop;
150
+ continue;
151
+ }
152
+ if (text.startsWith('/*', index)) {
153
+ index = endOfBlockComment(text, index, file);
154
+ continue;
155
+ }
156
+ const char = text.charAt(index);
157
+ if (char === "'" || char === '"') {
158
+ const end = endOfQuoted(text, index, char, file);
159
+ buffer += text.slice(index, end);
160
+ index = end;
161
+ continue;
162
+ }
163
+ if (char === '$') {
164
+ const tag = dollarTag(text, index);
165
+ if (tag !== undefined) {
166
+ const end = endOfDollarQuoted(text, index + tag.length, tag, file);
167
+ buffer += text.slice(index, end);
168
+ index = end;
169
+ continue;
170
+ }
171
+ }
172
+ if (char === ';') {
173
+ flush();
174
+ index += 1;
175
+ continue;
176
+ }
177
+ buffer += char;
178
+ index += 1;
179
+ }
180
+ flush();
181
+ return { up: statements.up, down: statements.down, destructive };
182
+ };
183
+ const statementsText = (statements) => statements.map((statement) => `${statement};\n`).join('\n');
184
+ /** The text of a migration file, from what the generator produced. */
185
+ export const migrationFileText = (name, generated) => [
186
+ [
187
+ `-- ${name}`,
188
+ '-- Written by `assemora db:generate`. A comment beginning `-- +` is read back by',
189
+ '-- `assemora db:migrate`; every other comment in this file is for you.',
190
+ ...generated.destructive.map((sentence) => `-- +destructive ${sentence}`),
191
+ ].join('\n'),
192
+ '-- +migration up',
193
+ statementsText(generated.up),
194
+ '-- +migration down',
195
+ statementsText(generated.down),
196
+ ].join('\n\n');
197
+ /**
198
+ * `0002_add-sku.sql`.
199
+ *
200
+ * The number is what decides the order migrations run in, so a file that does not
201
+ * carry one is refused rather than sorted somewhere arbitrary.
202
+ */
203
+ const MIGRATION_FILE = /^(\d+)_([A-Za-z0-9][A-Za-z0-9._-]*)\.sql$/;
204
+ /**
205
+ * A migration's name, as a filename gives it up.
206
+ *
207
+ * `name` is only what a reader calls it; the number is what orders the run, so it is
208
+ * parsed rather than left to the lexicographic accident of `0010` sorting before `02`.
209
+ */
210
+ const numbered = (filename, directory) => {
211
+ const match = MIGRATION_FILE.exec(filename);
212
+ if (match === null) {
213
+ throw new ConfigurationError(`${join(directory, filename)} is not named like a migration. It must be <number>_<name>.sql, ` +
214
+ 'for example 0001_add-products.sql.');
215
+ }
216
+ return { name: filename.slice(0, -'.sql'.length), number: Number(match[1] ?? '') };
217
+ };
218
+ const listing = async (directory) => {
219
+ try {
220
+ return await readdir(directory);
221
+ }
222
+ catch (error) {
223
+ // A project that has never generated a migration has no directory yet, and that
224
+ // is a state rather than a failure — it is the one `db:generate` exists to change.
225
+ if (isRecord(error) && error.code === 'ENOENT')
226
+ return [];
227
+ throw error;
228
+ }
229
+ };
230
+ /** Every migration in the directory, in the order they must run. */
231
+ export const readMigrations = async (directory) => {
232
+ const filenames = (await listing(directory)).filter((filename) => filename.endsWith('.sql'));
233
+ const found = filenames.map((filename) => ({ filename, ...numbered(filename, directory) }));
234
+ found.sort((left, right) => left.number - right.number || left.name.localeCompare(right.name));
235
+ for (let index = 1; index < found.length; index += 1) {
236
+ const previous = found[index - 1];
237
+ const current = found[index];
238
+ // Two branches that each generated 0004 and were then merged. Applying them in
239
+ // whatever order the filesystem offers leaves two machines with two databases, so
240
+ // the answer is to say so rather than to pick one.
241
+ if (previous !== undefined && current !== undefined && previous.number === current.number) {
242
+ throw new ConfigurationError(`${previous.filename} and ${current.filename} share a number, so nothing decides which ` +
243
+ 'runs first. Renumber the later one.');
244
+ }
245
+ }
246
+ return Promise.all(found.map(async (entry) => {
247
+ const path = join(directory, entry.filename);
248
+ const parsed = parseMigration(await readFile(path, 'utf8'), path);
249
+ return { name: entry.name, path, number: entry.number, ...parsed };
250
+ }));
251
+ };
252
+ /**
253
+ * What the runner needs, from what the file holds.
254
+ *
255
+ * A migration with no `down` section leaves `down` off entirely rather than carrying
256
+ * an empty list, so `rollbackLastMigration` can refuse it by name instead of quietly
257
+ * running nothing and marking it undone.
258
+ */
259
+ const toMigration = (file) => ({
260
+ name: file.name,
261
+ up: file.up,
262
+ ...(file.down.length === 0 ? {} : { down: file.down }),
263
+ });
264
+ /** One past the highest number already there, always four digits. */
265
+ export const nextMigrationNumber = (filenames) => {
266
+ const highest = filenames.reduce((max, filename) => {
267
+ const match = MIGRATION_FILE.exec(filename);
268
+ return match === null ? max : Math.max(max, Number(match[1] ?? ''));
269
+ }, 0);
270
+ return String(highest + 1).padStart(4, '0');
271
+ };
272
+ /**
273
+ * `Add products!` becomes `add-products`, which is how SPEC.md §34 writes one.
274
+ *
275
+ * Empty is a valid answer, and the caller is what refuses it: a name made entirely of
276
+ * punctuation is a mistake worth naming, not one to paper over with a default.
277
+ */
278
+ export const migrationSlug = (name) => name
279
+ .toLowerCase()
280
+ .replace(/[^a-z0-9]+/g, '-')
281
+ .replace(/^-+|-+$/g, '');
282
+ /** What `db:generate` calls a migration nobody named. */
283
+ const DEFAULT_SLUG = 'migration';
284
+ /*
285
+ * The snapshot.
286
+ *
287
+ * A diff is taken against this file rather than against a live database, so
288
+ * generation is deterministic, works offline and produces the same migration for two
289
+ * developers whose databases have drifted (ADR-0021).
290
+ */
291
+ const SNAPSHOT_FILE = 'schema.json';
292
+ const SNAPSHOT_VERSION = 1;
293
+ const snapshotPath = (loaded) => join(loaded.paths.generated, SNAPSHOT_FILE);
294
+ const looksLikeTable = (value) => isRecord(value) &&
295
+ typeof value.name === 'string' &&
296
+ typeof value.primaryKey === 'string' &&
297
+ Array.isArray(value.columns) &&
298
+ Array.isArray(value.relations);
299
+ /**
300
+ * The schema the last `db:generate` left behind, or `undefined` when there is no
301
+ * snapshot file at all.
302
+ *
303
+ * The two answers are not the same thing and the caller has to tell them apart: an
304
+ * empty snapshot means "the last migration left no tables", where a missing one means
305
+ * "nothing here knows what the last migration did".
306
+ */
307
+ const readSnapshot = async (loaded) => {
308
+ const path = snapshotPath(loaded);
309
+ let text;
310
+ try {
311
+ text = await readFile(path, 'utf8');
312
+ }
313
+ catch (error) {
314
+ if (isRecord(error) && error.code === 'ENOENT')
315
+ return undefined;
316
+ throw error;
317
+ }
318
+ const broken = (reason) => new ConfigurationError(`${path} ${reason}. It is written by \`assemora db:generate\` and never edited by hand; ` +
319
+ 'delete it to regenerate the whole schema as one migration.');
320
+ let parsed;
321
+ try {
322
+ parsed = JSON.parse(text);
323
+ }
324
+ catch {
325
+ throw broken('is not JSON');
326
+ }
327
+ if (!isRecord(parsed) || parsed.version !== SNAPSHOT_VERSION) {
328
+ throw broken(`was not written by version ${SNAPSHOT_VERSION} of this snapshot format`);
329
+ }
330
+ if (!Array.isArray(parsed.tables) || !parsed.tables.every(looksLikeTable)) {
331
+ throw broken('does not describe a set of tables');
332
+ }
333
+ return parsed.tables;
334
+ };
335
+ const writeSnapshot = async (loaded, migration, tables) => {
336
+ await mkdir(loaded.paths.generated, { recursive: true });
337
+ await writeFile(snapshotPath(loaded),
338
+ // The migration is named so that a merge conflict in this file says which two
339
+ // migrations disagree, rather than only that a hundred lines of JSON do.
340
+ `${JSON.stringify({ version: SNAPSHOT_VERSION, migration, tables }, null, 2)}\n`);
341
+ };
342
+ const isPostgres = (adapter) => typeof adapter.raw === 'function';
343
+ /**
344
+ * The adapter the application registered, if migrations can be run against it.
345
+ *
346
+ * Asking for `raw` and finding nothing is how this fails on the in-memory adapter,
347
+ * and the sentence it fails with is the whole reason to ask at all.
348
+ */
349
+ const postgresAdapter = () => {
350
+ const adapter = currentAdapter();
351
+ if (!isPostgres(adapter)) {
352
+ throw new ConfigurationError('Migrations run against PostgreSQL, and the application registered a different database ' +
353
+ 'adapter — give it `database: postgres()` to run them.');
354
+ }
355
+ return adapter;
356
+ };
357
+ /**
358
+ * Whether this is a place a destructive statement may run unasked (SPEC.md §34).
359
+ *
360
+ * The CLI has `NODE_ENV` and nothing else to go on, so the question is answered the
361
+ * safe way round: development is the value saying so, and everything else — staging,
362
+ * a typo, an unset variable — is treated as production. A developer who has never set
363
+ * `NODE_ENV` meets `--force` once and reads a sentence naming both the variable and
364
+ * the flag; the alternative failure is a dropped column in production, and only one
365
+ * of those two can be undone.
366
+ */
367
+ const DEVELOPMENT = new Set(['development', 'test']);
368
+ const inDevelopment = () => DEVELOPMENT.has(process.env.NODE_ENV ?? '');
369
+ /** The `NODE_ENV is not …` half of both refusals, written once. */
370
+ const NOT_DEVELOPMENT = 'NODE_ENV is not "development" or "test"';
371
+ /*
372
+ * The commands.
373
+ */
374
+ /**
375
+ * Why a missing snapshot is refused rather than warned about.
376
+ *
377
+ * Missing, the diff calls every table new. That is the truth for the very first
378
+ * migration and a lie the moment `database/migrations` already holds one: the file
379
+ * this would write re-creates every table, and `assemora db:migrate` fails on the
380
+ * first one that already exists — a failure that arrives later, on a different
381
+ * machine, naming neither the migration nor the statement.
382
+ *
383
+ * The snapshot cannot be reconstructed from the directory either: reading it back
384
+ * would mean executing the SQL those files hold, and this command exists precisely so
385
+ * that generation is deterministic and offline (ADR-0021). So the honest answer is to
386
+ * stop and say which two files disagree. A warning would be read after the migration
387
+ * was written, which is after the damage — and `--force` is there for the project
388
+ * whose migrations were written by hand and never had a snapshot at all.
389
+ */
390
+ const refuseWithoutSnapshot = (loaded, existing) => {
391
+ fail(`${loaded.paths.migrations} already holds ${count(existing, 'migration')}, and there is no ` +
392
+ `schema snapshot at ${snapshotPath(loaded)} to compare the models against. Generating now ` +
393
+ 'would write a migration that creates every table again, and `assemora db:migrate` would ' +
394
+ 'fail on the first one that already exists.');
395
+ detail('The snapshot is written by `assemora db:generate` and belongs in version control: restore ' +
396
+ 'it from there. Pass --force to diff against an empty schema anyway.');
397
+ return 1;
398
+ };
399
+ export const dbGenerate = defineCommand({
400
+ name: 'db:generate',
401
+ group: 'database',
402
+ summary: 'write a migration for everything the models changed',
403
+ usage: 'assemora db:generate [name] [--check] [--force]',
404
+ handler: async ({ args, cwd }) => {
405
+ const loaded = await loadConfig(cwd);
406
+ // Booting is what imports the project's models, and the registry they declare
407
+ // themselves into is the `after` side of the diff.
408
+ const application = await loadApplication(loaded);
409
+ const after = declaredTables();
410
+ if (after.length === 0) {
411
+ throw new ConfigurationError(`${loaded.file}: the application booted but declared no models, so there is no schema to ` +
412
+ 'generate from. If it does declare models, the CLI and the project are resolving two ' +
413
+ 'different copies of @assemora/data.');
414
+ }
415
+ const snapshot = await readSnapshot(loaded);
416
+ const existing = (await listing(loaded.paths.migrations)).filter((filename) => MIGRATION_FILE.test(filename));
417
+ if (snapshot === undefined && existing.length > 0 && !bool(args, 'force')) {
418
+ return refuseWithoutSnapshot(loaded, existing.length);
419
+ }
420
+ const generated = await generateMigration(snapshot ?? [], after, application.locales?.defaultLocale);
421
+ if (generated.up.length === 0) {
422
+ line('The models and the last migration agree. Nothing to generate.');
423
+ return 0;
424
+ }
425
+ for (const sentence of generated.destructive)
426
+ warn(sentence);
427
+ if (bool(args, 'check')) {
428
+ fail(`A migration is missing: ${count(generated.up.length, 'statement')} would be written by ` +
429
+ '`assemora db:generate`.');
430
+ for (const statement of generated.up)
431
+ detail(statement);
432
+ return 1;
433
+ }
434
+ const given = args.positionals[0];
435
+ const slug = given === undefined ? DEFAULT_SLUG : migrationSlug(given);
436
+ if (slug === '') {
437
+ fail(`"${given ?? ''}" leaves nothing to name a file with. Use letters and digits.`);
438
+ return 2;
439
+ }
440
+ const name = `${nextMigrationNumber(await listing(loaded.paths.migrations))}_${slug}`;
441
+ const path = join(loaded.paths.migrations, `${name}.sql`);
442
+ await mkdir(loaded.paths.migrations, { recursive: true });
443
+ await writeFile(path, migrationFileText(name, generated));
444
+ // Only now: a snapshot moved forward past a migration that was never written
445
+ // would silently swallow the change on the next run.
446
+ await writeSnapshot(loaded, name, after);
447
+ ok(`Wrote ${path}`);
448
+ return 0;
449
+ },
450
+ });
451
+ /**
452
+ * Runs the migrations, and says where the run stopped if it did.
453
+ *
454
+ * A statement that PostgreSQL rejects arrives as one redacted sentence naming neither
455
+ * the migration nor the statement (SPEC.md §83) — true of every database error, and
456
+ * useless here, where the file is the unit a person acts on. Each migration commits on
457
+ * its own, so asking again afterwards is what places the failure: what is still pending
458
+ * begins with the one that did not apply.
459
+ *
460
+ * The second question is best effort. A run that failed because the connection went is
461
+ * a run whose status cannot be read either, and the failure that matters is still the
462
+ * first one.
463
+ */
464
+ const apply = async (run, status) => {
465
+ try {
466
+ return await run();
467
+ }
468
+ catch (error) {
469
+ const pending = (await status().catch(() => [])).find((entry) => !entry.applied);
470
+ if (pending !== undefined)
471
+ detail(`The run stopped at ${pending.name}: nothing after it ran.`);
472
+ throw error;
473
+ }
474
+ };
475
+ export const dbMigrate = defineCommand({
476
+ name: 'db:migrate',
477
+ group: 'database',
478
+ summary: 'apply every migration that has not run yet',
479
+ usage: 'assemora db:migrate [--force]',
480
+ handler: async ({ args, cwd }) => {
481
+ const loaded = await loadConfig(cwd);
482
+ await loadApplication(loaded);
483
+ const adapter = postgresAdapter();
484
+ const files = await readMigrations(loaded.paths.migrations);
485
+ if (files.length === 0) {
486
+ line(`No migrations in ${loaded.paths.migrations}.`);
487
+ return 0;
488
+ }
489
+ const migrations = files.map(toMigration);
490
+ const { applyMigrations, migrationStatus } = await import('@assemora/database-postgres');
491
+ // Asked before applying, so that the guard below weighs what is about to run
492
+ // rather than what ran months ago.
493
+ const status = await migrationStatus(adapter, migrations);
494
+ const applied = new Set(status.filter((entry) => entry.applied).map((entry) => entry.name));
495
+ const risky = files.filter((file) => !applied.has(file.name) && file.destructive.length > 0);
496
+ for (const file of risky) {
497
+ for (const sentence of file.destructive)
498
+ warn(`${file.name}: ${sentence}`);
499
+ }
500
+ if (risky.length > 0 && !inDevelopment() && !bool(args, 'force')) {
501
+ fail(`${count(risky.length, 'pending migration')} change or destroy stored data, and ` +
502
+ `${NOT_DEVELOPMENT}. Pass --force to apply them anyway.`);
503
+ return 1;
504
+ }
505
+ const ran = await apply(() => applyMigrations(adapter, migrations), () => migrationStatus(adapter, migrations));
506
+ if (ran.length === 0) {
507
+ line('Every migration is already applied.');
508
+ return 0;
509
+ }
510
+ for (const name of ran)
511
+ line(name);
512
+ ok(`Applied ${count(ran.length, 'migration')}.`);
513
+ return 0;
514
+ },
515
+ });
516
+ export const dbRollback = defineCommand({
517
+ name: 'db:rollback',
518
+ group: 'database',
519
+ summary: 'undo the most recently applied migration',
520
+ usage: 'assemora db:rollback [--force]',
521
+ handler: async ({ args, cwd }) => {
522
+ const loaded = await loadConfig(cwd);
523
+ await loadApplication(loaded);
524
+ const adapter = postgresAdapter();
525
+ const files = await readMigrations(loaded.paths.migrations);
526
+ const migrations = files.map(toMigration);
527
+ const { migrationStatus, rollbackLastMigration } = await import('@assemora/database-postgres');
528
+ const status = await migrationStatus(adapter, migrations);
529
+ const last = [...status].reverse().find((entry) => entry.applied);
530
+ if (last === undefined) {
531
+ line('Nothing has been applied, so there is nothing to roll back.');
532
+ return 0;
533
+ }
534
+ // Every rollback is destructive: it discards whatever the migration wrote, which
535
+ // is the same reason SPEC.md §34 puts `--force` in front of one.
536
+ if (!inDevelopment() && !bool(args, 'force')) {
537
+ fail(`Rolling ${last.name} back discards everything it wrote, and ${NOT_DEVELOPMENT}. ` +
538
+ 'Pass --force to roll it back anyway.');
539
+ return 1;
540
+ }
541
+ const rolled = await rollbackLastMigration(adapter, migrations);
542
+ if (rolled === null) {
543
+ line('Nothing has been applied, so there is nothing to roll back.');
544
+ return 0;
545
+ }
546
+ ok(`Rolled ${rolled} back.`);
547
+ return 0;
548
+ },
549
+ });
550
+ export const dbStatus = defineCommand({
551
+ name: 'db:status',
552
+ group: 'database',
553
+ summary: 'list every migration and whether it is applied',
554
+ usage: 'assemora db:status [--json]',
555
+ handler: async ({ args, cwd }) => {
556
+ const loaded = await loadConfig(cwd);
557
+ await loadApplication(loaded);
558
+ const adapter = postgresAdapter();
559
+ const files = await readMigrations(loaded.paths.migrations);
560
+ const { migrationStatus } = await import('@assemora/database-postgres');
561
+ const status = await migrationStatus(adapter, files.map(toMigration));
562
+ if (bool(args, 'json')) {
563
+ json(status);
564
+ return 0;
565
+ }
566
+ if (status.length === 0) {
567
+ line(`No migrations in ${loaded.paths.migrations}.`);
568
+ return 0;
569
+ }
570
+ table(status, [
571
+ { header: 'migration', value: (entry) => entry.name },
572
+ { header: 'applied', value: (entry) => (entry.applied ? 'yes' : 'pending') },
573
+ {
574
+ header: 'applied at',
575
+ value: (entry) => (entry.appliedAt === undefined ? '' : entry.appliedAt.toISOString()),
576
+ },
577
+ ]);
578
+ const pending = status.filter((entry) => !entry.applied).length;
579
+ line();
580
+ line(pending === 0 ? 'Every migration is applied.' : `${count(pending, 'migration')} pending.`);
581
+ return 0;
582
+ },
583
+ });
584
+ register(dbGenerate, dbMigrate, dbRollback, dbStatus);
585
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/commands/db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Where the groups reach the command table.
3
+ *
4
+ * `registry.ts` holds the table; a group only reaches it by being imported, and this
5
+ * file is the one place that imports them. It is deliberately nothing else: a group
6
+ * added here is a group in the help, and there is no second list to keep in step.
7
+ *
8
+ * A group that needs a heavy import — `@assemora/database-postgres` for `db:*`, the
9
+ * SDK generator for `sdk:generate` — should reach for it inside its handler rather
10
+ * than at the top of its module, so that `assemora --help` stays instant.
11
+ */
12
+ import './new.js';
13
+ import './run.js';
14
+ import './db.js';
15
+ import './inspect.js';
16
+ import './artifacts.js';
17
+ import './agents.js';
18
+ import './console.js';
19
+ import './mcp.js';
20
+ import './make.js';
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,UAAU,CAAA;AACjB,OAAO,UAAU,CAAA;AACjB,OAAO,SAAS,CAAA;AAChB,OAAO,cAAc,CAAA;AACrB,OAAO,gBAAgB,CAAA;AACvB,OAAO,aAAa,CAAA;AACpB,OAAO,cAAc,CAAA;AACrB,OAAO,UAAU,CAAA;AAEjB,OAAO,WAAW,CAAA"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Where the groups reach the command table.
3
+ *
4
+ * `registry.ts` holds the table; a group only reaches it by being imported, and this
5
+ * file is the one place that imports them. It is deliberately nothing else: a group
6
+ * added here is a group in the help, and there is no second list to keep in step.
7
+ *
8
+ * A group that needs a heavy import — `@assemora/database-postgres` for `db:*`, the
9
+ * SDK generator for `sdk:generate` — should reach for it inside its handler rather
10
+ * than at the top of its module, so that `assemora --help` stays instant.
11
+ */
12
+ import './new.js';
13
+ import './run.js';
14
+ import './db.js';
15
+ import './inspect.js';
16
+ import './artifacts.js';
17
+ import './agents.js';
18
+ import './console.js';
19
+ import './mcp.js';
20
+ import './make.js';
21
+ //# sourceMappingURL=index.js.map