patchrelay 0.7.6 → 0.7.7

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 CHANGED
@@ -11,7 +11,7 @@ PatchRelay is the system around the model:
11
11
  - issue-to-repo routing
12
12
  - issue worktree and branch lifecycle
13
13
  - stage orchestration and thread continuity
14
- - comment forwarding into active runs
14
+ - native Linear agent input forwarding into active runs
15
15
  - read-only inspection and stage reporting
16
16
 
17
17
  If you want Codex to work inside your real repos with your real tools, secrets, SSH access, and deployment surface, PatchRelay is the harness that makes that loop reliable.
@@ -22,7 +22,7 @@ If you want Codex to work inside your real repos with your real tools, secrets,
22
22
  - Use your existing machine, repos, secrets, SSH config, shell tools, and deployment access.
23
23
  - Keep deterministic workflow logic outside the model: routing, staging, worktree ownership, and reporting.
24
24
  - Choose the Codex approval and sandbox settings that match your risk tolerance.
25
- - Let Linear drive the loop through delegation, workflow stages, and comments.
25
+ - Let Linear drive the loop through delegation, mentions, and workflow stages.
26
26
  - Drop into the exact issue worktree and resume control manually when needed.
27
27
 
28
28
  ## What PatchRelay Owns
@@ -34,7 +34,7 @@ PatchRelay does the deterministic harness work that you do not want to re-implem
34
34
  - creates and reuses one durable worktree and branch per issue lifecycle
35
35
  - starts or forks Codex threads for the workflows you bind to Linear states
36
36
  - persists enough state to correlate the Linear issue, local workspace, stage run, and Codex thread
37
- - reports progress back to Linear and forwards follow-up comments into active runs
37
+ - reports progress back to Linear and forwards follow-up agent input into active runs
38
38
  - exposes CLI and optional read-only inspection surfaces so operators can understand what happened
39
39
 
40
40
  ## System Layers
@@ -77,7 +77,7 @@ For the exact OAuth app settings and webhook categories, use the Linear onboardi
77
77
  2. PatchRelay verifies the webhook and routes the issue to the right local project.
78
78
  3. Delegated issues create or reuse the issue worktree and launch the matching workflow through `codex app-server`.
79
79
  4. PatchRelay persists thread ids, run state, and observations so the work stays inspectable and resumable.
80
- 5. Mentions stay conversational, while delegated sessions and issue comments can steer the active run. An operator can take over from the exact same worktree when needed.
80
+ 5. Mentions stay conversational, while delegated sessions and native agent prompts can steer the active run. An operator can take over from the exact same worktree when needed.
81
81
 
82
82
  ## Restart And Reconciliation
83
83
 
@@ -221,7 +221,7 @@ Important:
221
221
  1. Delegate a Linear issue to the PatchRelay app.
222
222
  2. PatchRelay reads the current Linear state like `Start`, `Ready for QA`, or `Deploy` to choose the matching workflow.
223
223
  3. Linear sends the delegation and agent-session webhooks to PatchRelay, which creates or reuses the issue worktree and launches the matching workflow.
224
- 4. Follow up in the issue comments to steer the active run or wake it with fresh input while it remains delegated.
224
+ 4. Follow up in the Linear agent session to steer the active run or wake it with fresh input while it remains delegated.
225
225
  5. Watch progress from the terminal or open the same worktree and take over manually.
226
226
 
227
227
  Useful commands:
