@axiom-lattice/pg-stores 5.1.2 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1769,6 +1769,43 @@ var createMcpServerConfigsTable = {
1769
1769
  await client.query("DROP TABLE IF EXISTS lattice_mcp_server_configs");
1770
1770
  }
1771
1771
  };
1772
+ var createPersonalMcpServerConfigsTable = {
1773
+ version: 220,
1774
+ name: "create_personal_mcp_server_configs_table",
1775
+ up: async (client) => {
1776
+ await client.query(`
1777
+ CREATE TABLE IF NOT EXISTS lattice_personal_mcp_server_configs (
1778
+ id VARCHAR(255) NOT NULL,
1779
+ tenant_id VARCHAR(255) NOT NULL,
1780
+ owner_assistant_id VARCHAR(255) NOT NULL,
1781
+ key VARCHAR(255) NOT NULL,
1782
+ name VARCHAR(255),
1783
+ description TEXT,
1784
+ config JSONB NOT NULL,
1785
+ selected_tools JSONB NOT NULL DEFAULT '[]',
1786
+ is_env_encrypted BOOLEAN NOT NULL DEFAULT FALSE,
1787
+ status VARCHAR(50) NOT NULL DEFAULT 'disconnected',
1788
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
1789
+ updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
1790
+
1791
+ PRIMARY KEY (tenant_id, owner_assistant_id, id)
1792
+ )
1793
+ `);
1794
+ await client.query(`
1795
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_lattice_personal_mcp_assistant_key
1796
+ ON lattice_personal_mcp_server_configs(tenant_id, owner_assistant_id, key)
1797
+ `);
1798
+ await client.query(`
1799
+ CREATE INDEX IF NOT EXISTS idx_lattice_personal_mcp_assistant
1800
+ ON lattice_personal_mcp_server_configs(tenant_id, owner_assistant_id)
1801
+ `);
1802
+ },
1803
+ down: async (client) => {
1804
+ await client.query("DROP INDEX IF EXISTS idx_lattice_personal_mcp_assistant_key");
1805
+ await client.query("DROP INDEX IF EXISTS idx_lattice_personal_mcp_assistant");
1806
+ await client.query("DROP TABLE IF EXISTS lattice_personal_mcp_server_configs");
1807
+ }
1808
+ };
1772
1809
 
1773
1810
  // src/stores/PostgreSQLMcpServerConfigStore.ts
1774
1811
  import { encrypt as encrypt3, safeDecrypt as safeDecrypt3 } from "@axiom-lattice/core";
@@ -1792,6 +1829,7 @@ var PostgreSQLMcpServerConfigStore = class {
1792
1829
  }
1793
1830
  this.migrationManager = new MigrationManager(this.pool);
1794
1831
  this.migrationManager.register(createMcpServerConfigsTable);
