@happyvertical/smrt-cli 0.45.3 → 0.46.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/AGENTS.md +66 -0
- package/README.md +10 -0
- package/dist/{commands-COd77prj.js → commands-C4xB-FxS.js} +253 -17
- package/dist/{config-BwrFRL8L.js → config-DfBo4hHU.js} +15 -1
- package/dist/index.js +14 -14
- package/dist/{json-validator-D5hN4DGj.js → json-validator-CjX8fHx9.js} +1 -1
- package/package.json +7 -7
package/AGENTS.md
CHANGED
|
@@ -15,6 +15,8 @@ smrt db:migrate --postgres-safe # PostgreSQL concurrent-index mode (see below)
|
|
|
15
15
|
smrt db:migrate --force-migration <exact-id> [--force-migration <exact-id>...] # Force exact generated migrations in one atomic batch
|
|
16
16
|
smrt db:migrate-uuid # Convert schema-declared UUID text columns after data remap
|
|
17
17
|
smrt db:migrate-int8 # Explicitly widen pre-#2373 int4 columns after preflight
|
|
18
|
+
smrt db:drop-framework-base-tables # One-time drop of the five #2644-orphaned framework-base tables
|
|
19
|
+
smrt db:drop-framework-base-tables --dry-run # Print the drop plan without executing
|
|
18
20
|
smrt db:diff # Show schema differences without generating migration files
|
|
19
21
|
smrt db:rollback # Roll back migrations by executing their recorded DOWN
|
|
20
22
|
smrt db:rollback --mark-only # Record-only flip; schema deliberately untouched
|
|
@@ -154,6 +156,12 @@ to run a build.
|
|
|
154
156
|
|
|
155
157
|
## Live-schema parity (#2368)
|
|
156
158
|
|
|
159
|
+
PostgreSQL role contracts also surface through read-only `doctor --db` and
|
|
160
|
+
`db:validate`. Explicit repair uses `db:permissions` with a reviewed fingerprint;
|
|
161
|
+
ordinary migrations never change ACLs. See the
|
|
162
|
+
[permission guide](../../docs/content/postgres-permissions.md) for configuration,
|
|
163
|
+
authority boundaries, and recovery.
|
|
164
|
+
|
|
157
165
|
`doctor --db` and `db:status --parity` share `src/commands/db-parity.ts`, which
|
|
158
166
|
runs core's `checkLiveSchemaParity()`. This answers a different question than
|
|
159
167
|
`db:status`/`db:diff`: those compare the live database to the **manifest**, i.e.
|
|
@@ -257,6 +265,64 @@ sessions/magic-link tokens/CLI-auth requests from `smrt-users`).
|
|
|
257
265
|
- Deployments running a jobs `TaskRunner` already get the same sweep every six
|
|
258
266
|
hours; this command is for those that do not, and for one-off operator runs.
|
|
259
267
|
|
|
268
|
+
## `db:drop-framework-base-tables` is a one-time remediation (#2647)
|
|
269
|
+
|
|
270
|
+
`db:migrate` no longer plans `smrt_objects`/`smrt_classes`/`smrt_collections`/
|
|
271
|
+
`smrt_hierarchicals`/`smrt_polymorphic_associations` (#2644), but any
|
|
272
|
+
deployment that ran `db:migrate` before that fix still has all five. This
|
|
273
|
+
command, backed by `planFrameworkBaseTableDrop()` /
|
|
274
|
+
`dropFrameworkBaseTables()` in `@happyvertical/smrt-core/migrations`, drops
|
|
275
|
+
exactly those five hardcoded names and nothing else — **never** derived from
|
|
276
|
+
`SchemaDiff.orphan_tables`, which would recreate the dangerous global orphan
|
|
277
|
+
drop `includeDroppedTables` (default `false`, both call sites explicit —
|
|
278
|
+
`differ.ts:450`, `db-diff.ts:210`) deliberately refuses to be.
|
|
279
|
+
|
|
280
|
+
- Execute-or-refuse, like `db:rollback`: it refuses (non-zero exit, nothing
|
|
281
|
+
dropped) if any target table has rows, has anything but that table's own
|
|
282
|
+
expected columns and types, or is referenced by a foreign key anywhere in
|
|
283
|
+
the live database. A consumer's own unrelated table sharing one of these
|
|
284
|
+
five names is exactly what the shape check protects.
|
|
285
|
+
- The expected shape is **per table, not one universal baseline**:
|
|
286
|
+
`smrt_objects`/`smrt_classes`/`smrt_collections` are exactly `id`/`slug`/
|
|
287
|
+
`context`/`created_at`/`updated_at`, but `smrt_hierarchicals` also
|
|
288
|
+
requires `parent_id` and `smrt_polymorphic_associations` also requires
|
|
289
|
+
`meta_type`/`meta_id`/`role`/`sort_order` — `SmrtHierarchical`'s and
|
|
290
|
+
`SmrtPolymorphicAssociation`'s own real fields, confirmed against a
|
|
291
|
+
genuine pre-#2644 `db:migrate` run. A table under either of those two
|
|
292
|
+
names with *only* the plain five columns is refused as unexpected shape,
|
|
293
|
+
not treated as safe.
|
|
294
|
+
- Companion indexes are enumerated from each table's live schema (never
|
|
295
|
+
guessed). `smrt_hierarchicals`/`smrt_polymorphic_associations` do not
|
|
296
|
+
carry the `created_at` list-ordering index the other three do (also
|
|
297
|
+
empirically confirmed, not assumed).
|
|
298
|
+
- Bounded PostgreSQL execution reuses the same `SET LOCAL lock_timeout` /
|
|
299
|
+
`statement_timeout` pattern as every other DDL path (#2362). Every target
|
|
300
|
+
is locked `IN ACCESS EXCLUSIVE MODE` before re-checking it — a plain
|
|
301
|
+
`SELECT COUNT(*)` alone would not block a concurrent writer — and shape,
|
|
302
|
+
type, and emptiness are all re-verified inside that transaction
|
|
303
|
+
immediately before dropping anything, via raw `information_schema.columns`
|
|
304
|
+
/ `PRAGMA table_info` (`getTableSchema()` is not available on the
|
|
305
|
+
transaction-scoped connection). Only `DROP TABLE` is ever executed —
|
|
306
|
+
never a `DROP INDEX` by name — so `DROP TABLE`'s own cascade removes the
|
|
307
|
+
table's indexes identity-safely instead of trusting a possibly-stale
|
|
308
|
+
planned index name.
|
|
309
|
+
- `--dry-run` prints the exact plan (which tables exist, their companion
|
|
310
|
+
indexes, and the DROP statements) without executing.
|
|
311
|
+
- Skipping it is safe: a table left behind is inert and permanently orphaned,
|
|
312
|
+
never written to or read from again. Documented, narrow residual risk, all
|
|
313
|
+
schema-integrity (never data loss — the target is always verified empty
|
|
314
|
+
first): DuckDB's adapter does not report foreign keys through
|
|
315
|
+
`getTableSchema()` at all; this module's reverse-FK scan (like every other
|
|
316
|
+
PostgreSQL schema tool in this package) only looks at the `public` schema;
|
|
317
|
+
and foreign keys are checked at planning time only, not re-scanned inside
|
|
318
|
+
the execution transaction. On PostgreSQL a foreign key that appeared after
|
|
319
|
+
planning is still caught there — `DROP TABLE` refuses when a real
|
|
320
|
+
dependent exists, dependency-based, empty parent or not. **This does not
|
|
321
|
+
hold on SQLite**: its FK enforcement on `DROP TABLE` is row-based, so an
|
|
322
|
+
empty parent (this command's precondition) drops cleanly past a real
|
|
323
|
+
foreign key, verified directly. The plan-time scan is the only gate on
|
|
324
|
+
SQLite/DuckDB, narrower than PostgreSQL's.
|
|
325
|
+
|
|
260
326
|
## Architecture
|
|
261
327
|
|
|
262
328
|
- **Lazy command loading**: commands loaded on-demand via dynamic import (~100ms overhead on first use)
|
package/README.md
CHANGED
|
@@ -47,10 +47,20 @@ The four snapshot options are atomic: supplying any one requires all four.
|
|
|
47
47
|
| `smrt db:migrate` | Apply pending migrations |
|
|
48
48
|
| `smrt db:migrate --force-migration <exact-id> [--force-migration <exact-id>...]` | Force one or more exact generated migrations in one atomic batch while preserving every other guard |
|
|
49
49
|
| `smrt db:migrate-uuid` | Convert schema-declared UUID text columns to native PostgreSQL uuid after data has been remapped |
|
|
50
|
+
| `smrt db:migrate-int8` | Widen legacy pre-#2373 int4 columns to BIGINT after reviewing the maintenance-window preflight |
|
|
51
|
+
| `smrt db:drop-framework-base-tables` | One-time removal of the five framework-base tables (`smrt_objects`, `smrt_classes`, `smrt_collections`, `smrt_hierarchicals`, `smrt_polymorphic_associations`) orphaned by #2644; refuses if any target table has rows, an unexpected shape, or an inbound foreign key |
|
|
52
|
+
| `smrt db:drop-framework-base-tables --dry-run` | Print the drop plan (tables and companion indexes) without executing |
|
|
50
53
|
| `smrt db:diff` | Show schema differences without generating migration files |
|
|
51
54
|
| `smrt db:rollback` | Roll back the last migration by executing its recorded DOWN script; refuses when no DOWN script exists |
|
|
52
55
|
| `smrt db:rollback --mark-only` | Record-only: mark migrations rolled back without running any DOWN script (schema untouched) |
|
|
53
56
|
| `smrt db:history` | Show migration history with active-vs-superseded failure classification |
|
|
57
|
+
| `smrt db:permissions --dry-run` | Plan the declared PostgreSQL role permission contract |
|
|
58
|
+
| `smrt db:permissions --apply --expected-fingerprint <hash>` | Explicitly apply a reviewed permission plan |
|
|
59
|
+
| `smrt db:validate` | Validate configured PostgreSQL permissions or JSON database integrity |
|
|
60
|
+
|
|
61
|
+
For separate migration-owner, runtime, and monitoring roles, see the
|
|
62
|
+
[PostgreSQL permissions guide](../../docs/content/postgres-permissions.md).
|
|
63
|
+
`doctor --db` includes read-only permission diagnostics when configured.
|
|
54
64
|
|
|
55
65
|
File-backed SQL/TypeScript migration generation is not supported. s-m-r-t schema
|
|
56
66
|
migrations are manifest-driven; model schema with s-m-r-t objects and apply changes
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { t as DEFAULT_CLI_CONFIG } from "./config-DfBo4hHU.js";
|
|
1
2
|
import { t as resolveManifestEntryPackageName } from "./index.js";
|
|
2
3
|
import { createRequire } from "node:module";
|
|
3
4
|
import * as fs from "node:fs";
|
|
@@ -11,6 +12,7 @@ import { access, cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
|
11
12
|
import { createLogger } from "@happyvertical/logger";
|
|
12
13
|
import glob from "fast-glob";
|
|
13
14
|
import { createHash } from "node:crypto";
|
|
15
|
+
import { getPackageConfig } from "@happyvertical/smrt-config";
|
|
14
16
|
import { toSnakeCase } from "@happyvertical/smrt-core/utils";
|
|
15
17
|
import { discoverScopedPackageDirectories, readAgentModuleDocs, readPackageAgentDoc, resolveAgentModuleDocPaths } from "@happyvertical/smrt-core/knowledge";
|
|
16
18
|
import { MCPGenerator } from "@happyvertical/smrt-core/generators";
|
|
@@ -20,7 +22,7 @@ import https from "node:https";
|
|
|
20
22
|
import { homedir, tmpdir } from "node:os";
|
|
21
23
|
import { extract } from "tar";
|
|
22
24
|
import { importWorkspaceModule } from "@happyvertical/smrt-core/utils/import-workspace-module";
|
|
23
|
-
import { buildIntegerWidthTableStatements, collectIntegerWidthTargets, parsePostgresTimeoutMs, preflightIntegerWidthWidening, widenIntegerColumnsToBigInt } from "@happyvertical/smrt-core/migrations";
|
|
25
|
+
import { FRAMEWORK_BASE_TABLE_NAMES, buildIntegerWidthTableStatements, collectIntegerWidthTargets, dropFrameworkBaseTables, parsePostgresTimeoutMs, planFrameworkBaseTableDrop, preflightIntegerWidthWidening, widenIntegerColumnsToBigInt } from "@happyvertical/smrt-core/migrations";
|
|
24
26
|
import { buildArchitectureContext, buildKnowledgeIndex, buildReviewContext, checkKnowledgeFreshness, compactContextResult, diffKnowledgeIndex, renderFreshnessResult, renderKnowledgeIndexMarkdown } from "@happyvertical/smrt-dev-mcp/knowledge";
|
|
25
27
|
//#region src/commands/db-command-utils.ts
|
|
26
28
|
var SENSITIVE_QUERY_PARAMS = /* @__PURE__ */ new Set([
|
|
@@ -123,7 +125,7 @@ var configExportCommand = {
|
|
|
123
125
|
process.exit(1);
|
|
124
126
|
}
|
|
125
127
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
126
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
128
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
127
129
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
128
130
|
if (!config.database?.url || config.database.url === ":memory:") {
|
|
129
131
|
if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
|
|
@@ -962,7 +964,7 @@ var dbDiffCommand = {
|
|
|
962
964
|
return;
|
|
963
965
|
}
|
|
964
966
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
965
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
967
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
966
968
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
967
969
|
if (!config.database?.url || config.database.url === ":memory:") {
|
|
968
970
|
if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
|
|
@@ -1285,7 +1287,7 @@ var dbHistoryCommand = {
|
|
|
1285
1287
|
let db;
|
|
1286
1288
|
try {
|
|
1287
1289
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
1288
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
1290
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
1289
1291
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
1290
1292
|
if (!config.database?.url || config.database.url === ":memory:") {
|
|
1291
1293
|
if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
|
|
@@ -1456,6 +1458,109 @@ function formatDateTime(date) {
|
|
|
1456
1458
|
return date.toISOString().replace("T", " ").substring(0, 19);
|
|
1457
1459
|
}
|
|
1458
1460
|
//#endregion
|
|
1461
|
+
//#region src/commands/db-permissions.ts
|
|
1462
|
+
/** The only mutating caller is the explicit permissions command. */
|
|
1463
|
+
async function runPostgresPermissions(options = {}, optional = false) {
|
|
1464
|
+
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
1465
|
+
const configured = config.postgresPermissions;
|
|
1466
|
+
const failure = (error) => ({
|
|
1467
|
+
skipped: false,
|
|
1468
|
+
plan: null,
|
|
1469
|
+
error
|
|
1470
|
+
});
|
|
1471
|
+
if (!configured && optional) return {
|
|
1472
|
+
skipped: true,
|
|
1473
|
+
plan: null,
|
|
1474
|
+
error: null
|
|
1475
|
+
};
|
|
1476
|
+
if (!configured) return failure("Configure postgresPermissions before inspecting or applying database permissions.");
|
|
1477
|
+
if (config.database?.type !== "postgres" || !config.database.url) return failure("PostgreSQL permissions require a configured PostgreSQL database.");
|
|
1478
|
+
if (options.apply && (options["dry-run"] || !options["expected-fingerprint"])) return failure("--apply requires --expected-fingerprint from a reviewed plan and cannot be combined with --dry-run.");
|
|
1479
|
+
let db;
|
|
1480
|
+
try {
|
|
1481
|
+
await autoDiscoverAndLoad();
|
|
1482
|
+
const { getDatabase } = await import("@happyvertical/sql");
|
|
1483
|
+
const { ObjectRegistry, getSystemTableShapes, planPostgresPermissions, applyPostgresPermissions } = await import("@happyvertical/smrt-core");
|
|
1484
|
+
db = await getDatabase({
|
|
1485
|
+
type: "postgres",
|
|
1486
|
+
url: config.database.url
|
|
1487
|
+
});
|
|
1488
|
+
const { rows } = await db.query("SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = $1", [configured.schema]);
|
|
1489
|
+
const present = new Set(rows.map((row) => row.tablename));
|
|
1490
|
+
const managedTables = [.../* @__PURE__ */ new Set([
|
|
1491
|
+
...Object.keys(ObjectRegistry.getAllSchemasAsDefinitions()),
|
|
1492
|
+
...[...getSystemTableShapes("postgres").keys()].filter((table) => present.has(table)),
|
|
1493
|
+
...configured.managedTables ?? []
|
|
1494
|
+
])].sort();
|
|
1495
|
+
const contract = {
|
|
1496
|
+
...configured,
|
|
1497
|
+
managedTables
|
|
1498
|
+
};
|
|
1499
|
+
return {
|
|
1500
|
+
skipped: false,
|
|
1501
|
+
plan: options.apply ? await applyPostgresPermissions(db, contract, { expectedFingerprint: options["expected-fingerprint"] ?? "" }) : await planPostgresPermissions(db, contract),
|
|
1502
|
+
error: null
|
|
1503
|
+
};
|
|
1504
|
+
} catch {
|
|
1505
|
+
return failure("PostgreSQL permissions could not be verified or applied. Check connectivity, contract validity, administrator authority, and the reviewed fingerprint.");
|
|
1506
|
+
} finally {
|
|
1507
|
+
try {
|
|
1508
|
+
await closeDatabaseConnection(db);
|
|
1509
|
+
} catch {}
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
function formatPermissionsOutcome(outcome) {
|
|
1513
|
+
if (outcome.skipped) return [];
|
|
1514
|
+
if (outcome.error) return [`PostgreSQL permissions: ${outcome.error}`];
|
|
1515
|
+
const plan = outcome.plan;
|
|
1516
|
+
if (!plan) return ["PostgreSQL permissions could not be verified."];
|
|
1517
|
+
return [
|
|
1518
|
+
`PostgreSQL permissions: ${plan.diagnostics.length} finding(s)`,
|
|
1519
|
+
...plan.diagnostics.map((finding) => ` ${finding.severity}: ${finding.role ? `${finding.role} · ` : ""}${finding.resource}: ${finding.message}`),
|
|
1520
|
+
`Plan fingerprint: ${plan.fingerprint}`,
|
|
1521
|
+
...plan.limitations.map((limitation) => `Scope: ${limitation}`),
|
|
1522
|
+
...plan.canApply ? [] : ["Automatic application refused; resolve unsupported conditions first."]
|
|
1523
|
+
];
|
|
1524
|
+
}
|
|
1525
|
+
function outputPermissionsOutcome(outcome, json = false) {
|
|
1526
|
+
if (json) console.log(JSON.stringify(outcome, null, 2));
|
|
1527
|
+
else for (const line of formatPermissionsOutcome(outcome)) console.log(line);
|
|
1528
|
+
if (outcome.error || outcome.plan?.diagnostics.length) process.exitCode = 1;
|
|
1529
|
+
}
|
|
1530
|
+
var dbPermissionsCommand = {
|
|
1531
|
+
name: "db:permissions",
|
|
1532
|
+
description: "Inspect PostgreSQL role permissions; explicitly apply a reviewed plan",
|
|
1533
|
+
args: [],
|
|
1534
|
+
options: {
|
|
1535
|
+
"dry-run": {
|
|
1536
|
+
type: "boolean",
|
|
1537
|
+
description: "Read-only plan (the default)"
|
|
1538
|
+
},
|
|
1539
|
+
apply: {
|
|
1540
|
+
type: "boolean",
|
|
1541
|
+
description: "Apply the reviewed plan explicitly",
|
|
1542
|
+
default: false
|
|
1543
|
+
},
|
|
1544
|
+
"expected-fingerprint": {
|
|
1545
|
+
type: "string",
|
|
1546
|
+
description: "Fingerprint from the reviewed read-only plan"
|
|
1547
|
+
},
|
|
1548
|
+
json: {
|
|
1549
|
+
type: "boolean",
|
|
1550
|
+
description: "Output plan and diagnostics as JSON",
|
|
1551
|
+
default: false
|
|
1552
|
+
}
|
|
1553
|
+
},
|
|
1554
|
+
handler: async (_args, options) => {
|
|
1555
|
+
const outcome = await runPostgresPermissions(options);
|
|
1556
|
+
outputPermissionsOutcome(outcome, options.json);
|
|
1557
|
+
if (!options.json && outcome.plan && !options.apply) {
|
|
1558
|
+
console.log("Read-only plan SQL:");
|
|
1559
|
+
for (const sql of outcome.plan.statements) console.log(sql);
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
};
|
|
1563
|
+
//#endregion
|
|
1459
1564
|
//#region src/commands/db-prune.ts
|
|
1460
1565
|
/**
|
|
1461
1566
|
* Packages that contribute retention tasks by registering them on import.
|
|
@@ -1595,7 +1700,7 @@ var dbPruneCommand = {
|
|
|
1595
1700
|
let db;
|
|
1596
1701
|
try {
|
|
1597
1702
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
1598
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
1703
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
1599
1704
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
1600
1705
|
if (!config.database?.url) {
|
|
1601
1706
|
const message = "Database not configured. Set database.url in smrt.config.ts.";
|
|
@@ -1755,7 +1860,7 @@ var dbRollbackCommand = {
|
|
|
1755
1860
|
const markOnly = options["mark-only"] ?? options.markOnly;
|
|
1756
1861
|
try {
|
|
1757
1862
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
1758
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
1863
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
1759
1864
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
1760
1865
|
if (!config.database?.url || config.database.url === ":memory:") {
|
|
1761
1866
|
if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
|
|
@@ -2013,7 +2118,7 @@ async function runLiveSchemaParity(options = {}) {
|
|
|
2013
2118
|
let db;
|
|
2014
2119
|
try {
|
|
2015
2120
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
2016
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
2121
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
2017
2122
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
2018
2123
|
if (!config.database?.url || config.database.url === ":memory:") return {
|
|
2019
2124
|
report: null,
|
|
@@ -2552,7 +2657,7 @@ var dbStatusCommand = {
|
|
|
2552
2657
|
let db;
|
|
2553
2658
|
try {
|
|
2554
2659
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
2555
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
2660
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
2556
2661
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
2557
2662
|
if (!config.database?.url || config.database.url === ":memory:") {
|
|
2558
2663
|
if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
|
|
@@ -2814,7 +2919,7 @@ async function getDispatchBus() {
|
|
|
2814
2919
|
const { createDispatchBus } = await import("@happyvertical/smrt-core");
|
|
2815
2920
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
2816
2921
|
const { getDatabase } = await import("@happyvertical/sql");
|
|
2817
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
2922
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
2818
2923
|
const dbConfig = getPackageConfig("cli", DEFAULT_CLI_CONFIG).database;
|
|
2819
2924
|
if (!dbConfig?.url) throw new Error("Database not configured. Set database.url in smrt.config.ts or use --db option.");
|
|
2820
2925
|
let db;
|
|
@@ -3732,7 +3837,7 @@ var exportCommand = {
|
|
|
3732
3837
|
let db;
|
|
3733
3838
|
try {
|
|
3734
3839
|
const { getConfig, getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
3735
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
3840
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
3736
3841
|
const smrtConfig = getConfig();
|
|
3737
3842
|
const cliConfig = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
3738
3843
|
if (!smrtConfig) {
|
|
@@ -6140,6 +6245,122 @@ var playgroundCommands = {
|
|
|
6140
6245
|
}
|
|
6141
6246
|
};
|
|
6142
6247
|
//#endregion
|
|
6248
|
+
//#region src/commands/db-drop-framework-base-tables.ts
|
|
6249
|
+
/**
|
|
6250
|
+
* db:drop-framework-base-tables Command
|
|
6251
|
+
*
|
|
6252
|
+
* One-time remediation for the five orphaned framework-base tables
|
|
6253
|
+
* (`smrt_objects`, `smrt_classes`, `smrt_collections`, `smrt_hierarchicals`,
|
|
6254
|
+
* `smrt_polymorphic_associations`) that a pre-#2644 `db:migrate` planned for
|
|
6255
|
+
* SMRT's abstract framework-base classes. #2644 stopped planning them; this
|
|
6256
|
+
* command drops the ones a deployment already created.
|
|
6257
|
+
*
|
|
6258
|
+
* Deliberately separate from `db:migrate` and from `db:diff`'s orphan-table
|
|
6259
|
+
* reporting: `SchemaDiff.includeDroppedTables` stays `false` so an ordinary
|
|
6260
|
+
* migration never drops a table just because it is absent from the manifest.
|
|
6261
|
+
* This command drops **only** the five hardcoded names above, and only after
|
|
6262
|
+
* verifying each one is empty, has no foreign keys pointing at it, and has
|
|
6263
|
+
* exactly that table's own expected columns — the universal `id`/`slug`/
|
|
6264
|
+
* `context`/`created_at`/`updated_at` base for `smrt_objects`/`smrt_classes`/
|
|
6265
|
+
* `smrt_collections`, extended with `parent_id` for `smrt_hierarchicals` and
|
|
6266
|
+
* `meta_type`/`meta_id`/`role`/`sort_order` for
|
|
6267
|
+
* `smrt_polymorphic_associations` (their own real fields, not the plain
|
|
6268
|
+
* baseline — see `@happyvertical/smrt-core/migrations`'
|
|
6269
|
+
* `planFrameworkBaseTableDrop()` for the full per-table safety model).
|
|
6270
|
+
*
|
|
6271
|
+
* Skipping this command is safe: a table left behind here is inert and
|
|
6272
|
+
* permanently orphaned, never written to or read from again.
|
|
6273
|
+
*/
|
|
6274
|
+
var DEFAULT_POSTGRES_LOCK_TIMEOUT_MS$1 = 3e4;
|
|
6275
|
+
var DEFAULT_POSTGRES_STATEMENT_TIMEOUT_MS$1 = 6e4;
|
|
6276
|
+
function describeRefusal(refusal) {
|
|
6277
|
+
switch (refusal.kind) {
|
|
6278
|
+
case "not-empty": return `has ${refusal.rowCount} row(s) — nothing should ever have written to this table`;
|
|
6279
|
+
case "unexpected-shape": {
|
|
6280
|
+
const parts = [];
|
|
6281
|
+
if (refusal.extraColumns.length > 0) parts.push(`unexpected column(s) [${refusal.extraColumns.join(", ")}]`);
|
|
6282
|
+
if (refusal.missingColumns.length > 0) parts.push(`missing baseline column(s) [${refusal.missingColumns.join(", ")}]`);
|
|
6283
|
+
return `has an unexpected shape: ${parts.join("; ")} (actual columns: ${refusal.actualColumns.join(", ")})`;
|
|
6284
|
+
}
|
|
6285
|
+
case "unexpected-column-type": return `has an unexpected column type: ${refusal.mismatches.map((mismatch) => `${mismatch.column} is "${mismatch.actualType}" (expected ${mismatch.expectedBuckets.join(" or ")})`).join(", ")}`;
|
|
6286
|
+
case "referenced-by-foreign-key": return `is referenced by foreign key(s) from: ${refusal.references.map((reference) => `${reference.table}.${reference.column}`).join(", ")}`;
|
|
6287
|
+
case "introspection-unavailable": return refusal.reason;
|
|
6288
|
+
default: return "is unsafe to drop for an unrecognized reason";
|
|
6289
|
+
}
|
|
6290
|
+
}
|
|
6291
|
+
var dbDropFrameworkBaseTablesCommand = {
|
|
6292
|
+
name: "db:drop-framework-base-tables",
|
|
6293
|
+
description: "One-time removal of the five framework-base tables orphaned by #2644 (smrt_objects, smrt_classes, smrt_collections, smrt_hierarchicals, smrt_polymorphic_associations). Refuses if any target table has rows, an unexpected shape, or an inbound foreign key.",
|
|
6294
|
+
aliases: ["drop-framework-base-tables", "db-drop-framework-base-tables"],
|
|
6295
|
+
args: [],
|
|
6296
|
+
options: {
|
|
6297
|
+
"dry-run": {
|
|
6298
|
+
type: "boolean",
|
|
6299
|
+
description: "Print the plan without dropping anything.",
|
|
6300
|
+
default: false
|
|
6301
|
+
},
|
|
6302
|
+
verbose: {
|
|
6303
|
+
type: "boolean",
|
|
6304
|
+
description: "Print a per-table report, including tables that are not present.",
|
|
6305
|
+
default: false,
|
|
6306
|
+
short: "v"
|
|
6307
|
+
}
|
|
6308
|
+
},
|
|
6309
|
+
handler: async (_args, options) => {
|
|
6310
|
+
let db;
|
|
6311
|
+
const dryRun = Boolean(options["dry-run"]);
|
|
6312
|
+
try {
|
|
6313
|
+
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
6314
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
6315
|
+
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
6316
|
+
if (!config.database?.url || config.database.url === ":memory:") throw new Error("Database configuration required for db:drop-framework-base-tables. Configure database.url in smrt.config.ts (or DATABASE_URL).");
|
|
6317
|
+
const dbType = config.database.type || "sqlite";
|
|
6318
|
+
const dbUrl = config.database.url;
|
|
6319
|
+
const { getDatabase } = await import("@happyvertical/sql");
|
|
6320
|
+
db = await getDatabase({
|
|
6321
|
+
type: dbType,
|
|
6322
|
+
url: dbUrl
|
|
6323
|
+
});
|
|
6324
|
+
console.log("\n🗑️ Framework base-table remediation (#2647)\n");
|
|
6325
|
+
console.log(`✓ Connected to ${formatDatabaseDisplayUrl(dbType, dbUrl)}\n`);
|
|
6326
|
+
const plan = await planFrameworkBaseTableDrop(db, { engineHint: dbType });
|
|
6327
|
+
const present = plan.tables.filter((table) => table.exists);
|
|
6328
|
+
const absent = plan.tables.filter((table) => !table.exists);
|
|
6329
|
+
if (options.verbose || present.length === 0) for (const table of absent) console.log(` - ${table.table}: not present, nothing to do`);
|
|
6330
|
+
for (const table of present) {
|
|
6331
|
+
if (table.refusals.length === 0) {
|
|
6332
|
+
console.log(` - ${table.table}: safe to drop (${table.indexNames.length} companion index(es))`);
|
|
6333
|
+
continue;
|
|
6334
|
+
}
|
|
6335
|
+
console.log(` - ${table.table}: UNSAFE`);
|
|
6336
|
+
for (const refusal of table.refusals) console.log(` ${describeRefusal(refusal)}`);
|
|
6337
|
+
}
|
|
6338
|
+
if (!plan.safe) throw new Error(`Refusing to drop framework base tables — ${FRAMEWORK_BASE_TABLE_NAMES.length} target name(s) checked, at least one is unsafe (see above). Nothing was dropped.`);
|
|
6339
|
+
if (present.length === 0) {
|
|
6340
|
+
console.log("\nNone of the five framework-base tables are present. Nothing to do.\n");
|
|
6341
|
+
return;
|
|
6342
|
+
}
|
|
6343
|
+
console.log(`\n${dryRun ? "DRY RUN — would execute" : "Applying"} ${plan.statements.length} statement(s):`);
|
|
6344
|
+
for (const statement of plan.statements) console.log(` ${statement};`);
|
|
6345
|
+
if (dryRun) {
|
|
6346
|
+
console.log("\nDry run complete — no changes applied.\n");
|
|
6347
|
+
return;
|
|
6348
|
+
}
|
|
6349
|
+
const postgresMigrationConfig = config.migrations?.postgres;
|
|
6350
|
+
const result = await dropFrameworkBaseTables(db, plan, {
|
|
6351
|
+
lockTimeout: parsePostgresTimeoutMs(postgresMigrationConfig?.lockTimeout, DEFAULT_POSTGRES_LOCK_TIMEOUT_MS$1),
|
|
6352
|
+
statementTimeout: parsePostgresTimeoutMs(postgresMigrationConfig?.statementTimeout, DEFAULT_POSTGRES_STATEMENT_TIMEOUT_MS$1)
|
|
6353
|
+
});
|
|
6354
|
+
console.log(`\n✓ Dropped ${result.droppedTables.length} table(s) and ${result.droppedIndexes.length} companion index(es): ${result.droppedTables.map((table) => quoteIdentifier(table)).join(", ")}\n`);
|
|
6355
|
+
} catch (error) {
|
|
6356
|
+
console.error(`\n❌ Framework base-table remediation failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
6357
|
+
process.exitCode = 1;
|
|
6358
|
+
} finally {
|
|
6359
|
+
await closeDatabaseConnection(db);
|
|
6360
|
+
}
|
|
6361
|
+
}
|
|
6362
|
+
};
|
|
6363
|
+
//#endregion
|
|
6143
6364
|
//#region src/commands/db-migrate-int8.ts
|
|
6144
6365
|
/**
|
|
6145
6366
|
* db:migrate-int8 Command
|
|
@@ -6175,7 +6396,7 @@ var dbMigrateInt8Command = {
|
|
|
6175
6396
|
const dryRun = Boolean(options["dry-run"]);
|
|
6176
6397
|
try {
|
|
6177
6398
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
6178
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
6399
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
6179
6400
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
6180
6401
|
if (!config.database?.url || config.database.url === ":memory:") throw new Error("Database configuration required for db:migrate-int8. Configure database.url in smrt.config.ts (or DATABASE_URL).");
|
|
6181
6402
|
await autoDiscoverAndLoad();
|
|
@@ -6429,7 +6650,7 @@ var dbMigrateUuidCommand = {
|
|
|
6429
6650
|
let db;
|
|
6430
6651
|
try {
|
|
6431
6652
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
6432
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
6653
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
6433
6654
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
6434
6655
|
if (!config.database?.url || config.database.url === ":memory:") {
|
|
6435
6656
|
console.error("\n❌ Database configuration required for db:migrate-uuid");
|
|
@@ -7916,7 +8137,7 @@ export default testManifest;
|
|
|
7916
8137
|
let db;
|
|
7917
8138
|
try {
|
|
7918
8139
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
7919
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
8140
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
7920
8141
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
7921
8142
|
if (!config.database?.url || config.database.url === ":memory:") {
|
|
7922
8143
|
console.error("❌ Database configuration required for db:setup");
|
|
@@ -8124,7 +8345,7 @@ export default testManifest;
|
|
|
8124
8345
|
},
|
|
8125
8346
|
"db:validate": {
|
|
8126
8347
|
name: "db:validate",
|
|
8127
|
-
description: "Validate JSON database integrity
|
|
8348
|
+
description: "Validate JSON database integrity or configured PostgreSQL permissions",
|
|
8128
8349
|
aliases: ["json:validate", "validate-db"],
|
|
8129
8350
|
args: [],
|
|
8130
8351
|
options: {
|
|
@@ -8159,8 +8380,18 @@ export default testManifest;
|
|
|
8159
8380
|
},
|
|
8160
8381
|
handler: async (_args, options) => {
|
|
8161
8382
|
const startTime = Date.now();
|
|
8383
|
+
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
8384
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
8385
|
+
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
8386
|
+
if (!options.data && config.database?.type === "postgres") {
|
|
8387
|
+
const permissions = await runPostgresPermissions({}, true);
|
|
8388
|
+
if (!permissions.skipped) {
|
|
8389
|
+
outputPermissionsOutcome(permissions, options.json);
|
|
8390
|
+
return;
|
|
8391
|
+
}
|
|
8392
|
+
}
|
|
8162
8393
|
try {
|
|
8163
|
-
const { resolveDataPath, discoverJsonFiles, JsonDatabaseValidator, displayValidationResults } = await import("./json-validator-
|
|
8394
|
+
const { resolveDataPath, discoverJsonFiles, JsonDatabaseValidator, displayValidationResults } = await import("./json-validator-CjX8fHx9.js");
|
|
8164
8395
|
const dataPath = await resolveDataPath(options.data);
|
|
8165
8396
|
if (!dataPath) {
|
|
8166
8397
|
console.error("\n❌ Could not find data directory");
|
|
@@ -8332,7 +8563,7 @@ export default testManifest;
|
|
|
8332
8563
|
const postgresTimestampMigration = resolvePostgresTimestampMigration(options["postgres-timestamp-legacy-timezone"]);
|
|
8333
8564
|
const isDryRun = options["dry-run"] ?? false;
|
|
8334
8565
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
8335
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
8566
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
8336
8567
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
8337
8568
|
if (!config.database?.url || config.database.url === ":memory:") {
|
|
8338
8569
|
console.error("❌ Database configuration required for db:migrate");
|
|
@@ -9049,7 +9280,7 @@ export default testManifest;
|
|
|
9049
9280
|
check("src/lib/server/smrt.ts exists", existsSync(resolve(cwd, "src/lib/server/smrt.ts")), "Missing server config - run: smrt init");
|
|
9050
9281
|
try {
|
|
9051
9282
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
9052
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
9283
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
9053
9284
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
9054
9285
|
if (config.database?.url && config.database.url !== ":memory:") check(`Database configured (${config.database.type || "sqlite"})`, true);
|
|
9055
9286
|
else check("Database configured", false, void 0, "Using in-memory database - set DATABASE_URL for persistence");
|
|
@@ -9075,6 +9306,9 @@ export default testManifest;
|
|
|
9075
9306
|
for (const finding of parityWarnings) warnings.push(`live schema: ${finding.table}${finding.target ? `.${finding.target}` : ""} (${finding.kind})`);
|
|
9076
9307
|
if (parityErrors.length === 0 && parityWarnings.length === 0) passed.push("Live schema parity");
|
|
9077
9308
|
}
|
|
9309
|
+
const permissions = await runPostgresPermissions({}, true);
|
|
9310
|
+
for (const line of formatPermissionsOutcome(permissions)) console.log(line);
|
|
9311
|
+
if (!permissions.skipped) check("PostgreSQL role permissions", !permissions.error && permissions.plan?.diagnostics.length === 0, permissions.error ?? "PostgreSQL role permissions differ from the configured contract");
|
|
9078
9312
|
console.log();
|
|
9079
9313
|
}
|
|
9080
9314
|
console.log("━".repeat(50));
|
|
@@ -9109,7 +9343,9 @@ export default testManifest;
|
|
|
9109
9343
|
"db:generate": dbGenerateCommand,
|
|
9110
9344
|
"db:migrate-uuid": dbMigrateUuidCommand,
|
|
9111
9345
|
"db:migrate-int8": dbMigrateInt8Command,
|
|
9346
|
+
"db:drop-framework-base-tables": dbDropFrameworkBaseTablesCommand,
|
|
9112
9347
|
"db:prune": dbPruneCommand,
|
|
9348
|
+
"db:permissions": dbPermissionsCommand,
|
|
9113
9349
|
"config:export": configExportCommand,
|
|
9114
9350
|
export: exportCommand
|
|
9115
9351
|
};
|
|
@@ -1,4 +1,18 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __exportAll = (all, no_symbols) => {
|
|
5
|
+
let target = {};
|
|
6
|
+
for (var name in all) __defProp(target, name, {
|
|
7
|
+
get: all[name],
|
|
8
|
+
enumerable: true
|
|
9
|
+
});
|
|
10
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
11
|
+
return target;
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
1
14
|
//#region src/config.ts
|
|
15
|
+
var config_exports = /* @__PURE__ */ __exportAll({ DEFAULT_CLI_CONFIG: () => DEFAULT_CLI_CONFIG });
|
|
2
16
|
/**
|
|
3
17
|
* Default CLI configuration values
|
|
4
18
|
*/
|
|
@@ -29,4 +43,4 @@ var DEFAULT_CLI_CONFIG = {
|
|
|
29
43
|
interactive: !process.env.CI
|
|
30
44
|
};
|
|
31
45
|
//#endregion
|
|
32
|
-
export { DEFAULT_CLI_CONFIG };
|
|
46
|
+
export { config_exports as n, DEFAULT_CLI_CONFIG as t };
|
package/dist/index.js
CHANGED
|
@@ -49,63 +49,63 @@ var _playgroundCommands = null;
|
|
|
49
49
|
var _workbenchCommands = null;
|
|
50
50
|
async function getGnodeCommands() {
|
|
51
51
|
if (!_gnodeCommands) {
|
|
52
|
-
const { gnodeCommands } = await import("./commands-
|
|
52
|
+
const { gnodeCommands } = await import("./commands-C4xB-FxS.js");
|
|
53
53
|
_gnodeCommands = gnodeCommands;
|
|
54
54
|
}
|
|
55
55
|
return _gnodeCommands;
|
|
56
56
|
}
|
|
57
57
|
async function getGitCommands() {
|
|
58
58
|
if (!_gitCommands) {
|
|
59
|
-
const { gitCommands } = await import("./commands-
|
|
59
|
+
const { gitCommands } = await import("./commands-C4xB-FxS.js");
|
|
60
60
|
_gitCommands = gitCommands;
|
|
61
61
|
}
|
|
62
62
|
return _gitCommands;
|
|
63
63
|
}
|
|
64
64
|
async function getGenerateCommands() {
|
|
65
65
|
if (!_generateCommands) {
|
|
66
|
-
const { generateCommands } = await import("./commands-
|
|
66
|
+
const { generateCommands } = await import("./commands-C4xB-FxS.js");
|
|
67
67
|
_generateCommands = generateCommands;
|
|
68
68
|
}
|
|
69
69
|
return _generateCommands;
|
|
70
70
|
}
|
|
71
71
|
async function getInitCommands() {
|
|
72
72
|
if (!_initCommands) {
|
|
73
|
-
const { initCommands } = await import("./commands-
|
|
73
|
+
const { initCommands } = await import("./commands-C4xB-FxS.js");
|
|
74
74
|
_initCommands = initCommands;
|
|
75
75
|
}
|
|
76
76
|
return _initCommands;
|
|
77
77
|
}
|
|
78
78
|
async function getUtilityCommands() {
|
|
79
79
|
if (!_utilityCommands) {
|
|
80
|
-
const { utilityCommands } = await import("./commands-
|
|
80
|
+
const { utilityCommands } = await import("./commands-C4xB-FxS.js");
|
|
81
81
|
_utilityCommands = utilityCommands;
|
|
82
82
|
}
|
|
83
83
|
return _utilityCommands;
|
|
84
84
|
}
|
|
85
85
|
async function getDispatchCommands() {
|
|
86
86
|
if (!_dispatchCommands) {
|
|
87
|
-
const { dispatchCommands } = await import("./commands-
|
|
87
|
+
const { dispatchCommands } = await import("./commands-C4xB-FxS.js");
|
|
88
88
|
_dispatchCommands = dispatchCommands;
|
|
89
89
|
}
|
|
90
90
|
return _dispatchCommands;
|
|
91
91
|
}
|
|
92
92
|
async function getDocsCommands() {
|
|
93
93
|
if (!_docsCommands) {
|
|
94
|
-
const { docsCommands } = await import("./commands-
|
|
94
|
+
const { docsCommands } = await import("./commands-C4xB-FxS.js");
|
|
95
95
|
_docsCommands = docsCommands;
|
|
96
96
|
}
|
|
97
97
|
return _docsCommands;
|
|
98
98
|
}
|
|
99
99
|
async function getPlaygroundCommands() {
|
|
100
100
|
if (!_playgroundCommands) {
|
|
101
|
-
const { playgroundCommands } = await import("./commands-
|
|
101
|
+
const { playgroundCommands } = await import("./commands-C4xB-FxS.js");
|
|
102
102
|
_playgroundCommands = playgroundCommands;
|
|
103
103
|
}
|
|
104
104
|
return _playgroundCommands;
|
|
105
105
|
}
|
|
106
106
|
async function getWorkbenchCommands() {
|
|
107
107
|
if (!_workbenchCommands) {
|
|
108
|
-
const { workbenchCommands } = await import("./commands-
|
|
108
|
+
const { workbenchCommands } = await import("./commands-C4xB-FxS.js");
|
|
109
109
|
_workbenchCommands = workbenchCommands;
|
|
110
110
|
}
|
|
111
111
|
return _workbenchCommands;
|
|
@@ -322,7 +322,7 @@ var CLIGenerator = class {
|
|
|
322
322
|
if (verbose) console.log("[CLI] Loading external classes...");
|
|
323
323
|
await this.loadExternalClasses();
|
|
324
324
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
325
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
325
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
326
326
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
327
327
|
const registeredCount = ObjectRegistry.getAllClasses().size;
|
|
328
328
|
if (verbose || config.verbose) console.log(`[CLI] Successfully loaded ${registeredCount} SMRT objects`);
|
|
@@ -337,7 +337,7 @@ var CLIGenerator = class {
|
|
|
337
337
|
*/
|
|
338
338
|
async loadLocalClasses() {
|
|
339
339
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
340
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
340
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
341
341
|
const fs = await import("node:fs");
|
|
342
342
|
const path = await import("node:path");
|
|
343
343
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
@@ -382,7 +382,7 @@ var CLIGenerator = class {
|
|
|
382
382
|
*/
|
|
383
383
|
async loadExternalClasses() {
|
|
384
384
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
385
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
385
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
386
386
|
const { loadLocalTestManifestSync } = await import("@happyvertical/smrt-core/manifest");
|
|
387
387
|
const fs = await import("node:fs");
|
|
388
388
|
const path = await import("node:path");
|
|
@@ -1359,7 +1359,7 @@ var CLIGenerator = class {
|
|
|
1359
1359
|
const { getConfig, getPackageConfig, getModuleConfig } = await import("@happyvertical/smrt-config");
|
|
1360
1360
|
const smrtConfig = getConfig() || {};
|
|
1361
1361
|
const moduleConfig = getModuleConfig(objectName.toLowerCase(), {});
|
|
1362
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
1362
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
1363
1363
|
const cliConfig = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
1364
1364
|
let db = this.context.db;
|
|
1365
1365
|
if (!db && cliConfig?.database?.url) {
|
|
@@ -1462,7 +1462,7 @@ var CLIGenerator = class {
|
|
|
1462
1462
|
let db = this.context.db;
|
|
1463
1463
|
if (!db) {
|
|
1464
1464
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
1465
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
1465
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
1466
1466
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
1467
1467
|
const { getDatabase } = await import("@happyvertical/sql");
|
|
1468
1468
|
db = await getDatabase({
|
|
@@ -85,7 +85,7 @@ async function resolveDataPath(explicitPath) {
|
|
|
85
85
|
return resolved;
|
|
86
86
|
}
|
|
87
87
|
try {
|
|
88
|
-
const { DEFAULT_CLI_CONFIG: defaultConfig } = await import("./config-
|
|
88
|
+
const { DEFAULT_CLI_CONFIG: defaultConfig } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
89
89
|
const config = getPackageConfig("cli", defaultConfig);
|
|
90
90
|
if (config.database?.url) {
|
|
91
91
|
const dbUrl = config.database.url;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.0",
|
|
4
4
|
"description": "Developer CLI for SMRT framework - introspection, testing, and project management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"acorn": "^8.17.0",
|
|
33
33
|
"fast-glob": "3.3.3",
|
|
34
34
|
"tar": "^7.5.19",
|
|
35
|
-
"@happyvertical/smrt-
|
|
36
|
-
"@happyvertical/smrt-
|
|
37
|
-
"@happyvertical/smrt-
|
|
38
|
-
"@happyvertical/smrt-
|
|
39
|
-
"@happyvertical/smrt-
|
|
40
|
-
"@happyvertical/smrt-
|
|
35
|
+
"@happyvertical/smrt-core": "0.46.0",
|
|
36
|
+
"@happyvertical/smrt-playground": "0.46.0",
|
|
37
|
+
"@happyvertical/smrt-agents": "0.46.0",
|
|
38
|
+
"@happyvertical/smrt-types": "0.46.0",
|
|
39
|
+
"@happyvertical/smrt-config": "0.46.0",
|
|
40
|
+
"@happyvertical/smrt-dev-mcp": "0.46.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "24.13.2",
|