@revealui/harnesses 0.1.8 → 0.1.9

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/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  HarnessCoordinator,
4
4
  checkHarnessesLicense
5
- } from "./chunk-6E2BKO6U.js";
5
+ } from "./chunk-YYAYTCRM.js";
6
6
  import {
7
7
  buildManifest,
8
8
  diffContent,
@@ -10,12 +10,12 @@ import {
10
10
  listContent,
11
11
  listGenerators,
12
12
  validateManifest
13
- } from "./chunk-PROC6EJC.js";
14
- import "./chunk-DGQ5OB6L.js";
13
+ } from "./chunk-ZNIQELKZ.js";
14
+ import "./chunk-ANX4L2PF.js";
15
15
  import {
16
16
  WorkboardManager
17
- } from "./chunk-4F4ANKIZ.js";
18
- import "./chunk-DGUM43GV.js";
17
+ } from "./chunk-Y4FFO3TO.js";
18
+ import "./chunk-3RG5ZIWI.js";
19
19
 
20
20
  // src/cli.ts
21
21
  import { mkdirSync, unlinkSync, writeFileSync } from "fs";
@@ -572,4 +572,3 @@ main().catch((err) => {
572
572
  `);
573
573
  process.exit(1);
574
574
  });
575
- //# sourceMappingURL=cli.js.map
@@ -192,7 +192,7 @@ declare function resolveTemplate(template: string, ctx: ResolverContext): string
192
192
  declare function listResolvers(): string[];
193
193
 
194
194
  /**
195
- * @revealui/harnesses/contentCanonical Content Layer
195
+ * @revealui/harnesses/content - Canonical Content Layer
196
196
  *
197
197
  * Tool-agnostic definitions for AI guidance content (rules, commands, agents, skills).
198
198
  * Generators produce tool-specific output (Claude Code, Cursor, etc.) from canonical definitions.
@@ -16,8 +16,8 @@ import {
16
16
  registerResolver,
17
17
  resolveTemplate,
18
18
  validateManifest
19
- } from "../chunk-PROC6EJC.js";
20
- import "../chunk-DGUM43GV.js";
19
+ } from "../chunk-ZNIQELKZ.js";
20
+ import "../chunk-3RG5ZIWI.js";
21
21
  export {
22
22
  AgentSchema,
23
23
  CommandSchema,
@@ -37,4 +37,3 @@ export {
37
37
  resolveTemplate,
38
38
  validateManifest
39
39
  };
40
- //# sourceMappingURL=index.js.map
@@ -0,0 +1,266 @@
1
+ /**
2
+ * PGlite schema for the RevDev Harness daemon.
3
+ *
4
+ * Five tables provide persistent state for multi-agent coordination:
5
+ * - agent_sessions: active and historical agent sessions
6
+ * - agent_messages: inter-agent mailbox (point-to-point + broadcast)
7
+ * - file_reservations: advisory file locks with CAS semantics
8
+ * - tasks: claimable work items with CAS ownership
9
+ * - events: append-only event log for audit trail
10
+ *
11
+ * Uses raw SQL (no Drizzle ORM) to keep the daemon dependency-free.
12
+ * PGlite runs in-process - no external database needed.
13
+ */
14
+ /** SQL statements to initialize the daemon database. */
15
+ declare const SCHEMA_SQL = "\n CREATE TABLE IF NOT EXISTS agent_sessions (\n id TEXT PRIMARY KEY,\n env TEXT NOT NULL DEFAULT '',\n task TEXT NOT NULL DEFAULT '(starting)',\n files TEXT NOT NULL DEFAULT '',\n pid INTEGER,\n started_at TIMESTAMP NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMP NOT NULL DEFAULT NOW(),\n ended_at TIMESTAMP,\n exit_summary TEXT\n );\n\n CREATE TABLE IF NOT EXISTS agent_messages (\n id SERIAL PRIMARY KEY,\n from_agent TEXT NOT NULL,\n to_agent TEXT NOT NULL,\n subject TEXT NOT NULL DEFAULT '',\n body TEXT NOT NULL DEFAULT '',\n read BOOLEAN NOT NULL DEFAULT FALSE,\n created_at TIMESTAMP NOT NULL DEFAULT NOW()\n );\n\n CREATE INDEX IF NOT EXISTS idx_messages_to_unread\n ON agent_messages (to_agent, read) WHERE read = FALSE;\n\n CREATE TABLE IF NOT EXISTS file_reservations (\n file_path TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL,\n reserved_at TIMESTAMP NOT NULL DEFAULT NOW(),\n expires_at TIMESTAMP NOT NULL,\n reason TEXT NOT NULL DEFAULT ''\n );\n\n CREATE INDEX IF NOT EXISTS idx_reservations_agent\n ON file_reservations (agent_id);\n\n CREATE TABLE IF NOT EXISTS tasks (\n id TEXT PRIMARY KEY,\n description TEXT NOT NULL DEFAULT '',\n status TEXT NOT NULL DEFAULT 'open',\n owner TEXT,\n claimed_at TIMESTAMP,\n completed_at TIMESTAMP,\n created_at TIMESTAMP NOT NULL DEFAULT NOW()\n );\n\n CREATE INDEX IF NOT EXISTS idx_tasks_status\n ON tasks (status);\n\n CREATE INDEX IF NOT EXISTS idx_tasks_owner\n ON tasks (owner) WHERE owner IS NOT NULL;\n\n CREATE TABLE IF NOT EXISTS events (\n id SERIAL PRIMARY KEY,\n agent_id TEXT NOT NULL,\n event_type TEXT NOT NULL,\n payload JSONB NOT NULL DEFAULT '{}',\n created_at TIMESTAMP NOT NULL DEFAULT NOW()\n );\n\n CREATE INDEX IF NOT EXISTS idx_events_agent\n ON events (agent_id, created_at DESC);\n\n CREATE TABLE IF NOT EXISTS worktrees (\n agent_id TEXT PRIMARY KEY,\n branch TEXT NOT NULL,\n worktree_path TEXT NOT NULL,\n base_branch TEXT NOT NULL DEFAULT 'test',\n status TEXT NOT NULL DEFAULT 'active',\n created_at TIMESTAMP NOT NULL DEFAULT NOW()\n );\n\n CREATE TABLE IF NOT EXISTS agent_memory (\n id SERIAL PRIMARY KEY,\n agent_id TEXT NOT NULL,\n memory_type TEXT NOT NULL,\n content TEXT NOT NULL,\n metadata JSONB NOT NULL DEFAULT '{}',\n created_at TIMESTAMP NOT NULL DEFAULT NOW()\n );\n\n CREATE INDEX IF NOT EXISTS idx_memory_agent_type\n ON agent_memory (agent_id, memory_type, created_at DESC);\n\n CREATE TABLE IF NOT EXISTS merge_requests (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL,\n task_id TEXT,\n source_branch TEXT NOT NULL,\n base_branch TEXT NOT NULL DEFAULT 'test',\n status TEXT NOT NULL DEFAULT 'pending',\n pr_number INTEGER,\n pr_url TEXT,\n retry_count INTEGER NOT NULL DEFAULT 0,\n error_message TEXT,\n ci_output TEXT,\n created_at TIMESTAMP NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMP NOT NULL DEFAULT NOW()\n );\n\n CREATE INDEX IF NOT EXISTS idx_merge_requests_agent\n ON merge_requests (agent_id, status);\n\n CREATE INDEX IF NOT EXISTS idx_merge_requests_branch\n ON merge_requests (source_branch);\n\n CREATE INDEX IF NOT EXISTS idx_merge_requests_pr\n ON merge_requests (pr_number) WHERE pr_number IS NOT NULL;\n";
16
+ /** Session row shape. */
17
+ interface AgentSession {
18
+ id: string;
19
+ env: string;
20
+ task: string;
21
+ files: string;
22
+ pid: number | null;
23
+ started_at: string;
24
+ updated_at: string;
25
+ ended_at: string | null;
26
+ exit_summary: string | null;
27
+ }
28
+ /** Message row shape. */
29
+ interface AgentMessage {
30
+ id: number;
31
+ from_agent: string;
32
+ to_agent: string;
33
+ subject: string;
34
+ body: string;
35
+ read: boolean;
36
+ created_at: string;
37
+ }
38
+ /** File reservation row shape. */
39
+ interface FileReservation {
40
+ file_path: string;
41
+ agent_id: string;
42
+ reserved_at: string;
43
+ expires_at: string;
44
+ reason: string;
45
+ }
46
+ /** Task row shape. */
47
+ interface AgentTask {
48
+ id: string;
49
+ description: string;
50
+ status: 'open' | 'claimed' | 'completed';
51
+ owner: string | null;
52
+ claimed_at: string | null;
53
+ completed_at: string | null;
54
+ created_at: string;
55
+ }
56
+ /** Event row shape. */
57
+ interface DaemonEvent {
58
+ id: number;
59
+ agent_id: string;
60
+ event_type: string;
61
+ payload: Record<string, unknown>;
62
+ created_at: string;
63
+ }
64
+ /** Worktree row shape. */
65
+ interface AgentWorktree {
66
+ agent_id: string;
67
+ branch: string;
68
+ worktree_path: string;
69
+ base_branch: string;
70
+ status: 'active' | 'merged' | 'abandoned';
71
+ created_at: string;
72
+ }
73
+ /** Merge request row shape. */
74
+ interface MergeRequest {
75
+ id: string;
76
+ agent_id: string;
77
+ task_id: string | null;
78
+ source_branch: string;
79
+ base_branch: string;
80
+ status: 'pending' | 'merging' | 'pr_created' | 'ci_running' | 'merged' | 'ci_failed' | 'conflict' | 'escalated';
81
+ pr_number: number | null;
82
+ pr_url: string | null;
83
+ retry_count: number;
84
+ error_message: string | null;
85
+ ci_output: string | null;
86
+ created_at: string;
87
+ updated_at: string;
88
+ }
89
+ /** Memory row shape. */
90
+ interface AgentMemoryEntry {
91
+ id: number;
92
+ agent_id: string;
93
+ memory_type: 'thought' | 'action' | 'result' | 'decision' | 'disagreement';
94
+ content: string;
95
+ metadata: Record<string, unknown>;
96
+ created_at: string;
97
+ }
98
+
99
+ /**
100
+ * DaemonStore - persistent state for the RevDev Harness daemon.
101
+ *
102
+ * Backed by PGlite (in-process PostgreSQL). The database file lives at
103
+ * ~/.local/share/revealui/harness.db and survives daemon restarts.
104
+ *
105
+ * All methods are async (PGlite queries return promises).
106
+ */
107
+
108
+ /** Configuration for DaemonStore. */
109
+ interface DaemonStoreConfig {
110
+ /** PGlite data directory (default: ~/.local/share/revealui/harness.db) */
111
+ dataDir: string;
112
+ }
113
+ declare class DaemonStore {
114
+ private db;
115
+ private readonly dataDir;
116
+ constructor(config: DaemonStoreConfig);
117
+ /** Initialize PGlite and create tables. */
118
+ init(): Promise<void>;
119
+ /** Shut down the database. */
120
+ close(): Promise<void>;
121
+ private getDb;
122
+ /** Register or update an agent session. */
123
+ registerSession(session: {
124
+ id: string;
125
+ env: string;
126
+ task?: string;
127
+ pid?: number;
128
+ }): Promise<AgentSession>;
129
+ /** Update a session's task and/or files. */
130
+ updateSession(id: string, updates: {
131
+ task?: string;
132
+ files?: string;
133
+ }): Promise<AgentSession | null>;
134
+ /** End a session (mark ended_at, record exit summary). */
135
+ endSession(id: string, exitSummary?: string): Promise<void>;
136
+ /** Get all active sessions (ended_at IS NULL). */
137
+ getActiveSessions(): Promise<AgentSession[]>;
138
+ /** Get session history for an agent (most recent first). */
139
+ getSessionHistory(agentId: string, limit: number): Promise<AgentSession[]>;
140
+ /** Send a message from one agent to another. */
141
+ sendMessage(msg: {
142
+ fromAgent: string;
143
+ toAgent: string;
144
+ subject: string;
145
+ body?: string;
146
+ }): Promise<AgentMessage>;
147
+ /** Broadcast a message to all active agents (except sender). */
148
+ broadcastMessage(msg: {
149
+ fromAgent: string;
150
+ subject: string;
151
+ body?: string;
152
+ }): Promise<number>;
153
+ /** Get unread messages for an agent. */
154
+ getInbox(agentId: string, unreadOnly: boolean): Promise<AgentMessage[]>;
155
+ /** Mark messages as read. */
156
+ markRead(messageIds: number[]): Promise<void>;
157
+ /** Reserve a file for an agent (CAS: fails if already reserved by another). */
158
+ reserveFile(reservation: {
159
+ filePath: string;
160
+ agentId: string;
161
+ ttlSeconds: number;
162
+ reason?: string;
163
+ }): Promise<{
164
+ success: boolean;
165
+ holder?: string;
166
+ }>;
167
+ /** Check who holds a file reservation. */
168
+ checkReservation(filePath: string): Promise<FileReservation | null>;
169
+ /** Release all reservations held by an agent. */
170
+ releaseAllReservations(agentId: string): Promise<number>;
171
+ /** Get all reservations for an agent. */
172
+ getReservations(agentId: string): Promise<FileReservation[]>;
173
+ /** Create a new task. */
174
+ createTask(task: {
175
+ id: string;
176
+ description: string;
177
+ }): Promise<AgentTask>;
178
+ /** Claim a task atomically (CAS: fails if already claimed by another agent). */
179
+ claimTask(taskId: string, agentId: string): Promise<{
180
+ success: boolean;
181
+ owner?: string;
182
+ }>;
183
+ /** Complete a task (only the owner can complete it). */
184
+ completeTask(taskId: string, agentId: string): Promise<boolean>;
185
+ /** Release a claimed task back to open (only the owner can release). */
186
+ releaseTask(taskId: string, agentId: string): Promise<boolean>;
187
+ /** List tasks, optionally filtered by status and/or owner. */
188
+ listTasks(filter?: {
189
+ status?: string;
190
+ owner?: string;
191
+ }): Promise<AgentTask[]>;
192
+ /** Append an event to the audit log. */
193
+ logEvent(event: {
194
+ agentId: string;
195
+ eventType: string;
196
+ payload?: Record<string, unknown>;
197
+ }): Promise<DaemonEvent>;
198
+ /** Get recent events (newest first). */
199
+ getRecentEvents(limit: number): Promise<DaemonEvent[]>;
200
+ /** Prune events older than a given number of days. */
201
+ pruneEvents(olderThanDays: number): Promise<number>;
202
+ /** Register a worktree for an agent. */
203
+ registerWorktree(wt: {
204
+ agentId: string;
205
+ branch: string;
206
+ worktreePath: string;
207
+ baseBranch?: string;
208
+ }): Promise<AgentWorktree>;
209
+ /** Get a worktree by agent ID. */
210
+ getWorktree(agentId: string): Promise<AgentWorktree | null>;
211
+ /** List all active worktrees. */
212
+ getActiveWorktrees(): Promise<AgentWorktree[]>;
213
+ /** Update worktree status (active → merged | abandoned). */
214
+ updateWorktreeStatus(agentId: string, status: 'merged' | 'abandoned'): Promise<boolean>;
215
+ /** Remove a worktree record. */
216
+ removeWorktree(agentId: string): Promise<boolean>;
217
+ /** Store a memory entry. */
218
+ storeMemory(entry: {
219
+ agentId: string;
220
+ memoryType: AgentMemoryEntry['memory_type'];
221
+ content: string;
222
+ metadata?: Record<string, unknown>;
223
+ }): Promise<AgentMemoryEntry>;
224
+ /** Recall memory entries by agent and type (newest first). */
225
+ recallMemory(query: {
226
+ agentId?: string;
227
+ memoryType?: AgentMemoryEntry['memory_type'];
228
+ keyword?: string;
229
+ limit?: number;
230
+ }): Promise<AgentMemoryEntry[]>;
231
+ /** Get a summary of recent memory (last N per type for context injection). */
232
+ summarizeMemory(agentId: string, perType: number): Promise<AgentMemoryEntry[]>;
233
+ /** Prune old memory entries (keep last N per agent). */
234
+ pruneMemory(keepPerAgent: number): Promise<number>;
235
+ /** Create a merge request for an agent's branch. */
236
+ createMergeRequest(mr: {
237
+ id: string;
238
+ agentId: string;
239
+ taskId?: string;
240
+ sourceBranch: string;
241
+ baseBranch?: string;
242
+ }): Promise<MergeRequest>;
243
+ /** Get a merge request by ID. */
244
+ getMergeRequest(id: string): Promise<MergeRequest | null>;
245
+ /** Get a merge request by source branch. */
246
+ getMergeRequestByBranch(branch: string): Promise<MergeRequest | null>;
247
+ /** Get a merge request by PR number. */
248
+ getMergeRequestByPr(prNumber: number): Promise<MergeRequest | null>;
249
+ /** Update a merge request's fields. */
250
+ updateMergeRequest(id: string, updates: {
251
+ status?: MergeRequest['status'];
252
+ prNumber?: number;
253
+ prUrl?: string;
254
+ errorMessage?: string;
255
+ ciOutput?: string;
256
+ }): Promise<MergeRequest | null>;
257
+ /** Increment the retry count for a merge request. */
258
+ incrementMergeRetry(id: string): Promise<number>;
259
+ /** List merge requests, optionally filtered by status and/or agent. */
260
+ listMergeRequests(filter?: {
261
+ status?: string;
262
+ agentId?: string;
263
+ }): Promise<MergeRequest[]>;
264
+ }
265
+
266
+ export { type AgentMessage as A, DaemonStore as D, type FileReservation as F, type MergeRequest as M, SCHEMA_SQL as S, type AgentSession as a, type AgentTask as b, type DaemonEvent as c, type DaemonStoreConfig as d };