1832
+ this.migrationManager.register(createPersonalMcpServerConfigsTable);
1795
1833
  if (options.autoMigrate !== false) {
1796
1834
  this.initialize().catch((error) => {
1797
1835
  console.error("Failed to initialize PostgreSQLMcpServerConfigStore:", error);
@@ -2019,6 +2057,231 @@ var PostgreSQLMcpServerConfigStore = class {
2019
2057
  );
2020
2058
  return result.rows.length > 0;
2021
2059
  }
2060
+ /**
2061
+ * Get all personal MCP server configurations owned by one assistant.
2062
+ */
2063
+ async getAllConfigsForAssistant(tenantId, ownerAssistantId) {
2064
+ await this.ensureInitialized();
2065
+ const result = await this.pool.query(
2066
+ `
2067
+ SELECT id, tenant_id, owner_assistant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at
2068
+ FROM lattice_personal_mcp_server_configs
2069
+ WHERE tenant_id = $1 AND owner_assistant_id = $2
2070
+ ORDER BY created_at DESC
2071
+ `,
2072
+ [tenantId, ownerAssistantId]
2073
+ );
2074
+ return result.rows.map((row) => this.mapPersonalRowToEntry(row));
2075
+ }
2076
+ /**
2077
+ * Get every personal MCP server configuration across tenants.
2078
+ *
2079
+ * Operations/tests only; startup restoration must not call this.
2080
+ */
2081
+ async getAllPersonalConfigsWithoutTenant() {
2082
+ await this.ensureInitialized();
2083
+ const result = await this.pool.query(
2084
+ `
2085
+ SELECT id, tenant_id, owner_assistant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at
2086
+ FROM lattice_personal_mcp_server_configs
2087
+ ORDER BY created_at DESC
2088
+ `
2089
+ );
2090
+ return result.rows.map((row) => this.mapPersonalRowToEntry(row));
2091
+ }
2092
+ /**
2093
+ * Get one personal MCP server configuration by id.
2094
+ */
2095
+ async getConfigByIdForAssistant(tenantId, ownerAssistantId, id) {
2096
+ await this.ensureInitialized();
2097
+ const result = await this.pool.query(
2098
+ `
2099
+ SELECT id, tenant_id, owner_assistant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at
2100
+ FROM lattice_personal_mcp_server_configs
2101
+ WHERE tenant_id = $1 AND owner_assistant_id = $2 AND id = $3
2102
+ `,
2103
+ [tenantId, ownerAssistantId, id]
2104
+ );
2105
+ if (result.rows.length === 0) {
2106
+ return null;
2107
+ }
2108
+ return this.mapPersonalRowToEntry(result.rows[0]);
2109
+ }
2110
+ /**
2111
+ * Get one personal MCP server configuration by business key.
2112
+ */
2113
+ async getConfigByKeyForAssistant(tenantId, ownerAssistantId, key) {
2114
+ await this.ensureInitialized();
2115
+ const result = await this.pool.query(
2116
+ `
2117
+ SELECT id, tenant_id, owner_assistant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at
2118
+ FROM lattice_personal_mcp_server_configs
2119
+ WHERE tenant_id = $1 AND owner_assistant_id = $2 AND key = $3
2120
+ `,
2121
+ [tenantId, ownerAssistantId, key]
2122
+ );
2123
+ if (result.rows.length === 0) {
2124
+ return null;
2125
+ }
2126
+ return this.mapPersonalRowToEntry(result.rows[0]);
2127
+ }
2128
+ /**
2129
+ * Create a personal MCP server configuration.
2130
+ */
2131
+ async createConfigForAssistant(tenantId, ownerAssistantId, id, data) {
2132
+ await this.ensureInitialized();
2133
+ const now = /* @__PURE__ */ new Date();
2134
+ const nowString = now.toISOString();
2135
+ const { config: configWithEncryptedEnv, isEnvEncrypted } = this.encryptEnvInConfig(data.config);
2136
+ await this.pool.query(
2137
+ `
2138
+ INSERT INTO lattice_personal_mcp_server_configs (id, tenant_id, owner_assistant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at)
2139
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11::timestamp, $12::timestamp)
2140
+ ON CONFLICT (tenant_id, owner_assistant_id, id) DO UPDATE SET
2141
+ key = EXCLUDED.key,
2142
+ name = EXCLUDED.name,
2143
+ description = EXCLUDED.description,
2144
+ config = EXCLUDED.config,
2145
+ selected_tools = EXCLUDED.selected_tools,
2146
+ is_env_encrypted = EXCLUDED.is_env_encrypted,
2147
+ status = EXCLUDED.status,
2148
+ updated_at = EXCLUDED.updated_at
2149
+ `,
2150
+ [
2151
+ id,
2152
+ tenantId,
2153
+ ownerAssistantId,
2154
+ data.key,
2155
+ data.name || null,
2156
+ data.description || null,
2157
+ JSON.stringify(configWithEncryptedEnv),
2158
+ JSON.stringify(data.selectedTools || []),
2159
+ isEnvEncrypted,
2160
+ "disconnected",
2161
+ nowString,
2162
+ nowString
2163
+ ]
2164
+ );
2165
+ return {
2166
+ id,
2167
+ tenantId,
2168
+ ownerAssistantId,
2169
+ key: data.key,
2170
+ config: data.config,
2171
+ selectedTools: data.selectedTools || [],
2172
+ isEnvEncrypted,
2173
+ status: "disconnected",
2174
+ name: data.name,
2175
+ description: data.description,
2176
+ createdAt: now,
2177
+ updatedAt: now
2178
+ };
2179
+ }
2180
+ /**
2181
+ * Update a personal MCP server configuration.
2182
+ */
2183
+ async updateConfigForAssistant(tenantId, ownerAssistantId, id, updates) {
2184
+ await this.ensureInitialized();
2185
+ const existing = await this.getConfigByIdForAssistant(
2186
+ tenantId,
2187
+ ownerAssistantId,
2188
+ id
2189
+ );
2190
+ if (!existing) {
2191
+ return null;
2192
+ }
2193
+ const updateData = {};
2194
+ if (updates.key !== void 0) {
2195
+ updateData.key = updates.key;
2196
+ }
2197
+ if (updates.name !== void 0) {
2198
+ updateData.name = updates.name || null;
2199
+ }
2200
+ if (updates.description !== void 0) {
2201
+ updateData.description = updates.description || null;
2202
+ }
2203
+ if (updates.config !== void 0) {
2204
+ const { config: configWithEncryptedEnv, isEnvEncrypted } = this.encryptEnvInConfig(updates.config);
2205
+ updateData.config = JSON.stringify(configWithEncryptedEnv);
2206
+ updateData.is_env_encrypted = isEnvEncrypted;
2207
+ }
2208
+ if (updates.selectedTools !== void 0) {
2209
+ updateData.selected_tools = JSON.stringify(updates.selectedTools);
2210
+ }
2211
+ if (updates.status !== void 0) {
2212
+ updateData.status = updates.status;
2213
+ }
2214
+ if (Object.keys(updateData).length === 0) {
2215
+ return existing;
2216
+ }
2217
+ updateData.updated_at = (/* @__PURE__ */ new Date()).toISOString();
2218
+ const fields = Object.keys(updateData);
2219
+ const values = Object.values(updateData);
2220
+ values.push(tenantId);
2221
+ values.push(ownerAssistantId);
2222
+ values.push(id);
2223
+ const setClauses = fields.map((field, index) => {
2224
+ if (field === "updated_at") {
2225
+ return `${field} = $${index + 1}::timestamp`;
2226
+ }
2227
+ return `${field} = $${index + 1}`;
2228
+ });
2229
+ const whereTenantIndex = fields.length + 1;
2230
+ const whereOwnerIndex = fields.length + 2;
2231
+ const whereIdIndex = fields.length + 3;
2232
+ const sql = `
2233
+ UPDATE lattice_personal_mcp_server_configs
2234
+ SET ${setClauses.join(", ")}
2235
+ WHERE tenant_id = $${whereTenantIndex}
2236
+ AND owner_assistant_id = $${whereOwnerIndex}
2237
+ AND id = $${whereIdIndex}
2238
+ `;
2239
+ await this.pool.query(sql, values);
2240
+ return this.getConfigByIdForAssistant(tenantId, ownerAssistantId, id);
2241
+ }
2242
+ /**
2243
+ * Delete one personal MCP server configuration by id.
2244
+ */
2245
+ async deleteConfigForAssistant(tenantId, ownerAssistantId, id) {
2246
+ await this.ensureInitialized();
2247
+ const result = await this.pool.query(
2248
+ `
2249
+ DELETE FROM lattice_personal_mcp_server_configs
2250
+ WHERE tenant_id = $1 AND owner_assistant_id = $2 AND id = $3
2251
+ `,
2252
+ [tenantId, ownerAssistantId, id]
2253
+ );
2254
+ return result.rowCount !== null && result.rowCount > 0;
2255
+ }
2256
+ /**
2257
+ * Delete every personal MCP server configuration owned by one assistant.
2258
+ */
2259
+ async deleteConfigsForAssistant(tenantId, ownerAssistantId) {
2260
+ await this.ensureInitialized();
2261
+ const result = await this.pool.query(
2262
+ `
2263
+ DELETE FROM lattice_personal_mcp_server_configs
2264
+ WHERE tenant_id = $1 AND owner_assistant_id = $2
2265
+ `,
2266
+ [tenantId, ownerAssistantId]
2267
+ );
2268
+ return result.rowCount ?? 0;
2269
+ }
2270
+ /**
2271
+ * Check whether a personal MCP server configuration exists.
2272
+ */
2273
+ async hasConfigForAssistant(tenantId, ownerAssistantId, id) {
2274
+ await this.ensureInitialized();
2275
+ const result = await this.pool.query(
2276
+ `
2277
+ SELECT 1 FROM lattice_personal_mcp_server_configs
2278
+ WHERE tenant_id = $1 AND owner_assistant_id = $2 AND id = $3
2279
+ LIMIT 1
2280
+ `,
2281
+ [tenantId, ownerAssistantId, id]
2282
+ );
2283
+ return result.rows.length > 0;
2284
+ }
2022
2285
  /**
2023
2286
  * Dispose resources and close the connection pool
2024
2287
  */
@@ -2069,6 +2332,15 @@ var PostgreSQLMcpServerConfigStore = class {
2069
2332
  updatedAt: row.updated_at
2070
2333
  };
2071
2334
  }
2335
+ /**
2336
+ * Map a personal table row, tagging the owning assistant.
2337
+ */
2338
+ mapPersonalRowToEntry(row) {
2339
+ return {
2340
+ ...this.mapRowToEntry(row),
2341
+ ownerAssistantId: row.owner_assistant_id
2342
+ };
2343
+ }
2072
2344
  /**
2073
2345
  * Encrypt env values in config before storing
2074
2346
  */
@@ -3262,6 +3534,9 @@ var PostgreSQLTenantStore = class {
3262
3534
 
3263
3535
  // src/stores/PostgreSQLUserTenantLinkStore.ts
3264
3536
  import { Pool as Pool10 } from "pg";
3537
+ import {
3538
+ assertNotPlatformTenant
3539
+ } from "@axiom-lattice/protocols";
3265
3540
 
3266
3541
  // src/migrations/user_tenant_link_migrations.ts
3267
3542
  var createUserTenantLinkTable = {
@@ -3420,6 +3695,7 @@ var PostgreSQLUserTenantLinkStore = class {
3420
3695
  return this.mapRowToLink(result.rows[0]);
3421
3696
  }
3422
3697
  async createLink(data) {
3698
+ assertNotPlatformTenant(data.tenantId);
3423
3699
  await this.ensureInitialized();
3424
3700
  const now = /* @__PURE__ */ new Date();
3425
3701
  const role = data.role || "member";
@@ -11015,6 +11291,49 @@ var addOidcProviderAllowedHosts = {
11015
11291
  }
11016
11292
  };
11017
11293
 
11294
+ // src/migrations/platform_audit_migration.ts
11295
+ var createPlatformAuditTable = {
11296
+ version: 219,
11297
+ name: "create_platform_audit_table",
11298
+ up: async (client) => {
11299
+ await client.query(`
11300
+ CREATE TABLE IF NOT EXISTS lattice_platform_audit (
11301
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
11302
+ initiator_user_id VARCHAR(255),
11303
+ initiator_role VARCHAR(16),
11304
+ initiator JSONB NOT NULL,
11305
+ source VARCHAR(32) NOT NULL,
11306
+ executor JSONB NOT NULL,
11307
+ tenant_id VARCHAR(255),
11308
+ action VARCHAR(16) NOT NULL,
11309
+ status VARCHAR(16) NOT NULL,
11310
+ summary JSONB NOT NULL,
11311
+ before JSONB,
11312
+ after JSONB,
11313
+ error_code VARCHAR(64),
11314
+ duration_ms INTEGER NOT NULL,
11315
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
11316
+ )
11317
+ `);
11318
+ await client.query(`
11319
+ CREATE INDEX IF NOT EXISTS idx_lattice_platform_audit_created
11320
+ ON lattice_platform_audit(created_at DESC, id DESC)
11321
+ `);
11322
+ await client.query(`
11323
+ CREATE INDEX IF NOT EXISTS idx_lattice_platform_audit_initiator
11324
+ ON lattice_platform_audit(initiator_user_id, created_at DESC)
11325
+ `);
11326
+ await client.query(`
11327
+ CREATE INDEX IF NOT EXISTS idx_lattice_platform_audit_tenant
11328
+ ON lattice_platform_audit(tenant_id, created_at DESC)
11329
+ WHERE tenant_id IS NOT NULL
11330
+ `);
11331
+ },
11332
+ down: async (client) => {
11333
+ await client.query("DROP TABLE IF EXISTS lattice_platform_audit");
11334
+ }
11335
+ };
11336
+
11018
11337
  // src/migrations/collection_migrations.ts
11019
11338
  var createCollectionsTable = {
11020
11339
  version: 137,
@@ -14739,6 +15058,146 @@ var PostgreSQLPlatformSettingsStore = class {
14739
15058
  }
14740
15059
  };
14741
15060
 
15061
+ // src/stores/PostgreSQLPlatformAuditStore.ts
15062
+ var TABLE8 = "lattice_platform_audit";
15063
+ function parseJson(value) {
15064
+ return typeof value === "string" ? JSON.parse(value) : value;
15065
+ }
15066
+ function normalizeBoundary(value) {
15067
+ if (value === void 0) return void 0;
15068
+ const trimmed = value.trim();
15069
+ if (trimmed === "") return void 0;
15070
+ const parsed = new Date(trimmed);
15071
+ if (Number.isNaN(parsed.getTime())) return void 0;
15072
+ return parsed.toISOString();
15073
+ }
15074
+ function normalizePagination(value, fallback) {
15075
+ if (value === void 0 || !Number.isFinite(value)) return fallback;
15076
+ return Math.max(0, Math.trunc(value));
15077
+ }
15078
+ function mapRow16(row) {
15079
+ return {
15080
+ id: row.id,
15081
+ initiator: parseJson(row.initiator),
15082
+ source: row.source,
15083
+ executor: parseJson(row.executor),
15084
+ ...row.tenant_id !== null ? { tenantId: row.tenant_id } : {},
15085
+ action: row.action,
15086
+ status: row.status,
15087
+ summary: parseJson(row.summary),
15088
+ ...row.before !== null ? { before: parseJson(row.before) } : {},
15089
+ ...row.after !== null ? { after: parseJson(row.after) } : {},
15090
+ ...row.error_code !== null ? { errorCode: row.error_code } : {},
15091
+ durationMs: Number(row.duration_ms),
15092
+ createdAt: row.created_at
15093
+ };
15094
+ }
15095
+ var PostgreSQLPlatformAuditStore = class {
15096
+ constructor(options) {
15097
+ this.options = options;
15098
+ }
15099
+ get pool() {
15100
+ return this.options.pool;
15101
+ }
15102
+ /** Appends a record, assigning a fresh id and creation timestamp. */
15103
+ async append(record) {
15104
+ const initiator = record.initiator;
15105
+ const initiatorUserId = initiator.type === "human" ? initiator.userId : null;
15106
+ const initiatorRole = initiator.type === "human" ? initiator.role : null;
15107
+ const durationMs = Number.isFinite(record.durationMs) ? Math.max(0, Math.round(record.durationMs)) : 0;
15108
+ const result = await this.pool.query(
15109
+ `INSERT INTO ${TABLE8}
15110
+ (initiator_user_id, initiator_role, initiator, source, executor,
15111
+ tenant_id, action, status, summary, before, after, error_code,
15112
+ duration_ms)
15113
+ VALUES ($1,$2,$3::jsonb,$4,$5::jsonb,$6,$7,$8,$9::jsonb,$10::jsonb,
15114
+ $11::jsonb,$12,$13)
15115
+ RETURNING *`,
15116
+ [
15117
+ initiatorUserId,
15118
+ initiatorRole,
15119
+ JSON.stringify(initiator),
15120
+ record.source,
15121
+ JSON.stringify(record.executor),
15122
+ record.tenantId ?? null,
15123
+ record.action,
15124
+ record.status,
15125
+ JSON.stringify(record.summary),
15126
+ record.before === void 0 ? null : JSON.stringify(record.before),
15127
+ record.after === void 0 ? null : JSON.stringify(record.after),
15128
+ record.errorCode ?? null,
15129
+ durationMs
15130
+ ]
15131
+ );
15132
+ const row = result.rows[0];
15133
+ if (!row) throw new Error("Platform audit record was not persisted");
15134
+ return mapRow16(row);
15135
+ }
15136
+ /** Returns a record by id, or null when it does not exist. */
15137
+ async get(id) {
15138
+ const result = await this.pool.query(
15139
+ `SELECT * FROM ${TABLE8} WHERE id = $1`,
15140
+ [id]
15141
+ );
15142
+ return result.rows[0] ? mapRow16(result.rows[0]) : null;
15143
+ }
15144
+ /**
15145
+ * Returns matching records newest-first.
15146
+ *
15147
+ * `initiatorUserId` only matches human initiators. `from` is inclusive and
15148
+ * `to` is exclusive after both are normalized to instants; invalid or empty
15149
+ * boundaries are ignored. Records are ordered by `createdAt` descending,
15150
+ * then by `id` descending. Results are paginated with a default limit of 100;
15151
+ * non-finite `offset`/`limit` fall back to defaults, finite values are
15152
+ * truncated to integers, and negatives are clamped to 0.
15153
+ */
15154
+ async query(params) {
15155
+ const clauses = [];
15156
+ const values = [];
15157
+ if (params.initiatorUserId !== void 0) {
15158
+ values.push(params.initiatorUserId);
15159
+ clauses.push(`initiator_user_id = $${values.length}`);
15160
+ }
15161
+ if (params.source !== void 0) {
15162
+ values.push(params.source);
15163
+ clauses.push(`source = $${values.length}`);
15164
+ }
15165
+ if (params.tenantId !== void 0) {
15166
+ values.push(params.tenantId);
15167
+ clauses.push(`tenant_id = $${values.length}`);
15168
+ }
15169
+ if (params.action !== void 0) {
15170
+ values.push(params.action);
15171
+ clauses.push(`action = $${values.length}`);
15172
+ }
15173
+ if (params.status !== void 0) {
15174
+ values.push(params.status);
15175
+ clauses.push(`status = $${values.length}`);
15176
+ }
15177
+ const from = normalizeBoundary(params.from);
15178
+ if (from !== void 0) {
15179
+ values.push(from);
15180
+ clauses.push(`created_at >= $${values.length}`);
15181
+ }
15182
+ const to = normalizeBoundary(params.to);
15183
+ if (to !== void 0) {
15184
+ values.push(to);
15185
+ clauses.push(`created_at < $${values.length}`);
15186
+ }
15187
+ const limit = normalizePagination(params.limit, 100);
15188
+ const offset = normalizePagination(params.offset, 0);
15189
+ values.push(limit, offset);
15190
+ const where = clauses.length > 0 ? ` WHERE ${clauses.join(" AND ")}` : "";
15191
+ const { rows } = await this.pool.query(
15192
+ `SELECT * FROM ${TABLE8}${where}
15193
+ ORDER BY created_at DESC, id DESC
15194
+ LIMIT $${values.length - 1} OFFSET $${values.length}`,
15195
+ values
15196
+ );
15197
+ return rows.map(mapRow16);
15198
+ }
15199
+ };
15200
+
14742
15201
  // src/stores/PostgreSQLChannelReplyJobStore.ts
14743
15202
  import { Pool as Pool31 } from "pg";
14744
15203
  import {
@@ -14764,7 +15223,7 @@ function toStatus(value) {
14764
15223
  }
14765
15224
  throw new Error(`Invalid channel reply job status: ${value}`);
14766
15225
  }
14767
- function mapRow16(row) {
15226
+ function mapRow17(row) {
14768
15227
  return {
14769
15228
  runId: row.run_id,
14770
15229
  tenantId: row.tenant_id,
@@ -14864,7 +15323,7 @@ var PostgreSQLChannelReplyJobStore = class {
14864
15323
  input.availableAt
14865
15324
  ]
14866
15325
  );
14867
- return mapRow16(result.rows[0]);
15326
+ return mapRow17(result.rows[0]);
14868
15327
  }
14869
15328
  /** Reads one job within a tenant scope. */
14870
15329
  async get(tenantId, runId) {
@@ -14874,7 +15333,7 @@ var PostgreSQLChannelReplyJobStore = class {
14874
15333
  WHERE tenant_id = $1 AND run_id = $2`,
14875
15334
  [tenantId, runId]
14876
15335
  );
14877
- return result.rowCount === 0 ? null : mapRow16(result.rows[0]);
15336
+ return result.rowCount === 0 ? null : mapRow17(result.rows[0]);
14878
15337
  }
14879
15338
  /** Lists claimable pending jobs that are due at `now`, oldest first. */
14880
15339
  async listPending(now, limit) {
@@ -14888,7 +15347,7 @@ var PostgreSQLChannelReplyJobStore = class {
14888
15347
  LIMIT $2`,
14889
15348
  [now, normalizeChannelReplyJobListLimit(limit)]
14890
15349
  );
14891
- return result.rows.map(mapRow16);
15350
+ return result.rows.map(mapRow17);
14892
15351
  }
14893
15352
  /**
14894
15353
  * Atomically leases a claimable job.
@@ -14912,7 +15371,7 @@ var PostgreSQLChannelReplyJobStore = class {
14912
15371
  RETURNING ${COLUMNS2}`,
14913
15372
  [tenantId, runId, owner, leaseMs]
14914
15373
  );
14915
- return result.rowCount === 0 ? null : mapRow16(result.rows[0]);
15374
+ return result.rowCount === 0 ? null : mapRow17(result.rows[0]);
14916
15375
  }
14917
15376
  /**
14918
15377
  * Marks a job delivered when `owner` still holds the lease.
@@ -14938,7 +15397,7 @@ var PostgreSQLChannelReplyJobStore = class {
14938
15397
  RETURNING ${COLUMNS2}`,
14939
15398
  [tenantId, runId, owner, outputMessageId]
14940
15399
  );
14941
- return result.rowCount === 0 ? null : mapRow16(result.rows[0]);
15400
+ return result.rowCount === 0 ? null : mapRow17(result.rows[0]);
14942
15401
  }
14943
15402
  /**
14944
15403
  * Returns a job to pending with an incremented attempt count.
@@ -14965,7 +15424,7 @@ var PostgreSQLChannelReplyJobStore = class {
14965
15424
  RETURNING ${COLUMNS2}`,
14966
15425
  [tenantId, runId, owner, error, availableAt]
14967
15426
  );
14968
- return result.rowCount === 0 ? null : mapRow16(result.rows[0]);
15427
+ return result.rowCount === 0 ? null : mapRow17(result.rows[0]);
14969
15428
  }
14970
15429
  /**
14971
15430
  * Marks a job terminally failed when `owner` still holds the lease.
@@ -14990,7 +15449,7 @@ var PostgreSQLChannelReplyJobStore = class {
14990
15449
  RETURNING ${COLUMNS2}`,
14991
15450
  [tenantId, runId, owner, error]
14992
15451
  );
14993
- return result.rowCount === 0 ? null : mapRow16(result.rows[0]);
15452
+ return result.rowCount === 0 ? null : mapRow17(result.rows[0]);
14994
15453
  }
14995
15454
  /** Deletes one job. Returns whether a row was removed. */
14996
15455
  async delete(tenantId, runId) {
@@ -15472,7 +15931,7 @@ import {
15472
15931
  storeExpiresAt,
15473
15932
  storePaginationValue
15474
15933
  } from "@axiom-lattice/protocols";
15475
- function mapRow17(row) {
15934
+ function mapRow18(row) {
15476
15935
  return {
15477
15936
  namespace: row.namespace,
15478
15937
  key: row.key,
@@ -15504,7 +15963,7 @@ var PostgreSQLStore = class {
15504
15963
  RETURNING tenant_id, namespace, key, value, created_at, updated_at, expires_at`,
15505
15964
  [tenantId, input.namespace, input.key, JSON.stringify(input.value), now, expiresAt]
15506
15965
  );
15507
- return mapRow17(result.rows[0]);
15966
+ return mapRow18(result.rows[0]);
15508
15967
  }
15509
15968
  async get(tenantId, namespace, key) {
15510
15969
  assertStoreIdentity(namespace, key);
@@ -15515,7 +15974,7 @@ var PostgreSQLStore = class {
15515
15974
  AND (expires_at IS NULL OR expires_at > $4)`,
15516
15975
  [tenantId, namespace, key, /* @__PURE__ */ new Date()]
15517
15976
  );
15518
- return result.rows[0] ? mapRow17(result.rows[0]) : null;
15977
+ return result.rows[0] ? mapRow18(result.rows[0]) : null;
15519
15978
  }
15520
15979
  async delete(tenantId, namespace, key) {
15521
15980
  assertStoreIdentity(namespace, key);
@@ -15559,7 +16018,7 @@ var PostgreSQLStore = class {
15559
16018
  LIMIT $${limitParam} OFFSET $${offsetParam}`,
15560
16019
  params
15561
16020
  );
15562
- return result.rows.map(mapRow17);
16021
+ return result.rows.map(mapRow18);
15563
16022
  }
15564
16023
  async listNamespaces(tenantId, prefix = [], limit = 100) {
15565
16024
  assertStoreNamespacePrefix(prefix);
@@ -15740,6 +16199,8 @@ async function createPgStoreConfig(connectionString) {
15740
16199
  mm.register(addOidcIdentityClaimInviteFields);
15741
16200
  mm.register(createPlatformSettingsTable);
15742
16201
  mm.register(addOidcProviderAllowedHosts);
16202
+ mm.register(createPlatformAuditTable);
16203
+ mm.register(createPersonalMcpServerConfigsTable);
15743
16204
  await mm.migrate();
15744
16205
  const checkpoint = PostgresSaver.fromConnString(connectionString);
15745
16206
  try {
@@ -15763,6 +16224,7 @@ async function createPgStoreConfig(connectionString) {
15763
16224
  oidcIdentityClaim: new PostgreSQLOidcIdentityClaimStore(opts),
15764
16225
  inviteLink: new PostgreSQLInviteLinkStore(opts),
15765
16226
  platformSettings: new PostgreSQLPlatformSettingsStore(opts),
16227
+ platformAudit: new PostgreSQLPlatformAuditStore(opts),
15766
16228
  channelBinding: new ChannelBindingStore(opts),
15767
16229
  channelInstallation: new PostgreSQLChannelInstallationStore(opts),
15768
16230
  thread: new PostgreSQLThreadStore(opts),
@@ -16383,6 +16845,7 @@ export {
16383
16845
  PostgreSQLOidcIdentityClaimStore,
16384
16846
  PostgreSQLOidcProviderConfigStore,
16385
16847
  PostgreSQLOpenAuditStore,
16848
+ PostgreSQLPlatformAuditStore,
16386
16849
  PostgreSQLPlatformInvitationStore,
16387
16850
  PostgreSQLPlatformMemberStore,
16388
16851
  PostgreSQLPlatformSettingsStore,
@@ -16454,7 +16917,9 @@ export {
16454
16917
  createOidcIdentityClaimsTable,
16455
16918
  createOidcProviderConfigsTable,
16456
16919
  createPGVectorStoreProvider,
16920
+ createPersonalMcpServerConfigsTable,
16457
16921
  createPgStoreConfig,
16922
+ createPlatformAuditTable,
16458
16923
  createPlatformInvitationsTable,
16459
16924
  createPlatformMembersTable,
16460
16925
  createPlatformSettingsTable,