patchrelay 0.36.8 → 0.36.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "service": "patchrelay",
3
- "version": "0.36.8",
4
- "commit": "a62440fe88ab",
5
- "builtAt": "2026-04-09T12:45:27.217Z"
3
+ "version": "0.36.10",
4
+ "commit": "35d99f024954",
5
+ "builtAt": "2026-04-09T16:10:38.473Z"
6
6
  }
@@ -20,7 +20,7 @@ export async function collectClusterHealth(config, db, runCommand) {
20
20
  });
21
21
  const snapshots = openIssues.map((issue) => {
22
22
  const tracked = db.getTrackedIssue(issue.projectId, issue.linearIssueId);
23
- const deps = db.listIssueDependencies(issue.projectId, issue.linearIssueId);
23
+ const deps = db.issues.listIssueDependencies(issue.projectId, issue.linearIssueId);
24
24
  const blockedBy = deps.filter((dep) => !isResolvedDependency(dep));
25
25
  const missingTrackedBlockers = blockedBy.filter((dep) => {
26
26
  if (trackedByLinearId.has(dep.blockerLinearIssueId))
package/dist/cli/data.js CHANGED
@@ -94,7 +94,7 @@ export class CliDataAccess extends CliOperatorApiClient {
94
94
  const issue = this.db.getTrackedIssueByKey(issueKey);
95
95
  if (!issue)
96
96
  return undefined;
97
- const dbIssue = this.db.getIssueByKey(issueKey);
97
+ const dbIssue = this.db.issues.getIssueByKey(issueKey);
98
98
  const activeRun = dbIssue.activeRunId ? this.db.runs.getRunById(dbIssue.activeRunId) : undefined;
99
99
  const latestRun = this.db.runs.getLatestRunForIssue(issue.projectId, issue.linearIssueId);
100
100
  const latestReport = normalizeStageReport(latestRun?.reportJson, latestRun?.status);
@@ -120,7 +120,7 @@ export class CliDataAccess extends CliOperatorApiClient {
120
120
  const issue = this.db.getTrackedIssueByKey(issueKey);
121
121
  if (!issue)
122
122
  return undefined;
123
- const dbIssue = this.db.getIssueByKey(issueKey);
123
+ const dbIssue = this.db.issues.getIssueByKey(issueKey);
124
124
  const run = dbIssue.activeRunId ? this.db.runs.getRunById(dbIssue.activeRunId) : undefined;
125
125
  if (!run)
126
126
  return undefined;
@@ -132,7 +132,7 @@ export class CliDataAccess extends CliOperatorApiClient {
132
132
  const issue = this.db.getTrackedIssueByKey(issueKey);
133
133
  if (!issue)
134
134
  return undefined;
135
- const dbIssue = this.db.getIssueByKey(issueKey);
135
+ const dbIssue = this.db.issues.getIssueByKey(issueKey);
136
136
  if (!dbIssue.branchName || !dbIssue.worktreePath)
137
137
  return undefined;
138
138
  return { issue, branchName: dbIssue.branchName, worktreePath: dbIssue.worktreePath, repoId: issue.projectId };
@@ -141,7 +141,7 @@ export class CliDataAccess extends CliOperatorApiClient {
141
141
  const worktree = this.worktree(issueKey);
142
142
  if (!worktree)
143
143
  return undefined;
144
- const dbIssue = this.db.getIssueByKey(issueKey);
144
+ const dbIssue = this.db.issues.getIssueByKey(issueKey);
145
145
  const resumeThreadId = dbIssue.threadId ?? undefined;
146
146
  return {
147
147
  ...worktree,
@@ -155,7 +155,7 @@ export class CliDataAccess extends CliOperatorApiClient {
155
155
  if (options?.ensureWorktree) {
156
156
  await this.ensureOpenWorktree(worktree);
157
157
  }
158
- const dbIssue = this.db.getIssueByKey(issueKey);
158
+ const dbIssue = this.db.issues.getIssueByKey(issueKey);
159
159
  const existingThreadId = dbIssue.threadId;
160
160
  if (existingThreadId && (await this.canReadThread(existingThreadId))) {
161
161
  return { ...worktree, resumeThreadId: existingThreadId };
@@ -165,7 +165,7 @@ export class CliDataAccess extends CliOperatorApiClient {
165
165
  }
166
166
  const codex = await this.getCodex();
167
167
  const thread = await codex.startThread({ cwd: worktree.worktreePath });
168
- this.db.upsertIssue({
168
+ this.db.issues.upsertIssue({
169
169
  projectId: worktree.issue.projectId,
170
170
  linearIssueId: worktree.issue.linearIssueId,
171
171
  threadId: thread.id,
@@ -179,7 +179,7 @@ export class CliDataAccess extends CliOperatorApiClient {
179
179
  const issue = this.db.getTrackedIssueByKey(issueKey);
180
180
  if (!issue)
181
181
  return undefined;
182
- const dbIssue = this.db.getIssueByKey(issueKey);
182
+ const dbIssue = this.db.issues.getIssueByKey(issueKey);
183
183
  const issueSession = this.db.issueSessions.getIssueSession(issue.projectId, issue.linearIssueId);
184
184
  if (dbIssue.activeRunId !== undefined) {
185
185
  throw new Error(`Issue ${issueKey} already has an active run.`);
@@ -200,7 +200,7 @@ export class CliDataAccess extends CliOperatorApiClient {
200
200
  ? "changes_requested"
201
201
  : "delegated";
202
202
  this.appendRetryWake(dbIssue, runType);
203
- this.db.upsertIssue({
203
+ this.db.issues.upsertIssue({
204
204
  projectId: issue.projectId,
205
205
  linearIssueId: issue.linearIssueId,
206
206
  pendingRunType: null,
@@ -214,13 +214,14 @@ export class CliDataAccess extends CliOperatorApiClient {
214
214
  const issue = this.db.getTrackedIssueByKey(issueKey);
215
215
  if (!issue)
216
216
  return undefined;
217
- const dbIssue = this.db.getIssueByKey(issueKey);
217
+ const dbIssue = this.db.issues.getIssueByKey(issueKey);
218
218
  const runs = this.db.runs.listRunsForIssue(issue.projectId, issue.linearIssueId);
219
219
  const sessions = runs
220
220
  .slice()
221
221
  .reverse()
222
222
  .map((run) => {
223
223
  const summary = summarizeRun(run);
224
+ const eventCount = this.db.runs.listThreadEvents(run.id).length;
224
225
  return {
225
226
  runId: run.id,
226
227
  runType: run.runType,
@@ -230,7 +231,8 @@ export class CliDataAccess extends CliOperatorApiClient {
230
231
  ...(run.parentThreadId ? { parentThreadId: run.parentThreadId } : {}),
231
232
  ...(summary ? { summary } : {}),
232
233
  ...(run.failureReason ? { failureReason: run.failureReason } : {}),
233
- eventCount: this.db.runs.listThreadEvents(run.id).length,
234
+ eventCount,
235
+ eventCountAvailable: this.config.runner.codex.persistExtendedHistory || eventCount > 0,
234
236
  startedAt: run.startedAt,
235
237
  ...(run.endedAt ? { endedAt: run.endedAt } : {}),
236
238
  isCurrentThread: run.threadId !== undefined && run.threadId === dbIssue.threadId,
@@ -106,7 +106,9 @@ export function formatSessionHistory(result, buildOpenForThread) {
106
106
  if (session.turnId) {
107
107
  lines.push(value("Turn", session.turnId));
108
108
  }
109
- lines.push(value("Events", session.eventCount));
109
+ lines.push(value("Events", session.eventCountAvailable
110
+ ? session.eventCount
111
+ : "not persisted (persistExtendedHistory=false)"));
110
112
  if (session.summary) {
111
113
  lines.push(value("Summary", truncateLine(session.summary)));
112
114
  }
@@ -4,24 +4,16 @@ export class IssueSessionStore {
4
4
  connection;
5
5
  mapIssueSessionRow;
6
6
  mapIssueSessionEventRow;
7
- getIssue;
7
+ issues;
8
+ runs;
8
9
  deriveImplicitReactiveWake;
9
- transaction;
10
- upsertIssue;
11
- finishRun;
12
- updateRunThread;
13
- setBranchOwner;
14
- constructor(connection, mapIssueSessionRow, mapIssueSessionEventRow, getIssue, deriveImplicitReactiveWake, transaction, upsertIssue, finishRun, updateRunThread, setBranchOwner) {
10
+ constructor(connection, mapIssueSessionRow, mapIssueSessionEventRow, issues, runs, deriveImplicitReactiveWake) {
15
11
  this.connection = connection;
16
12
  this.mapIssueSessionRow = mapIssueSessionRow;
17
13
  this.mapIssueSessionEventRow = mapIssueSessionEventRow;
18
- this.getIssue = getIssue;
14
+ this.issues = issues;
15
+ this.runs = runs;
19
16
  this.deriveImplicitReactiveWake = deriveImplicitReactiveWake;
20
- this.transaction = transaction;
21
- this.upsertIssue = upsertIssue;
22
- this.finishRun = finishRun;
23
- this.updateRunThread = updateRunThread;
24
- this.setBranchOwner = setBranchOwner;
25
17
  }
26
18
  getIssueSession(projectId, linearIssueId) {
27
19
  const row = this.connection
@@ -107,7 +99,7 @@ export class IssueSessionStore {
107
99
  return row !== undefined;
108
100
  }
109
101
  peekIssueSessionWake(projectId, linearIssueId) {
110
- const issue = this.getIssue(projectId, linearIssueId);
102
+ const issue = this.issues.getIssue(projectId, linearIssueId);
111
103
  if (!issue)
112
104
  return undefined;
113
105
  const events = this.listIssueSessionEvents(projectId, linearIssueId, { pendingOnly: true });
@@ -201,40 +193,40 @@ export class IssueSessionStore {
201
193
  return { projectId, linearIssueId, leaseId };
202
194
  }
203
195
  withIssueSessionLease(projectId, linearIssueId, leaseId, fn) {
204
- return this.transaction(() => {
196
+ return this.connection.transaction(() => {
205
197
  if (!this.hasActiveIssueSessionLease(projectId, linearIssueId, leaseId)) {
206
198
  return undefined;
207
199
  }
208
200
  return fn();
209
- });
201
+ })();
210
202
  }
211
203
  upsertIssueWithLease(lease, params) {
212
- return this.withIssueSessionLease(lease.projectId, lease.linearIssueId, lease.leaseId, () => this.upsertIssue(params));
204
+ return this.withIssueSessionLease(lease.projectId, lease.linearIssueId, lease.leaseId, () => this.issues.upsertIssue(params));
213
205
  }
214
206
  upsertIssueRespectingActiveLease(projectId, linearIssueId, params) {
215
207
  const lease = this.getActiveIssueSessionLease(projectId, linearIssueId);
216
208
  if (!lease) {
217
- return this.upsertIssue(params);
209
+ return this.issues.upsertIssue(params);
218
210
  }
219
211
  return this.upsertIssueWithLease(lease, params);
220
212
  }
221
213
  finishRunWithLease(lease, runId, params) {
222
214
  return this.withIssueSessionLease(lease.projectId, lease.linearIssueId, lease.leaseId, () => {
223
- this.finishRun(runId, params);
215
+ this.runs.finishRun(runId, params);
224
216
  return true;
225
217
  }) ?? false;
226
218
  }
227
219
  finishRunRespectingActiveLease(projectId, linearIssueId, runId, params) {
228
220
  const lease = this.getActiveIssueSessionLease(projectId, linearIssueId);
229
221
  if (!lease) {
230
- this.finishRun(runId, params);
222
+ this.runs.finishRun(runId, params);
231
223
  return true;
232
224
  }
233
225
  return this.finishRunWithLease(lease, runId, params);
234
226
  }
235
227
  updateRunThreadWithLease(lease, runId, params) {
236
228
  return this.withIssueSessionLease(lease.projectId, lease.linearIssueId, lease.leaseId, () => {
237
- this.updateRunThread(runId, params);
229
+ this.runs.updateRunThread(runId, params);
238
230
  return true;
239
231
  }) ?? false;
240
232
  }
@@ -273,14 +265,14 @@ export class IssueSessionStore {
273
265
  }
274
266
  setBranchOwnerWithLease(lease, owner) {
275
267
  return this.withIssueSessionLease(lease.projectId, lease.linearIssueId, lease.leaseId, () => {
276
- this.setBranchOwner(lease.projectId, lease.linearIssueId, owner);
268
+ this.issues.setBranchOwner(lease.projectId, lease.linearIssueId, owner);
277
269
  return true;
278
270
  }) ?? false;
279
271
  }
280
272
  setBranchOwnerRespectingActiveLease(projectId, linearIssueId, owner) {
281
273
  const lease = this.getActiveIssueSessionLease(projectId, linearIssueId);
282
274
  if (!lease) {
283
- this.setBranchOwner(projectId, linearIssueId, owner);
275
+ this.issues.setBranchOwner(projectId, linearIssueId, owner);
284
276
  return true;
285
277
  }
286
278
  return this.setBranchOwnerWithLease(lease, owner);