@mastra/pg 1.4.0 → 1.5.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.cjs CHANGED
@@ -3232,6 +3232,11 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3232
3232
  schema: storage.TABLE_SCHEMAS[storage.TABLE_AGENTS],
3233
3233
  ifNotExists: ["status", "authorId"]
3234
3234
  });
3235
+ await this.#db.alterTable({
3236
+ tableName: storage.TABLE_AGENT_VERSIONS,
3237
+ schema: storage.TABLE_SCHEMAS[storage.TABLE_AGENT_VERSIONS],
3238
+ ifNotExists: ["mcpClients", "requestContextSchema", "workspace", "skills", "skillsFormat"]
3239
+ });
3235
3240
  await this.#migrateToolsToJsonbFormat();
3236
3241
  await this.createDefaultIndexes();
3237
3242
  await this.createCustomIndexes();
@@ -3537,68 +3542,7 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3537
3542
  details: { agentId: id }
3538
3543
  });
3539
3544
  }
3540
- const { authorId, activeVersionId, metadata, ...configFields } = updates;
3541
- const configFieldNames = [
3542
- "name",
3543
- "description",
3544
- "instructions",
3545
- "model",
3546
- "tools",
3547
- "defaultOptions",
3548
- "workflows",
3549
- "agents",
3550
- "integrationTools",
3551
- "inputProcessors",
3552
- "outputProcessors",
3553
- "memory",
3554
- "scorers",
3555
- "mcpClients",
3556
- "requestContextSchema"
3557
- ];
3558
- const hasConfigUpdate = configFieldNames.some((field) => field in configFields);
3559
- if (hasConfigUpdate) {
3560
- const latestVersion = await this.getLatestVersion(id);
3561
- if (!latestVersion) {
3562
- throw new error.MastraError({
3563
- id: storage.createStorageErrorId("PG", "UPDATE_AGENT", "NO_VERSIONS"),
3564
- domain: error.ErrorDomain.STORAGE,
3565
- category: error.ErrorCategory.SYSTEM,
3566
- text: `No versions found for agent ${id}`,
3567
- details: { agentId: id }
3568
- });
3569
- }
3570
- const {
3571
- id: _versionId,
3572
- agentId: _agentId,
3573
- versionNumber: _versionNumber,
3574
- changedFields: _changedFields,
3575
- changeMessage: _changeMessage,
3576
- createdAt: _createdAt,
3577
- ...latestConfig
3578
- } = latestVersion;
3579
- const sanitizedConfigFields = Object.fromEntries(
3580
- Object.entries(configFields).map(([key, value]) => [key, value === null ? void 0 : value])
3581
- );
3582
- const newConfig = {
3583
- ...latestConfig,
3584
- ...sanitizedConfigFields
3585
- };
3586
- const changedFields = configFieldNames.filter(
3587
- (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
3588
- );
3589
- if (changedFields.length > 0) {
3590
- const newVersionId = crypto.randomUUID();
3591
- const newVersionNumber = latestVersion.versionNumber + 1;
3592
- await this.createVersion({
3593
- id: newVersionId,
3594
- agentId: id,
3595
- versionNumber: newVersionNumber,
3596
- ...newConfig,
3597
- changedFields,
3598
- changeMessage: `Updated ${changedFields.join(", ")}`
3599
- });
3600
- }
3601
- }
3545
+ const { authorId, activeVersionId, metadata, status } = updates;
3602
3546
  const setClauses = [];
3603
3547
  const values = [];
3604
3548
  let paramIndex = 1;
@@ -3610,6 +3554,10 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3610
3554
  setClauses.push(`"activeVersionId" = $${paramIndex++}`);
3611
3555
  values.push(activeVersionId);
3612
3556
  }
3557
+ if (status !== void 0) {
3558
+ setClauses.push(`status = $${paramIndex++}`);
3559
+ values.push(status);
3560
+ }
3613
3561
  if (metadata !== void 0) {
3614
3562
  setClauses.push(`metadata = $${paramIndex++}`);
3615
3563
  values.push(JSON.stringify(metadata));
@@ -3620,12 +3568,7 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3620
3568
  setClauses.push(`"updatedAtZ" = $${paramIndex++}`);
3621
3569
  values.push(now);
3622
3570
  values.push(id);
3623
- if (setClauses.length > 2) {
3624
- await this.#db.client.none(
3625
- `UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`,
3626
- values
3627
- );
3628
- }
3571
+ await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
3629
3572
  const updatedAgent = await this.getById(id);
