patchrelay 0.73.2 → 0.73.3
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/build-info.json
CHANGED
|
@@ -17,15 +17,17 @@ export class IdleIssueReconciler {
|
|
|
17
17
|
logger;
|
|
18
18
|
feed;
|
|
19
19
|
deployEvaluator;
|
|
20
|
+
syncIssue;
|
|
20
21
|
constructor(db, config, wakeDispatcher, logger, feed,
|
|
21
22
|
// Injectable for tests; production uses the real `gh`-backed watcher.
|
|
22
|
-
deployEvaluator = evaluateDeploy) {
|
|
23
|
+
deployEvaluator = evaluateDeploy, syncIssue) {
|
|
23
24
|
this.db = db;
|
|
24
25
|
this.config = config;
|
|
25
26
|
this.wakeDispatcher = wakeDispatcher;
|
|
26
27
|
this.logger = logger;
|
|
27
28
|
this.feed = feed;
|
|
28
29
|
this.deployEvaluator = deployEvaluator;
|
|
30
|
+
this.syncIssue = syncIssue;
|
|
29
31
|
}
|
|
30
32
|
async reconcile() {
|
|
31
33
|
// Wrap the entire reconcile pass in a dispatcher tick. Every
|
|
@@ -251,6 +253,12 @@ export class IdleIssueReconciler {
|
|
|
251
253
|
}
|
|
252
254
|
: {}),
|
|
253
255
|
});
|
|
256
|
+
const updatedIssue = this.db.issues.getIssue(issue.projectId, issue.linearIssueId) ?? issue;
|
|
257
|
+
if (this.syncIssue) {
|
|
258
|
+
void Promise.resolve(this.syncIssue(updatedIssue)).catch((error) => {
|
|
259
|
+
this.logger.warn({ issueKey: issue.issueKey, error: error instanceof Error ? error.message : String(error) }, "Failed to sync Linear workflow state after idle reconciliation");
|
|
260
|
+
});
|
|
261
|
+
}
|
|
254
262
|
if (options?.pendingRunType) {
|
|
255
263
|
this.recordWakeEvent(issue, options.pendingRunType, options.pendingRunContext, "idle_reconciliation");
|
|
256
264
|
}
|
package/dist/run-orchestrator.js
CHANGED
|
@@ -134,7 +134,7 @@ export class RunOrchestrator {
|
|
|
134
134
|
this.interruptedRunRecovery = new InterruptedRunRecovery(db, logger, this.linearSync, this.leasePorts.withHeldLease, this.leasePorts.releaseLease, this.recoveryPorts.failRunAndClear, this.recoveryPorts.restoreIdleWorktree, this.runCompletionPolicy, (projectId, issueId) => this.enqueueIssue(projectId, issueId), feed);
|
|
135
135
|
this.runReconciler = new RunReconciler(db, logger, linearProvider, this.linearSync, this.interruptedRunRecovery, this.runFinalizer, this.leasePorts.withHeldLease, this.leasePorts.releaseLease, this.threadPorts.readThreadWithRetry, this.recoveryPorts.recoverOrEscalate, (projectId) => this.config.projects.find((project) => project.id === projectId)?.github?.repoFullName, feed);
|
|
136
136
|
this.runWakePlanner = new RunWakePlanner(db);
|
|
137
|
-
this.idleReconciler = new IdleIssueReconciler(db, config, this.wakeDispatcher, logger, feed);
|
|
137
|
+
this.idleReconciler = new IdleIssueReconciler(db, config, this.wakeDispatcher, logger, feed, undefined, (issue) => this.linearSync.syncSession(issue));
|
|
138
138
|
this.mergedLinearCompletionReconciler = new MergedLinearCompletionReconciler(db, linearProvider, logger);
|
|
139
139
|
this.queueHealthMonitor = new QueueHealthMonitor(db, config, {
|
|
140
140
|
advanceIdleIssue: (issue, newState, options) => this.idleReconciler.advanceIdleIssue(issue, newState, options),
|
|
@@ -18,12 +18,12 @@ export function decideActiveRunRelease(p) {
|
|
|
18
18
|
return { release: false };
|
|
19
19
|
if (p.terminal)
|
|
20
20
|
return { release: true, reason: "Issue reached terminal state during active run" };
|
|
21
|
-
if (
|
|
21
|
+
if (!p.delegated)
|
|
22
22
|
return { release: true, reason: "Un-delegated from PatchRelay" };
|
|
23
23
|
return { release: false };
|
|
24
24
|
}
|
|
25
25
|
export function decideUnDelegation(p) {
|
|
26
|
-
if (p.
|
|
26
|
+
if (p.delegated)
|
|
27
27
|
return { clearPending: false };
|
|
28
28
|
if (!p.currentState)
|
|
29
29
|
return { clearPending: false };
|
|
@@ -18,11 +18,14 @@ export function resolveDelegationTruth(input) {
|
|
|
18
18
|
const observedDelegated = isDelegatedToPatchRelay(input.db, input.project, input.hydratedIssue);
|
|
19
19
|
const explicitDelegateSignal = input.triggerEvent === "delegateChanged";
|
|
20
20
|
const hasObservedDelegate = input.hydratedIssue.delegateId !== undefined;
|
|
21
|
+
const authoritativeDelegateObservation = hasObservedDelegate || explicitDelegateSignal || input.hydration === "live_linear";
|
|
21
22
|
let delegated = observedDelegated;
|
|
22
23
|
let reason = hasObservedDelegate
|
|
23
24
|
? "delegate_id_present"
|
|
24
|
-
:
|
|
25
|
-
|
|
25
|
+
: input.hydration === "live_linear"
|
|
26
|
+
? "live_linear_delegate_absent"
|
|
27
|
+
: `missing_delegate_identity_after_${input.hydration}`;
|
|
28
|
+
if (!authoritativeDelegateObservation && previousDelegated !== undefined) {
|
|
26
29
|
delegated = previousDelegated;
|
|
27
30
|
reason = `preserved_previous_delegation_after_${input.hydration}`;
|
|
28
31
|
}
|
package/dist/webhooks.js
CHANGED
|
@@ -75,15 +75,15 @@ function deriveTriggerEvent(payload) {
|
|
|
75
75
|
return "issueRemoved";
|
|
76
76
|
}
|
|
77
77
|
const updatedFields = new Set(Object.keys(payload.updatedFrom ?? {}));
|
|
78
|
+
if (updatedFields.has("delegateId") || updatedFields.has("delegate")) {
|
|
79
|
+
return "delegateChanged";
|
|
80
|
+
}
|
|
78
81
|
if (updatedFields.has("labels")) {
|
|
79
82
|
return "labelChanged";
|
|
80
83
|
}
|
|
81
84
|
if (updatedFields.has("stateId") || updatedFields.has("state")) {
|
|
82
85
|
return "statusChanged";
|
|
83
86
|
}
|
|
84
|
-
if (updatedFields.has("delegateId") || updatedFields.has("delegate")) {
|
|
85
|
-
return "delegateChanged";
|
|
86
|
-
}
|
|
87
87
|
if (updatedFields.has("assigneeId") || updatedFields.has("assignee")) {
|
|
88
88
|
return "assignmentChanged";
|
|
89
89
|
}
|