agents-relay 1.0.78 → 1.0.80

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
@@ -108,6 +108,10 @@ Pushes to `main` run `.github/workflows/publish.yml`: install, test, choose the
108
108
 
109
109
  Normal consumers should invoke the CLI with `npx agents-relay ...` (or `npx agents-relayd ...`).
110
110
 
111
+ After a successful npm publish, the workflow records one idempotent `agents-relay:package-published:v1` marker comment on the originating managed PR. The existing GitHub `issue_comment` webhook resolves that PR back to its durable Job and emits a correlated `package.published` events-bus event containing repository, package, version, registry, commit SHA, PR number, and webhook delivery ID. Its source identity is the GitHub delivery (`github/<repository>/delivery/<delivery-id>`), not a worker execution identity.
112
+
113
+ `package.published` is a release fact, not a service-management command. Agents Relay does not pull packages, restart PM2, or decide which local service consumes a package. An external deployment subscriber may listen for this event, verify that the exact version is pullable, update/restart the affected service, verify its running version and health, and publish its own deployment outcome event. This keeps publication, deployment, and healthy-running as separate facts and removes the need for an orchestrator thread to synchronously wait for npm readiness.
114
+
111
115
  For explicit local demo/test mode:
112
116
 
113
117
  ~~~sh
@@ -1,5 +1,32 @@
1
1
  import { createHmac, timingSafeEqual } from 'node:crypto';
2
+ export const PACKAGE_PUBLISHED_MARKER = 'agents-relay:package-published:v1';
2
3
  const WAKE_EVENTS = new Set(['pull_request', 'issue_comment', 'pull_request_review', 'pull_request_review_comment', 'check_run', 'check_suite', 'workflow_run']);
4
+ function parsePackagePublication(body) {
5
+ if (typeof body !== 'string')
6
+ return null;
7
+ const prefix = '<!-- ' + PACKAGE_PUBLISHED_MARKER + ' ';
8
+ const start = body.indexOf(prefix);
9
+ if (start < 0)
10
+ return null;
11
+ const end = body.indexOf(' -->', start + prefix.length);
12
+ if (end < 0)
13
+ return null;
14
+ let value;
15
+ try {
16
+ value = JSON.parse(body.slice(start + prefix.length, end));
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ if (typeof value.package !== 'string' || !value.package || typeof value.version !== 'string' || !value.version)
22
+ return null;
23
+ return {
24
+ package: value.package,
25
+ version: value.version,
26
+ registry: typeof value.registry === 'string' ? value.registry : null,
27
+ sha: typeof value.sha === 'string' ? value.sha : null,
28
+ };
29
+ }
3
30
  export function verifyGitHubWebhook(secret, body, signature) {
4
31
  if (!secret || !signature?.startsWith('sha256='))
5
32
  return false;
@@ -23,7 +50,16 @@ export function parseGitHubWebhook(headers, body) {
23
50
  const pullRequest = payload.pull_request;
24
51
  const issue = payload.issue;
25
52
  const number = Number(pullRequest?.number ?? (issue?.pull_request ? issue.number : 0));
26
- return { deliveryId, event, action: typeof payload.action === 'string' ? payload.action : null, repository: typeof repository?.full_name === 'string' ? repository.full_name : null, pullRequest: Number.isInteger(number) && number > 0 ? number : null };
53
+ const comment = payload.comment;
54
+ const publication = event === 'issue_comment' ? parsePackagePublication(comment?.body) : null;
55
+ return {
56
+ deliveryId,
57
+ event,
58
+ action: typeof payload.action === 'string' ? payload.action : null,
59
+ repository: typeof repository?.full_name === 'string' ? repository.full_name : null,
60
+ pullRequest: Number.isInteger(number) && number > 0 ? number : null,
61
+ publication,
62
+ };
27
63
  }
28
64
  export class DeliveryDeduper {
29
65
  ttlMs;
package/dist/pool.js CHANGED
@@ -108,9 +108,21 @@ export class RepositoryWorkerPool {
108
108
  await this.reconcile();
109
109
  });
110
110
  }
111
- async webhookWake(bus, job, deliveryId, event, action) {
111
+ async webhookWake(bus, job, wake) {
112
112
  if (bus) {
113
- await bus.publish(eventFor(job.id, 'github', null, 'github.webhook', 'queued', `GitHub webhook ${event}${action ? ':' + action : ''}`, 'orchestrator', { deliveryId, event, action, repository: job.repository, prNumber: job.prNumber }));
113
+ const source = { id: `github/${job.repository}/delivery/${wake.deliveryId}`, component: 'github-webhook' };
114
+ if (wake.publication) {
115
+ await bus.publish(eventFor(job.id, 'release', null, 'package.published', 'succeeded', `Published ${wake.publication.package}@${wake.publication.version}`, 'orchestrator', {
116
+ deliveryId: wake.deliveryId,
117
+ repository: job.repository,
118
+ prNumber: job.prNumber,
119
+ package: wake.publication.package,
120
+ version: wake.publication.version,
121
+ registry: wake.publication.registry,
122
+ sha: wake.publication.sha,
123
+ }, source));
124
+ }
125
+ await bus.publish(eventFor(job.id, 'github', null, 'github.webhook', 'queued', `GitHub webhook ${wake.event}${wake.action ? ':' + wake.action : ''}`, 'orchestrator', { deliveryId: wake.deliveryId, event: wake.event, action: wake.action, repository: job.repository, prNumber: job.prNumber }, source));
114
126
  return;
115
127
  }
116
128
  await this.reconcileTarget(job.repository, job.prNumber, job.id);
package/dist/relayd.js CHANGED
@@ -151,7 +151,7 @@ export async function runDaemon(argv) {
151
151
  try {
152
152
  const refreshed = cachedOverviews.filter(item => item.job.repository === event.repository && item.job.prNumber === event.pullRequest);
153
153
  for (const item of refreshed)
154
- await pool.webhookWake(bus, item.job, event.deliveryId, event.event, event.action);
154
+ await pool.webhookWake(bus, item.job, event);
155
155
  }
156
156
  catch (error) {
157
157
  process.stderr.write(`warning: webhook wake unavailable: ${error instanceof Error ? error.message : String(error)}\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agents-relay",
3
- "version": "1.0.78",
3
+ "version": "1.0.80",
4
4
  "description": "Durable async agent jobs coordinated through GitHub pull requests",
5
5
  "type": "module",
6
6
  "bin": {