3630
3573
  if (!updatedAgent) {
3631
3574
  throw new error.MastraError({
@@ -3671,7 +3614,7 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3671
3614
  }
3672
3615
  }
3673
3616
  async list(args) {
3674
- const { page = 0, perPage: perPageInput, orderBy } = args || {};
3617
+ const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};
3675
3618
  const { field, direction } = this.parseOrderBy(orderBy);
3676
3619
  if (page < 0) {
3677
3620
  throw new error.MastraError(
@@ -3688,7 +3631,26 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3688
3631
  const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
3689
3632
  try {
3690
3633
  const tableName = getTableName2({ indexName: storage.TABLE_AGENTS, schemaName: getSchemaName2(this.#schema) });
3691
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName}`);
3634
+ const conditions = [];
3635
+ const queryParams = [];
3636
+ let paramIdx = 1;
3637
+ if (status) {
3638
+ conditions.push(`status = $${paramIdx++}`);
3639
+ queryParams.push(status);
3640
+ }
3641
+ if (authorId !== void 0) {
3642
+ conditions.push(`"authorId" = $${paramIdx++}`);
3643
+ queryParams.push(authorId);
3644
+ }
3645
+ if (metadata && Object.keys(metadata).length > 0) {
3646
+ conditions.push(`metadata @> $${paramIdx++}::jsonb`);
3647
+ queryParams.push(JSON.stringify(metadata));
3648
+ }
3649
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
3650
+ const countResult = await this.#db.client.one(
3651
+ `SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`,
3652
+ queryParams
3653
+ );
3692
3654
  const total = parseInt(countResult.count, 10);
3693
3655
  if (total === 0) {
3694
3656
  return {
@@ -3701,8 +3663,8 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3701
3663
  }
3702
3664
  const limitValue = perPageInput === false ? total : perPage;
3703
3665
  const dataResult = await this.#db.client.manyOrNone(
3704
- `SELECT * FROM ${tableName} ORDER BY "${field}" ${direction} LIMIT $1 OFFSET $2`,
3705
- [limitValue, offset]
3666
+ `SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`,
3667
+ [...queryParams, limitValue, offset]
3706
3668
  );
3707
3669
  const agents = (dataResult || []).map((row) => this.parseRow(row));
3708
3670
  return {
@@ -3738,9 +3700,10 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3738
3700
  name, description, instructions, model, tools,
3739
3701
  "defaultOptions", workflows, agents, "integrationTools",
3740
3702
  "inputProcessors", "outputProcessors", memory, scorers,
3741
- "mcpClients", "requestContextSchema", "changedFields", "changeMessage",
3703
+ "mcpClients", "requestContextSchema", workspace, skills, "skillsFormat",
3704
+ "changedFields", "changeMessage",
3742
3705
  "createdAt", "createdAtZ"
3743
- ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22)`,
3706
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25)`,
3744
3707
  [
3745
3708
  input.id,
3746
3709
  input.agentId,
@@ -3760,6 +3723,9 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3760
3723
  input.scorers ? JSON.stringify(input.scorers) : null,
3761
3724
  input.mcpClients ? JSON.stringify(input.mcpClients) : null,
3762
3725
  input.requestContextSchema ? JSON.stringify(input.requestContextSchema) : null,
3726
+ input.workspace ? JSON.stringify(input.workspace) : null,
3727
+ input.skills ? JSON.stringify(input.skills) : null,
3728
+ input.skillsFormat ?? null,
3763
3729
  input.changedFields ? JSON.stringify(input.changedFields) : null,
3764
3730
  input.changeMessage ?? null,
3765
3731
  nowIso,
@@ -3999,12 +3965,92 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3999
3965
  scorers: this.parseJson(row.scorers, "scorers"),
4000
3966
  mcpClients: this.parseJson(row.mcpClients, "mcpClients"),
4001
3967
  requestContextSchema: this.parseJson(row.requestContextSchema, "requestContextSchema"),
3968
+ workspace: this.parseJson(row.workspace, "workspace"),
3969
+ skills: this.parseJson(row.skills, "skills"),
3970
+ skillsFormat: row.skillsFormat,
4002
3971
  changedFields: this.parseJson(row.changedFields, "changedFields"),
4003
3972
  changeMessage: row.changeMessage,
4004
3973
  createdAt: row.createdAtZ || row.createdAt
4005
3974
  };
4006
3975
  }
4007
3976
  };
3977
+ var BlobsPG = class extends storage.BlobStore {
3978
+ #db;
3979
+ #schema;
3980
+ static MANAGED_TABLES = [storage.TABLE_SKILL_BLOBS];
3981
+ constructor(config) {
3982
+ super();
3983
+ const { client, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
3984
+ this.#db = new PgDB({ client, schemaName, skipDefaultIndexes });
3985
+ this.#schema = schemaName || "public";
3986
+ }
3987
+ async init() {
3988
+ await this.#db.createTable({
3989
+ tableName: storage.TABLE_SKILL_BLOBS,
3990
+ schema: storage.TABLE_SCHEMAS[storage.TABLE_SKILL_BLOBS]
3991
+ });
3992
+ }
3993
+ async put(entry) {
3994
+ const tableName = getTableName2({ indexName: storage.TABLE_SKILL_BLOBS, schemaName: getSchemaName2(this.#schema) });
3995
+ const now = entry.createdAt ?? /* @__PURE__ */ new Date();
3996
+ const nowIso = now.toISOString();
3997
+ await this.#db.client.none(
3998
+ `INSERT INTO ${tableName} ("hash", "content", "size", "mimeType", "createdAt", "createdAtZ")
3999
+ VALUES ($1, $2, $3, $4, $5, $6)
4000
+ ON CONFLICT ("hash") DO NOTHING`,
4001
+ [entry.hash, entry.content, entry.size, entry.mimeType ?? null, nowIso, nowIso]
4002
+ );
4003
+ }
4004
+ async get(hash) {
4005
+ const tableName = getTableName2({ indexName: storage.TABLE_SKILL_BLOBS, schemaName: getSchemaName2(this.#schema) });
4006
+ const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "hash" = $1`, [hash]);
4007
+ if (!row) return null;
4008
+ return this.#parseRow(row);
4009
+ }
4010
+ async has(hash) {
4011
+ const tableName = getTableName2({ indexName: storage.TABLE_SKILL_BLOBS, schemaName: getSchemaName2(this.#schema) });
4012
+ const row = await this.#db.client.oneOrNone(`SELECT 1 FROM ${tableName} WHERE "hash" = $1 LIMIT 1`, [hash]);
4013
+ return row !== null;
4014
+ }
4015
+ async delete(hash) {
4016
+ const tableName = getTableName2({ indexName: storage.TABLE_SKILL_BLOBS, schemaName: getSchemaName2(this.#schema) });
4017
+ const result = await this.#db.client.query(`DELETE FROM ${tableName} WHERE "hash" = $1`, [hash]);
4018
+ return (result.rowCount ?? 0) > 0;
4019
+ }
4020
+ async putMany(entries) {
4021
+ if (entries.length === 0) return;
4022
+ for (const entry of entries) {
4023
+ await this.put(entry);
4024
+ }
4025
+ }
4026
+ async getMany(hashes) {
4027
+ const result = /* @__PURE__ */ new Map();
4028
+ if (hashes.length === 0) return result;
4029
+ const tableName = getTableName2({ indexName: storage.TABLE_SKILL_BLOBS, schemaName: getSchemaName2(this.#schema) });
4030
+ const placeholders = hashes.map((_, i) => `$${i + 1}`).join(", ");
4031
+ const rows = await this.#db.client.manyOrNone(
4032
+ `SELECT * FROM ${tableName} WHERE "hash" IN (${placeholders})`,
4033
+ hashes
4034
+ );
4035
+ for (const row of rows) {
4036
+ const entry = this.#parseRow(row);
4037
+ result.set(entry.hash, entry);
4038
+ }
4039
+ return result;
4040
+ }
4041
+ async dangerouslyClearAll() {
4042
+ await this.#db.clearTable({ tableName: storage.TABLE_SKILL_BLOBS });
4043
+ }
4044
+ #parseRow(row) {
4045
+ return {
4046
+ hash: row.hash,
4047
+ content: row.content,
4048
+ size: Number(row.size),
4049
+ mimeType: row.mimeType || void 0,
4050
+ createdAt: new Date(row.createdAtZ || row.createdAt)
4051
+ };
4052
+ }
4053
+ };
4008
4054
  function jsonbArg(value) {
4009
4055
  return value === void 0 || value === null ? null : JSON.stringify(value);
4010
4056
  }
@@ -4167,8 +4213,8 @@ var DatasetsPG = class _DatasetsPG extends storage.DatasetsStorage {
4167
4213
  name: input.name,
4168
4214
  description: input.description,
4169
4215
  metadata: input.metadata,
4170
- inputSchema: input.inputSchema,
4171
- groundTruthSchema: input.groundTruthSchema,
4216
+ inputSchema: input.inputSchema ?? void 0,
4217
+ groundTruthSchema: input.groundTruthSchema ?? void 0,
4172
4218
  version: 0,
4173
4219
  createdAt: now,
4174
4220
  updatedAt: now
@@ -4246,8 +4292,8 @@ var DatasetsPG = class _DatasetsPG extends storage.DatasetsStorage {
4246
4292
  name: args.name ?? existing.name,
4247
4293
  description: args.description ?? existing.description,
4248
4294
  metadata: args.metadata ?? existing.metadata,
4249
- inputSchema: args.inputSchema !== void 0 ? args.inputSchema : existing.inputSchema,
4250
- groundTruthSchema: args.groundTruthSchema !== void 0 ? args.groundTruthSchema : existing.groundTruthSchema,
4295
+ inputSchema: (args.inputSchema !== void 0 ? args.inputSchema : existing.inputSchema) ?? void 0,
4296
+ groundTruthSchema: (args.groundTruthSchema !== void 0 ? args.groundTruthSchema : existing.groundTruthSchema) ?? void 0,
4251
4297
  updatedAt: new Date(now)
4252
4298
  };
4253
4299
  } catch (error$1) {
@@ -5496,46 +5542,7 @@ var MCPClientsPG = class _MCPClientsPG extends storage.MCPClientsStorage {
5496
5542
  details: { mcpClientId: id }
5497
5543
  });
5498
5544
  }
5499
- const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
5500
- let versionCreated = false;
5501
- const hasConfigUpdate = SNAPSHOT_FIELDS.some((field) => field in configFields);
5502
- if (hasConfigUpdate) {
5503
- const latestVersion = await this.getLatestVersion(id);
5504
- if (!latestVersion) {
5505
- throw new error.MastraError({
5506
- id: storage.createStorageErrorId("PG", "UPDATE_MCP_CLIENT", "NO_VERSIONS"),
5507
- domain: error.ErrorDomain.STORAGE,
5508
- category: error.ErrorCategory.SYSTEM,
5509
- text: `No versions found for MCP client ${id}`,
5510
- details: { mcpClientId: id }
5511
- });
5512
- }
5513
- const {
5514
- id: _versionId,
5515
- mcpClientId: _mcpClientId,
5516
- versionNumber: _versionNumber,
5517
- changedFields: _changedFields,
5518
- changeMessage: _changeMessage,
5519
- createdAt: _createdAt,
5520
- ...latestConfig
5521
- } = latestVersion;
5522
- const newConfig = { ...latestConfig, ...configFields };
5523
- const changedFields = SNAPSHOT_FIELDS.filter(
5524
- (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
5525
- );
5526
- if (changedFields.length > 0) {
5527
- versionCreated = true;
5528
- const newVersionId = crypto.randomUUID();
5529
- await this.createVersion({
5530
- id: newVersionId,
5531
- mcpClientId: id,
5532
- versionNumber: latestVersion.versionNumber + 1,
5533
- ...newConfig,
5534
- changedFields: [...changedFields],
5535
- changeMessage: `Updated ${changedFields.join(", ")}`
5536
- });
5537
- }
5538
- }
5545
+ const { authorId, activeVersionId, metadata, status } = updates;
5539
5546
  const setClauses = [];
5540
5547
  const values = [];
5541
5548
  let paramIndex = 1;
@@ -5546,10 +5553,6 @@ var MCPClientsPG = class _MCPClientsPG extends storage.MCPClientsStorage {
5546
5553
  if (activeVersionId !== void 0) {
5547
5554
  setClauses.push(`"activeVersionId" = $${paramIndex++}`);
5548
5555
  values.push(activeVersionId);
5549
- if (status === void 0) {
5550
- setClauses.push(`status = $${paramIndex++}`);
5551
- values.push("published");
5552
- }
5553
5556
  }
5554
5557
  if (status !== void 0) {
5555
5558
  setClauses.push(`status = $${paramIndex++}`);
@@ -5566,12 +5569,7 @@ var MCPClientsPG = class _MCPClientsPG extends storage.MCPClientsStorage {
5566
5569
  setClauses.push(`"updatedAtZ" = $${paramIndex++}`);
5567
5570
  values.push(now);
5568
5571
  values.push(id);
5569
- if (setClauses.length > 2 || versionCreated) {
5570
- await this.#db.client.none(
5571
- `UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`,
5572
- values
5573
- );
5574
- }
5572
+ await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
5575
5573
  const updatedClient = await this.getById(id);
5576
5574
  if (!updatedClient) {
5577
5575
  throw new error.MastraError({
@@ -5615,7 +5613,7 @@ var MCPClientsPG = class _MCPClientsPG extends storage.MCPClientsStorage {
5615
5613
  }
5616
5614
  }
5617
5615
  async list(args) {
5618
- const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};
5616
+ const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status = "published" } = args || {};
5619
5617
  const { field, direction } = this.parseOrderBy(orderBy);
5620
5618
  if (page < 0) {
5621
5619
  throw new error.MastraError(
@@ -5635,6 +5633,8 @@ var MCPClientsPG = class _MCPClientsPG extends storage.MCPClientsStorage {
5635
5633
  const conditions = [];
5636
5634
  const queryParams = [];
5637
5635
  let paramIdx = 1;
5636
+ conditions.push(`status = $${paramIdx++}`);
5637
+ queryParams.push(status);
5638
5638
  if (authorId !== void 0) {
5639
5639
  conditions.push(`"authorId" = $${paramIdx++}`);
5640
5640
  queryParams.push(authorId);
@@ -5643,7 +5643,7 @@ var MCPClientsPG = class _MCPClientsPG extends storage.MCPClientsStorage {
5643
5643
  conditions.push(`metadata @> $${paramIdx++}::jsonb`);
5644
5644
  queryParams.push(JSON.stringify(metadata));
5645
5645
  }
5646
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
5646
+ const whereClause = `WHERE ${conditions.join(" AND ")}`;
5647
5647
  const countResult = await this.#db.client.one(
5648
5648
  `SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`,
5649
5649
  queryParams
@@ -7193,7 +7193,7 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
7193
7193
  const newThread = {
7194
7194
  id: newThreadId,
7195
7195
  resourceId: resourceId || sourceThread.resourceId,
7196
- title: title || (sourceThread.title ? `Clone of ${sourceThread.title}` : void 0),
7196
+ title: title || (sourceThread.title ? `Clone of ${sourceThread.title}` : ""),
7197
7197
  metadata: {
7198
7198
  ...metadata,
7199
7199
  clone: cloneMetadata
@@ -8985,46 +8985,7 @@ var PromptBlocksPG = class _PromptBlocksPG extends storage.PromptBlocksStorage {
8985
8985
  details: { blockId: id }
8986
8986
  });
8987
8987
  }
8988
- const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
8989
- let versionCreated = false;
8990
- const hasConfigUpdate = SNAPSHOT_FIELDS2.some((field) => field in configFields);
8991
- if (hasConfigUpdate) {
8992
- const latestVersion = await this.getLatestVersion(id);
8993
- if (!latestVersion) {
8994
- throw new error.MastraError({
8995
- id: storage.createStorageErrorId("PG", "UPDATE_PROMPT_BLOCK", "NO_VERSIONS"),
8996
- domain: error.ErrorDomain.STORAGE,
8997
- category: error.ErrorCategory.SYSTEM,
8998
- text: `No versions found for prompt block ${id}`,
8999
- details: { blockId: id }
9000
- });
9001
- }
9002
- const {
9003
- id: _versionId,
9004
- blockId: _blockId,
9005
- versionNumber: _versionNumber,
9006
- changedFields: _changedFields,
9007
- changeMessage: _changeMessage,
9008
- createdAt: _createdAt,
9009
- ...latestConfig
9010
- } = latestVersion;
9011
- const newConfig = { ...latestConfig, ...configFields };
9012
- const changedFields = SNAPSHOT_FIELDS2.filter(
9013
- (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
9014
- );
9015
- if (changedFields.length > 0) {
9016
- versionCreated = true;
9017
- const newVersionId = crypto.randomUUID();
9018
- await this.createVersion({
9019
- id: newVersionId,
9020
- blockId: id,
9021
- versionNumber: latestVersion.versionNumber + 1,
9022
- ...newConfig,
9023
- changedFields: [...changedFields],
9024
- changeMessage: `Updated ${changedFields.join(", ")}`
9025
- });
9026
- }
9027
- }
8988
+ const { authorId, activeVersionId, metadata, status } = updates;
9028
8989
  const setClauses = [];
9029
8990
  const values = [];
9030
8991
  let paramIndex = 1;
@@ -9035,10 +8996,6 @@ var PromptBlocksPG = class _PromptBlocksPG extends storage.PromptBlocksStorage {
9035
8996
  if (activeVersionId !== void 0) {
9036
8997
  setClauses.push(`"activeVersionId" = $${paramIndex++}`);
9037
8998
  values.push(activeVersionId);
9038
- if (status === void 0) {
9039
- setClauses.push(`status = $${paramIndex++}`);
9040
- values.push("published");
9041
- }
9042
8999
  }
9043
9000
  if (status !== void 0) {
9044
9001
  setClauses.push(`status = $${paramIndex++}`);
@@ -9055,12 +9012,7 @@ var PromptBlocksPG = class _PromptBlocksPG extends storage.PromptBlocksStorage {
9055
9012
  setClauses.push(`"updatedAtZ" = $${paramIndex++}`);
9056
9013
  values.push(now);
9057
9014
  values.push(id);
9058
- if (setClauses.length > 2 || versionCreated) {
9059
- await this.#db.client.none(
9060
- `UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`,
9061
- values
9062
- );
9063
- }
9015
+ await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
9064
9016
  const updatedBlock = await this.getById(id);
9065
9017
  if (!updatedBlock) {
9066
9018
  throw new error.MastraError({
@@ -9104,7 +9056,7 @@ var PromptBlocksPG = class _PromptBlocksPG extends storage.PromptBlocksStorage {
9104
9056
  }
9105
9057
  }
9106
9058
  async list(args) {
9107
- const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};
9059
+ const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status = "published" } = args || {};
9108
9060
  const { field, direction } = this.parseOrderBy(orderBy);
9109
9061
  if (page < 0) {
9110
9062
  throw new error.MastraError(
@@ -9124,6 +9076,8 @@ var PromptBlocksPG = class _PromptBlocksPG extends storage.PromptBlocksStorage {
9124
9076
  const conditions = [];
9125
9077
  const queryParams = [];
9126
9078
  let paramIdx = 1;
9079
+ conditions.push(`status = $${paramIdx++}`);
9080
+ queryParams.push(status);
9127
9081
  if (authorId !== void 0) {
9128
9082
  conditions.push(`"authorId" = $${paramIdx++}`);
9129
9083
  queryParams.push(authorId);
@@ -9132,7 +9086,7 @@ var PromptBlocksPG = class _PromptBlocksPG extends storage.PromptBlocksStorage {
9132
9086
  conditions.push(`metadata @> $${paramIdx++}::jsonb`);
9133
9087
  queryParams.push(JSON.stringify(metadata));
9134
9088
  }
9135
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
9089
+ const whereClause = `WHERE ${conditions.join(" AND ")}`;
9136
9090
  const countResult = await this.#db.client.one(
9137
9091
  `SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`,
9138
9092
  queryParams
@@ -9685,46 +9639,7 @@ var ScorerDefinitionsPG = class _ScorerDefinitionsPG extends storage.ScorerDefin
9685
9639
  details: { scorerDefinitionId: id }
9686
9640
  });
9687
9641
  }
9688
- const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
9689
- let versionCreated = false;
9690
- const hasConfigUpdate = SNAPSHOT_FIELDS3.some((field) => field in configFields);
9691
- if (hasConfigUpdate) {
9692
- const latestVersion = await this.getLatestVersion(id);
9693
- if (!latestVersion) {
9694
- throw new error.MastraError({
9695
- id: storage.createStorageErrorId("PG", "UPDATE_SCORER_DEFINITION", "NO_VERSIONS"),
9696
- domain: error.ErrorDomain.STORAGE,
9697
- category: error.ErrorCategory.SYSTEM,
9698
- text: `No versions found for scorer definition ${id}`,
9699
- details: { scorerDefinitionId: id }
9700
- });
9701
- }
9702
- const {
9703
- id: _versionId,
9704
- scorerDefinitionId: _scorerDefinitionId,
9705
- versionNumber: _versionNumber,
9706
- changedFields: _changedFields,
9707
- changeMessage: _changeMessage,
9708
- createdAt: _createdAt,
9709
- ...latestConfig
9710
- } = latestVersion;
9711
- const newConfig = { ...latestConfig, ...configFields };
9712
- const changedFields = SNAPSHOT_FIELDS3.filter(
9713
- (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
9714
- );
9715
- if (changedFields.length > 0) {
9716
- versionCreated = true;
9717
- const newVersionId = crypto.randomUUID();
9718
- await this.createVersion({
9719
- id: newVersionId,
9720
- scorerDefinitionId: id,
9721
- versionNumber: latestVersion.versionNumber + 1,
9722
- ...newConfig,
9723
- changedFields: [...changedFields],
9724
- changeMessage: `Updated ${changedFields.join(", ")}`
9725
- });
9726
- }
9727
- }
9642
+ const { authorId, activeVersionId, metadata, status } = updates;
9728
9643
  const setClauses = [];
9729
9644
  const values = [];
9730
9645
  let paramIndex = 1;
@@ -9735,10 +9650,6 @@ var ScorerDefinitionsPG = class _ScorerDefinitionsPG extends storage.ScorerDefin
9735
9650
  if (activeVersionId !== void 0) {
9736
9651
  setClauses.push(`"activeVersionId" = $${paramIndex++}`);
9737
9652
  values.push(activeVersionId);
9738
- if (status === void 0) {
9739
- setClauses.push(`status = $${paramIndex++}`);
9740
- values.push("published");
9741
- }
9742
9653
  }
9743
9654
  if (status !== void 0) {
9744
9655
  setClauses.push(`status = $${paramIndex++}`);
@@ -9755,12 +9666,7 @@ var ScorerDefinitionsPG = class _ScorerDefinitionsPG extends storage.ScorerDefin
9755
9666
  setClauses.push(`"updatedAtZ" = $${paramIndex++}`);
9756
9667
  values.push(now);
9757
9668
  values.push(id);
9758
- if (setClauses.length > 2 || versionCreated) {
9759
- await this.#db.client.none(
9760
- `UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`,
9761
- values
9762
- );
9763
- }
9669
+ await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
9764
9670
  const updatedScorer = await this.getById(id);
9765
9671
  if (!updatedScorer) {
9766
9672
  throw new error.MastraError({
@@ -9804,7 +9710,7 @@ var ScorerDefinitionsPG = class _ScorerDefinitionsPG extends storage.ScorerDefin
9804
9710
  }
9805
9711
  }
9806
9712
  async list(args) {
9807
- const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};
9713
+ const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};
9808
9714
  const { field, direction } = this.parseOrderBy(orderBy);
9809
9715
  if (page < 0) {
9810
9716
  throw new error.MastraError(
@@ -9824,6 +9730,10 @@ var ScorerDefinitionsPG = class _ScorerDefinitionsPG extends storage.ScorerDefin
9824
9730
  const conditions = [];
9825
9731
  const queryParams = [];
9826
9732
  let paramIdx = 1;
9733
+ if (status) {
9734
+ conditions.push(`status = $${paramIdx++}`);
9735
+ queryParams.push(status);
9736
+ }
9827
9737
  if (authorId !== void 0) {
9828
9738
  conditions.push(`"authorId" = $${paramIdx++}`);
9829
9739
  queryParams.push(authorId);
@@ -10595,94 +10505,66 @@ var ScoresPG = class _ScoresPG extends storage.ScoresStorage {
10595
10505
  }
10596
10506
  }
10597
10507
  };
10598
- function getSchemaName5(schema) {
10599
- return schema ? `"${schema}"` : '"public"';
10600
- }
10601
- function getTableName5({ indexName, schemaName }) {
10602
- const quotedIndexName = `"${indexName}"`;
10603
- return schemaName ? `${schemaName}.${quotedIndexName}` : quotedIndexName;
10604
- }
10605
- function sanitizeJsonForPg(jsonString) {
10606
- return jsonString.replace(/\\u(0000|[Dd][89A-Fa-f][0-9A-Fa-f]{2})/g, "");
10607
- }
10608
- var WorkflowsPG = class _WorkflowsPG extends storage.WorkflowsStorage {
10508
+ var SNAPSHOT_FIELDS4 = [
10509
+ "name",
10510
+ "description",
10511
+ "instructions",
10512
+ "license",
10513
+ "compatibility",
10514
+ "source",
10515
+ "references",
10516
+ "scripts",
10517
+ "assets",
10518
+ "metadata",
10519
+ "tree"
10520
+ ];
10521
+ var SkillsPG = class _SkillsPG extends storage.SkillsStorage {
10609
10522
  #db;
10610
10523
  #schema;
10611
10524
  #skipDefaultIndexes;
10612
10525
  #indexes;
10613
- /** Tables managed by this domain */
10614
- static MANAGED_TABLES = [storage.TABLE_WORKFLOW_SNAPSHOT];
10526
+ static MANAGED_TABLES = [storage.TABLE_SKILLS, storage.TABLE_SKILL_VERSIONS];
10615
10527
  constructor(config) {
10616
10528
  super();
10617
10529
  const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
10618
10530
  this.#db = new PgDB({ client, schemaName, skipDefaultIndexes });
10619
10531
  this.#schema = schemaName || "public";
10620
10532
  this.#skipDefaultIndexes = skipDefaultIndexes;
10621
- this.#indexes = indexes?.filter((idx) => _WorkflowsPG.MANAGED_TABLES.includes(idx.table));
10533
+ this.#indexes = indexes?.filter((idx) => _SkillsPG.MANAGED_TABLES.includes(idx.table));
10622
10534
  }
10623
- parseWorkflowRun(row) {
10624
- let parsedSnapshot = row.snapshot;
10625
- if (typeof parsedSnapshot === "string") {
10626
- try {
10627
- parsedSnapshot = JSON.parse(row.snapshot);
10628
- } catch (e) {
10629
- this.logger.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
10535
+ getDefaultIndexDefinitions() {
10536
+ return [
10537
+ {
10538
+ name: "idx_skill_versions_skill_version",
10539
+ table: storage.TABLE_SKILL_VERSIONS,
10540
+ columns: ["skillId", "versionNumber"],
10541
+ unique: true
10630
10542
  }
10631
- }
10632
- return {
10633
- workflowName: row.workflow_name,
10634
- runId: row.run_id,
10635
- snapshot: parsedSnapshot,
10636
- resourceId: row.resourceId,
10637
- createdAt: new Date(row.createdAtZ || row.createdAt),
10638
- updatedAt: new Date(row.updatedAtZ || row.updatedAt)
10639
- };
10640
- }
10641
- /**
10642
- * Returns all DDL statements for this domain: table with unique constraint.
10643
- * Used by exportSchemas to produce a complete, reproducible schema export.
10644
- */
10645
- static getExportDDL(schemaName) {
10646
- const statements = [];
10647
- statements.push(
10648
- generateTableSQL({
10649
- tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
10650
- schema: storage.TABLE_SCHEMAS[storage.TABLE_WORKFLOW_SNAPSHOT],
10651
- schemaName,
10652
- includeAllConstraints: true
10653
- })
10654
- );
10655
- return statements;
10656
- }
10657
- /**
10658
- * Returns default index definitions for the workflows domain tables.
10659
- * Currently no default indexes are defined for workflows.
10660
- */
10661
- getDefaultIndexDefinitions() {
10662
- return [];
10543
+ ];
10663
10544
  }
10664
- /**
10665
- * Creates default indexes for optimal query performance.
10666
- * Currently no default indexes are defined for workflows.
10667
- */
10668
10545
  async createDefaultIndexes() {
10669
10546
  if (this.#skipDefaultIndexes) {
10670
10547
  return;
10671
10548
  }
10549
+ for (const indexDef of this.getDefaultIndexDefinitions()) {
10550
+ try {
10551
+ await this.#db.createIndex(indexDef);
10552
+ } catch {
10553
+ }
10554
+ }
10672
10555
  }
10673
10556
  async init() {
10674
- await this.#db.createTable({ tableName: storage.TABLE_WORKFLOW_SNAPSHOT, schema: storage.TABLE_SCHEMAS[storage.TABLE_WORKFLOW_SNAPSHOT] });
10675
- await this.#db.alterTable({
10676
- tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
10677
- schema: storage.TABLE_SCHEMAS[storage.TABLE_WORKFLOW_SNAPSHOT],
10678
- ifNotExists: ["resourceId"]
10557
+ await this.#db.createTable({
10558
+ tableName: storage.TABLE_SKILLS,
10559
+ schema: storage.TABLE_SCHEMAS[storage.TABLE_SKILLS]
10560
+ });
10561
+ await this.#db.createTable({
10562
+ tableName: storage.TABLE_SKILL_VERSIONS,
10563
+ schema: storage.TABLE_SCHEMAS[storage.TABLE_SKILL_VERSIONS]
10679
10564
  });
10680
10565
  await this.createDefaultIndexes();
10681
10566
  await this.createCustomIndexes();
10682
10567
  }
10683
- /**
10684
- * Creates custom user-defined indexes for this domain's tables.
10685
- */
10686
10568
  async createCustomIndexes() {
10687
10569
  if (!this.#indexes || this.#indexes.length === 0) {
10688
10570
  return;
@@ -10696,225 +10578,1602 @@ var WorkflowsPG = class _WorkflowsPG extends storage.WorkflowsStorage {
10696
10578
  }
10697
10579
  }
10698
10580
  async dangerouslyClearAll() {
10699
- await this.#db.clearTable({ tableName: storage.TABLE_WORKFLOW_SNAPSHOT });
10700
- }
10701
- updateWorkflowResults({
10702
- // workflowName,
10703
- // runId,
10704
- // stepId,
10705
- // result,
10706
- // requestContext,
10707
- }) {
10708
- throw new Error("Method not implemented.");
10709
- }
10710
- updateWorkflowState({
10711
- // workflowName,
10712
- // runId,
10713
- // opts,
10714
- }) {
10715
- throw new Error("Method not implemented.");
10581
+ await this.#db.clearTable({ tableName: storage.TABLE_SKILL_VERSIONS });
10582
+ await this.#db.clearTable({ tableName: storage.TABLE_SKILLS });
10716
10583
  }
10717
- async persistWorkflowSnapshot({
10718
- workflowName,
10719
- runId,
10720
- resourceId,
10721
- snapshot,
10722
- createdAt,
10723
- updatedAt
10724
- }) {
10584
+ // ==========================================================================
10585
+ // Skill CRUD Methods
10586
+ // ==========================================================================
10587
+ async getById(id) {
10725
10588
  try {
10726
- const now = /* @__PURE__ */ new Date();
10727
- const createdAtValue = createdAt ? createdAt : now;
10728
- const updatedAtValue = updatedAt ? updatedAt : now;
10729
- const sanitizedSnapshot = sanitizeJsonForPg(JSON.stringify(snapshot));
10730
- await this.#db.client.none(
10731
- `INSERT INTO ${getTableName5({ indexName: storage.TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName5(this.#schema) })} (workflow_name, run_id, "resourceId", snapshot, "createdAt", "updatedAt")
10732
- VALUES ($1, $2, $3, $4, $5, $6)
10733
- ON CONFLICT (workflow_name, run_id) DO UPDATE
10734
- SET "resourceId" = $3, snapshot = $4, "updatedAt" = $6`,
10735
- [workflowName, runId, resourceId, sanitizedSnapshot, createdAtValue, updatedAtValue]
10736
- );
10589
+ const tableName = getTableName2({ indexName: storage.TABLE_SKILLS, schemaName: getSchemaName2(this.#schema) });
10590
+ const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
10591
+ if (!result) {
10592
+ return null;
10593
+ }
10594
+ return this.parseSkillRow(result);
10737
10595
  } catch (error$1) {
10596
+ if (error$1 instanceof error.MastraError) throw error$1;
10738
10597
  throw new error.MastraError(
10739
10598
  {
10740
- id: storage.createStorageErrorId("PG", "PERSIST_WORKFLOW_SNAPSHOT", "FAILED"),
10599
+ id: storage.createStorageErrorId("PG", "GET_SKILL_BY_ID", "FAILED"),
10741
10600
  domain: error.ErrorDomain.STORAGE,
10742
- category: error.ErrorCategory.THIRD_PARTY
10601
+ category: error.ErrorCategory.THIRD_PARTY,
10602
+ details: { skillId: id }
10743
10603
  },
10744
10604
  error$1
10745
10605
  );
10746
10606
  }
10747
10607
  }
10748
- async loadWorkflowSnapshot({
10749
- workflowName,
10750
- runId
10751
- }) {
10608
+ async create(input) {
10609
+ const { skill } = input;
10752
10610
  try {
10753
- const result = await this.#db.load({
10754
- tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
10755
- keys: { workflow_name: workflowName, run_id: runId }
10611
+ const tableName = getTableName2({ indexName: storage.TABLE_SKILLS, schemaName: getSchemaName2(this.#schema) });
10612
+ const now = /* @__PURE__ */ new Date();
10613
+ const nowIso = now.toISOString();
10614
+ await this.#db.client.none(
10615
+ `INSERT INTO ${tableName} (
10616
+ id, status, "activeVersionId", "authorId",
10617
+ "createdAt", "createdAtZ", "updatedAt", "updatedAtZ"
10618
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
10619
+ [skill.id, "draft", null, skill.authorId ?? null, nowIso, nowIso, nowIso, nowIso]
10620
+ );
10621
+ const { id: _id, authorId: _authorId, ...snapshotConfig } = skill;
10622
+ const versionId = crypto.randomUUID();
10623
+ await this.createVersion({
10624
+ id: versionId,
10625
+ skillId: skill.id,
10626
+ versionNumber: 1,
10627
+ ...snapshotConfig,
10628
+ changedFields: [...SNAPSHOT_FIELDS4],
10629
+ changeMessage: "Initial version"
10756
10630
  });
10757
- return result ? result.snapshot : null;
10631
+ return {
10632
+ id: skill.id,
10633
+ status: "draft",
10634
+ activeVersionId: void 0,
10635
+ authorId: skill.authorId,
10636
+ createdAt: now,
10637
+ updatedAt: now
10638
+ };
10758
10639
  } catch (error$1) {
10640
+ try {
10641
+ const tableName = getTableName2({
10642
+ indexName: storage.TABLE_SKILLS,
10643
+ schemaName: getSchemaName2(this.#schema)
10644
+ });
10645
+ await this.#db.client.none(
10646
+ `DELETE FROM ${tableName} WHERE id = $1 AND status = 'draft' AND "activeVersionId" IS NULL`,
10647
+ [skill.id]
10648
+ );
10649
+ } catch {
10650
+ }
10651
+ if (error$1 instanceof error.MastraError) throw error$1;
10759
10652
  throw new error.MastraError(
10760
10653
  {
10761
- id: storage.createStorageErrorId("PG", "LOAD_WORKFLOW_SNAPSHOT", "FAILED"),
10654
+ id: storage.createStorageErrorId("PG", "CREATE_SKILL", "FAILED"),
10762
10655
  domain: error.ErrorDomain.STORAGE,
10763
- category: error.ErrorCategory.THIRD_PARTY
10656
+ category: error.ErrorCategory.THIRD_PARTY,
10657
+ details: { skillId: skill.id }
10764
10658
  },
10765
10659
  error$1
10766
10660
  );
10767
10661
  }
10768
10662
  }
10769
- async getWorkflowRunById({
10770
- runId,
10771
- workflowName
10772
- }) {
10663
+ async update(input) {
10664
+ const { id, ...updates } = input;
10773
10665
  try {
10774
- const conditions = [];
10666
+ const tableName = getTableName2({ indexName: storage.TABLE_SKILLS, schemaName: getSchemaName2(this.#schema) });
10667
+ const existingSkill = await this.getById(id);
10668
+ if (!existingSkill) {
10669
+ throw new error.MastraError({
10670
+ id: storage.createStorageErrorId("PG", "UPDATE_SKILL", "NOT_FOUND"),
10671
+ domain: error.ErrorDomain.STORAGE,
10672
+ category: error.ErrorCategory.USER,
10673
+ text: `Skill ${id} not found`,
10674
+ details: { skillId: id }
10675
+ });
10676
+ }
10677
+ const { authorId, activeVersionId, status, ...configFields } = updates;
10678
+ let versionCreated = false;
10679
+ const hasConfigUpdate = SNAPSHOT_FIELDS4.some((field) => field in configFields);
10680
+ if (hasConfigUpdate) {
10681
+ const latestVersion = await this.getLatestVersion(id);
10682
+ if (!latestVersion) {
10683
+ throw new error.MastraError({
10684
+ id: storage.createStorageErrorId("PG", "UPDATE_SKILL", "NO_VERSIONS"),
10685
+ domain: error.ErrorDomain.STORAGE,
10686
+ category: error.ErrorCategory.SYSTEM,
10687
+ text: `No versions found for skill ${id}`,
10688
+ details: { skillId: id }
10689
+ });
10690
+ }
10691
+ const {
10692
+ id: _versionId,
10693
+ skillId: _skillId,
10694
+ versionNumber: _versionNumber,
10695
+ changedFields: _changedFields,
10696
+ changeMessage: _changeMessage,
10697
+ createdAt: _createdAt,
10698
+ ...latestConfig
10699
+ } = latestVersion;
10700
+ const newConfig = { ...latestConfig, ...configFields };
10701
+ const changedFields = SNAPSHOT_FIELDS4.filter(
10702
+ (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
10703
+ );
10704
+ if (changedFields.length > 0) {
10705
+ versionCreated = true;
10706
+ const newVersionId = crypto.randomUUID();
10707
+ await this.createVersion({
10708
+ id: newVersionId,
10709
+ skillId: id,
10710
+ versionNumber: latestVersion.versionNumber + 1,
10711
+ ...newConfig,
10712
+ changedFields: [...changedFields],
10713
+ changeMessage: `Updated ${changedFields.join(", ")}`
10714
+ });
10715
+ }
10716
+ }
10717
+ const setClauses = [];
10775
10718
  const values = [];
10776
10719
  let paramIndex = 1;
10777
- if (runId) {
10778
- conditions.push(`run_id = $${paramIndex}`);
10779
- values.push(runId);
10780
- paramIndex++;
10720
+ if (authorId !== void 0) {
10721
+ setClauses.push(`"authorId" = $${paramIndex++}`);
10722
+ values.push(authorId);
10781
10723
  }
10782
- if (workflowName) {
10783
- conditions.push(`workflow_name = $${paramIndex}`);
10784
- values.push(workflowName);
10785
- paramIndex++;
10724
+ if (activeVersionId !== void 0) {
10725
+ setClauses.push(`"activeVersionId" = $${paramIndex++}`);
10726
+ values.push(activeVersionId);
10727
+ if (status === void 0) {
10728
+ setClauses.push(`status = $${paramIndex++}`);
10729
+ values.push("published");
10730
+ }
10786
10731
  }
10787
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
10788
- const query = `
10789
- SELECT * FROM ${getTableName5({ indexName: storage.TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName5(this.#schema) })}
10790
- ${whereClause}
10791
- ORDER BY "createdAt" DESC LIMIT 1
10792
- `;
10793
- const queryValues = values;
10794
- const result = await this.#db.client.oneOrNone(query, queryValues);
10795
- if (!result) {
10796
- return null;
10732
+ if (status !== void 0) {
10733
+ setClauses.push(`status = $${paramIndex++}`);
10734
+ values.push(status);
10797
10735
  }
10798
- return this.parseWorkflowRun(result);
10736
+ const now = (/* @__PURE__ */ new Date()).toISOString();
10737
+ setClauses.push(`"updatedAt" = $${paramIndex++}`);
10738
+ values.push(now);
10739
+ setClauses.push(`"updatedAtZ" = $${paramIndex++}`);
10740
+ values.push(now);
10741
+ values.push(id);
10742
+ if (setClauses.length > 2 || versionCreated) {
10743
+ await this.#db.client.none(
10744
+ `UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`,
10745
+ values
10746
+ );
10747
+ }
10748
+ const updatedSkill = await this.getById(id);
10749
+ if (!updatedSkill) {
10750
+ throw new error.MastraError({
10751
+ id: storage.createStorageErrorId("PG", "UPDATE_SKILL", "NOT_FOUND_AFTER_UPDATE"),
10752
+ domain: error.ErrorDomain.STORAGE,
10753
+ category: error.ErrorCategory.SYSTEM,
10754
+ text: `Skill ${id} not found after update`,
10755
+ details: { skillId: id }
10756
+ });
10757
+ }
10758
+ return updatedSkill;
10799
10759
  } catch (error$1) {
10760
+ if (error$1 instanceof error.MastraError) throw error$1;
10800
10761
  throw new error.MastraError(
10801
10762
  {
10802
- id: storage.createStorageErrorId("PG", "GET_WORKFLOW_RUN_BY_ID", "FAILED"),
10763
+ id: storage.createStorageErrorId("PG", "UPDATE_SKILL", "FAILED"),
10803
10764
  domain: error.ErrorDomain.STORAGE,
10804
10765
  category: error.ErrorCategory.THIRD_PARTY,
10805
- details: {
10806
- runId,
10807
- workflowName: workflowName || ""
10808
- }
10766
+ details: { skillId: id }
10809
10767
  },
10810
10768
  error$1
10811
10769
  );
10812
10770
  }
10813
10771
  }
10814
- async deleteWorkflowRunById({ runId, workflowName }) {
10772
+ async delete(id) {
10815
10773
  try {
10816
- await this.#db.client.none(
10817
- `DELETE FROM ${getTableName5({ indexName: storage.TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName5(this.#schema) })} WHERE run_id = $1 AND workflow_name = $2`,
10818
- [runId, workflowName]
10819
- );
10774
+ const tableName = getTableName2({ indexName: storage.TABLE_SKILLS, schemaName: getSchemaName2(this.#schema) });
10775
+ await this.deleteVersionsByParentId(id);
10776
+ await this.#db.client.none(`DELETE FROM ${tableName} WHERE id = $1`, [id]);
10820
10777
  } catch (error$1) {
10778
+ if (error$1 instanceof error.MastraError) throw error$1;
10821
10779
  throw new error.MastraError(
10822
10780
  {
10823
- id: storage.createStorageErrorId("PG", "DELETE_WORKFLOW_RUN_BY_ID", "FAILED"),
10781
+ id: storage.createStorageErrorId("PG", "DELETE_SKILL", "FAILED"),
10824
10782
  domain: error.ErrorDomain.STORAGE,
10825
10783
  category: error.ErrorCategory.THIRD_PARTY,
10826
- details: {
10827
- runId,
10828
- workflowName
10829
- }
10784
+ details: { skillId: id }
10830
10785
  },
10831
10786
  error$1
10832
10787
  );
10833
10788
  }
10834
10789
  }
10835
- async listWorkflowRuns({
10836
- workflowName,
10837
- fromDate,
10838
- toDate,
10839
- perPage,
10840
- page,
10841
- resourceId,
10842
- status
10843
- } = {}) {
10790
+ async list(args) {
10791
+ const { page = 0, perPage: perPageInput, orderBy, authorId } = args || {};
10792
+ const { field, direction } = this.parseOrderBy(orderBy);
10793
+ if (page < 0) {
10794
+ throw new error.MastraError(
10795
+ {
10796
+ id: storage.createStorageErrorId("PG", "LIST_SKILLS", "INVALID_PAGE"),
10797
+ domain: error.ErrorDomain.STORAGE,
10798
+ category: error.ErrorCategory.USER,
10799
+ details: { page }
10800
+ },
10801
+ new Error("page must be >= 0")
10802
+ );
10803
+ }
10804
+ const perPage = storage.normalizePerPage(perPageInput, 100);
10805
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
10844
10806
  try {
10807
+ const tableName = getTableName2({ indexName: storage.TABLE_SKILLS, schemaName: getSchemaName2(this.#schema) });
10845
10808
  const conditions = [];
10846
- const values = [];
10847
- let paramIndex = 1;
10848
- if (workflowName) {
10849
- conditions.push(`workflow_name = $${paramIndex}`);
10850
- values.push(workflowName);
10851
- paramIndex++;
10852
- }
10853
- if (status) {
10854
- conditions.push(
10855
- `regexp_replace(snapshot::text, '\\\\u(0000|[Dd][89A-Fa-f][0-9A-Fa-f]{2})', '', 'g')::jsonb ->> 'status' = $${paramIndex}`
10856
- );
10857
- values.push(status);
10858
- paramIndex++;
10859
- }
10860
- if (resourceId) {
10861
- const hasResourceId = await this.#db.hasColumn(storage.TABLE_WORKFLOW_SNAPSHOT, "resourceId");
10862
- if (hasResourceId) {
10863
- conditions.push(`"resourceId" = $${paramIndex}`);
10864
- values.push(resourceId);
10865
- paramIndex++;
10866
- } else {
10867
- this.logger?.warn?.(`[${storage.TABLE_WORKFLOW_SNAPSHOT}] resourceId column not found. Skipping resourceId filter.`);
10868
- }
10809
+ const queryParams = [];
10810
+ let paramIdx = 1;
10811
+ if (authorId !== void 0) {
10812
+ conditions.push(`"authorId" = $${paramIdx++}`);
10813
+ queryParams.push(authorId);
10869
10814
  }
10870
- if (fromDate) {
10871
- conditions.push(`"createdAt" >= $${paramIndex}`);
10872
- values.push(fromDate);
10873
- paramIndex++;
10815
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
10816
+ const countResult = await this.#db.client.one(
10817
+ `SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`,
10818
+ queryParams
10819
+ );
10820
+ const total = parseInt(countResult.count, 10);
10821
+ if (total === 0) {
10822
+ return {
10823
+ skills: [],
10824
+ total: 0,
10825
+ page,
10826
+ perPage: perPageForResponse,
10827
+ hasMore: false
10828
+ };
10874
10829
  }
10875
- if (toDate) {
10876
- conditions.push(`"createdAt" <= $${paramIndex}`);
10877
- values.push(toDate);
10878
- paramIndex++;
10830
+ const limitValue = perPageInput === false ? total : perPage;
10831
+ const dataResult = await this.#db.client.manyOrNone(
10832
+ `SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`,
10833
+ [...queryParams, limitValue, offset]
10834
+ );
10835
+ const skills = (dataResult || []).map((row) => this.parseSkillRow(row));
10836
+ return {
10837
+ skills,
10838
+ total,
10839
+ page,
10840
+ perPage: perPageForResponse,
10841
+ hasMore: perPageInput === false ? false : offset + perPage < total
10842
+ };
10843
+ } catch (error$1) {
10844
+ if (error$1 instanceof error.MastraError) throw error$1;
10845
+ throw new error.MastraError(
10846
+ {
10847
+ id: storage.createStorageErrorId("PG", "LIST_SKILLS", "FAILED"),
10848
+ domain: error.ErrorDomain.STORAGE,
10849
+ category: error.ErrorCategory.THIRD_PARTY
10850
+ },
10851
+ error$1
10852
+ );
10853
+ }
10854
+ }
10855
+ // ==========================================================================
10856
+ // Skill Version Methods
10857
+ // ==========================================================================
10858
+ async createVersion(input) {
10859
+ try {
10860
+ const tableName = getTableName2({
10861
+ indexName: storage.TABLE_SKILL_VERSIONS,
10862
+ schemaName: getSchemaName2(this.#schema)
10863
+ });
10864
+ const now = /* @__PURE__ */ new Date();
10865
+ const nowIso = now.toISOString();
10866
+ await this.#db.client.none(
10867
+ `INSERT INTO ${tableName} (
10868
+ id, "skillId", "versionNumber",
10869
+ name, description, instructions, license, compatibility,
10870
+ source, "references", scripts, assets, metadata, tree,
10871
+ "changedFields", "changeMessage",
10872
+ "createdAt", "createdAtZ"
10873
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)`,
10874
+ [
10875
+ input.id,
10876
+ input.skillId,
10877
+ input.versionNumber,
10878
+ input.name,
10879
+ input.description ?? null,
10880
+ input.instructions ?? null,
10881
+ input.license ?? null,
10882
+ input.compatibility ? JSON.stringify(input.compatibility) : null,
10883
+ input.source ? JSON.stringify(input.source) : null,
10884
+ input.references ? JSON.stringify(input.references) : null,
10885
+ input.scripts ? JSON.stringify(input.scripts) : null,
10886
+ input.assets ? JSON.stringify(input.assets) : null,
10887
+ input.metadata ? JSON.stringify(input.metadata) : null,
10888
+ input.tree ? JSON.stringify(input.tree) : null,
10889
+ input.changedFields ? JSON.stringify(input.changedFields) : null,
10890
+ input.changeMessage ?? null,
10891
+ nowIso,
10892
+ nowIso
10893
+ ]
10894
+ );
10895
+ return {
10896
+ ...input,
10897
+ createdAt: now
10898
+ };
10899
+ } catch (error$1) {
10900
+ if (error$1 instanceof error.MastraError) throw error$1;
10901
+ throw new error.MastraError(
10902
+ {
10903
+ id: storage.createStorageErrorId("PG", "CREATE_SKILL_VERSION", "FAILED"),
10904
+ domain: error.ErrorDomain.STORAGE,
10905
+ category: error.ErrorCategory.THIRD_PARTY,
10906
+ details: { versionId: input.id, skillId: input.skillId }
10907
+ },
10908
+ error$1
10909
+ );
10910
+ }
10911
+ }
10912
+ async getVersion(id) {
10913
+ try {
10914
+ const tableName = getTableName2({
10915
+ indexName: storage.TABLE_SKILL_VERSIONS,
10916
+ schemaName: getSchemaName2(this.#schema)
10917
+ });
10918
+ const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
10919
+ if (!result) {
10920
+ return null;
10879
10921
  }
10880
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
10881
- let total = 0;
10882
- const usePagination = typeof perPage === "number" && typeof page === "number";
10883
- if (usePagination) {
10884
- const countResult = await this.#db.client.one(
10885
- `SELECT COUNT(*) as count FROM ${getTableName5({ indexName: storage.TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName5(this.#schema) })} ${whereClause}`,
10886
- values
10887
- );
10888
- total = Number(countResult.count);
10922
+ return this.parseVersionRow(result);
10923
+ } catch (error$1) {
10924
+ if (error$1 instanceof error.MastraError) throw error$1;
10925
+ throw new error.MastraError(
10926
+ {
10927
+ id: storage.createStorageErrorId("PG", "GET_SKILL_VERSION", "FAILED"),
10928
+ domain: error.ErrorDomain.STORAGE,
10929
+ category: error.ErrorCategory.THIRD_PARTY,
10930
+ details: { versionId: id }
10931
+ },
10932
+ error$1
10933
+ );
10934
+ }
10935
+ }
10936
+ async getVersionByNumber(skillId, versionNumber) {
10937
+ try {
10938
+ const tableName = getTableName2({
10939
+ indexName: storage.TABLE_SKILL_VERSIONS,
10940
+ schemaName: getSchemaName2(this.#schema)
10941
+ });
10942
+ const result = await this.#db.client.oneOrNone(
10943
+ `SELECT * FROM ${tableName} WHERE "skillId" = $1 AND "versionNumber" = $2`,
10944
+ [skillId, versionNumber]
10945
+ );
10946
+ if (!result) {
10947
+ return null;
10889
10948
  }
10890
- const normalizedPerPage = usePagination ? storage.normalizePerPage(perPage, Number.MAX_SAFE_INTEGER) : 0;
10891
- const offset = usePagination ? page * normalizedPerPage : void 0;
10892
- const query = `
10893
- SELECT * FROM ${getTableName5({ indexName: storage.TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName5(this.#schema) })}
10894
- ${whereClause}
10895
- ORDER BY "createdAt" DESC
10896
- ${usePagination ? ` LIMIT $${paramIndex} OFFSET $${paramIndex + 1}` : ""}
10897
- `;
10898
- const queryValues = usePagination ? [...values, normalizedPerPage, offset] : values;
10899
- const result = await this.#db.client.manyOrNone(query, queryValues);
10900
- const runs = (result || []).map((row) => {
10901
- return this.parseWorkflowRun(row);
10949
+ return this.parseVersionRow(result);
10950
+ } catch (error$1) {
10951
+ if (error$1 instanceof error.MastraError) throw error$1;
10952
+ throw new error.MastraError(
10953
+ {
10954
+ id: storage.createStorageErrorId("PG", "GET_SKILL_VERSION_BY_NUMBER", "FAILED"),
10955
+ domain: error.ErrorDomain.STORAGE,
10956
+ category: error.ErrorCategory.THIRD_PARTY,
10957
+ details: { skillId, versionNumber }
10958
+ },
10959
+ error$1
10960
+ );
10961
+ }
10962
+ }
10963
+ async getLatestVersion(skillId) {
10964
+ try {
10965
+ const tableName = getTableName2({
10966
+ indexName: storage.TABLE_SKILL_VERSIONS,
10967
+ schemaName: getSchemaName2(this.#schema)
10902
10968
  });
10903
- return { runs, total: total || runs.length };
10969
+ const result = await this.#db.client.oneOrNone(
10970
+ `SELECT * FROM ${tableName} WHERE "skillId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`,
10971
+ [skillId]
10972
+ );
10973
+ if (!result) {
10974
+ return null;
10975
+ }
10976
+ return this.parseVersionRow(result);
10904
10977
  } catch (error$1) {
10978
+ if (error$1 instanceof error.MastraError) throw error$1;
10905
10979
  throw new error.MastraError(
10906
10980
  {
10907
- id: storage.createStorageErrorId("PG", "LIST_WORKFLOW_RUNS", "FAILED"),
10981
+ id: storage.createStorageErrorId("PG", "GET_LATEST_SKILL_VERSION", "FAILED"),
10908
10982
  domain: error.ErrorDomain.STORAGE,
10909
10983
  category: error.ErrorCategory.THIRD_PARTY,
10910
- details: {
10911
- workflowName: workflowName || "all"
10912
- }
10984
+ details: { skillId }
10913
10985
  },
10914
10986
  error$1
10915
10987
  );
10916
10988
  }
10917
10989
  }
10990
+ async listVersions(input) {
10991
+ const { skillId, page = 0, perPage: perPageInput, orderBy } = input;
10992
+ if (page < 0) {
10993
+ throw new error.MastraError(
10994
+ {
10995
+ id: storage.createStorageErrorId("PG", "LIST_SKILL_VERSIONS", "INVALID_PAGE"),
10996
+ domain: error.ErrorDomain.STORAGE,
10997
+ category: error.ErrorCategory.USER,
10998
+ details: { page }
10999
+ },
11000
+ new Error("page must be >= 0")
11001
+ );
11002
+ }
11003
+ const perPage = storage.normalizePerPage(perPageInput, 20);
11004
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
11005
+ try {
11006
+ const { field, direction } = this.parseVersionOrderBy(orderBy);
11007
+ const tableName = getTableName2({
11008
+ indexName: storage.TABLE_SKILL_VERSIONS,
11009
+ schemaName: getSchemaName2(this.#schema)
11010
+ });
11011
+ const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "skillId" = $1`, [
11012
+ skillId
11013
+ ]);
11014
+ const total = parseInt(countResult.count, 10);
11015
+ if (total === 0) {
11016
+ return {
11017
+ versions: [],
11018
+ total: 0,
11019
+ page,
11020
+ perPage: perPageForResponse,
11021
+ hasMore: false
11022
+ };
11023
+ }
11024
+ const limitValue = perPageInput === false ? total : perPage;
11025
+ const dataResult = await this.#db.client.manyOrNone(
11026
+ `SELECT * FROM ${tableName} WHERE "skillId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`,
11027
+ [skillId, limitValue, offset]
11028
+ );
11029
+ const versions = (dataResult || []).map((row) => this.parseVersionRow(row));
11030
+ return {
11031
+ versions,
11032
+ total,
11033
+ page,
11034
+ perPage: perPageForResponse,
11035
+ hasMore: perPageInput === false ? false : offset + perPage < total
11036
+ };
11037
+ } catch (error$1) {
11038
+ if (error$1 instanceof error.MastraError) throw error$1;
11039
+ throw new error.MastraError(
11040
+ {
11041
+ id: storage.createStorageErrorId("PG", "LIST_SKILL_VERSIONS", "FAILED"),
11042
+ domain: error.ErrorDomain.STORAGE,
11043
+ category: error.ErrorCategory.THIRD_PARTY,
11044
+ details: { skillId }
11045
+ },
11046
+ error$1
11047
+ );
11048
+ }
11049
+ }
11050
+ async deleteVersion(id) {
11051
+ try {
11052
+ const tableName = getTableName2({
11053
+ indexName: storage.TABLE_SKILL_VERSIONS,
11054
+ schemaName: getSchemaName2(this.#schema)
11055
+ });
11056
+ await this.#db.client.none(`DELETE FROM ${tableName} WHERE id = $1`, [id]);
11057
+ } catch (error$1) {
11058
+ if (error$1 instanceof error.MastraError) throw error$1;
11059
+ throw new error.MastraError(
11060
+ {
11061
+ id: storage.createStorageErrorId("PG", "DELETE_SKILL_VERSION", "FAILED"),
11062
+ domain: error.ErrorDomain.STORAGE,
11063
+ category: error.ErrorCategory.THIRD_PARTY,
11064
+ details: { versionId: id }
11065
+ },
11066
+ error$1
11067
+ );
11068
+ }
11069
+ }
11070
+ async deleteVersionsByParentId(entityId) {
11071
+ try {
11072
+ const tableName = getTableName2({
11073
+ indexName: storage.TABLE_SKILL_VERSIONS,
11074
+ schemaName: getSchemaName2(this.#schema)
11075
+ });
11076
+ await this.#db.client.none(`DELETE FROM ${tableName} WHERE "skillId" = $1`, [entityId]);
11077
+ } catch (error$1) {
11078
+ if (error$1 instanceof error.MastraError) throw error$1;
11079
+ throw new error.MastraError(
11080
+ {
11081
+ id: storage.createStorageErrorId("PG", "DELETE_SKILL_VERSIONS_BY_SKILL_ID", "FAILED"),
11082
+ domain: error.ErrorDomain.STORAGE,
11083
+ category: error.ErrorCategory.THIRD_PARTY,
11084
+ details: { skillId: entityId }
11085
+ },
11086
+ error$1
11087
+ );
11088
+ }
11089
+ }
11090
+ async countVersions(skillId) {
11091
+ try {
11092
+ const tableName = getTableName2({
11093
+ indexName: storage.TABLE_SKILL_VERSIONS,
11094
+ schemaName: getSchemaName2(this.#schema)
11095
+ });
11096
+ const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "skillId" = $1`, [
11097
+ skillId
11098
+ ]);
11099
+ return parseInt(result.count, 10);
11100
+ } catch (error$1) {
11101
+ if (error$1 instanceof error.MastraError) throw error$1;
11102
+ throw new error.MastraError(
11103
+ {
11104
+ id: storage.createStorageErrorId("PG", "COUNT_SKILL_VERSIONS", "FAILED"),
11105
+ domain: error.ErrorDomain.STORAGE,
11106
+ category: error.ErrorCategory.THIRD_PARTY,
11107
+ details: { skillId }
11108
+ },
11109
+ error$1
11110
+ );
11111
+ }
11112
+ }
11113
+ // ==========================================================================
11114
+ // Private Helper Methods
11115
+ // ==========================================================================
11116
+ parseJson(value, fieldName) {
11117
+ if (!value) return void 0;
11118
+ if (typeof value !== "string") return value;
11119
+ try {
11120
+ return JSON.parse(value);
11121
+ } catch (error$1) {
11122
+ if (error$1 instanceof error.MastraError) throw error$1;
11123
+ const details = {
11124
+ value: value.length > 100 ? value.substring(0, 100) + "..." : value
11125
+ };
11126
+ if (fieldName) {
11127
+ details.field = fieldName;
11128
+ }
11129
+ throw new error.MastraError(
11130
+ {
11131
+ id: storage.createStorageErrorId("PG", "PARSE_JSON", "INVALID_JSON"),
11132
+ domain: error.ErrorDomain.STORAGE,
11133
+ category: error.ErrorCategory.SYSTEM,
11134
+ text: `Failed to parse JSON${fieldName ? ` for field "${fieldName}"` : ""}: ${error$1 instanceof Error ? error$1.message : "Unknown error"}`,
11135
+ details
11136
+ },
11137
+ error$1
11138
+ );
11139
+ }
11140
+ }
11141
+ parseSkillRow(row) {
11142
+ return {
11143
+ id: row.id,
11144
+ status: row.status,
11145
+ activeVersionId: row.activeVersionId,
11146
+ authorId: row.authorId,
11147
+ createdAt: new Date(row.createdAtZ || row.createdAt),
11148
+ updatedAt: new Date(row.updatedAtZ || row.updatedAt)
11149
+ };
11150
+ }
11151
+ parseVersionRow(row) {
11152
+ return {
11153
+ id: row.id,
11154
+ skillId: row.skillId,
11155
+ versionNumber: row.versionNumber,
11156
+ name: row.name,
11157
+ description: row.description,
11158
+ instructions: row.instructions,
11159
+ license: row.license,
11160
+ compatibility: this.parseJson(row.compatibility, "compatibility"),
11161
+ source: this.parseJson(row.source, "source"),
11162
+ references: this.parseJson(row.references, "references"),
11163
+ scripts: this.parseJson(row.scripts, "scripts"),
11164
+ assets: this.parseJson(row.assets, "assets"),
11165
+ metadata: this.parseJson(row.metadata, "metadata"),
11166
+ tree: this.parseJson(row.tree, "tree"),
11167
+ changedFields: this.parseJson(row.changedFields, "changedFields"),
11168
+ changeMessage: row.changeMessage,
11169
+ createdAt: new Date(row.createdAtZ || row.createdAt)
11170
+ };
11171
+ }
11172
+ };
11173
+ function getSchemaName5(schema) {
11174
+ return schema ? `"${schema}"` : '"public"';
11175
+ }
11176
+ function getTableName5({ indexName, schemaName }) {
11177
+ const quotedIndexName = `"${indexName}"`;
11178
+ return schemaName ? `${schemaName}.${quotedIndexName}` : quotedIndexName;
11179
+ }
11180
+ function sanitizeJsonForPg(jsonString) {
11181
+ return jsonString.replace(/\\u(0000|[Dd][89A-Fa-f][0-9A-Fa-f]{2})/g, "");
11182
+ }
11183
+ var WorkflowsPG = class _WorkflowsPG extends storage.WorkflowsStorage {
11184
+ #db;
11185
+ #schema;
11186
+ #skipDefaultIndexes;
11187
+ #indexes;
11188
+ /** Tables managed by this domain */
11189
+ static MANAGED_TABLES = [storage.TABLE_WORKFLOW_SNAPSHOT];
11190
+ constructor(config) {
11191
+ super();
11192
+ const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
11193
+ this.#db = new PgDB({ client, schemaName, skipDefaultIndexes });
11194
+ this.#schema = schemaName || "public";
11195
+ this.#skipDefaultIndexes = skipDefaultIndexes;
11196
+ this.#indexes = indexes?.filter((idx) => _WorkflowsPG.MANAGED_TABLES.includes(idx.table));
11197
+ }
11198
+ parseWorkflowRun(row) {
11199
+ let parsedSnapshot = row.snapshot;
11200
+ if (typeof parsedSnapshot === "string") {
11201
+ try {
11202
+ parsedSnapshot = JSON.parse(row.snapshot);
11203
+ } catch (e) {
11204
+ this.logger.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
11205
+ }
11206
+ }
11207
+ return {
11208
+ workflowName: row.workflow_name,
11209
+ runId: row.run_id,
11210
+ snapshot: parsedSnapshot,
11211
+ resourceId: row.resourceId,
11212
+ createdAt: new Date(row.createdAtZ || row.createdAt),
11213
+ updatedAt: new Date(row.updatedAtZ || row.updatedAt)
11214
+ };
11215
+ }
11216
+ /**
11217
+ * Returns all DDL statements for this domain: table with unique constraint.
11218
+ * Used by exportSchemas to produce a complete, reproducible schema export.
11219
+ */
11220
+ static getExportDDL(schemaName) {
11221
+ const statements = [];
11222
+ statements.push(
11223
+ generateTableSQL({
11224
+ tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
11225
+ schema: storage.TABLE_SCHEMAS[storage.TABLE_WORKFLOW_SNAPSHOT],
11226
+ schemaName,
11227
+ includeAllConstraints: true
11228
+ })
11229
+ );
11230
+ return statements;
11231
+ }
11232
+ /**
11233
+ * Returns default index definitions for the workflows domain tables.
11234
+ * Currently no default indexes are defined for workflows.
11235
+ */
11236
+ getDefaultIndexDefinitions() {
11237
+ return [];
11238
+ }
11239
+ /**
11240
+ * Creates default indexes for optimal query performance.
11241
+ * Currently no default indexes are defined for workflows.
11242
+ */
11243
+ async createDefaultIndexes() {
11244
+ if (this.#skipDefaultIndexes) {
11245
+ return;
11246
+ }
11247
+ }
11248
+ async init() {
11249
+ await this.#db.createTable({ tableName: storage.TABLE_WORKFLOW_SNAPSHOT, schema: storage.TABLE_SCHEMAS[storage.TABLE_WORKFLOW_SNAPSHOT] });
11250
+ await this.#db.alterTable({
11251
+ tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
11252
+ schema: storage.TABLE_SCHEMAS[storage.TABLE_WORKFLOW_SNAPSHOT],
11253
+ ifNotExists: ["resourceId"]
11254
+ });
11255
+ await this.createDefaultIndexes();
11256
+ await this.createCustomIndexes();
11257
+ }
11258
+ /**
11259
+ * Creates custom user-defined indexes for this domain's tables.
11260
+ */
11261
+ async createCustomIndexes() {
11262
+ if (!this.#indexes || this.#indexes.length === 0) {
11263
+ return;
11264
+ }
11265
+ for (const indexDef of this.#indexes) {
11266
+ try {
11267
+ await this.#db.createIndex(indexDef);
11268
+ } catch (error) {
11269
+ this.logger?.warn?.(`Failed to create custom index ${indexDef.name}:`, error);
11270
+ }
11271
+ }
11272
+ }
11273
+ async dangerouslyClearAll() {
11274
+ await this.#db.clearTable({ tableName: storage.TABLE_WORKFLOW_SNAPSHOT });
11275
+ }
11276
+ updateWorkflowResults({
11277
+ // workflowName,
11278
+ // runId,
11279
+ // stepId,
11280
+ // result,
11281
+ // requestContext,
11282
+ }) {
11283
+ throw new Error("Method not implemented.");
11284
+ }
11285
+ updateWorkflowState({
11286
+ // workflowName,
11287
+ // runId,
11288
+ // opts,
11289
+ }) {
11290
+ throw new Error("Method not implemented.");
11291
+ }
11292
+ async persistWorkflowSnapshot({
11293
+ workflowName,
11294
+ runId,
11295
+ resourceId,
11296
+ snapshot,
11297
+ createdAt,
11298
+ updatedAt
11299
+ }) {
11300
+ try {
11301
+ const now = /* @__PURE__ */ new Date();
11302
+ const createdAtValue = createdAt ? createdAt : now;
11303
+ const updatedAtValue = updatedAt ? updatedAt : now;
11304
+ const sanitizedSnapshot = sanitizeJsonForPg(JSON.stringify(snapshot));
11305
+ await this.#db.client.none(
11306
+ `INSERT INTO ${getTableName5({ indexName: storage.TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName5(this.#schema) })} (workflow_name, run_id, "resourceId", snapshot, "createdAt", "updatedAt")
11307
+ VALUES ($1, $2, $3, $4, $5, $6)
11308
+ ON CONFLICT (workflow_name, run_id) DO UPDATE
11309
+ SET "resourceId" = $3, snapshot = $4, "updatedAt" = $6`,
11310
+ [workflowName, runId, resourceId, sanitizedSnapshot, createdAtValue, updatedAtValue]
11311
+ );
11312
+ } catch (error$1) {
11313
+ throw new error.MastraError(
11314
+ {
11315
+ id: storage.createStorageErrorId("PG", "PERSIST_WORKFLOW_SNAPSHOT", "FAILED"),
11316
+ domain: error.ErrorDomain.STORAGE,
11317
+ category: error.ErrorCategory.THIRD_PARTY
11318
+ },
11319
+ error$1
11320
+ );
11321
+ }
11322
+ }
11323
+ async loadWorkflowSnapshot({
11324
+ workflowName,
11325
+ runId
11326
+ }) {
11327
+ try {
11328
+ const result = await this.#db.load({
11329
+ tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
11330
+ keys: { workflow_name: workflowName, run_id: runId }
11331
+ });
11332
+ return result ? result.snapshot : null;
11333
+ } catch (error$1) {
11334
+ throw new error.MastraError(
11335
+ {
11336
+ id: storage.createStorageErrorId("PG", "LOAD_WORKFLOW_SNAPSHOT", "FAILED"),
11337
+ domain: error.ErrorDomain.STORAGE,
11338
+ category: error.ErrorCategory.THIRD_PARTY
11339
+ },
11340
+ error$1
11341
+ );
11342
+ }
11343
+ }
11344
+ async getWorkflowRunById({
11345
+ runId,
11346
+ workflowName
11347
+ }) {
11348
+ try {
11349
+ const conditions = [];
11350
+ const values = [];
11351
+ let paramIndex = 1;
11352
+ if (runId) {
11353
+ conditions.push(`run_id = $${paramIndex}`);
11354
+ values.push(runId);
11355
+ paramIndex++;
11356
+ }
11357
+ if (workflowName) {
11358
+ conditions.push(`workflow_name = $${paramIndex}`);
11359
+ values.push(workflowName);
11360
+ paramIndex++;
11361
+ }
11362
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
11363
+ const query = `
11364
+ SELECT * FROM ${getTableName5({ indexName: storage.TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName5(this.#schema) })}
11365
+ ${whereClause}
11366
+ ORDER BY "createdAt" DESC LIMIT 1
11367
+ `;
11368
+ const queryValues = values;
11369
+ const result = await this.#db.client.oneOrNone(query, queryValues);
11370
+ if (!result) {
11371
+ return null;
11372
+ }
11373
+ return this.parseWorkflowRun(result);
11374
+ } catch (error$1) {
11375
+ throw new error.MastraError(
11376
+ {
11377
+ id: storage.createStorageErrorId("PG", "GET_WORKFLOW_RUN_BY_ID", "FAILED"),
11378
+ domain: error.ErrorDomain.STORAGE,
11379
+ category: error.ErrorCategory.THIRD_PARTY,
11380
+ details: {
11381
+ runId,
11382
+ workflowName: workflowName || ""
11383
+ }
11384
+ },
11385
+ error$1
11386
+ );
11387
+ }
11388
+ }
11389
+ async deleteWorkflowRunById({ runId, workflowName }) {
11390
+ try {
11391
+ await this.#db.client.none(
11392
+ `DELETE FROM ${getTableName5({ indexName: storage.TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName5(this.#schema) })} WHERE run_id = $1 AND workflow_name = $2`,
11393
+ [runId, workflowName]
11394
+ );
11395
+ } catch (error$1) {
11396
+ throw new error.MastraError(
11397
+ {
11398
+ id: storage.createStorageErrorId("PG", "DELETE_WORKFLOW_RUN_BY_ID", "FAILED"),
11399
+ domain: error.ErrorDomain.STORAGE,
11400
+ category: error.ErrorCategory.THIRD_PARTY,
11401
+ details: {
11402
+ runId,
11403
+ workflowName
11404
+ }
11405
+ },
11406
+ error$1
11407
+ );
11408
+ }
11409
+ }
11410
+ async listWorkflowRuns({
11411
+ workflowName,
11412
+ fromDate,
11413
+ toDate,
11414
+ perPage,
11415
+ page,
11416
+ resourceId,
11417
+ status
11418
+ } = {}) {
11419
+ try {
11420
+ const conditions = [];
11421
+ const values = [];
11422
+ let paramIndex = 1;
11423
+ if (workflowName) {
11424
+ conditions.push(`workflow_name = $${paramIndex}`);
11425
+ values.push(workflowName);
11426
+ paramIndex++;
11427
+ }
11428
+ if (status) {
11429
+ conditions.push(
11430
+ `regexp_replace(snapshot::text, '\\\\u(0000|[Dd][89A-Fa-f][0-9A-Fa-f]{2})', '', 'g')::jsonb ->> 'status' = $${paramIndex}`
11431
+ );
11432
+ values.push(status);
11433
+ paramIndex++;
11434
+ }
11435
+ if (resourceId) {
11436
+ const hasResourceId = await this.#db.hasColumn(storage.TABLE_WORKFLOW_SNAPSHOT, "resourceId");
11437
+ if (hasResourceId) {
11438
+ conditions.push(`"resourceId" = $${paramIndex}`);
11439
+ values.push(resourceId);
11440
+ paramIndex++;
11441
+ } else {
11442
+ this.logger?.warn?.(`[${storage.TABLE_WORKFLOW_SNAPSHOT}] resourceId column not found. Skipping resourceId filter.`);
11443
+ }
11444
+ }
11445
+ if (fromDate) {
11446
+ conditions.push(`"createdAt" >= $${paramIndex}`);
11447
+ values.push(fromDate);
11448
+ paramIndex++;
11449
+ }
11450
+ if (toDate) {
11451
+ conditions.push(`"createdAt" <= $${paramIndex}`);
11452
+ values.push(toDate);
11453
+ paramIndex++;
11454
+ }
11455
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
11456
+ let total = 0;
11457
+ const usePagination = typeof perPage === "number" && typeof page === "number";
11458
+ if (usePagination) {
11459
+ const countResult = await this.#db.client.one(
11460
+ `SELECT COUNT(*) as count FROM ${getTableName5({ indexName: storage.TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName5(this.#schema) })} ${whereClause}`,
11461
+ values
11462
+ );
11463
+ total = Number(countResult.count);
11464
+ }
11465
+ const normalizedPerPage = usePagination ? storage.normalizePerPage(perPage, Number.MAX_SAFE_INTEGER) : 0;
11466
+ const offset = usePagination ? page * normalizedPerPage : void 0;
11467
+ const query = `
11468
+ SELECT * FROM ${getTableName5({ indexName: storage.TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName5(this.#schema) })}
11469
+ ${whereClause}
11470
+ ORDER BY "createdAt" DESC
11471
+ ${usePagination ? ` LIMIT $${paramIndex} OFFSET $${paramIndex + 1}` : ""}
11472
+ `;
11473
+ const queryValues = usePagination ? [...values, normalizedPerPage, offset] : values;
11474
+ const result = await this.#db.client.manyOrNone(query, queryValues);
11475
+ const runs = (result || []).map((row) => {
11476
+ return this.parseWorkflowRun(row);
11477
+ });
11478
+ return { runs, total: total || runs.length };
11479
+ } catch (error$1) {
11480
+ throw new error.MastraError(
11481
+ {
11482
+ id: storage.createStorageErrorId("PG", "LIST_WORKFLOW_RUNS", "FAILED"),
11483
+ domain: error.ErrorDomain.STORAGE,
11484
+ category: error.ErrorCategory.THIRD_PARTY,
11485
+ details: {
11486
+ workflowName: workflowName || "all"
11487
+ }
11488
+ },
11489
+ error$1
11490
+ );
11491
+ }
11492
+ }
11493
+ };
11494
+ var SNAPSHOT_FIELDS5 = [
11495
+ "name",
11496
+ "description",
11497
+ "filesystem",
11498
+ "sandbox",
11499
+ "mounts",
11500
+ "search",
11501
+ "skills",
11502
+ "tools",
11503
+ "autoSync",
11504
+ "operationTimeout"
11505
+ ];
11506
+ var WorkspacesPG = class _WorkspacesPG extends storage.WorkspacesStorage {
11507
+ #db;
11508
+ #schema;
11509
+ #skipDefaultIndexes;
11510
+ #indexes;
11511
+ static MANAGED_TABLES = [storage.TABLE_WORKSPACES, storage.TABLE_WORKSPACE_VERSIONS];
11512
+ constructor(config) {
11513
+ super();
11514
+ const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
11515
+ this.#db = new PgDB({ client, schemaName, skipDefaultIndexes });
11516
+ this.#schema = schemaName || "public";
11517
+ this.#skipDefaultIndexes = skipDefaultIndexes;
11518
+ this.#indexes = indexes?.filter((idx) => _WorkspacesPG.MANAGED_TABLES.includes(idx.table));
11519
+ }
11520
+ getDefaultIndexDefinitions() {
11521
+ return [
11522
+ {
11523
+ name: "idx_workspace_versions_workspace_version",
11524
+ table: storage.TABLE_WORKSPACE_VERSIONS,
11525
+ columns: ["workspaceId", "versionNumber"],
11526
+ unique: true
11527
+ }
11528
+ ];
11529
+ }
11530
+ async createDefaultIndexes() {
11531
+ if (this.#skipDefaultIndexes) {
11532
+ return;
11533
+ }
11534
+ for (const indexDef of this.getDefaultIndexDefinitions()) {
11535
+ try {
11536
+ await this.#db.createIndex(indexDef);
11537
+ } catch {
11538
+ }
11539
+ }
11540
+ }
11541
+ async init() {
11542
+ await this.#db.createTable({
11543
+ tableName: storage.TABLE_WORKSPACES,
11544
+ schema: storage.TABLE_SCHEMAS[storage.TABLE_WORKSPACES]
11545
+ });
11546
+ await this.#db.createTable({
11547
+ tableName: storage.TABLE_WORKSPACE_VERSIONS,
11548
+ schema: storage.TABLE_SCHEMAS[storage.TABLE_WORKSPACE_VERSIONS]
11549
+ });
11550
+ await this.createDefaultIndexes();
11551
+ await this.createCustomIndexes();
11552
+ }
11553
+ async createCustomIndexes() {
11554
+ if (!this.#indexes || this.#indexes.length === 0) {
11555
+ return;
11556
+ }
11557
+ for (const indexDef of this.#indexes) {
11558
+ try {
11559
+ await this.#db.createIndex(indexDef);
11560
+ } catch (error) {
11561
+ this.logger?.warn?.(`Failed to create custom index ${indexDef.name}:`, error);
11562
+ }
11563
+ }
11564
+ }
11565
+ async dangerouslyClearAll() {
11566
+ await this.#db.clearTable({ tableName: storage.TABLE_WORKSPACE_VERSIONS });
11567
+ await this.#db.clearTable({ tableName: storage.TABLE_WORKSPACES });
11568
+ }
11569
+ // ==========================================================================
11570
+ // Workspace CRUD Methods
11571
+ // ==========================================================================
11572
+ async getById(id) {
11573
+ try {
11574
+ const tableName = getTableName2({ indexName: storage.TABLE_WORKSPACES, schemaName: getSchemaName2(this.#schema) });
11575
+ const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
11576
+ if (!result) {
11577
+ return null;
11578
+ }
11579
+ return this.parseWorkspaceRow(result);
11580
+ } catch (error$1) {
11581
+ if (error$1 instanceof error.MastraError) throw error$1;
11582
+ throw new error.MastraError(
11583
+ {
11584
+ id: storage.createStorageErrorId("PG", "GET_WORKSPACE_BY_ID", "FAILED"),
11585
+ domain: error.ErrorDomain.STORAGE,
11586
+ category: error.ErrorCategory.THIRD_PARTY,
11587
+ details: { workspaceId: id }
11588
+ },
11589
+ error$1
11590
+ );
11591
+ }
11592
+ }
11593
+ async create(input) {
11594
+ const { workspace } = input;
11595
+ try {
11596
+ const tableName = getTableName2({ indexName: storage.TABLE_WORKSPACES, schemaName: getSchemaName2(this.#schema) });
11597
+ const now = /* @__PURE__ */ new Date();
11598
+ const nowIso = now.toISOString();
11599
+ await this.#db.client.none(
11600
+ `INSERT INTO ${tableName} (
11601
+ id, status, "activeVersionId", "authorId", metadata,
11602
+ "createdAt", "createdAtZ", "updatedAt", "updatedAtZ"
11603
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
11604
+ [
11605
+ workspace.id,
11606
+ "draft",
11607
+ null,
11608
+ workspace.authorId ?? null,
11609
+ workspace.metadata ? JSON.stringify(workspace.metadata) : null,
11610
+ nowIso,
11611
+ nowIso,
11612
+ nowIso,
11613
+ nowIso
11614
+ ]
11615
+ );
11616
+ const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace;
11617
+ const versionId = crypto.randomUUID();
11618
+ await this.createVersion({
11619
+ id: versionId,
11620
+ workspaceId: workspace.id,
11621
+ versionNumber: 1,
11622
+ ...snapshotConfig,
11623
+ changedFields: [...SNAPSHOT_FIELDS5],
11624
+ changeMessage: "Initial version"
11625
+ });
11626
+ return {
11627
+ id: workspace.id,
11628
+ status: "draft",
11629
+ activeVersionId: void 0,
11630
+ authorId: workspace.authorId,
11631
+ metadata: workspace.metadata,
11632
+ createdAt: now,
11633
+ updatedAt: now
11634
+ };
11635
+ } catch (error$1) {
11636
+ try {
11637
+ const tableName = getTableName2({
11638
+ indexName: storage.TABLE_WORKSPACES,
11639
+ schemaName: getSchemaName2(this.#schema)
11640
+ });
11641
+ await this.#db.client.none(
11642
+ `DELETE FROM ${tableName} WHERE id = $1 AND status = 'draft' AND "activeVersionId" IS NULL`,
11643
+ [workspace.id]
11644
+ );
11645
+ } catch {
11646
+ }
11647
+ if (error$1 instanceof error.MastraError) throw error$1;
11648
+ throw new error.MastraError(
11649
+ {
11650
+ id: storage.createStorageErrorId("PG", "CREATE_WORKSPACE", "FAILED"),
11651
+ domain: error.ErrorDomain.STORAGE,
11652
+ category: error.ErrorCategory.THIRD_PARTY,
11653
+ details: { workspaceId: workspace.id }
11654
+ },
11655
+ error$1
11656
+ );
11657
+ }
11658
+ }
11659
+ async update(input) {
11660
+ const { id, ...updates } = input;
11661
+ try {
11662
+ const tableName = getTableName2({ indexName: storage.TABLE_WORKSPACES, schemaName: getSchemaName2(this.#schema) });
11663
+ const existingWorkspace = await this.getById(id);
11664
+ if (!existingWorkspace) {
11665
+ throw new error.MastraError({
11666
+ id: storage.createStorageErrorId("PG", "UPDATE_WORKSPACE", "NOT_FOUND"),
11667
+ domain: error.ErrorDomain.STORAGE,
11668
+ category: error.ErrorCategory.USER,
11669
+ text: `Workspace ${id} not found`,
11670
+ details: { workspaceId: id }
11671
+ });
11672
+ }
11673
+ const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
11674
+ let versionCreated = false;
11675
+ const hasConfigUpdate = SNAPSHOT_FIELDS5.some((field) => field in configFields);
11676
+ if (hasConfigUpdate) {
11677
+ const latestVersion = await this.getLatestVersion(id);
11678
+ if (!latestVersion) {
11679
+ throw new error.MastraError({
11680
+ id: storage.createStorageErrorId("PG", "UPDATE_WORKSPACE", "NO_VERSIONS"),
11681
+ domain: error.ErrorDomain.STORAGE,
11682
+ category: error.ErrorCategory.SYSTEM,
11683
+ text: `No versions found for workspace ${id}`,
11684
+ details: { workspaceId: id }
11685
+ });
11686
+ }
11687
+ const {
11688
+ id: _versionId,
11689
+ workspaceId: _workspaceId,
11690
+ versionNumber: _versionNumber,
11691
+ changedFields: _changedFields,
11692
+ changeMessage: _changeMessage,
11693
+ createdAt: _createdAt,
11694
+ ...latestConfig
11695
+ } = latestVersion;
11696
+ const newConfig = { ...latestConfig, ...configFields };
11697
+ const changedFields = SNAPSHOT_FIELDS5.filter(
11698
+ (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
11699
+ );
11700
+ if (changedFields.length > 0) {
11701
+ versionCreated = true;
11702
+ const newVersionId = crypto.randomUUID();
11703
+ await this.createVersion({
11704
+ id: newVersionId,
11705
+ workspaceId: id,
11706
+ versionNumber: latestVersion.versionNumber + 1,
11707
+ ...newConfig,
11708
+ changedFields: [...changedFields],
11709
+ changeMessage: `Updated ${changedFields.join(", ")}`
11710
+ });
11711
+ }
11712
+ }
11713
+ const setClauses = [];
11714
+ const values = [];
11715
+ let paramIndex = 1;
11716
+ if (authorId !== void 0) {
11717
+ setClauses.push(`"authorId" = $${paramIndex++}`);
11718
+ values.push(authorId);
11719
+ }
11720
+ if (activeVersionId !== void 0) {
11721
+ setClauses.push(`"activeVersionId" = $${paramIndex++}`);
11722
+ values.push(activeVersionId);
11723
+ if (status === void 0) {
11724
+ setClauses.push(`status = $${paramIndex++}`);
11725
+ values.push("published");
11726
+ }
11727
+ }
11728
+ if (status !== void 0) {
11729
+ setClauses.push(`status = $${paramIndex++}`);
11730
+ values.push(status);
11731
+ }
11732
+ if (metadata !== void 0) {
11733
+ const mergedMetadata = { ...existingWorkspace.metadata || {}, ...metadata };
11734
+ setClauses.push(`metadata = $${paramIndex++}`);
11735
+ values.push(JSON.stringify(mergedMetadata));
11736
+ }
11737
+ const now = (/* @__PURE__ */ new Date()).toISOString();
11738
+ setClauses.push(`"updatedAt" = $${paramIndex++}`);
11739
+ values.push(now);
11740
+ setClauses.push(`"updatedAtZ" = $${paramIndex++}`);
11741
+ values.push(now);
11742
+ values.push(id);
11743
+ if (setClauses.length > 2 || versionCreated) {
11744
+ await this.#db.client.none(
11745
+ `UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`,
11746
+ values
11747
+ );
11748
+ }
11749
+ const updatedWorkspace = await this.getById(id);
11750
+ if (!updatedWorkspace) {
11751
+ throw new error.MastraError({
11752
+ id: storage.createStorageErrorId("PG", "UPDATE_WORKSPACE", "NOT_FOUND_AFTER_UPDATE"),
11753
+ domain: error.ErrorDomain.STORAGE,
11754
+ category: error.ErrorCategory.SYSTEM,
11755
+ text: `Workspace ${id} not found after update`,
11756
+ details: { workspaceId: id }
11757
+ });
11758
+ }
11759
+ return updatedWorkspace;
11760
+ } catch (error$1) {
11761
+ if (error$1 instanceof error.MastraError) throw error$1;
11762
+ throw new error.MastraError(
11763
+ {
11764
+ id: storage.createStorageErrorId("PG", "UPDATE_WORKSPACE", "FAILED"),
11765
+ domain: error.ErrorDomain.STORAGE,
11766
+ category: error.ErrorCategory.THIRD_PARTY,
11767
+ details: { workspaceId: id }
11768
+ },
11769
+ error$1
11770
+ );
11771
+ }
11772
+ }
11773
+ async delete(id) {
11774
+ try {
11775
+ const tableName = getTableName2({ indexName: storage.TABLE_WORKSPACES, schemaName: getSchemaName2(this.#schema) });
11776
+ await this.deleteVersionsByParentId(id);
11777
+ await this.#db.client.none(`DELETE FROM ${tableName} WHERE id = $1`, [id]);
11778
+ } catch (error$1) {
11779
+ if (error$1 instanceof error.MastraError) throw error$1;
11780
+ throw new error.MastraError(
11781
+ {
11782
+ id: storage.createStorageErrorId("PG", "DELETE_WORKSPACE", "FAILED"),
11783
+ domain: error.ErrorDomain.STORAGE,
11784
+ category: error.ErrorCategory.THIRD_PARTY,
11785
+ details: { workspaceId: id }
11786
+ },
11787
+ error$1
11788
+ );
11789
+ }
11790
+ }
11791
+ async list(args) {
11792
+ const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};
11793
+ const { field, direction } = this.parseOrderBy(orderBy);
11794
+ if (page < 0) {
11795
+ throw new error.MastraError(
11796
+ {
11797
+ id: storage.createStorageErrorId("PG", "LIST_WORKSPACES", "INVALID_PAGE"),
11798
+ domain: error.ErrorDomain.STORAGE,
11799
+ category: error.ErrorCategory.USER,
11800
+ details: { page }
11801
+ },
11802
+ new Error("page must be >= 0")
11803
+ );
11804
+ }
11805
+ const perPage = storage.normalizePerPage(perPageInput, 100);
11806
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
11807
+ try {
11808
+ const tableName = getTableName2({ indexName: storage.TABLE_WORKSPACES, schemaName: getSchemaName2(this.#schema) });
11809
+ const conditions = [];
11810
+ const queryParams = [];
11811
+ let paramIdx = 1;
11812
+ if (authorId !== void 0) {
11813
+ conditions.push(`"authorId" = $${paramIdx++}`);
11814
+ queryParams.push(authorId);
11815
+ }
11816
+ if (metadata && Object.keys(metadata).length > 0) {
11817
+ conditions.push(`metadata @> $${paramIdx++}::jsonb`);
11818
+ queryParams.push(JSON.stringify(metadata));
11819
+ }
11820
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
11821
+ const countResult = await this.#db.client.one(
11822
+ `SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`,
11823
+ queryParams
11824
+ );
11825
+ const total = parseInt(countResult.count, 10);
11826
+ if (total === 0) {
11827
+ return {
11828
+ workspaces: [],
11829
+ total: 0,
11830
+ page,
11831
+ perPage: perPageForResponse,
11832
+ hasMore: false
11833
+ };
11834
+ }
11835
+ const limitValue = perPageInput === false ? total : perPage;
11836
+ const dataResult = await this.#db.client.manyOrNone(
11837
+ `SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`,
11838
+ [...queryParams, limitValue, offset]
11839
+ );
11840
+ const workspaces = (dataResult || []).map((row) => this.parseWorkspaceRow(row));
11841
+ return {
11842
+ workspaces,
11843
+ total,
11844
+ page,
11845
+ perPage: perPageForResponse,
11846
+ hasMore: perPageInput === false ? false : offset + perPage < total
11847
+ };
11848
+ } catch (error$1) {
11849
+ if (error$1 instanceof error.MastraError) throw error$1;
11850
+ throw new error.MastraError(
11851
+ {
11852
+ id: storage.createStorageErrorId("PG", "LIST_WORKSPACES", "FAILED"),
11853
+ domain: error.ErrorDomain.STORAGE,
11854
+ category: error.ErrorCategory.THIRD_PARTY
11855
+ },
11856
+ error$1
11857
+ );
11858
+ }
11859
+ }
11860
+ // ==========================================================================
11861
+ // Workspace Version Methods
11862
+ // ==========================================================================
11863
+ async createVersion(input) {
11864
+ try {
11865
+ const tableName = getTableName2({
11866
+ indexName: storage.TABLE_WORKSPACE_VERSIONS,
11867
+ schemaName: getSchemaName2(this.#schema)
11868
+ });
11869
+ const now = /* @__PURE__ */ new Date();
11870
+ const nowIso = now.toISOString();
11871
+ await this.#db.client.none(
11872
+ `INSERT INTO ${tableName} (
11873
+ id, "workspaceId", "versionNumber",
11874
+ name, description, filesystem, sandbox, mounts, search, skills, tools,
11875
+ "autoSync", "operationTimeout",
11876
+ "changedFields", "changeMessage",
11877
+ "createdAt", "createdAtZ"
11878
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)`,
11879
+ [
11880
+ input.id,
11881
+ input.workspaceId,
11882
+ input.versionNumber,
11883
+ input.name,
11884
+ input.description ?? null,
11885
+ input.filesystem ? JSON.stringify(input.filesystem) : null,
11886
+ input.sandbox ? JSON.stringify(input.sandbox) : null,
11887
+ input.mounts ? JSON.stringify(input.mounts) : null,
11888
+ input.search ? JSON.stringify(input.search) : null,
11889
+ input.skills ? JSON.stringify(input.skills) : null,
11890
+ input.tools ? JSON.stringify(input.tools) : null,
11891
+ input.autoSync ?? false,
11892
+ input.operationTimeout ?? null,
11893
+ input.changedFields ? JSON.stringify(input.changedFields) : null,
11894
+ input.changeMessage ?? null,
11895
+ nowIso,
11896
+ nowIso
11897
+ ]
11898
+ );
11899
+ return {
11900
+ ...input,
11901
+ createdAt: now
11902
+ };
11903
+ } catch (error$1) {
11904
+ if (error$1 instanceof error.MastraError) throw error$1;
11905
+ throw new error.MastraError(
11906
+ {
11907
+ id: storage.createStorageErrorId("PG", "CREATE_WORKSPACE_VERSION", "FAILED"),
11908
+ domain: error.ErrorDomain.STORAGE,
11909
+ category: error.ErrorCategory.THIRD_PARTY,
11910
+ details: { versionId: input.id, workspaceId: input.workspaceId }
11911
+ },
11912
+ error$1
11913
+ );
11914
+ }
11915
+ }
11916
+ async getVersion(id) {
11917
+ try {
11918
+ const tableName = getTableName2({
11919
+ indexName: storage.TABLE_WORKSPACE_VERSIONS,
11920
+ schemaName: getSchemaName2(this.#schema)
11921
+ });
11922
+ const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
11923
+ if (!result) {
11924
+ return null;
11925
+ }
11926
+ return this.parseVersionRow(result);
11927
+ } catch (error$1) {
11928
+ if (error$1 instanceof error.MastraError) throw error$1;
11929
+ throw new error.MastraError(
11930
+ {
11931
+ id: storage.createStorageErrorId("PG", "GET_WORKSPACE_VERSION", "FAILED"),
11932
+ domain: error.ErrorDomain.STORAGE,
11933
+ category: error.ErrorCategory.THIRD_PARTY,
11934
+ details: { versionId: id }
11935
+ },
11936
+ error$1
11937
+ );
11938
+ }
11939
+ }
11940
+ async getVersionByNumber(workspaceId, versionNumber) {
11941
+ try {
11942
+ const tableName = getTableName2({
11943
+ indexName: storage.TABLE_WORKSPACE_VERSIONS,
11944
+ schemaName: getSchemaName2(this.#schema)
11945
+ });
11946
+ const result = await this.#db.client.oneOrNone(
11947
+ `SELECT * FROM ${tableName} WHERE "workspaceId" = $1 AND "versionNumber" = $2`,
11948
+ [workspaceId, versionNumber]
11949
+ );
11950
+ if (!result) {
11951
+ return null;
11952
+ }
11953
+ return this.parseVersionRow(result);
11954
+ } catch (error$1) {
11955
+ if (error$1 instanceof error.MastraError) throw error$1;
11956
+ throw new error.MastraError(
11957
+ {
11958
+ id: storage.createStorageErrorId("PG", "GET_WORKSPACE_VERSION_BY_NUMBER", "FAILED"),
11959
+ domain: error.ErrorDomain.STORAGE,
11960
+ category: error.ErrorCategory.THIRD_PARTY,
11961
+ details: { workspaceId, versionNumber }
11962
+ },
11963
+ error$1
11964
+ );
11965
+ }
11966
+ }
11967
+ async getLatestVersion(workspaceId) {
11968
+ try {
11969
+ const tableName = getTableName2({
11970
+ indexName: storage.TABLE_WORKSPACE_VERSIONS,
11971
+ schemaName: getSchemaName2(this.#schema)
11972
+ });
11973
+ const result = await this.#db.client.oneOrNone(
11974
+ `SELECT * FROM ${tableName} WHERE "workspaceId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`,
11975
+ [workspaceId]
11976
+ );
11977
+ if (!result) {
11978
+ return null;
11979
+ }
11980
+ return this.parseVersionRow(result);
11981
+ } catch (error$1) {
11982
+ if (error$1 instanceof error.MastraError) throw error$1;
11983
+ throw new error.MastraError(
11984
+ {
11985
+ id: storage.createStorageErrorId("PG", "GET_LATEST_WORKSPACE_VERSION", "FAILED"),
11986
+ domain: error.ErrorDomain.STORAGE,
11987
+ category: error.ErrorCategory.THIRD_PARTY,
11988
+ details: { workspaceId }
11989
+ },
11990
+ error$1
11991
+ );
11992
+ }
11993
+ }
11994
+ async listVersions(input) {
11995
+ const { workspaceId, page = 0, perPage: perPageInput, orderBy } = input;
11996
+ if (page < 0) {
11997
+ throw new error.MastraError(
11998
+ {
11999
+ id: storage.createStorageErrorId("PG", "LIST_WORKSPACE_VERSIONS", "INVALID_PAGE"),
12000
+ domain: error.ErrorDomain.STORAGE,
12001
+ category: error.ErrorCategory.USER,
12002
+ details: { page }
12003
+ },
12004
+ new Error("page must be >= 0")
12005
+ );
12006
+ }
12007
+ const perPage = storage.normalizePerPage(perPageInput, 20);
12008
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
12009
+ try {
12010
+ const { field, direction } = this.parseVersionOrderBy(orderBy);
12011
+ const tableName = getTableName2({
12012
+ indexName: storage.TABLE_WORKSPACE_VERSIONS,
12013
+ schemaName: getSchemaName2(this.#schema)
12014
+ });
12015
+ const countResult = await this.#db.client.one(
12016
+ `SELECT COUNT(*) as count FROM ${tableName} WHERE "workspaceId" = $1`,
12017
+ [workspaceId]
12018
+ );
12019
+ const total = parseInt(countResult.count, 10);
12020
+ if (total === 0) {
12021
+ return {
12022
+ versions: [],
12023
+ total: 0,
12024
+ page,
12025
+ perPage: perPageForResponse,
12026
+ hasMore: false
12027
+ };
12028
+ }
12029
+ const limitValue = perPageInput === false ? total : perPage;
12030
+ const dataResult = await this.#db.client.manyOrNone(
12031
+ `SELECT * FROM ${tableName} WHERE "workspaceId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`,
12032
+ [workspaceId, limitValue, offset]
12033
+ );
12034
+ const versions = (dataResult || []).map((row) => this.parseVersionRow(row));
12035
+ return {
12036
+ versions,
12037
+ total,
12038
+ page,
12039
+ perPage: perPageForResponse,
12040
+ hasMore: perPageInput === false ? false : offset + perPage < total
12041
+ };
12042
+ } catch (error$1) {
12043
+ if (error$1 instanceof error.MastraError) throw error$1;
12044
+ throw new error.MastraError(
12045
+ {
12046
+ id: storage.createStorageErrorId("PG", "LIST_WORKSPACE_VERSIONS", "FAILED"),
12047
+ domain: error.ErrorDomain.STORAGE,
12048
+ category: error.ErrorCategory.THIRD_PARTY,
12049
+ details: { workspaceId }
12050
+ },
12051
+ error$1
12052
+ );
12053
+ }
12054
+ }
12055
+ async deleteVersion(id) {
12056
+ try {
12057
+ const tableName = getTableName2({
12058
+ indexName: storage.TABLE_WORKSPACE_VERSIONS,
12059
+ schemaName: getSchemaName2(this.#schema)
12060
+ });
12061
+ await this.#db.client.none(`DELETE FROM ${tableName} WHERE id = $1`, [id]);
12062
+ } catch (error$1) {
12063
+ if (error$1 instanceof error.MastraError) throw error$1;
12064
+ throw new error.MastraError(
12065
+ {
12066
+ id: storage.createStorageErrorId("PG", "DELETE_WORKSPACE_VERSION", "FAILED"),
12067
+ domain: error.ErrorDomain.STORAGE,
12068
+ category: error.ErrorCategory.THIRD_PARTY,
12069
+ details: { versionId: id }
12070
+ },
12071
+ error$1
12072
+ );
12073
+ }
12074
+ }
12075
+ async deleteVersionsByParentId(entityId) {
12076
+ try {
12077
+ const tableName = getTableName2({
12078
+ indexName: storage.TABLE_WORKSPACE_VERSIONS,
12079
+ schemaName: getSchemaName2(this.#schema)
12080
+ });
12081
+ await this.#db.client.none(`DELETE FROM ${tableName} WHERE "workspaceId" = $1`, [entityId]);
12082
+ } catch (error$1) {
12083
+ if (error$1 instanceof error.MastraError) throw error$1;
12084
+ throw new error.MastraError(
12085
+ {
12086
+ id: storage.createStorageErrorId("PG", "DELETE_WORKSPACE_VERSIONS_BY_WORKSPACE_ID", "FAILED"),
12087
+ domain: error.ErrorDomain.STORAGE,
12088
+ category: error.ErrorCategory.THIRD_PARTY,
12089
+ details: { workspaceId: entityId }
12090
+ },
12091
+ error$1
12092
+ );
12093
+ }
12094
+ }
12095
+ async countVersions(workspaceId) {
12096
+ try {
12097
+ const tableName = getTableName2({
12098
+ indexName: storage.TABLE_WORKSPACE_VERSIONS,
12099
+ schemaName: getSchemaName2(this.#schema)
12100
+ });
12101
+ const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "workspaceId" = $1`, [
12102
+ workspaceId
12103
+ ]);
12104
+ return parseInt(result.count, 10);
12105
+ } catch (error$1) {
12106
+ if (error$1 instanceof error.MastraError) throw error$1;
12107
+ throw new error.MastraError(
12108
+ {
12109
+ id: storage.createStorageErrorId("PG", "COUNT_WORKSPACE_VERSIONS", "FAILED"),
12110
+ domain: error.ErrorDomain.STORAGE,
12111
+ category: error.ErrorCategory.THIRD_PARTY,
12112
+ details: { workspaceId }
12113
+ },
12114
+ error$1
12115
+ );
12116
+ }
12117
+ }
12118
+ // ==========================================================================
12119
+ // Private Helper Methods
12120
+ // ==========================================================================
12121
+ parseJson(value, fieldName) {
12122
+ if (!value) return void 0;
12123
+ if (typeof value !== "string") return value;
12124
+ try {
12125
+ return JSON.parse(value);
12126
+ } catch (error$1) {
12127
+ if (error$1 instanceof error.MastraError) throw error$1;
12128
+ const details = {
12129
+ value: value.length > 100 ? value.substring(0, 100) + "..." : value
12130
+ };
12131
+ if (fieldName) {
12132
+ details.field = fieldName;
12133
+ }
12134
+ throw new error.MastraError(
12135
+ {
12136
+ id: storage.createStorageErrorId("PG", "PARSE_JSON", "INVALID_JSON"),
12137
+ domain: error.ErrorDomain.STORAGE,
12138
+ category: error.ErrorCategory.SYSTEM,
12139
+ text: `Failed to parse JSON${fieldName ? ` for field "${fieldName}"` : ""}: ${error$1 instanceof Error ? error$1.message : "Unknown error"}`,
12140
+ details
12141
+ },
12142
+ error$1
12143
+ );
12144
+ }
12145
+ }
12146
+ parseWorkspaceRow(row) {
12147
+ return {
12148
+ id: row.id,
12149
+ status: row.status,
12150
+ activeVersionId: row.activeVersionId,
12151
+ authorId: row.authorId,
12152
+ metadata: this.parseJson(row.metadata, "metadata"),
12153
+ createdAt: new Date(row.createdAtZ || row.createdAt),
12154
+ updatedAt: new Date(row.updatedAtZ || row.updatedAt)
12155
+ };
12156
+ }
12157
+ parseVersionRow(row) {
12158
+ return {
12159
+ id: row.id,
12160
+ workspaceId: row.workspaceId,
12161
+ versionNumber: row.versionNumber,
12162
+ name: row.name,
12163
+ description: row.description,
12164
+ filesystem: this.parseJson(row.filesystem, "filesystem"),
12165
+ sandbox: this.parseJson(row.sandbox, "sandbox"),
12166
+ mounts: this.parseJson(row.mounts, "mounts"),
12167
+ search: this.parseJson(row.search, "search"),
12168
+ skills: this.parseJson(row.skills, "skills"),
12169
+ tools: this.parseJson(row.tools, "tools"),
12170
+ autoSync: Boolean(row.autoSync),
12171
+ operationTimeout: row.operationTimeout != null ? Number(row.operationTimeout) : void 0,
12172
+ changedFields: this.parseJson(row.changedFields, "changedFields"),
12173
+ changeMessage: row.changeMessage,
12174
+ createdAt: new Date(row.createdAtZ || row.createdAt)
12175
+ };
12176
+ }
10918
12177
  };
10919
12178
 
10920
12179
  // src/storage/index.ts
@@ -10978,6 +12237,9 @@ var PostgresStore = class extends storage.MastraCompositeStore {
10978
12237
  promptBlocks: new PromptBlocksPG(domainConfig),
10979
12238
  scorerDefinitions: new ScorerDefinitionsPG(domainConfig),
10980
12239
  mcpClients: new MCPClientsPG(domainConfig),
12240
+ workspaces: new WorkspacesPG(domainConfig),
12241
+ skills: new SkillsPG(domainConfig),
12242
+ blobs: new BlobsPG(domainConfig),
10981
12243
  datasets: new DatasetsPG(domainConfig),
10982
12244
  experiments: new ExperimentsPG(domainConfig)
10983
12245
  };
@@ -11169,6 +12431,7 @@ Example Complex Query:
11169
12431
  }`;
11170
12432
 
11171
12433
  exports.AgentsPG = AgentsPG;
12434
+ exports.BlobsPG = BlobsPG;
11172
12435
  exports.DatasetsPG = DatasetsPG;
11173
12436
  exports.ExperimentsPG = ExperimentsPG;
11174
12437
  exports.MCPClientsPG = MCPClientsPG;
@@ -11181,7 +12444,9 @@ exports.PostgresStore = PostgresStore;
11181
12444
  exports.PromptBlocksPG = PromptBlocksPG;
11182
12445
  exports.ScorerDefinitionsPG = ScorerDefinitionsPG;
11183
12446
  exports.ScoresPG = ScoresPG;
12447
+ exports.SkillsPG = SkillsPG;
11184
12448
  exports.WorkflowsPG = WorkflowsPG;
12449
+ exports.WorkspacesPG = WorkspacesPG;
11185
12450
  exports.exportSchemas = exportSchemas;
11186
12451
  //# sourceMappingURL=index.cjs.map
11187
12452
  //# sourceMappingURL=index.cjs.map