@revealui/harnesses 0.1.8 → 0.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/README.md +6 -6
- package/dist/{chunk-DGUM43GV.js → chunk-3RG5ZIWI.js} +0 -1
- package/dist/{chunk-4F4ANKIZ.js → chunk-ADRJ4TTV.js} +27 -11
- package/dist/{chunk-DGQ5OB6L.js → chunk-ANX4L2PF.js} +273 -2
- package/dist/{chunk-PROC6EJC.js → chunk-HHIAUUJB.js} +186 -342
- package/dist/{chunk-6E2BKO6U.js → chunk-VQWARLZO.js} +1330 -354
- package/dist/cli.js +5 -6
- package/dist/content/index.d.ts +1 -1
- package/dist/content/index.js +2 -3
- package/dist/index-w5ashbfb.d.ts +266 -0
- package/dist/index.d.ts +539 -85
- package/dist/index.js +34 -11
- package/dist/storage/index.d.ts +1 -170
- package/dist/storage/index.js +2 -3
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +0 -1
- package/dist/workboard/index.d.ts +27 -27
- package/dist/workboard/index.js +2 -7
- package/package.json +23 -6
- package/dist/chunk-4F4ANKIZ.js.map +0 -1
- package/dist/chunk-6E2BKO6U.js.map +0 -1
- package/dist/chunk-DGQ5OB6L.js.map +0 -1
- package/dist/chunk-DGUM43GV.js.map +0 -1
- package/dist/chunk-PROC6EJC.js.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/content/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/storage/index.js.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/workboard/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# @revealui/harnesses
|
|
2
2
|
|
|
3
|
-
> **Commercial package**
|
|
3
|
+
> **Commercial package** - requires a [RevealUI Pro license](https://revealui.com/pro). Free to install and evaluate; a license key is required for production use.
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
AI harness coordination for RevealUI
|
|
6
|
+
AI harness coordination for RevealUI - enables multiple AI coding tools to work on the same codebase safely and in parallel.
|
|
7
7
|
|
|
8
8
|
## Features
|
|
9
9
|
|
|
@@ -99,10 +99,10 @@ pnpm --filter @revealui/harnesses build
|
|
|
99
99
|
|
|
100
100
|
## Related Documentation
|
|
101
101
|
|
|
102
|
-
- [Coordination Rules](../../.claude/rules/coordination.md)
|
|
103
|
-
- [Architecture Guide](../../docs/ARCHITECTURE.md)
|
|
104
|
-
- [Editors Package](../editors/README.md)
|
|
102
|
+
- [Coordination Rules](../../.claude/rules/coordination.md) - Multi-instance protocol
|
|
103
|
+
- [Architecture Guide](../../docs/ARCHITECTURE.md) - System architecture
|
|
104
|
+
- [Editors Package](../editors/README.md) - Editor daemon (parallel architecture)
|
|
105
105
|
|
|
106
106
|
## License
|
|
107
107
|
|
|
108
|
-
Commercial
|
|
108
|
+
Commercial - see [LICENSE.commercial](../../LICENSE.commercial)
|
|
@@ -89,11 +89,31 @@ function lockPathFor(workboardPath) {
|
|
|
89
89
|
// src/workboard/session-identity.ts
|
|
90
90
|
import { readFileSync as readFileSync2 } from "fs";
|
|
91
91
|
function detectSessionType() {
|
|
92
|
+
const vaughnId = process.env.VAUGHN_AGENT_ID;
|
|
93
|
+
if (vaughnId) {
|
|
94
|
+
const tool = vaughnId.split("-")[0]?.toLowerCase();
|
|
95
|
+
if (tool === "claude") return "claude";
|
|
96
|
+
if (tool === "codex") return "codex";
|
|
97
|
+
if (tool === "cursor") return "cursor";
|
|
98
|
+
if (tool === "zed") return "zed";
|
|
99
|
+
return "terminal";
|
|
100
|
+
}
|
|
101
|
+
if (process.env.CLAUDE_AGENT_ROLE) return "claude";
|
|
102
|
+
try {
|
|
103
|
+
const cachePath = `/tmp/vaughn-session-${process.ppid}.id`;
|
|
104
|
+
const cached = readFileSync2(cachePath, "utf8").trim();
|
|
105
|
+
if (cached === "claude" || cached === "codex" || cached === "zed" || cached === "cursor") {
|
|
106
|
+
return cached;
|
|
107
|
+
}
|
|
108
|
+
} catch {
|
|
109
|
+
}
|
|
92
110
|
try {
|
|
93
111
|
let pid = process.ppid;
|
|
94
112
|
for (let depth = 0; depth < 8; depth++) {
|
|
95
113
|
if (!pid || pid <= 1) break;
|
|
96
114
|
const cmdline = readFileSync2(`/proc/${pid}/cmdline`, "utf8").replace(/\0/g, " ").toLowerCase();
|
|
115
|
+
if (cmdline.includes("claude")) return "claude";
|
|
116
|
+
if (cmdline.includes("codex")) return "codex";
|
|
97
117
|
if (cmdline.includes("zed")) return "zed";
|
|
98
118
|
if (cmdline.includes("cursor")) return "cursor";
|
|
99
119
|
const status = readFileSync2(`/proc/${pid}/status`, "utf8");
|
|
@@ -158,7 +178,7 @@ function parseTable(lines) {
|
|
|
158
178
|
for (let j = 0; j < columns.length; j++) {
|
|
159
179
|
const col = columns[j];
|
|
160
180
|
const raw = (cells[j] || "").trim();
|
|
161
|
-
row[col] = raw === "
|
|
181
|
+
row[col] = raw === "-" ? "" : raw;
|
|
162
182
|
}
|
|
163
183
|
rows.push(row);
|
|
164
184
|
}
|
|
@@ -204,13 +224,13 @@ function parseWorkboard(content) {
|
|
|
204
224
|
return state;
|
|
205
225
|
}
|
|
206
226
|
function padCell(value, width) {
|
|
207
|
-
const str = String(value || "
|
|
227
|
+
const str = String(value || " - ");
|
|
208
228
|
return str.length >= width ? str : str + " ".repeat(width - str.length);
|
|
209
229
|
}
|
|
210
230
|
function serializeTable(headers, rows) {
|
|
211
231
|
if (headers.length === 0) return "(none)";
|
|
212
232
|
const widths = headers.map((h) => {
|
|
213
|
-
const dataMax = rows.reduce((max, row) => Math.max(max, String(row[h] || "
|
|
233
|
+
const dataMax = rows.reduce((max, row) => Math.max(max, String(row[h] || " - ").length), 0);
|
|
214
234
|
return Math.max(h.length, dataMax, 3);
|
|
215
235
|
});
|
|
216
236
|
const headerLine = `| ${headers.map((h, i) => padCell(h, widths[i])).join(" | ")} |`;
|
|
@@ -287,6 +307,7 @@ var WorkboardManager = class {
|
|
|
287
307
|
}
|
|
288
308
|
this.lockPath = lockPathFor(resolved);
|
|
289
309
|
}
|
|
310
|
+
workboardPath;
|
|
290
311
|
lockPath;
|
|
291
312
|
// ---- Read/Write ----
|
|
292
313
|
read() {
|
|
@@ -522,20 +543,15 @@ var WorkboardManager = class {
|
|
|
522
543
|
function emptyState() {
|
|
523
544
|
return { preamble: [], agents: [], tasks: [], blocked: [], done: [], log: [], _extra: {} };
|
|
524
545
|
}
|
|
525
|
-
var registerSession = WorkboardManager.prototype.registerAgent;
|
|
526
|
-
var unregisterSession = WorkboardManager.prototype.unregisterAgent;
|
|
527
546
|
|
|
528
547
|
export {
|
|
548
|
+
detectSessionType,
|
|
549
|
+
deriveSessionId,
|
|
529
550
|
acquireLock,
|
|
530
551
|
releaseLock,
|
|
531
552
|
withLock,
|
|
532
553
|
withLockAsync,
|
|
533
554
|
atomicWriteSync,
|
|
534
555
|
lockPathFor,
|
|
535
|
-
WorkboardManager
|
|
536
|
-
registerSession,
|
|
537
|
-
unregisterSession,
|
|
538
|
-
detectSessionType,
|
|
539
|
-
deriveSessionId
|
|
556
|
+
WorkboardManager
|
|
540
557
|
};
|
|
541
|
-
//# sourceMappingURL=chunk-4F4ANKIZ.js.map
|
|
@@ -62,6 +62,52 @@ var SCHEMA_SQL = `
|
|
|
62
62
|
|
|
63
63
|
CREATE INDEX IF NOT EXISTS idx_events_agent
|
|
64
64
|
ON events (agent_id, created_at DESC);
|
|
65
|
+
|
|
66
|
+
CREATE TABLE IF NOT EXISTS worktrees (
|
|
67
|
+
agent_id TEXT PRIMARY KEY,
|
|
68
|
+
branch TEXT NOT NULL,
|
|
69
|
+
worktree_path TEXT NOT NULL,
|
|
70
|
+
base_branch TEXT NOT NULL DEFAULT 'test',
|
|
71
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
72
|
+
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
CREATE TABLE IF NOT EXISTS agent_memory (
|
|
76
|
+
id SERIAL PRIMARY KEY,
|
|
77
|
+
agent_id TEXT NOT NULL,
|
|
78
|
+
memory_type TEXT NOT NULL,
|
|
79
|
+
content TEXT NOT NULL,
|
|
80
|
+
metadata JSONB NOT NULL DEFAULT '{}',
|
|
81
|
+
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
CREATE INDEX IF NOT EXISTS idx_memory_agent_type
|
|
85
|
+
ON agent_memory (agent_id, memory_type, created_at DESC);
|
|
86
|
+
|
|
87
|
+
CREATE TABLE IF NOT EXISTS merge_requests (
|
|
88
|
+
id TEXT PRIMARY KEY,
|
|
89
|
+
agent_id TEXT NOT NULL,
|
|
90
|
+
task_id TEXT,
|
|
91
|
+
source_branch TEXT NOT NULL,
|
|
92
|
+
base_branch TEXT NOT NULL DEFAULT 'test',
|
|
93
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
94
|
+
pr_number INTEGER,
|
|
95
|
+
pr_url TEXT,
|
|
96
|
+
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
97
|
+
error_message TEXT,
|
|
98
|
+
ci_output TEXT,
|
|
99
|
+
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
100
|
+
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
CREATE INDEX IF NOT EXISTS idx_merge_requests_agent
|
|
104
|
+
ON merge_requests (agent_id, status);
|
|
105
|
+
|
|
106
|
+
CREATE INDEX IF NOT EXISTS idx_merge_requests_branch
|
|
107
|
+
ON merge_requests (source_branch);
|
|
108
|
+
|
|
109
|
+
CREATE INDEX IF NOT EXISTS idx_merge_requests_pr
|
|
110
|
+
ON merge_requests (pr_number) WHERE pr_number IS NOT NULL;
|
|
65
111
|
`;
|
|
66
112
|
|
|
67
113
|
// src/storage/daemon-store.ts
|
|
@@ -85,7 +131,7 @@ var DaemonStore = class {
|
|
|
85
131
|
}
|
|
86
132
|
}
|
|
87
133
|
getDb() {
|
|
88
|
-
if (!this.db) throw new Error("DaemonStore not initialized
|
|
134
|
+
if (!this.db) throw new Error("DaemonStore not initialized - call init() first");
|
|
89
135
|
return this.db;
|
|
90
136
|
}
|
|
91
137
|
// ---------------------------------------------------------------------------
|
|
@@ -371,10 +417,235 @@ var DaemonStore = class {
|
|
|
371
417
|
);
|
|
372
418
|
return result.affectedRows ?? 0;
|
|
373
419
|
}
|
|
420
|
+
// ---------------------------------------------------------------------------
|
|
421
|
+
// Worktrees
|
|
422
|
+
// ---------------------------------------------------------------------------
|
|
423
|
+
/** Register a worktree for an agent. */
|
|
424
|
+
async registerWorktree(wt) {
|
|
425
|
+
const db = this.getDb();
|
|
426
|
+
const result = await db.query(
|
|
427
|
+
`INSERT INTO worktrees (agent_id, branch, worktree_path, base_branch)
|
|
428
|
+
VALUES ($1, $2, $3, $4)
|
|
429
|
+
ON CONFLICT (agent_id) DO UPDATE SET
|
|
430
|
+
branch = EXCLUDED.branch,
|
|
431
|
+
worktree_path = EXCLUDED.worktree_path,
|
|
432
|
+
base_branch = EXCLUDED.base_branch,
|
|
433
|
+
status = 'active'
|
|
434
|
+
RETURNING *`,
|
|
435
|
+
[wt.agentId, wt.branch, wt.worktreePath, wt.baseBranch ?? "test"]
|
|
436
|
+
);
|
|
437
|
+
return result.rows[0];
|
|
438
|
+
}
|
|
439
|
+
/** Get a worktree by agent ID. */
|
|
440
|
+
async getWorktree(agentId) {
|
|
441
|
+
const db = this.getDb();
|
|
442
|
+
const result = await db.query("SELECT * FROM worktrees WHERE agent_id = $1", [
|
|
443
|
+
agentId
|
|
444
|
+
]);
|
|
445
|
+
return result.rows[0] ?? null;
|
|
446
|
+
}
|
|
447
|
+
/** List all active worktrees. */
|
|
448
|
+
async getActiveWorktrees() {
|
|
449
|
+
const db = this.getDb();
|
|
450
|
+
const result = await db.query(
|
|
451
|
+
"SELECT * FROM worktrees WHERE status = 'active' ORDER BY created_at"
|
|
452
|
+
);
|
|
453
|
+
return result.rows;
|
|
454
|
+
}
|
|
455
|
+
/** Update worktree status (active → merged | abandoned). */
|
|
456
|
+
async updateWorktreeStatus(agentId, status) {
|
|
457
|
+
const db = this.getDb();
|
|
458
|
+
const result = await db.query(
|
|
459
|
+
"UPDATE worktrees SET status = $2 WHERE agent_id = $1 RETURNING agent_id",
|
|
460
|
+
[agentId, status]
|
|
461
|
+
);
|
|
462
|
+
return (result.rows?.length ?? 0) > 0;
|
|
463
|
+
}
|
|
464
|
+
/** Remove a worktree record. */
|
|
465
|
+
async removeWorktree(agentId) {
|
|
466
|
+
const db = this.getDb();
|
|
467
|
+
const result = await db.query("DELETE FROM worktrees WHERE agent_id = $1 RETURNING agent_id", [
|
|
468
|
+
agentId
|
|
469
|
+
]);
|
|
470
|
+
return (result.rows?.length ?? 0) > 0;
|
|
471
|
+
}
|
|
472
|
+
// ---------------------------------------------------------------------------
|
|
473
|
+
// Agent Memory
|
|
474
|
+
// ---------------------------------------------------------------------------
|
|
475
|
+
/** Store a memory entry. */
|
|
476
|
+
async storeMemory(entry) {
|
|
477
|
+
const db = this.getDb();
|
|
478
|
+
const result = await db.query(
|
|
479
|
+
`INSERT INTO agent_memory (agent_id, memory_type, content, metadata)
|
|
480
|
+
VALUES ($1, $2, $3, $4)
|
|
481
|
+
RETURNING *`,
|
|
482
|
+
[entry.agentId, entry.memoryType, entry.content, JSON.stringify(entry.metadata ?? {})]
|
|
483
|
+
);
|
|
484
|
+
return result.rows[0];
|
|
485
|
+
}
|
|
486
|
+
/** Recall memory entries by agent and type (newest first). */
|
|
487
|
+
async recallMemory(query) {
|
|
488
|
+
const db = this.getDb();
|
|
489
|
+
const conditions = [];
|
|
490
|
+
const params = [];
|
|
491
|
+
let paramIdx = 1;
|
|
492
|
+
if (query.agentId) {
|
|
493
|
+
conditions.push(`agent_id = $${paramIdx++}`);
|
|
494
|
+
params.push(query.agentId);
|
|
495
|
+
}
|
|
496
|
+
if (query.memoryType) {
|
|
497
|
+
conditions.push(`memory_type = $${paramIdx++}`);
|
|
498
|
+
params.push(query.memoryType);
|
|
499
|
+
}
|
|
500
|
+
if (query.keyword) {
|
|
501
|
+
conditions.push(`content ILIKE $${paramIdx++}`);
|
|
502
|
+
params.push(`%${query.keyword}%`);
|
|
503
|
+
}
|
|
504
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
505
|
+
const limit = query.limit ?? 20;
|
|
506
|
+
params.push(limit);
|
|
507
|
+
const result = await db.query(
|
|
508
|
+
`SELECT * FROM agent_memory ${where} ORDER BY created_at DESC LIMIT $${paramIdx}`,
|
|
509
|
+
params
|
|
510
|
+
);
|
|
511
|
+
return result.rows;
|
|
512
|
+
}
|
|
513
|
+
/** Get a summary of recent memory (last N per type for context injection). */
|
|
514
|
+
async summarizeMemory(agentId, perType) {
|
|
515
|
+
const db = this.getDb();
|
|
516
|
+
const result = await db.query(
|
|
517
|
+
`SELECT * FROM (
|
|
518
|
+
SELECT *, ROW_NUMBER() OVER (PARTITION BY memory_type ORDER BY created_at DESC) AS rn
|
|
519
|
+
FROM agent_memory WHERE agent_id = $1
|
|
520
|
+
) sub WHERE rn <= $2
|
|
521
|
+
ORDER BY memory_type, created_at DESC`,
|
|
522
|
+
[agentId, perType]
|
|
523
|
+
);
|
|
524
|
+
return result.rows;
|
|
525
|
+
}
|
|
526
|
+
/** Prune old memory entries (keep last N per agent). */
|
|
527
|
+
async pruneMemory(keepPerAgent) {
|
|
528
|
+
const db = this.getDb();
|
|
529
|
+
const result = await db.query(
|
|
530
|
+
`DELETE FROM agent_memory WHERE id IN (
|
|
531
|
+
SELECT id FROM (
|
|
532
|
+
SELECT id, ROW_NUMBER() OVER (PARTITION BY agent_id ORDER BY created_at DESC) AS rn
|
|
533
|
+
FROM agent_memory
|
|
534
|
+
) sub WHERE rn > $1
|
|
535
|
+
)`,
|
|
536
|
+
[keepPerAgent]
|
|
537
|
+
);
|
|
538
|
+
return result.affectedRows ?? 0;
|
|
539
|
+
}
|
|
540
|
+
// ---------------------------------------------------------------------------
|
|
541
|
+
// Merge Requests
|
|
542
|
+
// ---------------------------------------------------------------------------
|
|
543
|
+
/** Create a merge request for an agent's branch. */
|
|
544
|
+
async createMergeRequest(mr) {
|
|
545
|
+
const db = this.getDb();
|
|
546
|
+
const result = await db.query(
|
|
547
|
+
`INSERT INTO merge_requests (id, agent_id, task_id, source_branch, base_branch)
|
|
548
|
+
VALUES ($1, $2, $3, $4, $5)
|
|
549
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
550
|
+
status = 'pending',
|
|
551
|
+
retry_count = merge_requests.retry_count,
|
|
552
|
+
updated_at = NOW()
|
|
553
|
+
RETURNING *`,
|
|
554
|
+
[mr.id, mr.agentId, mr.taskId ?? null, mr.sourceBranch, mr.baseBranch ?? "test"]
|
|
555
|
+
);
|
|
556
|
+
return result.rows[0];
|
|
557
|
+
}
|
|
558
|
+
/** Get a merge request by ID. */
|
|
559
|
+
async getMergeRequest(id) {
|
|
560
|
+
const db = this.getDb();
|
|
561
|
+
const result = await db.query("SELECT * FROM merge_requests WHERE id = $1", [id]);
|
|
562
|
+
return result.rows[0] ?? null;
|
|
563
|
+
}
|
|
564
|
+
/** Get a merge request by source branch. */
|
|
565
|
+
async getMergeRequestByBranch(branch) {
|
|
566
|
+
const db = this.getDb();
|
|
567
|
+
const result = await db.query(
|
|
568
|
+
"SELECT * FROM merge_requests WHERE source_branch = $1 AND status NOT IN ('merged', 'escalated') ORDER BY created_at DESC LIMIT 1",
|
|
569
|
+
[branch]
|
|
570
|
+
);
|
|
571
|
+
return result.rows[0] ?? null;
|
|
572
|
+
}
|
|
573
|
+
/** Get a merge request by PR number. */
|
|
574
|
+
async getMergeRequestByPr(prNumber) {
|
|
575
|
+
const db = this.getDb();
|
|
576
|
+
const result = await db.query(
|
|
577
|
+
"SELECT * FROM merge_requests WHERE pr_number = $1 ORDER BY created_at DESC LIMIT 1",
|
|
578
|
+
[prNumber]
|
|
579
|
+
);
|
|
580
|
+
return result.rows[0] ?? null;
|
|
581
|
+
}
|
|
582
|
+
/** Update a merge request's fields. */
|
|
583
|
+
async updateMergeRequest(id, updates) {
|
|
584
|
+
const db = this.getDb();
|
|
585
|
+
const sets = ["updated_at = NOW()"];
|
|
586
|
+
const params = [];
|
|
587
|
+
let paramIdx = 1;
|
|
588
|
+
if (updates.status !== void 0) {
|
|
589
|
+
sets.push(`status = $${paramIdx++}`);
|
|
590
|
+
params.push(updates.status);
|
|
591
|
+
}
|
|
592
|
+
if (updates.prNumber !== void 0) {
|
|
593
|
+
sets.push(`pr_number = $${paramIdx++}`);
|
|
594
|
+
params.push(updates.prNumber);
|
|
595
|
+
}
|
|
596
|
+
if (updates.prUrl !== void 0) {
|
|
597
|
+
sets.push(`pr_url = $${paramIdx++}`);
|
|
598
|
+
params.push(updates.prUrl);
|
|
599
|
+
}
|
|
600
|
+
if (updates.errorMessage !== void 0) {
|
|
601
|
+
sets.push(`error_message = $${paramIdx++}`);
|
|
602
|
+
params.push(updates.errorMessage);
|
|
603
|
+
}
|
|
604
|
+
if (updates.ciOutput !== void 0) {
|
|
605
|
+
sets.push(`ci_output = $${paramIdx++}`);
|
|
606
|
+
params.push(updates.ciOutput);
|
|
607
|
+
}
|
|
608
|
+
params.push(id);
|
|
609
|
+
const result = await db.query(
|
|
610
|
+
`UPDATE merge_requests SET ${sets.join(", ")} WHERE id = $${paramIdx} RETURNING *`,
|
|
611
|
+
params
|
|
612
|
+
);
|
|
613
|
+
return result.rows[0] ?? null;
|
|
614
|
+
}
|
|
615
|
+
/** Increment the retry count for a merge request. */
|
|
616
|
+
async incrementMergeRetry(id) {
|
|
617
|
+
const db = this.getDb();
|
|
618
|
+
const result = await db.query(
|
|
619
|
+
`UPDATE merge_requests SET retry_count = retry_count + 1, updated_at = NOW()
|
|
620
|
+
WHERE id = $1 RETURNING retry_count`,
|
|
621
|
+
[id]
|
|
622
|
+
);
|
|
623
|
+
return result.rows[0]?.retry_count ?? 0;
|
|
624
|
+
}
|
|
625
|
+
/** List merge requests, optionally filtered by status and/or agent. */
|
|
626
|
+
async listMergeRequests(filter) {
|
|
627
|
+
const db = this.getDb();
|
|
628
|
+
const conditions = [];
|
|
629
|
+
const params = [];
|
|
630
|
+
let paramIdx = 1;
|
|
631
|
+
if (filter?.status) {
|
|
632
|
+
conditions.push(`status = $${paramIdx++}`);
|
|
633
|
+
params.push(filter.status);
|
|
634
|
+
}
|
|
635
|
+
if (filter?.agentId) {
|
|
636
|
+
conditions.push(`agent_id = $${paramIdx++}`);
|
|
637
|
+
params.push(filter.agentId);
|
|
638
|
+
}
|
|
639
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
640
|
+
const result = await db.query(
|
|
641
|
+
`SELECT * FROM merge_requests ${where} ORDER BY created_at DESC`,
|
|
642
|
+
params
|
|
643
|
+
);
|
|
644
|
+
return result.rows;
|
|
645
|
+
}
|
|
374
646
|
};
|
|
375
647
|
|
|
376
648
|
export {
|
|
377
649
|
SCHEMA_SQL,
|
|
378
650
|
DaemonStore
|
|
379
651
|
};
|
|
380
|
-
//# sourceMappingURL=chunk-DGQ5OB6L.js.map
|