bopodev-db 0.1.23 → 0.1.25

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bopodev-db",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
package/src/bootstrap.ts CHANGED
@@ -20,6 +20,9 @@ export async function bootstrapDatabase(dbPath?: string) {
20
20
  description TEXT,
21
21
  status TEXT NOT NULL DEFAULT 'planned',
22
22
  planned_start_at TIMESTAMP,
23
+ monthly_budget_usd NUMERIC(12, 4) NOT NULL DEFAULT 100,
24
+ used_budget_usd NUMERIC(12, 4) NOT NULL DEFAULT 0,
25
+ budget_window_start_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
23
26
  execution_workspace_policy TEXT,
24
27
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
25
28
  updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
@@ -37,6 +40,18 @@ export async function bootstrapDatabase(dbPath?: string) {
37
40
  ALTER TABLE projects
38
41
  ADD COLUMN IF NOT EXISTS execution_workspace_policy TEXT;
39
42
  `);
43
+ await db.execute(sql`
44
+ ALTER TABLE projects
45
+ ADD COLUMN IF NOT EXISTS monthly_budget_usd NUMERIC(12, 4) NOT NULL DEFAULT 100;
46
+ `);
47
+ await db.execute(sql`
48
+ ALTER TABLE projects
49
+ ADD COLUMN IF NOT EXISTS used_budget_usd NUMERIC(12, 4) NOT NULL DEFAULT 0;
50
+ `);
51
+ await db.execute(sql`
52
+ ALTER TABLE projects
53
+ ADD COLUMN IF NOT EXISTS budget_window_start_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
54
+ `);
40
55
  await db.execute(sql`
41
56
  ALTER TABLE projects
42
57
  ADD COLUMN IF NOT EXISTS updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
@@ -79,6 +94,8 @@ export async function bootstrapDatabase(dbPath?: string) {
79
94
  company_id TEXT NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
80
95
  manager_agent_id TEXT,
81
96
  role TEXT NOT NULL,
97
+ role_key TEXT,
98
+ title TEXT,
82
99
  name TEXT NOT NULL,
83
100
  provider_type TEXT NOT NULL,
84
101
  status TEXT NOT NULL DEFAULT 'idle',
@@ -107,6 +124,14 @@ export async function bootstrapDatabase(dbPath?: string) {
107
124
  ALTER TABLE agents
108
125
  ADD COLUMN IF NOT EXISTS avatar_seed TEXT NOT NULL DEFAULT '';
109
126
  `);
127
+ await db.execute(sql`
128
+ ALTER TABLE agents
129
+ ADD COLUMN IF NOT EXISTS role_key TEXT;
130
+ `);
131
+ await db.execute(sql`
132
+ ALTER TABLE agents
133
+ ADD COLUMN IF NOT EXISTS title TEXT;
134
+ `);
110
135
  await db.execute(sql`
111
136
  ALTER TABLE agents
112
137
  ADD COLUMN IF NOT EXISTS runtime_command TEXT;
@@ -195,10 +220,20 @@ export async function bootstrapDatabase(dbPath?: string) {
195
220
  company_id TEXT NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
196
221
  author_type TEXT NOT NULL,
197
222
  author_id TEXT,
223
+ recipients_json TEXT NOT NULL DEFAULT '[]',
224
+ run_id TEXT,
198
225
  body TEXT NOT NULL,
199
226
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
200
227
  );
201
228
  `);
229
+ await db.execute(sql`
230
+ ALTER TABLE issue_comments
231
+ ADD COLUMN IF NOT EXISTS recipients_json TEXT NOT NULL DEFAULT '[]';
232
+ `);
233
+ await db.execute(sql`
234
+ ALTER TABLE issue_comments
235
+ ADD COLUMN IF NOT EXISTS run_id TEXT;
236
+ `);
202
237
  await db.execute(sql`
203
238
  CREATE TABLE IF NOT EXISTS issue_attachments (
204
239
  id TEXT PRIMARY KEY,
@@ -237,6 +272,35 @@ export async function bootstrapDatabase(dbPath?: string) {
237
272
  message TEXT
238
273
  );
239
274
  `);
275
+ await db.execute(sql`
276
+ CREATE TABLE IF NOT EXISTS heartbeat_run_queue (
277
+ id TEXT PRIMARY KEY,
278
+ company_id TEXT NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
279
+ agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
280
+ job_type TEXT NOT NULL,
281
+ payload_json TEXT NOT NULL DEFAULT '{}',
282
+ status TEXT NOT NULL DEFAULT 'pending',
283
+ priority INTEGER NOT NULL DEFAULT 100,
284
+ idempotency_key TEXT,
285
+ available_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
286
+ attempt_count INTEGER NOT NULL DEFAULT 0,
287
+ max_attempts INTEGER NOT NULL DEFAULT 10,
288
+ last_error TEXT,
289
+ started_at TIMESTAMP,
290
+ finished_at TIMESTAMP,
291
+ heartbeat_run_id TEXT REFERENCES heartbeat_runs(id) ON DELETE SET NULL,
292
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
293
+ updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
294
+ );
295
+ `);
296
+ await db.execute(sql`
297
+ ALTER TABLE heartbeat_run_queue
298
+ ADD COLUMN IF NOT EXISTS idempotency_key TEXT;
299
+ `);
300
+ await db.execute(sql`
301
+ ALTER TABLE heartbeat_run_queue
302
+ ADD COLUMN IF NOT EXISTS heartbeat_run_id TEXT REFERENCES heartbeat_runs(id) ON DELETE SET NULL;
303
+ `);
240
304
  await db.execute(sql`
241
305
  CREATE TABLE IF NOT EXISTS heartbeat_run_messages (
242
306
  id TEXT PRIMARY KEY,
@@ -289,6 +353,20 @@ export async function bootstrapDatabase(dbPath?: string) {
289
353
  PRIMARY KEY (company_id, actor_id, approval_id)
290
354
  );
291
355
  `);
356
+ await db.execute(sql`
357
+ CREATE TABLE IF NOT EXISTS attention_inbox_states (
358
+ company_id TEXT NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
359
+ actor_id TEXT NOT NULL,
360
+ item_key TEXT NOT NULL,
361
+ seen_at TIMESTAMP,
362
+ acknowledged_at TIMESTAMP,
363
+ dismissed_at TIMESTAMP,
364
+ resolved_at TIMESTAMP,
365
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
366
+ updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
367
+ PRIMARY KEY (company_id, actor_id, item_key)
368
+ );
369
+ `);
292
370
  await db.execute(sql`
293
371
  CREATE TABLE IF NOT EXISTS cost_ledger (
294
372
  id TEXT PRIMARY KEY,
@@ -442,6 +520,10 @@ export async function bootstrapDatabase(dbPath?: string) {
442
520
  CREATE INDEX IF NOT EXISTS idx_issues_company_status
443
521
  ON issues (company_id, status, updated_at);
444
522
  `);
523
+ await db.execute(sql`
524
+ CREATE INDEX IF NOT EXISTS idx_issues_assignee_claim_priority
525
+ ON issues (company_id, assignee_agent_id, is_claimed, status, priority, updated_at);
526
+ `);
445
527
  await db.execute(sql`
446
528
  CREATE INDEX IF NOT EXISTS idx_issue_attachments_company_issue
447
529
  ON issue_attachments (company_id, issue_id, created_at DESC);
@@ -463,6 +545,19 @@ export async function bootstrapDatabase(dbPath?: string) {
463
545
  ON heartbeat_runs (company_id, agent_id)
464
546
  WHERE status = 'started';
465
547
  `);
548
+ await db.execute(sql`
549
+ CREATE INDEX IF NOT EXISTS idx_heartbeat_run_queue_status_available_priority
550
+ ON heartbeat_run_queue (company_id, status, available_at ASC, priority ASC, created_at ASC);
551
+ `);
552
+ await db.execute(sql`
553
+ CREATE INDEX IF NOT EXISTS idx_heartbeat_run_queue_agent_status
554
+ ON heartbeat_run_queue (company_id, agent_id, status, available_at ASC, created_at ASC);
555
+ `);
556
+ await db.execute(sql`
557
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_heartbeat_run_queue_idempotency
558
+ ON heartbeat_run_queue (company_id, agent_id, idempotency_key)
559
+ WHERE idempotency_key IS NOT NULL AND btrim(idempotency_key) <> '';
560
+ `);
466
561
  await db.execute(sql`
467
562
  CREATE INDEX IF NOT EXISTS idx_heartbeat_run_messages_company_run_sequence
468
563
  ON heartbeat_run_messages (company_id, run_id, sequence ASC);
@@ -475,6 +570,10 @@ export async function bootstrapDatabase(dbPath?: string) {
475
570
  CREATE INDEX IF NOT EXISTS idx_approval_inbox_states_company_actor_updated
476
571
  ON approval_inbox_states (company_id, actor_id, updated_at DESC);
477
572
  `);
573
+ await db.execute(sql`
574
+ CREATE INDEX IF NOT EXISTS idx_attention_inbox_states_company_actor_updated
575
+ ON attention_inbox_states (company_id, actor_id, updated_at DESC);
576
+ `);
478
577
  await db.execute(sql`
479
578
  CREATE INDEX IF NOT EXISTS idx_plugin_configs_company_enabled_priority
480
579
  ON plugin_configs (company_id, enabled, priority ASC, plugin_id ASC);