@happyvertical/smrt-cli 0.45.3 → 0.47.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-C9UEWEvb.js} +254 -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 +8 -8
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,110 @@ 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
|
+
managedTriggerFunctions: configured.managedTriggerFunctions ?? []
|
|
1499
|
+
};
|
|
1500
|
+
return {
|
|
1501
|
+
skipped: false,
|
|
1502
|
+
plan: options.apply ? await applyPostgresPermissions(db, contract, { expectedFingerprint: options["expected-fingerprint"] ?? "" }) : await planPostgresPermissions(db, contract),
|
|
1503
|
+
error: null
|
|
1504
|
+
};
|
|
1505
|
+
} catch {
|
|
1506
|
+
return failure("PostgreSQL permissions could not be verified or applied. Check connectivity, contract validity, administrator authority, and the reviewed fingerprint.");
|
|
1507
|
+
} finally {
|
|
1508
|
+
try {
|
|
1509
|
+
await closeDatabaseConnection(db);
|
|
1510
|
+
} catch {}
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
function formatPermissionsOutcome(outcome) {
|
|
1514
|
+
if (outcome.skipped) return [];
|
|
1515
|
+
if (outcome.error) return [`PostgreSQL permissions: ${outcome.error}`];
|
|
1516
|
+
const plan = outcome.plan;
|
|
1517
|
+
if (!plan) return ["PostgreSQL permissions could not be verified."];
|
|
1518
|
+
return [
|
|
1519
|
+
`PostgreSQL permissions: ${plan.diagnostics.length} finding(s)`,
|
|
1520
|
+
...plan.diagnostics.map((finding) => ` ${finding.severity}: ${finding.role ? `${finding.role} · ` : ""}${finding.resource}: ${finding.message}`),
|
|
1521
|
+
`Plan fingerprint: ${plan.fingerprint}`,
|
|
1522
|
+
...plan.limitations.map((limitation) => `Scope: ${limitation}`),
|
|
1523
|
+
...plan.canApply ? [] : ["Automatic application refused; resolve unsupported conditions first."]
|
|
1524
|
+
];
|
|
1525
|
+
}
|
|
1526
|
+
function outputPermissionsOutcome(outcome, json = false) {
|
|
1527
|
+
if (json) console.log(JSON.stringify(outcome, null, 2));
|
|
1528
|
+
else for (const line of formatPermissionsOutcome(outcome)) console.log(line);
|
|
1529
|
+
if (outcome.error || outcome.plan?.diagnostics.length) process.exitCode = 1;
|
|
1530
|
+
}
|
|
1531
|
+
var dbPermissionsCommand = {
|
|
1532
|
+
name: "db:permissions",
|
|
1533
|
+
description: "Inspect PostgreSQL role permissions; explicitly apply a reviewed plan",
|
|
1534
|
+
args: [],
|
|
1535
|
+
options: {
|
|
1536
|
+
"dry-run": {
|
|
1537
|
+
type: "boolean",
|
|
1538
|
+
description: "Read-only plan (the default)"
|
|
1539
|
+
},
|
|
1540
|
+
apply: {
|
|
1541
|
+
type: "boolean",
|
|
1542
|
+
description: "Apply the reviewed plan explicitly",
|
|
1543
|
+
default: false
|
|
1544
|
+
},
|
|
1545
|
+
"expected-fingerprint": {
|
|
1546
|
+
type: "string",
|
|
1547
|
+
description: "Fingerprint from the reviewed read-only plan"
|
|
1548
|
+
},
|
|
1549
|
+
json: {
|
|
1550
|
+
type: "boolean",
|
|
1551
|
+
description: "Output plan and diagnostics as JSON",
|
|
1552
|
+
default: false
|
|
1553
|
+
}
|
|
1554
|
+
},
|
|
1555
|
+
handler: async (_args, options) => {
|
|
1556
|
+
const outcome = await runPostgresPermissions(options);
|
|
1557
|
+
outputPermissionsOutcome(outcome, options.json);
|
|
1558
|
+
if (!options.json && outcome.plan && !options.apply) {
|
|
1559
|
+
console.log("Read-only plan SQL:");
|
|
1560
|
+
for (const sql of outcome.plan.statements) console.log(sql);
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
};
|
|
1564
|
+
//#endregion
|
|
1459
1565
|
//#region src/commands/db-prune.ts
|
|
1460
1566
|
/**
|
|
1461
1567
|
* Packages that contribute retention tasks by registering them on import.
|
|
@@ -1595,7 +1701,7 @@ var dbPruneCommand = {
|
|
|
1595
1701
|
let db;
|
|
1596
1702
|
try {
|
|
1597
1703
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
1598
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
1704
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
1599
1705
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
1600
1706
|
if (!config.database?.url) {
|
|
1601
1707
|
const message = "Database not configured. Set database.url in smrt.config.ts.";
|
|
@@ -1755,7 +1861,7 @@ var dbRollbackCommand = {
|
|
|
1755
1861
|
const markOnly = options["mark-only"] ?? options.markOnly;
|
|
1756
1862
|
try {
|
|
1757
1863
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
1758
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
1864
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
1759
1865
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
1760
1866
|
if (!config.database?.url || config.database.url === ":memory:") {
|
|
1761
1867
|
if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
|
|
@@ -2013,7 +2119,7 @@ async function runLiveSchemaParity(options = {}) {
|
|
|
2013
2119
|
let db;
|
|
2014
2120
|
try {
|
|
2015
2121
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
2016
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
2122
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
2017
2123
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
2018
2124
|
if (!config.database?.url || config.database.url === ":memory:") return {
|
|
2019
2125
|
report: null,
|
|
@@ -2552,7 +2658,7 @@ var dbStatusCommand = {
|
|
|
2552
2658
|
let db;
|
|
2553
2659
|
try {
|
|
2554
2660
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
2555
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
2661
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
2556
2662
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
2557
2663
|
if (!config.database?.url || config.database.url === ":memory:") {
|
|
2558
2664
|
if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
|
|
@@ -2814,7 +2920,7 @@ async function getDispatchBus() {
|
|
|
2814
2920
|
const { createDispatchBus } = await import("@happyvertical/smrt-core");
|
|
2815
2921
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
2816
2922
|
const { getDatabase } = await import("@happyvertical/sql");
|
|
2817
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
2923
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
2818
2924
|
const dbConfig = getPackageConfig("cli", DEFAULT_CLI_CONFIG).database;
|
|
2819
2925
|
if (!dbConfig?.url) throw new Error("Database not configured. Set database.url in smrt.config.ts or use --db option.");
|
|
2820
2926
|
let db;
|
|
@@ -3732,7 +3838,7 @@ var exportCommand = {
|
|
|
3732
3838
|
let db;
|
|
3733
3839
|
try {
|
|
3734
3840
|
const { getConfig, getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
3735
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
3841
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
3736
3842
|
const smrtConfig = getConfig();
|
|
3737
3843
|
const cliConfig = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
3738
3844
|
if (!smrtConfig) {
|
|
@@ -6140,6 +6246,122 @@ var playgroundCommands = {
|
|
|
6140
6246
|
}
|
|
6141
6247
|
};
|
|
6142
6248
|
//#endregion
|
|
6249
|
+
//#region src/commands/db-drop-framework-base-tables.ts
|
|
6250
|
+
/**
|
|
6251
|
+
* db:drop-framework-base-tables Command
|
|
6252
|
+
*
|
|
6253
|
+
* One-time remediation for the five orphaned framework-base tables
|
|
6254
|
+
* (`smrt_objects`, `smrt_classes`, `smrt_collections`, `smrt_hierarchicals`,
|
|
6255
|
+
* `smrt_polymorphic_associations`) that a pre-#2644 `db:migrate` planned for
|
|
6256
|
+
* SMRT's abstract framework-base classes. #2644 stopped planning them; this
|
|
6257
|
+
* command drops the ones a deployment already created.
|
|
6258
|
+
*
|
|
6259
|
+
* Deliberately separate from `db:migrate` and from `db:diff`'s orphan-table
|
|
6260
|
+
* reporting: `SchemaDiff.includeDroppedTables` stays `false` so an ordinary
|
|
6261
|
+
* migration never drops a table just because it is absent from the manifest.
|
|
6262
|
+
* This command drops **only** the five hardcoded names above, and only after
|
|
6263
|
+
* verifying each one is empty, has no foreign keys pointing at it, and has
|
|
6264
|
+
* exactly that table's own expected columns — the universal `id`/`slug`/
|
|
6265
|
+
* `context`/`created_at`/`updated_at` base for `smrt_objects`/`smrt_classes`/
|
|
6266
|
+
* `smrt_collections`, extended with `parent_id` for `smrt_hierarchicals` and
|
|
6267
|
+
* `meta_type`/`meta_id`/`role`/`sort_order` for
|
|
6268
|
+
* `smrt_polymorphic_associations` (their own real fields, not the plain
|
|
6269
|
+
* baseline — see `@happyvertical/smrt-core/migrations`'
|
|
6270
|
+
* `planFrameworkBaseTableDrop()` for the full per-table safety model).
|
|
6271
|
+
*
|
|
6272
|
+
* Skipping this command is safe: a table left behind here is inert and
|
|
6273
|
+
* permanently orphaned, never written to or read from again.
|
|
6274
|
+
*/
|
|
6275
|
+
var DEFAULT_POSTGRES_LOCK_TIMEOUT_MS$1 = 3e4;
|
|
6276
|
+
var DEFAULT_POSTGRES_STATEMENT_TIMEOUT_MS$1 = 6e4;
|
|
6277
|
+
function describeRefusal(refusal) {
|
|
6278
|
+
switch (refusal.kind) {
|
|
6279
|
+
case "not-empty": return `has ${refusal.rowCount} row(s) — nothing should ever have written to this table`;
|
|
6280
|
+
case "unexpected-shape": {
|
|
6281
|
+
const parts = [];
|
|
6282
|
+
if (refusal.extraColumns.length > 0) parts.push(`unexpected column(s) [${refusal.extraColumns.join(", ")}]`);
|
|
6283
|
+
if (refusal.missingColumns.length > 0) parts.push(`missing baseline column(s) [${refusal.missingColumns.join(", ")}]`);
|
|
6284
|
+
return `has an unexpected shape: ${parts.join("; ")} (actual columns: ${refusal.actualColumns.join(", ")})`;
|
|
6285
|
+
}
|
|
6286
|
+
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(", ")}`;
|
|
6287
|
+
case "referenced-by-foreign-key": return `is referenced by foreign key(s) from: ${refusal.references.map((reference) => `${reference.table}.${reference.column}`).join(", ")}`;
|
|
6288
|
+
case "introspection-unavailable": return refusal.reason;
|
|
6289
|
+
default: return "is unsafe to drop for an unrecognized reason";
|
|
6290
|
+
}
|
|
6291
|
+
}
|
|
6292
|
+
var dbDropFrameworkBaseTablesCommand = {
|
|
6293
|
+
name: "db:drop-framework-base-tables",
|
|
6294
|
+
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.",
|
|
6295
|
+
aliases: ["drop-framework-base-tables", "db-drop-framework-base-tables"],
|
|
6296
|
+
args: [],
|
|
6297
|
+
options: {
|
|
6298
|
+
"dry-run": {
|
|
6299
|
+
type: "boolean",
|
|
6300
|
+
description: "Print the plan without dropping anything.",
|
|
6301
|
+
default: false
|
|
6302
|
+
},
|
|
6303
|
+
verbose: {
|
|
6304
|
+
type: "boolean",
|
|
6305
|
+
description: "Print a per-table report, including tables that are not present.",
|
|
6306
|
+
default: false,
|
|
6307
|
+
short: "v"
|
|
6308
|
+
}
|
|
6309
|
+
},
|
|
6310
|
+
handler: async (_args, options) => {
|
|
6311
|
+
let db;
|
|
6312
|
+
const dryRun = Boolean(options["dry-run"]);
|
|
6313
|
+
try {
|
|
6314
|
+
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
6315
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
6316
|
+
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
6317
|
+
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).");
|
|
6318
|
+
const dbType = config.database.type || "sqlite";
|
|
6319
|
+
const dbUrl = config.database.url;
|
|
6320
|
+
const { getDatabase } = await import("@happyvertical/sql");
|
|
6321
|
+
db = await getDatabase({
|
|
6322
|
+
type: dbType,
|
|
6323
|
+
url: dbUrl
|
|
6324
|
+
});
|
|
6325
|
+
console.log("\n🗑️ Framework base-table remediation (#2647)\n");
|
|
6326
|
+
console.log(`✓ Connected to ${formatDatabaseDisplayUrl(dbType, dbUrl)}\n`);
|
|
6327
|
+
const plan = await planFrameworkBaseTableDrop(db, { engineHint: dbType });
|
|
6328
|
+
const present = plan.tables.filter((table) => table.exists);
|
|
6329
|
+
const absent = plan.tables.filter((table) => !table.exists);
|
|
6330
|
+
if (options.verbose || present.length === 0) for (const table of absent) console.log(` - ${table.table}: not present, nothing to do`);
|
|
6331
|
+
for (const table of present) {
|
|
6332
|
+
if (table.refusals.length === 0) {
|
|
6333
|
+
console.log(` - ${table.table}: safe to drop (${table.indexNames.length} companion index(es))`);
|
|
6334
|
+
continue;
|
|
6335
|
+
}
|
|
6336
|
+
console.log(` - ${table.table}: UNSAFE`);
|
|
6337
|
+
for (const refusal of table.refusals) console.log(` ${describeRefusal(refusal)}`);
|
|
6338
|
+
}
|
|
6339
|
+
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.`);
|
|
6340
|
+
if (present.length === 0) {
|
|
6341
|
+
console.log("\nNone of the five framework-base tables are present. Nothing to do.\n");
|
|
6342
|
+
return;
|
|
6343
|
+
}
|
|
6344
|
+
console.log(`\n${dryRun ? "DRY RUN — would execute" : "Applying"} ${plan.statements.length} statement(s):`);
|
|
6345
|
+
for (const statement of plan.statements) console.log(` ${statement};`);
|
|
6346
|
+
if (dryRun) {
|
|
6347
|
+
console.log("\nDry run complete — no changes applied.\n");
|
|
6348
|
+
return;
|
|
6349
|
+
}
|
|
6350
|
+
const postgresMigrationConfig = config.migrations?.postgres;
|
|
6351
|
+
const result = await dropFrameworkBaseTables(db, plan, {
|
|
6352
|
+
lockTimeout: parsePostgresTimeoutMs(postgresMigrationConfig?.lockTimeout, DEFAULT_POSTGRES_LOCK_TIMEOUT_MS$1),
|
|
6353
|
+
statementTimeout: parsePostgresTimeoutMs(postgresMigrationConfig?.statementTimeout, DEFAULT_POSTGRES_STATEMENT_TIMEOUT_MS$1)
|
|
6354
|
+
});
|
|
6355
|
+
console.log(`\n✓ Dropped ${result.droppedTables.length} table(s) and ${result.droppedIndexes.length} companion index(es): ${result.droppedTables.map((table) => quoteIdentifier(table)).join(", ")}\n`);
|
|
6356
|
+
} catch (error) {
|
|
6357
|
+
console.error(`\n❌ Framework base-table remediation failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
6358
|
+
process.exitCode = 1;
|
|
6359
|
+
} finally {
|
|
6360
|
+
await closeDatabaseConnection(db);
|
|
6361
|
+
}
|
|
6362
|
+
}
|
|
6363
|
+
};
|
|
6364
|
+
//#endregion
|
|
6143
6365
|
//#region src/commands/db-migrate-int8.ts
|
|
6144
6366
|
/**
|
|
6145
6367
|
* db:migrate-int8 Command
|
|
@@ -6175,7 +6397,7 @@ var dbMigrateInt8Command = {
|
|
|
6175
6397
|
const dryRun = Boolean(options["dry-run"]);
|
|
6176
6398
|
try {
|
|
6177
6399
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
6178
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
6400
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
6179
6401
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
6180
6402
|
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
6403
|
await autoDiscoverAndLoad();
|
|
@@ -6429,7 +6651,7 @@ var dbMigrateUuidCommand = {
|
|
|
6429
6651
|
let db;
|
|
6430
6652
|
try {
|
|
6431
6653
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
6432
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
6654
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
6433
6655
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
6434
6656
|
if (!config.database?.url || config.database.url === ":memory:") {
|
|
6435
6657
|
console.error("\n❌ Database configuration required for db:migrate-uuid");
|
|
@@ -7916,7 +8138,7 @@ export default testManifest;
|
|
|
7916
8138
|
let db;
|
|
7917
8139
|
try {
|
|
7918
8140
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
7919
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
8141
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
7920
8142
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
7921
8143
|
if (!config.database?.url || config.database.url === ":memory:") {
|
|
7922
8144
|
console.error("❌ Database configuration required for db:setup");
|
|
@@ -8124,7 +8346,7 @@ export default testManifest;
|
|
|
8124
8346
|
},
|
|
8125
8347
|
"db:validate": {
|
|
8126
8348
|
name: "db:validate",
|
|
8127
|
-
description: "Validate JSON database integrity
|
|
8349
|
+
description: "Validate JSON database integrity or configured PostgreSQL permissions",
|
|
8128
8350
|
aliases: ["json:validate", "validate-db"],
|
|
8129
8351
|
args: [],
|
|
8130
8352
|
options: {
|
|
@@ -8159,8 +8381,18 @@ export default testManifest;
|
|
|
8159
8381
|
},
|
|
8160
8382
|
handler: async (_args, options) => {
|
|
8161
8383
|
const startTime = Date.now();
|
|
8384
|
+
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
8385
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
8386
|
+
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
8387
|
+
if (!options.data && config.database?.type === "postgres") {
|
|
8388
|
+
const permissions = await runPostgresPermissions({}, true);
|
|
8389
|
+
if (!permissions.skipped) {
|
|
8390
|
+
outputPermissionsOutcome(permissions, options.json);
|
|
8391
|
+
return;
|
|
8392
|
+
}
|
|
8393
|
+
}
|
|
8162
8394
|
try {
|
|
8163
|
-
const { resolveDataPath, discoverJsonFiles, JsonDatabaseValidator, displayValidationResults } = await import("./json-validator-
|
|
8395
|
+
const { resolveDataPath, discoverJsonFiles, JsonDatabaseValidator, displayValidationResults } = await import("./json-validator-CjX8fHx9.js");
|
|
8164
8396
|
const dataPath = await resolveDataPath(options.data);
|
|
8165
8397
|
if (!dataPath) {
|
|
8166
8398
|
console.error("\n❌ Could not find data directory");
|
|
@@ -8332,7 +8564,7 @@ export default testManifest;
|
|
|
8332
8564
|
const postgresTimestampMigration = resolvePostgresTimestampMigration(options["postgres-timestamp-legacy-timezone"]);
|
|
8333
8565
|
const isDryRun = options["dry-run"] ?? false;
|
|
8334
8566
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
8335
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
8567
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
8336
8568
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
8337
8569
|
if (!config.database?.url || config.database.url === ":memory:") {
|
|
8338
8570
|
console.error("❌ Database configuration required for db:migrate");
|
|
@@ -9049,7 +9281,7 @@ export default testManifest;
|
|
|
9049
9281
|
check("src/lib/server/smrt.ts exists", existsSync(resolve(cwd, "src/lib/server/smrt.ts")), "Missing server config - run: smrt init");
|
|
9050
9282
|
try {
|
|
9051
9283
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
9052
|
-
const { DEFAULT_CLI_CONFIG } = await import("./config-
|
|
9284
|
+
const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
|
|
9053
9285
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
9054
9286
|
if (config.database?.url && config.database.url !== ":memory:") check(`Database configured (${config.database.type || "sqlite"})`, true);
|
|
9055
9287
|
else check("Database configured", false, void 0, "Using in-memory database - set DATABASE_URL for persistence");
|
|
@@ -9075,6 +9307,9 @@ export default testManifest;
|
|
|
9075
9307
|
for (const finding of parityWarnings) warnings.push(`live schema: ${finding.table}${finding.target ? `.${finding.target}` : ""} (${finding.kind})`);
|
|
9076
9308
|
if (parityErrors.length === 0 && parityWarnings.length === 0) passed.push("Live schema parity");
|
|
9077
9309
|
}
|
|
9310
|
+
const permissions = await runPostgresPermissions({}, true);
|
|
9311
|
+
for (const line of formatPermissionsOutcome(permissions)) console.log(line);
|
|
9312
|
+
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
9313
|
console.log();
|
|
9079
9314
|
}
|
|
9080
9315
|
console.log("━".repeat(50));
|
|
@@ -9109,7 +9344,9 @@ export default testManifest;
|
|
|
9109
9344
|
"db:generate": dbGenerateCommand,
|
|
9110
9345
|
"db:migrate-uuid": dbMigrateUuidCommand,
|
|
9111
9346
|
"db:migrate-int8": dbMigrateInt8Command,
|
|
9347
|
+
"db:drop-framework-base-tables": dbDropFrameworkBaseTablesCommand,
|
|
9112
9348
|
"db:prune": dbPruneCommand,
|
|
9349
|
+
"db:permissions": dbPermissionsCommand,
|
|
9113
9350
|
"config:export": configExportCommand,
|
|
9114
9351
|
export: exportCommand
|
|
9115
9352
|
};
|
|
@@ -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-C9UEWEvb.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-C9UEWEvb.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-C9UEWEvb.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-C9UEWEvb.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-C9UEWEvb.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-C9UEWEvb.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-C9UEWEvb.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-C9UEWEvb.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-C9UEWEvb.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.47.0",
|
|
4
4
|
"description": "Developer CLI for SMRT framework - introspection, testing, and project management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -27,17 +27,17 @@
|
|
|
27
27
|
"@happyvertical/ai": "^0.89.4",
|
|
28
28
|
"@happyvertical/files": "^0.89.4",
|
|
29
29
|
"@happyvertical/logger": "^0.89.4",
|
|
30
|
+
"@happyvertical/smrt-agents": "0.47.0",
|
|
31
|
+
"@happyvertical/smrt-config": "0.47.0",
|
|
32
|
+
"@happyvertical/smrt-core": "0.47.0",
|
|
33
|
+
"@happyvertical/smrt-dev-mcp": "0.47.0",
|
|
34
|
+
"@happyvertical/smrt-playground": "0.47.0",
|
|
35
|
+
"@happyvertical/smrt-types": "0.47.0",
|
|
30
36
|
"@happyvertical/sql": "^0.89.4",
|
|
31
37
|
"@happyvertical/utils": "^0.89.4",
|
|
32
38
|
"acorn": "^8.17.0",
|
|
33
39
|
"fast-glob": "3.3.3",
|
|
34
|
-
"tar": "^7.5.19"
|
|
35
|
-
"@happyvertical/smrt-agents": "0.45.3",
|
|
36
|
-
"@happyvertical/smrt-config": "0.45.3",
|
|
37
|
-
"@happyvertical/smrt-core": "0.45.3",
|
|
38
|
-
"@happyvertical/smrt-dev-mcp": "0.45.3",
|
|
39
|
-
"@happyvertical/smrt-types": "0.45.3",
|
|
40
|
-
"@happyvertical/smrt-playground": "0.45.3"
|
|
40
|
+
"tar": "^7.5.19"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "24.13.2",
|