@@ -11,24 +11,24 @@ function titleCase(value) {
11
11
  function buildPlan(stage, statuses) {
12
12
  const stageLabel = titleCase(formatStageLabel(stage));
13
13
  return [
14
- { label: "Prepare workspace", status: statuses[0] },
15
- { label: `Run ${stageLabel} workflow`, status: statuses[1] },
16
- { label: "Review next Linear step", status: statuses[2] },
14
+ { content: "Prepare workspace", status: statuses[0] },
15
+ { content: `Run ${stageLabel} workflow`, status: statuses[1] },
16
+ { content: "Review next Linear step", status: statuses[2] },
17
17
  ];
18
18
  }
19
19
  export function buildPreparingSessionPlan(stage) {
20
- return buildPlan(stage, ["in_progress", "pending", "pending"]);
20
+ return buildPlan(stage, ["inProgress", "pending", "pending"]);
21
21
  }
22
22
  export function buildRunningSessionPlan(stage) {
23
- return buildPlan(stage, ["completed", "in_progress", "pending"]);
23
+ return buildPlan(stage, ["completed", "inProgress", "pending"]);
24
24
  }
25
25
  export function buildCompletedSessionPlan(stage) {
26
26
  return buildPlan(stage, ["completed", "completed", "completed"]);
27
27
  }
28
28
  export function buildAwaitingHandoffSessionPlan(stage) {
29
- return buildPlan(stage, ["completed", "completed", "in_progress"]);
29
+ return buildPlan(stage, ["completed", "completed", "inProgress"]);
30
30
  }
31
31
  export function buildFailedSessionPlan(stage, stageRun) {
32
- const workflowStepStatus = stageRun?.threadId || stageRun?.turnId ? "completed" : "in_progress";
32
+ const workflowStepStatus = stageRun?.threadId || stageRun?.turnId ? "completed" : "inProgress";
33
33
  return buildPlan(stage, ["completed", workflowStepStatus, "pending"]);
34
34
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "service": "patchrelay",
3
- "version": "0.7.6",
4
- "commit": "cd9193b4a7b1",
5
- "builtAt": "2026-03-17T08:05:09.587Z"
3
+ "version": "0.7.7",
4
+ "commit": "b39ec3de1f37",
5
+ "builtAt": "2026-03-17T09:39:30.228Z"
6
6
  }
package/dist/config.js CHANGED
@@ -101,7 +101,7 @@ const configSchema = z.object({
101
101
  });
102
102
  function defaultTriggerEvents(actor) {
103
103
  if (actor === "app") {
104
- return ["issueCreated", "agentSessionCreated", "agentPrompted", "statusChanged"];
104
+ return ["agentSessionCreated", "agentPrompted"];
105
105
  }
106
106
  return ["statusChanged"];
107
107
  }
@@ -7,12 +7,6 @@ export function resolveProject(config, issue) {
7
7
  return undefined;
8
8
  }
9
9
  export function triggerEventAllowed(project, triggerEvent) {
10
- if (project.triggerEvents.includes(triggerEvent)) {
11
- return true;
12
- }
13
- if (triggerEvent === "agentSessionCreated") {
14
- return project.triggerEvents.includes("delegateChanged") || project.triggerEvents.includes("statusChanged");
15
- }
16
10
  return project.triggerEvents.includes(triggerEvent);
17
11
  }
18
12
  function normalizeTrustValue(value) {
@@ -76,27 +76,14 @@ export class WebhookDesiredStageRecorder {
76
76
  if (!normalizedIssue) {
77
77
  return undefined;
78
78
  }
79
- const stageAllowed = triggerEventAllowed(project, normalized.triggerEvent);
80
- let desiredStage;
81
- if (normalized.triggerEvent === "delegateChanged") {
82
- desiredStage = delegatedToPatchRelay ? resolveWorkflowStage(project, normalizedIssue.stateName) : undefined;
83
- if (!desiredStage) {
84
- return undefined;
85
- }
86
- if (!stageAllowed && !project.triggerEvents.includes("statusChanged")) {
87
- return undefined;
88
- }
89
- }
90
- else if (normalized.triggerEvent === "agentSessionCreated" || normalized.triggerEvent === "agentPrompted") {
91
- if (!delegatedToPatchRelay || !stageAllowed) {
92
- return undefined;
93
- }
94
- desiredStage = resolveWorkflowStage(project, normalizedIssue.stateName);
79
+ if (normalized.triggerEvent !== "agentSessionCreated" && normalized.triggerEvent !== "agentPrompted") {
80
+ return undefined;
95
81
  }
96
- else if (stageAllowed) {
97
- desiredStage = resolveWorkflowStage(project, normalizedIssue.stateName);
82
+ if (!delegatedToPatchRelay || !triggerEventAllowed(project, normalized.triggerEvent)) {
83
+ return undefined;
98
84
  }
99
- else {
85
+ const desiredStage = resolveWorkflowStage(project, normalizedIssue.stateName);
86
+ if (!desiredStage) {
100
87
  return undefined;
101
88
  }
102
89
  if (activeStageRun && desiredStage === activeStageRun.stage) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchrelay",
3
- "version": "0.7.6",
3
+ "version": "0.7.7",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {