@axiom-lattice/local-stores 3.1.8 → 3.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1381,6 +1381,22 @@ function mapRow4(row) {
1381
1381
  createdAt
1382
1382
  };
1383
1383
  }
1384
+ function mapRowsTolerant(rows2, scope) {
1385
+ const messages = [];
1386
+ for (const row of rows2) {
1387
+ try {
1388
+ messages.push(mapRow4(row));
1389
+ } catch (error) {
1390
+ console.warn("[ProjectRoomMessageStore] Skipping invalid message row", {
1391
+ tenantId: scope.tenantId,
1392
+ roomId: scope.roomId,
1393
+ rowId: typeof row.id === "string" ? row.id : void 0,
1394
+ reason: error instanceof Error ? error.message : String(error)
1395
+ });
1396
+ }
1397
+ }
1398
+ return messages;
1399
+ }
1384
1400
  var LocalProjectRoomMessageStore = class {
1385
1401
  constructor(db) {
1386
1402
  this.db = db;
@@ -1396,7 +1412,7 @@ var LocalProjectRoomMessageStore = class {
1396
1412
  if (input.before && !validDate(input.before.createdAt)) throw new RangeError("Project room message cursor date is invalid");
1397
1413
  const limit = Math.min(100, Math.max(1, Math.trunc(Number.isFinite(input.limit) ? input.limit : 1)));
1398
1414
  const rows2 = input.before ? this.db.prepare(`SELECT ${columns4} FROM lt_project_room_messages WHERE tenant_id = ? AND room_id = ? AND (created_at < ? OR (created_at = ? AND id < ?)) ORDER BY created_at DESC, id DESC LIMIT ?`).all(input.tenantId, input.roomId, input.before.createdAt.toISOString(), input.before.createdAt.toISOString(), input.before.id, limit) : this.db.prepare(`SELECT ${columns4} FROM lt_project_room_messages WHERE tenant_id = ? AND room_id = ? ORDER BY created_at DESC, id DESC LIMIT ?`).all(input.tenantId, input.roomId, limit);
1399
- return rows2.map(mapRow4);
1415
+ return mapRowsTolerant(rows2, { tenantId: input.tenantId, roomId: input.roomId });
1400
1416
  }
1401
1417
  async findById(tenantId, id) {
1402
1418
  const row = this.byId(tenantId, id);
@@ -3800,6 +3816,7 @@ CREATE TABLE IF NOT EXISTS lt_a2a_api_keys (
3800
3816
  tenant_id TEXT NOT NULL,
3801
3817
  project_id TEXT,
3802
3818
  assistant_ids TEXT,
3819
+ grants TEXT,
3803
3820
  label TEXT,
3804
3821
  enabled INTEGER NOT NULL DEFAULT 1,
3805
3822
  created_at TEXT NOT NULL,
@@ -3809,6 +3826,15 @@ CREATE TABLE IF NOT EXISTS lt_a2a_api_keys (
3809
3826
  function generateApiKey() {
3810
3827
  return `a2a_${randomUUID3().replace(/-/g, "")}`;
3811
3828
  }
3829
+ function parseGrants(raw) {
3830
+ if (!raw) return void 0;
3831
+ try {
3832
+ const parsed = JSON.parse(raw);
3833
+ return Array.isArray(parsed) ? parsed : void 0;
3834
+ } catch {
3835
+ return void 0;
3836
+ }
3837
+ }
3812
3838
  function parseAssistantIds(raw) {
3813
3839
  if (!raw) return void 0;
3814
3840
  try {
@@ -3823,6 +3849,7 @@ var LocalA2AApiKeyStore = class {
3823
3849
  this.db = db;
3824
3850
  ensureTable(db, DDL16);
3825
3851
  this.ensureColumn("lt_a2a_api_keys", "assistant_ids", "assistant_ids TEXT");
3852
+ this.ensureColumn("lt_a2a_api_keys", "grants", "grants TEXT");
3826
3853
  this.repairManagementIds();
3827
3854
  }
3828
3855
  /** Add a column if it does not exist (SQLite version compatible). */
@@ -3883,9 +3910,9 @@ var LocalA2AApiKeyStore = class {
3883
3910
  const key = generateApiKey();
3884
3911
  const now = nowISO();
3885
3912
  this.db.prepare(
3886
- `INSERT INTO lt_a2a_api_keys (id, key_value, tenant_id, project_id, assistant_ids, label, created_at, updated_at)
3887
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
3888
- ).run(id, encrypt3(key), input.tenantId, input.projectId, input.assistantIds ? JSON.stringify(input.assistantIds) : null, input.label || null, now, now);
3913
+ `INSERT INTO lt_a2a_api_keys (id, key_value, tenant_id, project_id, assistant_ids, grants, label, created_at, updated_at)
3914
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
3915
+ ).run(id, encrypt3(key), input.tenantId, input.projectId, input.assistantIds ? JSON.stringify(input.assistantIds) : null, input.grants ? JSON.stringify(input.grants) : null, input.label || null, now, now);
3889
3916
  const record2 = {
3890
3917
  id,
3891
3918
  key,
@@ -3917,6 +3944,38 @@ var LocalA2AApiKeyStore = class {
3917
3944
  if (!row) throw new Error(`A2A API key not found: ${id}`);
3918
3945
  return mapRowToRecord(row);
3919
3946
  }
3947
+ async update(id, input) {
3948
+ const sets = [];
3949
+ const values = [];
3950
+ if (input.label !== void 0) {
3951
+ sets.push("label = ?");
3952
+ values.push(input.label || null);
3953
+ }
3954
+ if (input.projectId !== void 0) {
3955
+ sets.push("project_id = ?");
3956
+ values.push(input.projectId);
3957
+ }
3958
+ if (input.assistantIds !== void 0) {
3959
+ sets.push("assistant_ids = ?");
3960
+ values.push(input.assistantIds ? JSON.stringify(input.assistantIds) : null);
3961
+ }
3962
+ if (input.grants !== void 0) {
3963
+ sets.push("grants = ?");
3964
+ values.push(input.grants ? JSON.stringify(input.grants) : null);
3965
+ }
3966
+ if (sets.length === 0) {
3967
+ const row2 = this.db.prepare("SELECT * FROM lt_a2a_api_keys WHERE id = ?").get(id);
3968
+ if (!row2) throw new Error(`A2A API key not found: ${id}`);
3969
+ return mapRowToRecord(row2);
3970
+ }
3971
+ sets.push("updated_at = ?");
3972
+ values.push(nowISO());
3973
+ values.push(id);
3974
+ this.db.prepare(`UPDATE lt_a2a_api_keys SET ${sets.join(", ")} WHERE id = ?`).run(...values);
3975
+ const row = this.db.prepare("SELECT * FROM lt_a2a_api_keys WHERE id = ?").get(id);
3976
+ if (!row) throw new Error(`A2A API key not found: ${id}`);
3977
+ return mapRowToRecord(row);
3978
+ }
3920
3979
  async rotate(id) {
3921
3980
  const key = generateApiKey();
3922
3981
  const now = nowISO();
@@ -3965,6 +4024,7 @@ function mapRowToRecord(row) {
3965
4024
  tenantId: row.tenant_id,
3966
4025
  projectId: row.project_id,
3967
4026
  assistantIds: parseAssistantIds(row.assistant_ids),
4027
+ grants: parseGrants(row.grants),
3968
4028
  label: row.label || void 0,
3969
4029
  enabled: row.enabled === 1,
3970
4030
  createdAt: parseISO(row.created_at),
@@ -3972,13 +4032,103 @@ function mapRowToRecord(row) {
3972
4032
  };
3973
4033
  }
3974
4034
 
4035
+ // src/stores/LocalOpenAuditStore.ts
4036
+ import { randomUUID as randomUUID4 } from "crypto";
4037
+ var DDL17 = `
4038
+ CREATE TABLE IF NOT EXISTS lt_open_audit (
4039
+ id TEXT PRIMARY KEY,
4040
+ tenant_id TEXT NOT NULL,
4041
+ credential_id TEXT NOT NULL,
4042
+ credential_kind TEXT NOT NULL,
4043
+ project_id TEXT NOT NULL,
4044
+ domain TEXT NOT NULL,
4045
+ action TEXT NOT NULL,
4046
+ args TEXT,
4047
+ status TEXT NOT NULL,
4048
+ error_code TEXT,
4049
+ duration_ms INTEGER NOT NULL,
4050
+ created_at TEXT NOT NULL
4051
+ );
4052
+ `;
4053
+ var LocalOpenAuditStore = class {
4054
+ constructor(db) {
4055
+ this.db = db;
4056
+ ensureTable(db, DDL17);
4057
+ }
4058
+ async query(params) {
4059
+ const clauses = ["tenant_id = ?"];
4060
+ const values = [params.tenantId];
4061
+ if (params.credentialId) {
4062
+ clauses.push("credential_id = ?");
4063
+ values.push(params.credentialId);
4064
+ }
4065
+ if (params.domain) {
4066
+ clauses.push("domain = ?");
4067
+ values.push(params.domain);
4068
+ }
4069
+ if (params.status) {
4070
+ clauses.push("status = ?");
4071
+ values.push(params.status);
4072
+ }
4073
+ if (params.from) {
4074
+ clauses.push("created_at >= ?");
4075
+ values.push(params.from);
4076
+ }
4077
+ if (params.to) {
4078
+ clauses.push("created_at < ?");
4079
+ values.push(params.to);
4080
+ }
4081
+ const limit = params.limit ?? 100;
4082
+ const offset = params.offset ?? 0;
4083
+ values.push(limit, offset);
4084
+ const rows2 = this.db.prepare(
4085
+ `SELECT * FROM lt_open_audit WHERE ${clauses.join(" AND ")}
4086
+ ORDER BY created_at DESC LIMIT ? OFFSET ?`
4087
+ ).all(...values);
4088
+ return rows2.map((row) => ({
4089
+ id: row.id,
4090
+ tenantId: row.tenant_id,
4091
+ credentialId: row.credential_id,
4092
+ credentialKind: row.credential_kind,
4093
+ projectId: row.project_id,
4094
+ domain: row.domain,
4095
+ action: row.action,
4096
+ args: row.args ? JSON.parse(row.args) : void 0,
4097
+ status: row.status,
4098
+ errorCode: row.error_code ?? void 0,
4099
+ durationMs: row.duration_ms,
4100
+ createdAt: parseISO(row.created_at)
4101
+ }));
4102
+ }
4103
+ async append(record2) {
4104
+ this.db.prepare(
4105
+ `INSERT INTO lt_open_audit
4106
+ (id, tenant_id, credential_id, credential_kind, project_id, domain, action, args, status, error_code, duration_ms, created_at)
4107
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
4108
+ ).run(
4109
+ randomUUID4(),
4110
+ record2.tenantId,
4111
+ record2.credentialId,
4112
+ record2.credentialKind,
4113
+ record2.projectId,
4114
+ record2.domain,
4115
+ record2.action,
4116
+ record2.args === void 0 ? null : JSON.stringify(record2.args),
4117
+ record2.status,
4118
+ record2.errorCode ?? null,
4119
+ Math.max(0, Math.round(record2.durationMs)),
4120
+ nowISO()
4121
+ );
4122
+ }
4123
+ };
4124
+
3975
4125
  // src/stores/LocalThreadMessageQueueStore.ts
3976
4126
  import {
3977
4127
  parseQueuedExecutionMode,
3978
4128
  parseTrustedRunContext
3979
4129
  } from "@axiom-lattice/protocols";
3980
- import { randomUUID as randomUUID4 } from "crypto";
3981
- var DDL17 = `
4130
+ import { randomUUID as randomUUID5 } from "crypto";
4131
+ var DDL18 = `
3982
4132
  CREATE TABLE IF NOT EXISTS lt_thread_message_queue (
3983
4133
  id TEXT PRIMARY KEY,
3984
4134
  thread_id TEXT NOT NULL,
@@ -4004,7 +4154,7 @@ var LocalThreadMessageQueueStore = class {
4004
4154
  constructor(db) {
4005
4155
  this.capacityTail = Promise.resolve();
4006
4156
  this.db = db;
4007
- ensureTable(db, DDL17);
4157
+ ensureTable(db, DDL18);
4008
4158
  const columns6 = db.prepare("PRAGMA table_info(lt_thread_message_queue)").all();
4009
4159
  const names = new Set(columns6.map(({ name }) => name));
4010
4160
  if (!names.has("trusted_run_context")) {
@@ -4017,7 +4167,7 @@ var LocalThreadMessageQueueStore = class {
4017
4167
  async addMessage(params) {
4018
4168
  const trusted = validateQueueTrust(params);
4019
4169
  const now = nowISO();
4020
- const id = params.id || randomUUID4();
4170
+ const id = params.id || randomUUID5();
4021
4171
  const seqRow = this.db.prepare(
4022
4172
  `SELECT COALESCE(MAX(sequence_order), 0) + 1 as next_seq FROM lt_thread_message_queue WHERE thread_id = ?`
4023
4173
  ).get(params.threadId);
@@ -4060,7 +4210,7 @@ var LocalThreadMessageQueueStore = class {
4060
4210
  projectId: params.projectId
4061
4211
  };
4062
4212
  const filter = scopeClause(scope);
4063
- const id = params.id || randomUUID4();
4213
+ const id = params.id || randomUUID5();
4064
4214
  const limit = maxSize === Infinity ? -1 : maxSize;
4065
4215
  const result = this.db.prepare(
4066
4216
  `INSERT INTO lt_thread_message_queue (id, thread_id, tenant_id, assistant_id, workspace_id, project_id, message_content, message_type, sequence_order, priority, command, custom_run_config, trusted_run_context, execution_mode, created_at)
@@ -4098,7 +4248,7 @@ var LocalThreadMessageQueueStore = class {
4098
4248
  async addMessageAtHead(params) {
4099
4249
  const trusted = validateQueueTrust(params);
4100
4250
  const now = nowISO();
4101
- const id = params.id || randomUUID4();
4251
+ const id = params.id || randomUUID5();
4102
4252
  const seqRow = this.db.prepare(
4103
4253
  `SELECT COALESCE(MAX(sequence_order), 0) + 1 as next_seq FROM lt_thread_message_queue WHERE thread_id = ?`
4104
4254
  ).get(params.threadId);
@@ -4217,7 +4367,7 @@ function rowToMessage(row) {
4217
4367
  }
4218
4368
 
4219
4369
  // src/stores/LocalSkillStore.ts
4220
- var DDL18 = `
4370
+ var DDL19 = `
4221
4371
  CREATE TABLE IF NOT EXISTS lt_skills (
4222
4372
  id TEXT NOT NULL,
4223
4373
  tenant_id TEXT NOT NULL,
@@ -4236,7 +4386,7 @@ CREATE TABLE IF NOT EXISTS lt_skills (
4236
4386
  var LocalSkillStore = class {
4237
4387
  constructor(db) {
4238
4388
  this.db = db;
4239
- ensureTable(db, DDL18);
4389
+ ensureTable(db, DDL19);
4240
4390
  }
4241
4391
  async getAllSkills(tenantId, _context) {
4242
4392
  const rows2 = this.db.prepare(
@@ -4386,7 +4536,7 @@ function mapRowToSkill(row) {
4386
4536
  }
4387
4537
 
4388
4538
  // src/stores/LocalScheduleStorage.ts
4389
- var DDL19 = `
4539
+ var DDL20 = `
4390
4540
  CREATE TABLE IF NOT EXISTS lt_scheduled_tasks (
4391
4541
  task_id TEXT PRIMARY KEY,
4392
4542
  task_type TEXT NOT NULL,
@@ -4419,7 +4569,7 @@ CREATE INDEX IF NOT EXISTS idx_lt_st_tenant ON lt_scheduled_tasks(tenant_id);
4419
4569
  var LocalScheduleStorage = class {
4420
4570
  constructor(db) {
4421
4571
  this.db = db;
4422
- ensureTable(db, DDL19);
4572
+ ensureTable(db, DDL20);
4423
4573
  }
4424
4574
  async save(task) {
4425
4575
  this.db.prepare(
@@ -4713,7 +4863,7 @@ function mapRowToTask(row) {
4713
4863
  }
4714
4864
 
4715
4865
  // src/stores/LocalTaskStore.ts
4716
- import { randomUUID as randomUUID5 } from "crypto";
4866
+ import { randomUUID as randomUUID6 } from "crypto";
4717
4867
  var MAX_CANONICAL_TASK_TIME = "9999-12-31T23:59:59.999Z";
4718
4868
  var TASK_STATUSES = /* @__PURE__ */ new Set([
4719
4869
  "pending",
@@ -4729,7 +4879,7 @@ var NEXT_UPDATED_AT_SQL = `updated_at = CASE
4729
4879
  THEN strftime('%Y-%m-%dT%H:%M:%fZ', updated_at, '+0.001 seconds')
4730
4880
  ELSE ?
4731
4881
  END`;
4732
- var DDL20 = `
4882
+ var DDL21 = `
4733
4883
  CREATE TABLE IF NOT EXISTS lt_tasks (
4734
4884
  id TEXT NOT NULL,
4735
4885
  tenant_id TEXT NOT NULL,
@@ -4802,7 +4952,7 @@ function assertPage(limit, offset = 0) {
4802
4952
  var LocalTaskStore = class {
4803
4953
  constructor(db) {
4804
4954
  this.db = db;
4805
- ensureTable(db, DDL20);
4955
+ ensureTable(db, DDL21);
4806
4956
  this.ensureColumn("lt_tasks", "require_review", "require_review INTEGER DEFAULT 0");
4807
4957
  this.ensureColumn("lt_tasks", "dependencies", "dependencies TEXT");
4808
4958
  this.ensureColumn("lt_tasks", "result", "result TEXT");
@@ -4819,7 +4969,7 @@ var LocalTaskStore = class {
4819
4969
  }
4820
4970
  }
4821
4971
  async create(params) {
4822
- const id = params.id ?? randomUUID5();
4972
+ const id = params.id ?? randomUUID6();
4823
4973
  const now = nowISO();
4824
4974
  this.db.prepare(
4825
4975
  `INSERT INTO lt_tasks (id, tenant_id, owner_type, owner_id, title, description, status, priority, due_date, metadata, parent_id, source_id, context, require_review, dependencies, result, failure_reason, workspace_id, project_id, files, created_at, updated_at)
@@ -5479,7 +5629,7 @@ var PROJECT_LIFECYCLE_ACTIONS = /* @__PURE__ */ new Set([
5479
5629
  "cancelled",
5480
5630
  "reassigned"
5481
5631
  ]);
5482
- var DDL21 = `
5632
+ var DDL22 = `
5483
5633
  CREATE TABLE IF NOT EXISTS lt_task_work_items (
5484
5634
  id TEXT NOT NULL,
5485
5635
  tenant_id TEXT NOT NULL,
@@ -5553,7 +5703,7 @@ function assertLifecyclePage(query) {
5553
5703
  var LocalTaskWorkItemStore = class {
5554
5704
  constructor(db) {
5555
5705
  this.db = db;
5556
- ensureTable(db, DDL21);
5706
+ ensureTable(db, DDL22);
5557
5707
  this.ensureColumn("lt_task_work_items", "workspace_id", "workspace_id TEXT");
5558
5708
  this.ensureColumn("lt_task_work_items", "project_id", "project_id TEXT");
5559
5709
  this.ensureColumn("lt_task_work_items", "event_key", "event_key TEXT");
@@ -5749,8 +5899,8 @@ var LocalTaskWorkItemStore = class {
5749
5899
  };
5750
5900
 
5751
5901
  // src/stores/LocalCapabilityBundleStore.ts
5752
- import { randomUUID as randomUUID6 } from "crypto";
5753
- var DDL22 = `CREATE TABLE IF NOT EXISTS lt_capability_bundles (id TEXT NOT NULL, tenant_id TEXT NOT NULL, bundle_key TEXT NOT NULL, name TEXT NOT NULL, description TEXT, capabilities TEXT NOT NULL DEFAULT '[]', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, PRIMARY KEY (tenant_id, id), UNIQUE (tenant_id, bundle_key)); CREATE INDEX IF NOT EXISTS idx_lt_capability_bundles_tenant ON lt_capability_bundles(tenant_id);`;
5902
+ import { randomUUID as randomUUID7 } from "crypto";
5903
+ var DDL23 = `CREATE TABLE IF NOT EXISTS lt_capability_bundles (id TEXT NOT NULL, tenant_id TEXT NOT NULL, bundle_key TEXT NOT NULL, name TEXT NOT NULL, description TEXT, capabilities TEXT NOT NULL DEFAULT '[]', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, PRIMARY KEY (tenant_id, id), UNIQUE (tenant_id, bundle_key)); CREATE INDEX IF NOT EXISTS idx_lt_capability_bundles_tenant ON lt_capability_bundles(tenant_id);`;
5754
5904
  var duplicateMessage = "Capability bundle key already exists for tenant";
5755
5905
  function map(row) {
5756
5906
  return { id: row.id, tenantId: row.tenant_id, key: row.bundle_key, name: row.name, description: row.description ?? void 0, capabilities: JSON.parse(row.capabilities), createdAt: parseISO(row.created_at).toISOString(), updatedAt: parseISO(row.updated_at).toISOString() };
@@ -5771,7 +5921,7 @@ var LocalCapabilityBundleStore = class {
5771
5921
  */
5772
5922
  constructor(db) {
5773
5923
  this.db = db;
5774
- ensureTable(db, DDL22);
5924
+ ensureTable(db, DDL23);
5775
5925
  }
5776
5926
  async listByTenant(tenantId) {
5777
5927
  return this.db.prepare("SELECT * FROM lt_capability_bundles WHERE tenant_id = ? ORDER BY created_at").all(tenantId).map(map);
@@ -5788,7 +5938,7 @@ var LocalCapabilityBundleStore = class {
5788
5938
  }
5789
5939
  async create(tenantId, input) {
5790
5940
  const now = nextTimestamp();
5791
- const id = randomUUID6();
5941
+ const id = randomUUID7();
5792
5942
  try {
5793
5943
  this.db.prepare("INSERT INTO lt_capability_bundles (id, tenant_id, bundle_key, name, description, capabilities, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)").run(id, tenantId, input.key, input.name, input.description ?? null, JSON.stringify(input.capabilities), now, now);
5794
5944
  } catch (error) {
@@ -5870,6 +6020,7 @@ async function createLocalStoreConfig(options = {}) {
5870
6020
  channelBinding: new LocalChannelBindingStore(db),
5871
6021
  channelInstallation: new LocalChannelInstallationStore(db),
5872
6022
  a2aApiKey: new LocalA2AApiKeyStore(db),
6023
+ openAudit: new LocalOpenAuditStore(db),
5873
6024
  threadMessageQueue: new LocalThreadMessageQueueStore(db),
5874
6025
  skill: new LocalSkillStore(db),
5875
6026
  schedule: new LocalScheduleStorage(db),
@@ -5931,6 +6082,7 @@ export {
5931
6082
  LocalEvalStore,
5932
6083
  LocalMcpServerConfigStore,
5933
6084
  LocalMetricsServerConfigStore,
6085
+ LocalOpenAuditStore,
5934
6086
  LocalProjectBotMembershipStore,
5935
6087
  LocalProjectMembershipStore,
5936
6088
  LocalProjectRoomMessageStore,