@happyvertical/smrt-core 0.51.31 → 0.51.33
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/build-knowledge.md +13 -0
- package/dist/__tests__/fixtures/collection-coverage-fixtures.d.ts +8 -0
- package/dist/__tests__/fixtures/inheritance-resolver-fixtures.d.ts +9 -0
- package/dist/__tests__/fixtures/inheritance-test-classes.d.ts +5 -0
- package/dist/__tests__/fixtures/object-ai-memory-fixtures.d.ts +10 -0
- package/dist/__typechecks__/collection-read-plan.d.ts +2 -2
- package/dist/adapters/ai-usage.d.ts +5 -2
- package/dist/adapters/cost-rates.d.ts +1 -1
- package/dist/adapters/metrics.d.ts +7 -1
- package/dist/adapters/pubsub.d.ts +7 -1
- package/dist/browser.d.ts +1 -0
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +2 -1
- package/dist/cascade.d.ts +69 -3
- package/dist/change-feed-authz.d.ts +85 -2
- package/dist/change-feed.d.ts +133 -2
- package/dist/change-signals.d.ts +66 -1
- package/dist/child-accessors.d.ts +39 -1
- package/dist/class.d.ts +17 -8
- package/dist/class.d.ts.map +1 -1
- package/dist/class.js +22 -0
- package/dist/class.js.map +1 -1
- package/dist/collection-cache.d.ts +47 -1
- package/dist/collection-read-plan.d.ts +3 -3
- package/dist/collection.d.ts +4 -3
- package/dist/config.d.ts +15 -6
- package/dist/consumer-plugin/index.d.ts +7 -3
- package/dist/consumer-plugin/index.d.ts.map +1 -1
- package/dist/consumer-plugin/index.js +2 -0
- package/dist/consumer-plugin/index.js.map +1 -1
- package/dist/data-query.d.ts +12 -1
- package/dist/database.d.ts +10 -2
- package/dist/decisions.d.ts +24 -2
- package/dist/decisions.d.ts.map +1 -1
- package/dist/decisions.js +71 -1
- package/dist/decisions.js.map +1 -1
- package/dist/decorators/index.d.ts +11 -5
- package/dist/dispatch/bus.d.ts +27 -2
- package/dist/dispatch/collections/DispatchSubscriptions.d.ts +7 -2
- package/dist/dispatch/collections/Dispatches.d.ts +8 -3
- package/dist/dispatch/models/Dispatch.d.ts +7 -1
- package/dist/dispatch/types.d.ts +7 -2
- package/dist/embedded-write-queue.d.ts +1 -1
- package/dist/embeddings/provider.d.ts +8 -1
- package/dist/embeddings/storage.d.ts +8 -2
- package/dist/filesystem-loader.d.ts +16 -1
- package/dist/generators/changes-route.d.ts +34 -1
- package/dist/generators/custom-action.d.ts +10 -2
- package/dist/generators/events-route.d.ts +41 -4
- package/dist/generators/mcp-runtime-template.d.ts +13 -2
- package/dist/generators/mcp.d.ts +6 -1
- package/dist/generators/rest.d.ts +10 -5
- package/dist/generators/tool-schema.d.ts +1 -1
- package/dist/hierarchical.d.ts +37 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/interceptors.d.ts +45 -1
- package/dist/junction.d.ts +24 -0
- package/dist/knowledge-config.d.ts +1 -1
- package/dist/knowledge-discovery.d.ts +2 -25
- package/dist/knowledge-discovery.d.ts.map +1 -1
- package/dist/knowledge-discovery.js +1 -53
- package/dist/knowledge-graph.d.ts +2 -94
- package/dist/knowledge-graph.d.ts.map +1 -1
- package/dist/knowledge-graph.js +1 -267
- package/dist/knowledge.d.ts +4 -23
- package/dist/knowledge.d.ts.map +1 -1
- package/dist/knowledge.js +3 -52
- package/dist/knowledge.js.map +1 -1
- package/dist/learning/memory.d.ts +21 -1
- package/dist/manifest/generator.d.ts +5 -1
- package/dist/manifest/index.d.ts +5 -1
- package/dist/manifest/manager.d.ts +1 -1
- package/dist/manifest/manifest-loader.d.ts +24 -2
- package/dist/manifest/sources/composite.d.ts +17 -1
- package/dist/manifest/sources/embedded.d.ts +10 -1
- package/dist/manifest/sources/explicit-paths.d.ts +13 -1
- package/dist/manifest/sources/fallback.d.ts +15 -1
- package/dist/manifest/sources/local-test.d.ts +10 -1
- package/dist/manifest/sources/static.d.ts +12 -1
- package/dist/manifest/sources/test.d.ts +9 -1
- package/dist/manifest/sources/types.d.ts +7 -1
- package/dist/manifest/static-manifest.d.ts +6 -1
- package/dist/manifest/static-manifest.js +1 -1
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.d.ts +22 -3
- package/dist/manifest/store.js +1 -1
- package/dist/manifest.json +1 -1
- package/dist/migrations/backfill-tracker.d.ts +15 -1
- package/dist/migrations/differ.d.ts +8 -2
- package/dist/migrations/framework-base-tables.d.ts +57 -2
- package/dist/migrations/generator.d.ts +8 -2
- package/dist/migrations/integer-width.d.ts +10 -2
- package/dist/migrations/minor-units.d.ts +40 -1
- package/dist/migrations/null-equal-indexes.d.ts +3 -2
- package/dist/migrations/orchestrate.d.ts +15 -3
- package/dist/migrations/sqlite-rebuild.d.ts +67 -2
- package/dist/migrations/tracker.d.ts +9 -3
- package/dist/migrations/types.d.ts +7 -2
- package/dist/object.d.ts +7 -6
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +6 -17
- package/dist/object.js.map +1 -1
- package/dist/polymorphic-association.d.ts +44 -1
- package/dist/postgres-permissions.d.ts +1 -1
- package/dist/prebuild/index.d.ts +5 -1
- package/dist/query-bounds.d.ts +26 -0
- package/dist/registry/cache-config.d.ts +10 -1
- package/dist/registry/class-registration.d.ts +10 -2
- package/dist/registry/collection-resolution.d.ts +1 -1
- package/dist/registry/embedding-manager.d.ts +9 -1
- package/dist/registry/inheritance-resolver.d.ts +8 -3
- package/dist/registry/manifest-field-merge.d.ts +2 -2
- package/dist/registry/name-resolver.d.ts +22 -2
- package/dist/registry/relationship-graph.d.ts +9 -1
- package/dist/registry/schema-builder.d.ts +8 -3
- package/dist/registry/shared-state.d.ts +12 -2
- package/dist/registry/types.d.ts +15 -7
- package/dist/registry/validator.d.ts +10 -2
- package/dist/registry.d.ts +40 -11
- package/dist/relationship-loader.d.ts +1 -1
- package/dist/run-once.d.ts +110 -1
- package/dist/runtime/client.d.ts +4 -1
- package/dist/runtime/server.d.ts +5 -2
- package/dist/scanner/import-scanner.d.ts +1 -1
- package/dist/scanner/manifest-generator.d.ts +4 -1
- package/dist/scanner/types.d.ts +4 -1
- package/dist/schema/code-generator.d.ts +6 -2
- package/dist/schema/column-data-probes.d.ts +27 -2
- package/dist/schema/ddl/base-strategy.d.ts +8 -2
- package/dist/schema/ddl/duckdb-strategy.d.ts +14 -2
- package/dist/schema/ddl/index.d.ts +2 -2
- package/dist/schema/ddl/json-duckdb-strategy.d.ts +10 -2
- package/dist/schema/ddl/materialize-manifest.d.ts +1 -1
- package/dist/schema/ddl/null-equal-index.d.ts +1 -1
- package/dist/schema/ddl/postgres-strategy.d.ts +12 -2
- package/dist/schema/ddl/sqlite-strategy.d.ts +12 -2
- package/dist/schema/ddl/types.d.ts +10 -1
- package/dist/schema/foreign-key-ddl.d.ts +2 -2
- package/dist/schema/foreign-key-orphan-report.d.ts +25 -3
- package/dist/schema/foreign-key-planner.d.ts +2 -2
- package/dist/schema/foreign-key-policy.d.ts +1 -1
- package/dist/schema/generator.d.ts +7 -3
- package/dist/schema/index-utils.d.ts +11 -2
- package/dist/schema/live-parity.d.ts +27 -3
- package/dist/schema/manifest-schema.d.ts +21 -2
- package/dist/schema/schema-aggregator.d.ts +35 -2
- package/dist/schema/schema-manager.d.ts +13 -4
- package/dist/schema/system-table-shapes.d.ts +20 -1
- package/dist/schema/table-verifier.d.ts +1 -1
- package/dist/schema/text-cast-probe.d.ts +24 -1
- package/dist/schema/utils.d.ts +13 -4
- package/dist/schema/uuid-convergence.d.ts +32 -1
- package/dist/signals/bus.d.ts +8 -2
- package/dist/signals/sanitizer.d.ts +7 -1
- package/dist/smrt-knowledge.json +8 -9
- package/dist/system/bootstrap.d.ts +2 -1
- package/dist/system/compatibility.d.ts +1 -1
- package/dist/system/diagnostics.d.ts +17 -2
- package/dist/system/retention.d.ts +46 -1
- package/dist/system/schema.d.ts +7 -1
- package/dist/system-fields.d.ts +9 -1
- package/dist/test-utils.d.ts +7 -1
- package/dist/testing/database.d.ts +18 -1
- package/dist/testing/notifications-stub.d.ts +15 -1
- package/dist/tools/tool-executor.d.ts +6 -1
- package/dist/tools/tool-generator.d.ts +8 -2
- package/dist/utils/json.d.ts +9 -1
- package/dist/utils/qualified-names.d.ts +10 -1
- package/dist/utils/scanner-module.d.ts +2 -2
- package/dist/utils.d.ts +1 -1
- package/dist/vite-plugin/api-client-entries.d.ts +9 -1
- package/dist/vite-plugin/changes-route.d.ts +33 -2
- package/dist/vite-plugin/dev-plane-route.d.ts +12 -1
- package/dist/vite-plugin/events-route.d.ts +37 -2
- package/dist/vite-plugin/generated-client.d.ts +9 -1
- package/dist/vite-plugin/index.d.ts +9 -5
- package/dist/vite-plugin/resources-route.d.ts +82 -1
- package/dist/vite-plugin/sveltekit-generator.d.ts +8 -4
- package/dist/vite-plugin/sveltekit-route-coordinator.d.ts +3 -3
- package/dist/vite-plugin/sync-apply-route.d.ts +19 -2
- package/dist/vite-plugin/web-collections.d.ts +25 -2
- package/dist/vite-plugin/worker-registration.d.ts +21 -1
- package/package.json +7 -8
- package/dist/knowledge-discovery.js.map +0 -1
- package/dist/knowledge-graph.js.map +0 -1
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* JSON Adapter DDL Strategy
|
|
3
|
+
*
|
|
4
|
+
* The JSON adapter is backed by DuckDB, so it needs DuckDB's inline UNIQUE
|
|
5
|
+
* constraints for UPSERT. However, DuckDB's Node API currently round-trips
|
|
6
|
+
* native UUID values as their 128-bit numeric representation, so SMRT stores
|
|
7
|
+
* UUID columns as TEXT for JSON-backed databases.
|
|
8
|
+
*/
|
|
9
|
+
import type { SQLDataType } from '../types.js';
|
|
2
10
|
import { DuckDBStrategy } from './duckdb-strategy.js';
|
|
3
|
-
import { DatabaseEngine } from './types.js';
|
|
11
|
+
import type { DatabaseEngine } from './types.js';
|
|
4
12
|
export declare class JsonDuckDBStrategy extends DuckDBStrategy {
|
|
5
13
|
readonly engine: DatabaseEngine;
|
|
6
14
|
mapType(type: SQLDataType): string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IndexDefinition } from '../types.js';
|
|
1
|
+
import type { IndexDefinition } from '../types.js';
|
|
2
2
|
/** Identifies version-gated, transaction-only framework index DDL to the planner. */
|
|
3
3
|
export declare const NULL_EQUAL_INDEX_MARKER = "-- smrt:null-equal-conflict-index";
|
|
4
4
|
export declare function renderNullEqualConflictIndex(tableName: string, index: IndexDefinition): string;
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL DDL Strategy
|
|
3
|
+
*
|
|
4
|
+
* PostgreSQL-specific DDL generation with the following characteristics:
|
|
5
|
+
* - JSONB type for JSON columns (more efficient than JSON)
|
|
6
|
+
* - Native BOOLEAN type
|
|
7
|
+
* - Full trigger support with PL/pgSQL functions
|
|
8
|
+
* - UNIQUE can be inline or separate indexes
|
|
9
|
+
* - Supports CAST in DEFAULT values
|
|
10
|
+
*/
|
|
11
|
+
import type { SchemaDefinition, SQLDataType, TriggerDefinition } from '../types.js';
|
|
2
12
|
import { BaseDDLStrategy } from './base-strategy.js';
|
|
3
|
-
import { DatabaseEngine } from './types.js';
|
|
13
|
+
import type { DatabaseEngine } from './types.js';
|
|
4
14
|
export declare class PostgresStrategy extends BaseDDLStrategy {
|
|
5
15
|
readonly engine: DatabaseEngine;
|
|
6
16
|
generateIndexes(schema: SchemaDefinition): string[];
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* SQLite DDL Strategy
|
|
3
|
+
*
|
|
4
|
+
* SQLite-specific DDL generation with the following characteristics:
|
|
5
|
+
* - No CAST expressions in DEFAULT values
|
|
6
|
+
* - BOOLEAN stored as INTEGER (0/1)
|
|
7
|
+
* - JSON stored as TEXT (with JSON1 extension functions)
|
|
8
|
+
* - Supports triggers with SQLite syntax
|
|
9
|
+
* - UNIQUE can be inline or separate indexes
|
|
10
|
+
*/
|
|
11
|
+
import type { SQLDataType } from '../types.js';
|
|
2
12
|
import { BaseDDLStrategy } from './base-strategy.js';
|
|
3
|
-
import { DatabaseEngine } from './types.js';
|
|
13
|
+
import type { DatabaseEngine } from './types.js';
|
|
4
14
|
export declare class SQLiteStrategy extends BaseDDLStrategy {
|
|
5
15
|
readonly engine: DatabaseEngine;
|
|
6
16
|
/**
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* DDL Generator Types for Per-Engine SQL Generation
|
|
3
|
+
*
|
|
4
|
+
* SMRT handles ALL database maintenance directly. SDK SQL remains a pure query/CRUD layer.
|
|
5
|
+
* Each database engine has different DDL requirements:
|
|
6
|
+
* - SQLite: No CAST in DEFAULT, INTEGER for booleans
|
|
7
|
+
* - DuckDB: Inline UNIQUE constraints required for UPSERT to work
|
|
8
|
+
* - PostgreSQL: JSONB type, full trigger support
|
|
9
|
+
*/
|
|
10
|
+
import type { SchemaDefinition, SQLDataType } from '../types.js';
|
|
2
11
|
/**
|
|
3
12
|
* Supported database engines
|
|
4
13
|
* - sqlite: SQLite/LibSQL databases
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DatabaseEngine } from './ddl/types.js';
|
|
2
|
-
import { ForeignKeyDefinition, SchemaDefinition } from './types.js';
|
|
1
|
+
import type { DatabaseEngine } from './ddl/types.js';
|
|
2
|
+
import type { ForeignKeyDefinition, SchemaDefinition } from './types.js';
|
|
3
3
|
export type ForeignKeyUuidCastSide = 'child' | 'parent' | 'both' | 'none';
|
|
4
4
|
export declare function foreignKeyConstraintName(tableName: string, foreignKey: ForeignKeyDefinition): string;
|
|
5
5
|
export declare function renderForeignKeyConstraint(tableName: string, foreignKey: ForeignKeyDefinition): string;
|
|
@@ -1,6 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Per-foreign-key orphan count report (#2753)
|
|
3
|
+
*
|
|
4
|
+
* `foreign-key-ddl.ts` already builds the orphan probe SQL and the suggested
|
|
5
|
+
* repair the migration differ uses to gate `ADD CONSTRAINT` — deliberately
|
|
6
|
+
* refusing to repair anything, since only the relationship's owner knows
|
|
7
|
+
* whether an orphan should be reassigned, nulled, or deleted. What is
|
|
8
|
+
* missing is the counting: `renderForeignKeyOrphanDetector({ limitOne: true })`
|
|
9
|
+
* makes the probe a gate, not a report.
|
|
10
|
+
*
|
|
11
|
+
* This module runs the same probe as a `COUNT(*)` aggregate (via
|
|
12
|
+
* `renderForeignKeyOrphanDetector({ countOnly: true })`, so the exact
|
|
13
|
+
* FROM/JOIN/WHERE predicate is never duplicated) for every manifest-declared
|
|
14
|
+
* foreign key, and reports child/parent table and column, the orphan count,
|
|
15
|
+
* and whether the child column is nullable — so the two dispositions the
|
|
16
|
+
* repair-SQL builder already distinguishes (manual repair vs. null-out) are
|
|
17
|
+
* visible up front.
|
|
18
|
+
*
|
|
19
|
+
* Strictly read-only and diagnostic: it never repairs, and a relationship
|
|
20
|
+
* whose child or parent table does not exist live is skipped and reported
|
|
21
|
+
* separately rather than failing the whole report.
|
|
22
|
+
*/
|
|
23
|
+
import type { DatabaseInterface } from '@happyvertical/sql';
|
|
24
|
+
import type { DatabaseEngine } from './ddl/types.js';
|
|
25
|
+
import type { SchemaDefinition } from './types.js';
|
|
4
26
|
/** One manifest foreign key's live orphan count. */
|
|
5
27
|
export interface ForeignKeyOrphanCount {
|
|
6
28
|
childTable: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DatabaseEngine } from './ddl/types.js';
|
|
2
|
-
import { ForeignKeyDefinition, SchemaDefinition } from './types.js';
|
|
1
|
+
import type { DatabaseEngine } from './ddl/types.js';
|
|
2
|
+
import type { ForeignKeyDefinition, SchemaDefinition } from './types.js';
|
|
3
3
|
export interface ForeignKeyCreationPlan {
|
|
4
4
|
schemas: SchemaDefinition[];
|
|
5
5
|
deferredStatements: string[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ForeignKeyAction } from './types.js';
|
|
1
|
+
import type { ForeignKeyAction } from './types.js';
|
|
2
2
|
/** Normalize decorator action spelling into the SQL vocabulary. */
|
|
3
3
|
export declare function normalizeForeignKeyAction(value: unknown): ForeignKeyAction | undefined;
|
|
4
4
|
/** Validate an externally supplied action rather than interpolating raw SQL. */
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Schema generator for SMRT objects
|
|
3
|
+
* Converts AST field definitions to database schema definitions
|
|
4
|
+
*/
|
|
5
|
+
import type { FieldDefinition, FieldMeta, ManifestSchema, SmartObjectManifest } from '../scanner/types.js';
|
|
6
|
+
import type { DatabaseEngine } from './ddl/types.js';
|
|
7
|
+
import type { DeclaredIndexDefinition, SchemaDefinition } from './types.js';
|
|
4
8
|
/**
|
|
5
9
|
* Structural shape of a field as read from either the build-time manifest
|
|
6
10
|
* (`FieldDefinition`) or the runtime ObjectRegistry (`getAllFields()` returns
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Index-rendering helpers shared across DDL strategies, schema aggregator,
|
|
3
|
+
* and the migration generator/differ.
|
|
4
|
+
*
|
|
5
|
+
* IMPORTANT: this module must remain a pure utility with **type-only
|
|
6
|
+
* imports** to avoid introducing a cycle with `registry.ts` /
|
|
7
|
+
* `collection.ts`. Don't add runtime imports that pull SmrtClass /
|
|
8
|
+
* SmrtCollection / ObjectRegistry through here.
|
|
9
|
+
*/
|
|
10
|
+
import type { DatabaseEngine } from './ddl/types.js';
|
|
11
|
+
import type { IndexDefinition } from './types.js';
|
|
3
12
|
/**
|
|
4
13
|
* Render the SQL target of a CREATE INDEX statement.
|
|
5
14
|
*
|
|
@@ -1,6 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Live-schema parity check (#2368)
|
|
3
|
+
*
|
|
4
|
+
* Compares a **live** database against the shape the model layer assumes.
|
|
5
|
+
* Three inputs define "expected":
|
|
6
|
+
*
|
|
7
|
+
* 1. **Declared table shapes** — the manifest schemas the caller passes in.
|
|
8
|
+
* These give tables, columns, types, nullability, and declared indexes.
|
|
9
|
+
* 2. **Hand-DDL system tables** — `_smrt_*` tables parsed out of
|
|
10
|
+
* `src/system/schema.ts` (see `system-table-shapes.ts`). They never enter
|
|
11
|
+
* the manifest, so nothing else has ever diffed them.
|
|
12
|
+
* 3. **An expected-shape index policy that does not consult the manifest** —
|
|
13
|
+
* every foreign-key / cross-package-ref / tenant column carries a leading
|
|
14
|
+
* index, every declared upsert conflict target is backed by a matching
|
|
15
|
+
* UNIQUE index, and every `unique: true` column is actually unique in the
|
|
16
|
+
* live database.
|
|
17
|
+
*
|
|
18
|
+
* Point 3 is the reason this module exists rather than reusing the migration
|
|
19
|
+
* differ: the differ compares the live database to the manifest, i.e. to the
|
|
20
|
+
* artifact that dropped the index in the first place, which is why a database
|
|
21
|
+
* missing 164 tenant-column indexes reported "in sync" (#2356).
|
|
22
|
+
*
|
|
23
|
+
* This module is read-only. It emits findings; it never repairs.
|
|
24
|
+
*/
|
|
25
|
+
import type { DatabaseInterface } from '@happyvertical/sql';
|
|
26
|
+
import type { DatabaseEngine } from './ddl/types.js';
|
|
27
|
+
import type { SchemaDefinition } from './types.js';
|
|
4
28
|
/** How badly a finding breaks the deployment. */
|
|
5
29
|
export type LiveParitySeverity = 'error' | 'warning' | 'info';
|
|
6
30
|
/** The class of drift a finding describes. */
|
|
@@ -1,5 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Manifest schema → structured `SchemaDefinition` helpers (#2358).
|
|
3
|
+
*
|
|
4
|
+
* A manifest's `schema.ddl` string is an engine-neutral CREATE TABLE preview:
|
|
5
|
+
* it carries no indexes and no per-engine type mapping, so nothing that needs
|
|
6
|
+
* an executable schema may treat it as authoritative. Every consumer that
|
|
7
|
+
* reads raw manifest JSON — `SchemaAggregator`, `createIsolatedTestDbFromManifest`
|
|
8
|
+
* in `@happyvertical/smrt-vitest`, third-party tooling — should collect the
|
|
9
|
+
* structured `columns` / `indexes` through this module and render them with
|
|
10
|
+
* `getDDLStrategy(engine)`, exactly as `db:migrate` does.
|
|
11
|
+
*
|
|
12
|
+
* The cached `ddl` string is used only when a manifest object exposes no
|
|
13
|
+
* structured columns at all (hand-authored or pre-structured manifests); that
|
|
14
|
+
* legacy path keeps working but is not engine-complete.
|
|
15
|
+
*
|
|
16
|
+
* Keep this module light — type-only imports plus the DDL strategies and the
|
|
17
|
+
* logger — so it can be re-exported from lightweight entry points without
|
|
18
|
+
* pulling the registry/collection module graph in by itself.
|
|
19
|
+
*/
|
|
20
|
+
import type { DatabaseEngine, EngineSpecificDDL } from './ddl/types.js';
|
|
21
|
+
import type { ColumnDefinition, IndexDefinition, SchemaDefinition } from './types.js';
|
|
3
22
|
/**
|
|
4
23
|
* Column shape as it appears in raw manifest JSON. `ManifestColumnDefinition`
|
|
5
24
|
* spells the default `default`; registry-side `ColumnDefinition` spells it
|
|
@@ -1,5 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Schema Aggregator
|
|
3
|
+
*
|
|
4
|
+
* Aggregates database schemas across multiple SMRT package manifests.
|
|
5
|
+
* Handles STI table deduplication, index merging, and sorting for deterministic output.
|
|
6
|
+
*
|
|
7
|
+
* Tables and indexes are rendered from the manifests' structured `columns` /
|
|
8
|
+
* `indexes` through the dialect's DDL strategy (`getDDLStrategy`), the same
|
|
9
|
+
* renderer `smrt db:migrate` uses — never from the cached `schema.ddl` string,
|
|
10
|
+
* which carries no indexes and no per-engine types (#2358). Objects that expose
|
|
11
|
+
* no structured columns fall back to their cached `ddl` for the CREATE TABLE.
|
|
12
|
+
*
|
|
13
|
+
* This replaces the manual generate-schema.ts pattern used by downstream
|
|
14
|
+
* projects like blindmanpress.com (Issue #1013).
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { SchemaAggregator } from '@happyvertical/smrt-core/schema';
|
|
19
|
+
*
|
|
20
|
+
* // Auto-discover from installed @happyvertical packages in node_modules
|
|
21
|
+
* const aggregator = new SchemaAggregator();
|
|
22
|
+
* const result = aggregator.aggregate();
|
|
23
|
+
*
|
|
24
|
+
* // Or with explicit packages
|
|
25
|
+
* const result = aggregator.aggregate({
|
|
26
|
+
* packages: ['@happyvertical/smrt-profiles', '@happyvertical/smrt-events'],
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* console.log(result.sql); // Combined CREATE TABLE + INDEX SQL
|
|
30
|
+
* console.log(result.tables); // Map of table info
|
|
31
|
+
* console.log(result.manifests); // Loaded manifests by package
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
import type { SmartObjectManifest } from '../scanner/types.js';
|
|
35
|
+
import { type CollectedManifestTable, type ManifestColumnLike } from './manifest-schema.js';
|
|
3
36
|
/**
|
|
4
37
|
* Aggregated table information including DDL, indexes, and source tracking.
|
|
5
38
|
*/
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Schema Manager - Direct DDL Execution for SMRT
|
|
3
|
+
*
|
|
4
|
+
* SMRT handles ALL database maintenance directly.
|
|
5
|
+
* SDK SQL remains a pure query/CRUD layer.
|
|
6
|
+
*
|
|
7
|
+
* This module replaces the use of SDK's syncSchema() with direct DDL execution
|
|
8
|
+
* using engine-specific DDL strategies.
|
|
9
|
+
*/
|
|
10
|
+
import type { DatabaseInterface } from '@happyvertical/sql';
|
|
11
|
+
import { type DatabaseEngine, type EngineSpecificDDL } from './ddl/index.js';
|
|
12
|
+
import { type ForeignKeyUuidCastSide } from './foreign-key-ddl.js';
|
|
13
|
+
import type { ForeignKeyDefinition, SchemaDefinition } from './types.js';
|
|
5
14
|
/**
|
|
6
15
|
* Schema Manager Options
|
|
7
16
|
*/
|
|
@@ -1,4 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* System-table shape parsing (#2368)
|
|
3
|
+
*
|
|
4
|
+
* `_smrt_*` tables are created from hand-written DDL in `src/system/schema.ts`
|
|
5
|
+
* rather than from decorated classes, so they never enter the manifest and the
|
|
6
|
+
* manifest-driven differ has never compared them against a live database.
|
|
7
|
+
*
|
|
8
|
+
* This module parses that DDL back into a structural description — columns,
|
|
9
|
+
* declared indexes, and inline `UNIQUE (...)` constraints — so the live-schema
|
|
10
|
+
* parity check can hold system tables to the same standard as application
|
|
11
|
+
* tables. The DDL is the source of truth for these tables; parsing it (rather
|
|
12
|
+
* than duplicating a hand-maintained expectation table) keeps the two from
|
|
13
|
+
* drifting apart.
|
|
14
|
+
*
|
|
15
|
+
* The parser is deliberately narrow: it understands the portable subset SMRT
|
|
16
|
+
* actually writes (`CREATE TABLE IF NOT EXISTS`, `CREATE [UNIQUE] INDEX IF NOT
|
|
17
|
+
* EXISTS`, simple column definitions, inline `UNIQUE`/`PRIMARY KEY` table
|
|
18
|
+
* constraints) and ignores anything else rather than guessing.
|
|
19
|
+
*/
|
|
20
|
+
import type { DatabaseEngine } from './ddl/types.js';
|
|
2
21
|
/** One column as declared by hand-written system-table DDL. */
|
|
3
22
|
export interface SystemTableColumnShape {
|
|
4
23
|
name: string;
|
|
@@ -1,4 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Shared "probe, then cast" helpers for text-column type convergence (#2771,
|
|
3
|
+
* #2772).
|
|
4
|
+
*
|
|
5
|
+
* Two drift shapes on a table SMRT itself creates share one problem: a live
|
|
6
|
+
* `text` column holds values that would parse losslessly into the manifest's
|
|
7
|
+
* declared PostgreSQL type (`timestamptz` or `jsonb`), but the differ cannot
|
|
8
|
+
* know that without looking at the data. `probeCastSafety()` answers that with
|
|
9
|
+
* a genuine, exception-safe cast attempt — not a shape heuristic — over every
|
|
10
|
+
* non-null value, and returns one sample so a fail-closed diagnostic can name
|
|
11
|
+
* the offending value without dumping the whole column into JS.
|
|
12
|
+
*
|
|
13
|
+
* PostgreSQL has no `TRY_CAST`/safe-cast builtin before 17 (`pg_input_is_valid`),
|
|
14
|
+
* and this fleet targets 16 (see `.github/workflows/postgres-tests.yml`), so a
|
|
15
|
+
* real per-row safe cast needs PL/pgSQL's exception handling. That handler is
|
|
16
|
+
* created as a session-scoped (`pg_temp`) function, which is why the create
|
|
17
|
+
* statement and the probe query run inside one `db.transaction()` — the two
|
|
18
|
+
* must land on the same physical connection, and a pooled adapter only
|
|
19
|
+
* guarantees that within one transaction. `target_type` is never derived from
|
|
20
|
+
* column data (always the literal `'jsonb'`/`'timestamptz'` this module
|
|
21
|
+
* passes), so the dynamic `EXECUTE format(...)` it builds cannot be steered by
|
|
22
|
+
* a row value; `%L` quotes the probed value as a literal.
|
|
23
|
+
*/
|
|
24
|
+
import type { DatabaseInterface } from '@happyvertical/sql';
|
|
2
25
|
/** Outcome of a server-side cast-safety probe over one column's non-null values. */
|
|
3
26
|
export type ShapeProbeResult = {
|
|
4
27
|
status: 'clean';
|
package/dist/schema/utils.d.ts
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Schema generation utilities - Node.js only
|
|
3
|
+
*
|
|
4
|
+
* These functions use SchemaGenerator which depends on node:crypto.
|
|
5
|
+
* Separated from main utils.ts to prevent bundling in browser builds.
|
|
6
|
+
*
|
|
7
|
+
* SMRT handles ALL database maintenance directly.
|
|
8
|
+
* SDK SQL remains a pure query/CRUD layer.
|
|
9
|
+
*/
|
|
10
|
+
import type { DatabaseInterface } from '@happyvertical/sql';
|
|
11
|
+
import type { SmrtObject } from '../object.js';
|
|
12
|
+
import type { FieldDefinition } from '../scanner/types.js';
|
|
13
|
+
import { type DatabaseEngine } from './ddl/index.js';
|
|
5
14
|
export { materializeManifestDDLForEngine, tokenizeSQLDDLBody, } from './ddl/materialize-manifest.js';
|
|
6
15
|
export { assertIdentifierFits, identifierByteLength, isJsonPathIndex, isStiSubtypeUniqueIndex, MAX_IDENTIFIER_BYTES, renderIndexTarget, shortenIdentifier, } from './index-utils.js';
|
|
7
16
|
export { type CollectedManifestTable, collectManifestTables, type ManifestColumnLike, type ManifestIndexLike, type ManifestSchemaLike, manifestColumnsToDefinitions, manifestIndexesToDefinitions, manifestSchemaToDefinition, mergeSchemaDefinitionInto, renderCollectedManifestTable, } from './manifest-schema.js';
|
|
@@ -1,4 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* UUID convergence for pre-R11 PostgreSQL databases (#2608).
|
|
3
|
+
*
|
|
4
|
+
* R11 made SMRT identifiers and references native `uuid` on PostgreSQL.
|
|
5
|
+
* Databases created before that change still carry `text` id columns, while
|
|
6
|
+
* every column added afterwards materializes as `uuid`. PostgreSQL cannot
|
|
7
|
+
* implement a `FOREIGN KEY` across those two physical types — there is no
|
|
8
|
+
* cast inside FK DDL — so `ALTER TABLE … ADD CONSTRAINT … NOT VALID` fails
|
|
9
|
+
* with SQLSTATE 42804 and takes the rest of the migration batch with it.
|
|
10
|
+
*
|
|
11
|
+
* This module owns the deterministic half of the repair:
|
|
12
|
+
*
|
|
13
|
+
* - {@link renderUuidColumnConversion} renders the one-time
|
|
14
|
+
* `ALTER COLUMN … TYPE uuid USING …::uuid` (plus the `DROP DEFAULT` a live
|
|
15
|
+
* text default would otherwise block), and
|
|
16
|
+
* - {@link planUuidConvergence} decides *which* columns must convert, by
|
|
17
|
+
* grouping every manifest-declared UUID relationship into connected
|
|
18
|
+
* components and converging a component only when the live database already
|
|
19
|
+
* proves the target shape (at least one side is native `uuid`).
|
|
20
|
+
*
|
|
21
|
+
* The planner never coerces data: a component converges only when a caller
|
|
22
|
+
* supplied probe confirms every non-null value is uuid-shaped, no live
|
|
23
|
+
* foreign key depends on a column being rewritten, and no member carries some
|
|
24
|
+
* third physical type. Anything else is returned as a *block* with an
|
|
25
|
+
* operator-facing reason, so `db:status` can report "blocked" instead of
|
|
26
|
+
* "pending" and `db:migrate` never attempts DDL PostgreSQL will reject.
|
|
27
|
+
*
|
|
28
|
+
* A database whose relationship is `text` on *both* sides is left alone: that
|
|
29
|
+
* is the tolerated pre-R11 shape (see the R11 uuid/text equivalence in
|
|
30
|
+
* `migrations/differ.ts`), and its foreign keys apply fine.
|
|
31
|
+
*/
|
|
32
|
+
import type { SchemaDefinition } from './types.js';
|
|
2
33
|
/** One physical column participating in a manifest UUID relationship. */
|
|
3
34
|
export interface UuidConvergenceNode {
|
|
4
35
|
table: string;
|
package/dist/signals/bus.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Signal Bus for Universal Event Distribution
|
|
3
|
+
*
|
|
4
|
+
* This module provides the central SignalBus for distributing signals
|
|
5
|
+
* to registered adapters (logging, metrics, pub/sub, etc.).
|
|
6
|
+
*/
|
|
7
|
+
import type { Signal, SignalAdapter } from '@happyvertical/smrt-types';
|
|
8
|
+
import type { SanitizationConfig } from './sanitizer.js';
|
|
3
9
|
/**
|
|
4
10
|
* Central signal distribution bus
|
|
5
11
|
*
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Signal payload sanitization for security
|
|
3
|
+
*
|
|
4
|
+
* Prevents sensitive data (passwords, tokens, PII) from being leaked
|
|
5
|
+
* into logs, metrics, or other signal outputs.
|
|
6
|
+
*/
|
|
7
|
+
import type { Signal } from '@happyvertical/smrt-types';
|
|
2
8
|
/**
|
|
3
9
|
* Sanitization configuration
|
|
4
10
|
*/
|
package/dist/smrt-knowledge.json
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
"sensitiveFieldsExcluded": true,
|
|
4
4
|
"generatedAt": "1970-01-01T00:00:00.000Z",
|
|
5
5
|
"packageName": "@happyvertical/smrt-core",
|
|
6
|
-
"packageVersion": "0.51.
|
|
6
|
+
"packageVersion": "0.51.33",
|
|
7
7
|
"sourceManifestPath": "dist/manifest.json",
|
|
8
8
|
"agentDocPath": "AGENTS.md",
|
|
9
9
|
"sourceHashes": {
|
|
10
|
-
"manifest": "
|
|
11
|
-
"packageJson": "
|
|
10
|
+
"manifest": "0e598c41a70d94e0f311ca2c6c717499d7d360bfde2a10c982e722bd8cc6e928",
|
|
11
|
+
"packageJson": "624a187e41615d1b71afb40c725502618367487547cf4fe00127265c02c2c2cc",
|
|
12
12
|
"agents": "79356014d92fdf656f648e5c765374913104445a5542243f4819ef362c77a8e5",
|
|
13
13
|
"moduleDoc:agents/object-runtime.md": "34a4e740c109467cd5486c4af0e3bf4b63915697721ab584df0e5506ea9290ca",
|
|
14
14
|
"moduleDoc:agents/revision-guard.md": "aa6b1ddb5b6b49fa27ebbe575ec7fcd6d5ceb35ee25acc702f877a226eb9a99a",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"moduleDoc:agents/change-feed.md": "2151843f5d059cff54d7f6a32a6d57c43b9551fc4673edce13209764a09a9ae1",
|
|
20
20
|
"moduleDoc:agents/change-signals.md": "a2dbe7077483b5a19bd5ea9589b5a08fe847377c8e05d01d57f813c6d9cbc28b",
|
|
21
21
|
"moduleDoc:agents/generators.md": "4bc7787947fbcb5c084ce3e7849eff7a240580226e6b64271de7493870683cdf",
|
|
22
|
-
"moduleDoc:agents/build-knowledge.md": "
|
|
22
|
+
"moduleDoc:agents/build-knowledge.md": "41eff6b3603f00e59eb91820c5ad9e50fb103d25bb5b9947f5b09b59d54a79ea",
|
|
23
23
|
"moduleDoc:agents/memory.md": "a86bdf370403d08ecad3be86e341eb322dfe6e6b7a4e8806a6f8be9bf3421da5",
|
|
24
24
|
"moduleDoc:agents/system-diagnostics.md": "b7ccae18ee312bf788d5470f95fa78d3535f1789247d5372e40ca86538290772",
|
|
25
25
|
"moduleDoc:agents/registry-snapshot.md": "6234aa540427396d1dda1825a4641b1072e247187d5ddf413ae46c691344ee30",
|
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
"oxc-transform": "0.150.0",
|
|
72
72
|
"pluralize": "^8.0.0",
|
|
73
73
|
"tsx": "^4.23.13",
|
|
74
|
+
"vite": "8.1.4",
|
|
74
75
|
"yaml": "^2.9.1",
|
|
75
76
|
"@faker-js/faker": "^10.6.0",
|
|
76
77
|
"@huggingface/transformers": ">=3.0.0 <5.0.0",
|
|
@@ -80,10 +81,8 @@
|
|
|
80
81
|
"@types/pluralize": "^0.0.33",
|
|
81
82
|
"@xenova/transformers": "^2.17.2",
|
|
82
83
|
"svelte": "^5.57.1",
|
|
83
|
-
"svelte-check": "4.7.6",
|
|
84
|
-
"typescript": "
|
|
85
|
-
"vite": "8.1.4",
|
|
86
|
-
"vite-plugin-dts": "5.1.0",
|
|
84
|
+
"svelte-check": "^4.7.6",
|
|
85
|
+
"typescript": "6.0.3",
|
|
87
86
|
"vitest": "4.1.10"
|
|
88
87
|
},
|
|
89
88
|
"smrtDependencies": [
|
|
@@ -1108,7 +1107,7 @@
|
|
|
1108
1107
|
{
|
|
1109
1108
|
"path": "agents/build-knowledge.md",
|
|
1110
1109
|
"module": "build-knowledge",
|
|
1111
|
-
"content": "# Decorators, build integration, and knowledge\n\nKey options: `tableName`, `tableStrategy` ('cti'|'sti'), `conflictColumns`, `indexes` (declared multi-column indexes; see [schema-paths.md](schema-paths.md)), `api`/`mcp`/`cli` (generation config), `ai` (callable methods), `hooks` (beforeSave/afterSave/beforeDelete/afterDelete), `embeddings` (auto-generate), `tenantScoped`, `agent`, `ui` (`{ icon, label, description }` — nav/help hints round-tripped through the manifest as plain data; `description` is the object-level seed for form-level help, #2046).\n\nRegistration sets `SMRT_TABLE_NAME` static property (survives minification).\n\n## @field() UI hints (#2046)\n\n`@field({ ui: { basic, group, order, locked } })` — a static, presentation-only\nseed for the field-policy rail (epic #2045). Carried in the manifest under the\nfield's `_meta.ui` (never a top-level `FieldDefinition` key), readable at\nruntime via `getAllFields()` at `field._meta.ui`, and emitted (sanitized) with\n`description` into generated web-collection definitions and browser MCP tool\nschemas. No schema/persistence/security effect — `sensitive`/`readPermission`\nstay the security rail, and `sensitive`/`transient` fields never emit to the\nclient at all.\n\n## Worker registration artifact (#3117)\n\nWith `svelteKit.enabled`, a production `vite build` compiles the generated\n`smrt-register.ts` into `.smrt/runtime/register.js` after the server build\n(`src/vite-plugin/worker-registration.ts`, called once from `closeBundle`).\nadapter-node re-bundles the server from its own entries, so the web bundle is\nnever importable by a separate Node process; this artifact is how a deployed\ntask/schedule worker registers the app's local objects (and, through the\n`.smrt/register.js` it imports, consumed packages' objects) with the same\nqualified identities and isolated manifests as the web server. It is a nested\nSSR build with no consumer plugins: only aliases pointing into the project\nsources (e.g. `$lib`) apply, and every other bare import stays external so the\nworker shares the installed `@happyvertical/smrt-core` registry. SvelteKit\nvirtual modules (`$env/*`, `$app/*`) are not available to a worker; an object\nimporting one fails at worker startup. A failure fails the build.\n\n## Lightweight discovery\n\n`src/knowledge-discovery.ts`, exported through `smrt-core/knowledge`, enumerates\ninstalled scope directories and reads canonical AGENTS/legacy CLAUDE docs without\nloading package code, artifacts, or scanning objects. CLI snapshots and MCP share\nthese primitives. Callers retain selection policy: snapshots resolve links and\nfall back to `packages/*` only when no installed SMRT package loads; MCP preserves\nnode_modules paths, deduplicates realpaths, excludes authored workspace links,\nand then enriches the selected packages. Workspace-root/glob discovery remains\nowned by each consumer.\n\n## Domain Knowledge Artifacts\n\n`smrtPlugin()` writes runtime manifests and agent/developer knowledge artifacts:\n\n- local dev/build: `.smrt/manifest.json` and `.smrt/smrt-knowledge.json`\n- package build: `dist/manifest.json` and `dist/smrt-knowledge.json`\n\nKeep `manifest.json` runtime-focused. `smrt-knowledge.json` is the deterministic\nagent contract for downstream review and architecture tools.\n\nThe CLI's schema-command gate reads that same merged file: a pure-consumer\nproject (0 local objects) qualifies on the consumed packages its manifest\nrecords, so a clobbered `objects` map is what made `smrt db:migrate` report\n`missing_local_manifest` (#2925).\n\n`.smrt/manifest.json` has two writers and neither owns all of it: `smrtPlugin()`\ncontributes the project's scanned objects and `smrtConsumer()` the consumed\npackages' entries. Both writes are merge-preserving, keyed on each entry's\nrecorded `packageName` — a plain overwrite in either direction silently drops\nthe other's objects, and the last pass of a multi-environment build is not\nreliably the aggregating one (#1760, #2925). `dist/manifest.json` stays\nlocal-only: a published package must not carry its dependencies' objects.\n\nThe schema-version-1 object projection is additive and high-signal: it retains\nnormalized tenant mode/field, explicit `cti`/`sti` strategy, conflict columns,\nmethod signatures, and field defaults/constraints/readonly/transient flags.\nSensitive fields are removed before both `fields` and `relationships` are\nderived, including legacy flags stored under `_meta`; matching field and\nsnake-case column names are also removed from projected conflict columns, and a\nsensitive custom tenant field is omitted while retaining scope and mode.\nGenerated artifacts assert this boundary with `sensitiveFieldsExcluded: true`;\nthe optional marker keeps schema version 1 additive while letting readers\nidentify older artifacts that require raw-manifest corroboration.\n\nConfig precedence for knowledge is defaults → top-level `knowledge` in\n`smrt.config.ts` → `packages[packageName].knowledge` → plugin option →\nobject-level `@smrt({ knowledge })`.\n\nObject-level `knowledge: false` excludes an object from authored context only;\nit must not change runtime manifest registration. Use\n`knowledge: { tags, summary, risks }` for review-sensitive domain objects.\n\nHTTP knowledge routes are disabled by default. If `knowledge.api.enabled` is\ntrue, generated SvelteKit routes must stay GET-only and guarded by dev mode or\nadmin auth.\n\n\n## Vite Plugin\n\n```typescript\n// vite.config.ts — required for @smrt() decorators (Vite 8+, oxc transform)\nexport default defineConfig({\n oxc: {\n decorator: {\n legacy: true,\n emitDecoratorMetadata: true,\n },\n },\n});\n```\n\nUnder Vite 8 the oxc transform does not honor the pre-Vite-8 `esbuild.tsconfigRaw`\nrecipe (or tsconfig `experimentalDecorators` reached through SvelteKit's\n`extends \"./.svelte-kit/tsconfig.json\"` chain), so that recipe throws\n`SyntaxError: Invalid or unexpected token` on the first SSR request. Configure\ndecorators through `oxc.decorator` instead. Consumers still pinned on vite<8 need\nthe legacy `esbuild.tsconfigRaw` form with `experimentalDecorators: true,\nemitDecoratorMetadata: true`.\n\nFor independent CI invocations, both `smrtPlugin()` and `smrtConsumer()` accept\nthe same `generationSnapshot: { path, sha256, provenance, sourceRoot }`. The\nschema-v1 snapshot produced by `serializeSmrtGenerationSnapshot()` contains the\nmerged project/dependency manifest, portable source paths, and source-file\ndigests; each plugin selects its own view. Reuse mode fails closed on\nbyte/provenance/path/content drift, skips scans and manifest writes, and still\ngenerates routes, types, registration, and virtual modules. Omit it for normal\nlocal development and watch mode.\n"
|
|
1110
|
+
"content": "# Decorators, build integration, and knowledge\n\nKey options: `tableName`, `tableStrategy` ('cti'|'sti'), `conflictColumns`, `indexes` (declared multi-column indexes; see [schema-paths.md](schema-paths.md)), `api`/`mcp`/`cli` (generation config), `ai` (callable methods), `hooks` (beforeSave/afterSave/beforeDelete/afterDelete), `embeddings` (auto-generate), `tenantScoped`, `agent`, `ui` (`{ icon, label, description }` — nav/help hints round-tripped through the manifest as plain data; `description` is the object-level seed for form-level help, #2046).\n\nRegistration sets `SMRT_TABLE_NAME` static property (survives minification).\n\n## @field() UI hints (#2046)\n\n`@field({ ui: { basic, group, order, locked } })` — a static, presentation-only\nseed for the field-policy rail (epic #2045). Carried in the manifest under the\nfield's `_meta.ui` (never a top-level `FieldDefinition` key), readable at\nruntime via `getAllFields()` at `field._meta.ui`, and emitted (sanitized) with\n`description` into generated web-collection definitions and browser MCP tool\nschemas. No schema/persistence/security effect — `sensitive`/`readPermission`\nstay the security rail, and `sensitive`/`transient` fields never emit to the\nclient at all.\n\n## Worker registration artifact (#3117)\n\nWith `svelteKit.enabled`, a production `vite build` compiles the generated\n`smrt-register.ts` into `.smrt/runtime/register.js` after the server build\n(`src/vite-plugin/worker-registration.ts`, called once from `closeBundle`).\nadapter-node re-bundles the server from its own entries, so the web bundle is\nnever importable by a separate Node process; this artifact is how a deployed\ntask/schedule worker registers the app's local objects (and, through the\n`.smrt/register.js` it imports, consumed packages' objects) with the same\nqualified identities and isolated manifests as the web server. It is a nested\nSSR build with no consumer plugins: only aliases pointing into the project\nsources (e.g. `$lib`) apply, and every other bare import stays external so the\nworker shares the installed `@happyvertical/smrt-core` registry. SvelteKit\nvirtual modules (`$env/*`, `$app/*`) are not available to a worker; an object\nimporting one fails at worker startup. A failure fails the build.\n\n## Lightweight discovery\n\nFilesystem-only discovery, module-doc parsing, and graph freshness are owned by\n`@happyvertical/smrt-scanner/knowledge`. Core's knowledge exports remain compatible\nreexports. Runtime manifest projection and custom-action semantics stay in core.\n\n`src/knowledge-discovery.ts`, exported through `smrt-core/knowledge`, enumerates\ninstalled scope directories and reads canonical AGENTS/legacy CLAUDE docs without\nloading package code, artifacts, or scanning objects. CLI snapshots and MCP share\nthese primitives. Callers retain selection policy: snapshots resolve links and\nfall back to `packages/*` only when no installed SMRT package loads; MCP preserves\nnode_modules paths, deduplicates realpaths, excludes authored workspace links,\nand then enriches the selected packages. Workspace-root/glob discovery remains\nowned by each consumer.\n\n## Domain Knowledge Artifacts\n\n`smrtPlugin()` writes runtime manifests and agent/developer knowledge artifacts:\n\n- local dev/build: `.smrt/manifest.json` and `.smrt/smrt-knowledge.json`\n- package build: `dist/manifest.json` and `dist/smrt-knowledge.json`\n\nKeep `manifest.json` runtime-focused. `smrt-knowledge.json` is the deterministic\nagent contract for downstream review and architecture tools.\n\nThe CLI's schema-command gate reads that same merged file: a pure-consumer\nproject (0 local objects) qualifies on the consumed packages its manifest\nrecords, so a clobbered `objects` map is what made `smrt db:migrate` report\n`missing_local_manifest` (#2925).\n\n`.smrt/manifest.json` has two writers and neither owns all of it: `smrtPlugin()`\ncontributes the project's scanned objects and `smrtConsumer()` the consumed\npackages' entries. Both writes are merge-preserving, keyed on each entry's\nrecorded `packageName` — a plain overwrite in either direction silently drops\nthe other's objects, and the last pass of a multi-environment build is not\nreliably the aggregating one (#1760, #2925). `dist/manifest.json` stays\nlocal-only: a published package must not carry its dependencies' objects.\n\nThe schema-version-1 object projection is additive and high-signal: it retains\nnormalized tenant mode/field, explicit `cti`/`sti` strategy, conflict columns,\nmethod signatures, and field defaults/constraints/readonly/transient flags.\nSensitive fields are removed before both `fields` and `relationships` are\nderived, including legacy flags stored under `_meta`; matching field and\nsnake-case column names are also removed from projected conflict columns, and a\nsensitive custom tenant field is omitted while retaining scope and mode.\nGenerated artifacts assert this boundary with `sensitiveFieldsExcluded: true`;\nthe optional marker keeps schema version 1 additive while letting readers\nidentify older artifacts that require raw-manifest corroboration.\n\nConfig precedence for knowledge is defaults → top-level `knowledge` in\n`smrt.config.ts` → `packages[packageName].knowledge` → plugin option →\nobject-level `@smrt({ knowledge })`.\n\nObject-level `knowledge: false` excludes an object from authored context only;\nit must not change runtime manifest registration. Use\n`knowledge: { tags, summary, risks }` for review-sensitive domain objects.\n\nHTTP knowledge routes are disabled by default. If `knowledge.api.enabled` is\ntrue, generated SvelteKit routes must stay GET-only and guarded by dev mode or\nadmin auth.\n\n\n## Vite Plugin\n\n```typescript\n// vite.config.ts — required for @smrt() decorators (Vite 8+, oxc transform)\nexport default defineConfig({\n oxc: {\n decorator: {\n legacy: true,\n emitDecoratorMetadata: true,\n },\n },\n});\n```\n\nUnder Vite 8 the oxc transform does not honor the pre-Vite-8 `esbuild.tsconfigRaw`\nrecipe (or tsconfig `experimentalDecorators` reached through SvelteKit's\n`extends \"./.svelte-kit/tsconfig.json\"` chain), so that recipe throws\n`SyntaxError: Invalid or unexpected token` on the first SSR request. Configure\ndecorators through `oxc.decorator` instead. Consumers still pinned on vite<8 need\nthe legacy `esbuild.tsconfigRaw` form with `experimentalDecorators: true,\nemitDecoratorMetadata: true`.\n\nFor independent CI invocations, both `smrtPlugin()` and `smrtConsumer()` accept\nthe same `generationSnapshot: { path, sha256, provenance, sourceRoot }`. The\nschema-v1 snapshot produced by `serializeSmrtGenerationSnapshot()` contains the\nmerged project/dependency manifest, portable source paths, and source-file\ndigests; each plugin selects its own view. Reuse mode fails closed on\nbyte/provenance/path/content drift, skips scans and manifest writes, and still\ngenerates routes, types, registration, and virtual modules. Omit it for normal\nlocal development and watch mode.\n\n## Clean consumer type checks (TypeScript 6)\n\nThe consumer config hook writes `.smrt/register.js` alongside generated types\nafter route preflight succeeds. Generated SvelteKit registration imports that\nmodule, so it must exist during `svelte-kit sync`, before Vite's `buildStart`.\nBoth hosted routes and the legacy `svelteKit: true` mode follow this order.\nThe clean-consumer regression fixture ships real provider declarations and\nchecks the generated imports with `svelte-check`.\n"
|
|
1112
1111
|
},
|
|
1113
1112
|
{
|
|
1114
1113
|
"path": "agents/memory.md",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DatabaseInterface } from '@happyvertical/sql';
|
|
1
|
+
import type { DatabaseInterface } from '@happyvertical/sql';
|
|
2
2
|
import { detectEngine } from '../schema/ddl/index.js';
|
|
3
3
|
export declare function tableExists(db: DatabaseInterface, tableName: string, typeHint?: string): Promise<boolean>;
|
|
4
4
|
export declare function getDatabaseEngine(db: DatabaseInterface, typeHint?: string): ReturnType<typeof detectEngine>;
|
|
@@ -1,5 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* SMRT system-diagnostics reader.
|
|
3
|
+
*
|
|
4
|
+
* A typed, SELECT-only view over the framework-owned `_smrt_*` system tables
|
|
5
|
+
* for development tooling (smrt-dev-mcp runtime diagnostics). Every read is a
|
|
6
|
+
* bounded SELECT against explicitly projected safe columns; sensitive columns
|
|
7
|
+
* are never selected and no statement here writes.
|
|
8
|
+
*
|
|
9
|
+
* The reader takes a `DatabaseInterface` (connection resolution lives with the
|
|
10
|
+
* caller) and degrades per category to a `CategoryUnavailable` result when its
|
|
11
|
+
* table is missing or a read fails — it never throws for missing tables and
|
|
12
|
+
* never fabricates data. `_smrt_registry` is a retired system table
|
|
13
|
+
* ({@link RETIRED_SYSTEM_TABLES}) and is reported as retired rather than
|
|
14
|
+
* queried.
|
|
15
|
+
*/
|
|
16
|
+
import type { DatabaseInterface } from '@happyvertical/sql';
|
|
17
|
+
import { type ChangeFeedEntry } from '../change-feed.js';
|
|
3
18
|
/** Physical `_smrt_*` tables the diagnostics reader knows about. */
|
|
4
19
|
export declare const SYSTEM_DIAGNOSTICS_TABLES: {
|
|
5
20
|
readonly migrations: "_smrt_schema_migrations";
|