relay-claude-channel 0.3.2-staging.0 → 0.3.2

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.
@@ -8,7 +8,7 @@
8
8
  "plugins": [
9
9
  {
10
10
  "name": "relay",
11
- "version": "0.3.2-staging.0",
11
+ "version": "0.3.2",
12
12
  "source": "./plugin",
13
13
  "description": "Relay Messenger channel for Claude Code with durable acknowledged delivery and retry-safe replies.",
14
14
  "category": "productivity",
@@ -3,7 +3,7 @@
3
3
  "name": "relay",
4
4
  "displayName": "Relay Messenger",
5
5
  "description": "Relay Messenger channel for Claude Code with durable acknowledged delivery, explicit Read receipts, and retry-safe replies.",
6
- "version": "0.3.2-staging.0",
6
+ "version": "0.3.2",
7
7
  "author": {
8
8
  "name": "Relay Messenger",
9
9
  "url": "https://relayapp.im"
package/README.md CHANGED
@@ -130,18 +130,20 @@ Required first call for every Relay channel event. Takes `delivery_id` from the
130
130
  `<channel>` tag and marks that Chat Read through the public Relay API. Do not
131
131
  process the content if the tool returns an error. Success opens one turn-scoped
132
132
  reply origin with a ten-minute maximum lease. Starting another turn closes
133
- the previous one as superseded. A superseded or expired delivery that was
134
- never answered goes back to the inbox: the channel notifies it again on the
135
- first flush after the active turn closes (never while another turn is
133
+ the previous one as superseded. If the channel process stops or is replaced
134
+ (a crash, a kill, a Claude Code restart) while a turn is open, the inherited
135
+ lease closes as interrupted. A superseded, expired, or interrupted delivery
136
+ that was never answered goes back to the inbox: the channel notifies it again
137
+ on the first flush after the active turn closes (never while another turn is
136
138
  running, so the two cannot keep superseding each other), and
137
139
  `begin_processing` then opens a fresh turn for it (the closed turn stays
138
140
  recorded for audit). New deliveries that never had a turn are still notified
139
141
  at once. Each time the state store opens it applies the same reset to any
140
- delivery an older channel version left stuck after a superseded or expired
141
- turn, so no Message stays lost on an existing install. A delivery that was
142
- answered by `reply` or closed
143
- by `complete_processing` stays closed and cannot be reactivated, so no Message
144
- is answered twice and none is silently lost.
142
+ delivery an older channel version left stuck after a superseded, expired, or
143
+ interrupted turn, so no Message stays lost on an existing install. Only the
144
+ model's own verdict is final: a delivery that was answered by `reply` or
145
+ closed by `complete_processing` (completed or failed) stays closed and cannot
146
+ be reactivated, so no Message is answered twice and none is silently lost.
145
147
 
146
148
  ### `complete_processing`
147
149
 
@@ -199,7 +201,8 @@ State is account-scoped below `~/.claude/channels/relay/state/` and includes:
199
201
  - pending channel deliveries and explicit Read-start status;
200
202
  - one short-lived, per-session delivery-turn lease used for reply and
201
203
  Chat isolation, plus closed-turn markers that prevent reactivation of
202
- answered deliveries (superseded and expired ones return to pending);
204
+ answered deliveries (superseded, expired, and interrupted ones return to
205
+ pending);
203
206
  - the complete last FULL-sync snapshot;
204
207
  - observed reply destinations;
205
208
  - logical outbound sends.
@@ -7,8 +7,8 @@
7
7
  },
8
8
  "relaySdk": {
9
9
  "package": "@relaymessenger/sdk",
10
- "version": "0.3.1-staging.2",
11
- "integrity": "sha512-76hUul0ihr3Zyx3gN/DC4FG8nP+tKhWW1KkrZhgKlHiD7NYq5tg5Pn2mMPYSnoVA+I4OXNVoEGFY7XbIfU5wdg==",
10
+ "version": "0.3.1",
11
+ "integrity": "sha512-VWg62E81N34XdICg9+phflzSh56yB8KU7btXDgd3KWakZAAVpwv6wJMykWDujJvIABeINnCT+1B/5RKKQymGgA==",
12
12
  "workspaceOpenapiSha256": "7094178cb01c0ddc05f9254dc91094900a0a7b6273979c0cad6257eec486f0d8"
13
13
  },
14
14
  "claudeCode": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "relay-claude-channel",
3
- "version": "0.3.2-staging.0",
3
+ "version": "0.3.2",
4
4
  "description": "Relay Messenger channel for Claude Code over Relay v1 WebSocket delivery.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@modelcontextprotocol/sdk": "1.30.0",
43
- "@relaymessenger/sdk": "0.3.1-staging.2"
43
+ "@relaymessenger/sdk": "0.3.1"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "26.0.0",
@@ -3,7 +3,7 @@
3
3
  "name": "relay",
4
4
  "displayName": "Relay Messenger",
5
5
  "description": "Relay Messenger channel for Claude Code with durable acknowledged delivery, explicit Read receipts, and retry-safe replies.",
6
- "version": "0.3.2-staging.0",
6
+ "version": "0.3.2",
7
7
  "author": {
8
8
  "name": "Relay Messenger",
9
9
  "url": "https://relayapp.im"
package/plugin/README.md CHANGED
@@ -130,18 +130,20 @@ Required first call for every Relay channel event. Takes `delivery_id` from the
130
130
  `<channel>` tag and marks that Chat Read through the public Relay API. Do not
131
131
  process the content if the tool returns an error. Success opens one turn-scoped
132
132
  reply origin with a ten-minute maximum lease. Starting another turn closes
133
- the previous one as superseded. A superseded or expired delivery that was
134
- never answered goes back to the inbox: the channel notifies it again on the
135
- first flush after the active turn closes (never while another turn is
133
+ the previous one as superseded. If the channel process stops or is replaced
134
+ (a crash, a kill, a Claude Code restart) while a turn is open, the inherited
135
+ lease closes as interrupted. A superseded, expired, or interrupted delivery
136
+ that was never answered goes back to the inbox: the channel notifies it again
137
+ on the first flush after the active turn closes (never while another turn is
136
138
  running, so the two cannot keep superseding each other), and
137
139
  `begin_processing` then opens a fresh turn for it (the closed turn stays
138
140
  recorded for audit). New deliveries that never had a turn are still notified
139
141
  at once. Each time the state store opens it applies the same reset to any
140
- delivery an older channel version left stuck after a superseded or expired
141
- turn, so no Message stays lost on an existing install. A delivery that was
142
- answered by `reply` or closed
143
- by `complete_processing` stays closed and cannot be reactivated, so no Message
144
- is answered twice and none is silently lost.
142
+ delivery an older channel version left stuck after a superseded, expired, or
143
+ interrupted turn, so no Message stays lost on an existing install. Only the
144
+ model's own verdict is final: a delivery that was answered by `reply` or
145
+ closed by `complete_processing` (completed or failed) stays closed and cannot
146
+ be reactivated, so no Message is answered twice and none is silently lost.
145
147
 
146
148
  ### `complete_processing`
147
149
 
@@ -199,7 +201,8 @@ State is account-scoped below `~/.claude/channels/relay/state/` and includes:
199
201
  - pending channel deliveries and explicit Read-start status;
200
202
  - one short-lived, per-session delivery-turn lease used for reply and
201
203
  Chat isolation, plus closed-turn markers that prevent reactivation of
202
- answered deliveries (superseded and expired ones return to pending);
204
+ answered deliveries (superseded, expired, and interrupted ones return to
205
+ pending);
203
206
  - the complete last FULL-sync snapshot;
204
207
  - observed reply destinations;
205
208
  - logical outbound sends.
@@ -7,8 +7,8 @@
7
7
  },
8
8
  "relaySdk": {
9
9
  "package": "@relaymessenger/sdk",
10
- "version": "0.3.1-staging.2",
11
- "integrity": "sha512-76hUul0ihr3Zyx3gN/DC4FG8nP+tKhWW1KkrZhgKlHiD7NYq5tg5Pn2mMPYSnoVA+I4OXNVoEGFY7XbIfU5wdg==",
10
+ "version": "0.3.1",
11
+ "integrity": "sha512-VWg62E81N34XdICg9+phflzSh56yB8KU7btXDgd3KWakZAAVpwv6wJMykWDujJvIABeINnCT+1B/5RKKQymGgA==",
12
12
  "workspaceOpenapiSha256": "7094178cb01c0ddc05f9254dc91094900a0a7b6273979c0cad6257eec486f0d8"
13
13
  },
14
14
  "claudeCode": {
@@ -22884,7 +22884,7 @@ var RelayChannel = class {
22884
22884
  this.#config = params.config;
22885
22885
  this.#redactor = params.redactor;
22886
22886
  this.#log = params.log;
22887
- this.#state.clearActiveTurn("failed");
22887
+ this.#state.clearActiveTurn("interrupted");
22888
22888
  this.relay = params.relay ?? new Relay({
22889
22889
  apiKey: params.config.agentToken,
22890
22890
  baseURL: params.config.baseURL
@@ -22936,7 +22936,7 @@ var RelayChannel = class {
22936
22936
  });
22937
22937
  }
22938
22938
  stop() {
22939
- this.#state.clearActiveTurn("failed");
22939
+ this.#state.clearActiveTurn("interrupted");
22940
22940
  this.#abort.abort();
22941
22941
  if (this.#timer) clearInterval(this.#timer);
22942
22942
  this.#timer = null;
@@ -23260,7 +23260,8 @@ var TURN_OUTCOMES = /* @__PURE__ */ new Set([
23260
23260
  "completed",
23261
23261
  "failed",
23262
23262
  "expired",
23263
- "superseded"
23263
+ "superseded",
23264
+ "interrupted"
23264
23265
  ]);
23265
23266
  function isTurnOutcome(value) {
23266
23267
  return typeof value === "string" && TURN_OUTCOMES.has(value);
@@ -23633,8 +23634,8 @@ var RelayStateStore = class {
23633
23634
  }
23634
23635
  return lease.deliveryId;
23635
23636
  }
23636
- /** Before requeue-on-close existed, a superseded or expired turn left its
23637
- * delivery stuck at `processing` for good. Repair such rows once per open:
23637
+ /** Before requeue-on-close existed, a superseded, expired, or interrupted
23638
+ * turn left its delivery stuck at `processing` for good. Repair such rows once per open:
23638
23639
  * the same reset the close-time path applies, then the same notification
23639
23640
  * gate. A delivery holding the current lease is live, not stranded. */
23640
23641
  #requeueStrandedDeliveries() {
@@ -23725,7 +23726,9 @@ var RelayStateStore = class {
23725
23726
  return true;
23726
23727
  });
23727
23728
  }
23728
- clearActiveTurn(outcome = "failed", now = Date.now()) {
23729
+ /** Close whatever lease this process inherited or still holds. The outcome
23730
+ * is the caller's to name; only the model's own `failed` is final. */
23731
+ clearActiveTurn(outcome, now = Date.now()) {
23729
23732
  return transaction(
23730
23733
  this.#db,
23731
23734
  () => this.#closeActiveTurn(outcome, now) !== null
@@ -23870,7 +23873,7 @@ var RelayStateStore = class {
23870
23873
  };
23871
23874
 
23872
23875
  // server.ts
23873
- var VERSION = true ? "0.3.2-staging.0" : createRequire(import.meta.url)("./package.json").version;
23876
+ var VERSION = true ? "0.3.2" : createRequire(import.meta.url)("./package.json").version;
23874
23877
  if (process.argv.includes("--version")) {
23875
23878
  process.stdout.write(`${VERSION}
23876
23879
  `);
@@ -22884,7 +22884,7 @@ var RelayChannel = class {
22884
22884
  this.#config = params.config;
22885
22885
  this.#redactor = params.redactor;
22886
22886
  this.#log = params.log;
22887
- this.#state.clearActiveTurn("failed");
22887
+ this.#state.clearActiveTurn("interrupted");
22888
22888
  this.relay = params.relay ?? new Relay({
22889
22889
  apiKey: params.config.agentToken,
22890
22890
  baseURL: params.config.baseURL
@@ -22936,7 +22936,7 @@ var RelayChannel = class {
22936
22936
  });
22937
22937
  }
22938
22938
  stop() {
22939
- this.#state.clearActiveTurn("failed");
22939
+ this.#state.clearActiveTurn("interrupted");
22940
22940
  this.#abort.abort();
22941
22941
  if (this.#timer) clearInterval(this.#timer);
22942
22942
  this.#timer = null;
@@ -23260,7 +23260,8 @@ var TURN_OUTCOMES = /* @__PURE__ */ new Set([
23260
23260
  "completed",
23261
23261
  "failed",
23262
23262
  "expired",
23263
- "superseded"
23263
+ "superseded",
23264
+ "interrupted"
23264
23265
  ]);
23265
23266
  function isTurnOutcome(value) {
23266
23267
  return typeof value === "string" && TURN_OUTCOMES.has(value);
@@ -23633,8 +23634,8 @@ var RelayStateStore = class {
23633
23634
  }
23634
23635
  return lease.deliveryId;
23635
23636
  }
23636
- /** Before requeue-on-close existed, a superseded or expired turn left its
23637
- * delivery stuck at `processing` for good. Repair such rows once per open:
23637
+ /** Before requeue-on-close existed, a superseded, expired, or interrupted
23638
+ * turn left its delivery stuck at `processing` for good. Repair such rows once per open:
23638
23639
  * the same reset the close-time path applies, then the same notification
23639
23640
  * gate. A delivery holding the current lease is live, not stranded. */
23640
23641
  #requeueStrandedDeliveries() {
@@ -23725,7 +23726,9 @@ var RelayStateStore = class {
23725
23726
  return true;
23726
23727
  });
23727
23728
  }
23728
- clearActiveTurn(outcome = "failed", now = Date.now()) {
23729
+ /** Close whatever lease this process inherited or still holds. The outcome
23730
+ * is the caller's to name; only the model's own `failed` is final. */
23731
+ clearActiveTurn(outcome, now = Date.now()) {
23729
23732
  return transaction(
23730
23733
  this.#db,
23731
23734
  () => this.#closeActiveTurn(outcome, now) !== null
@@ -23870,7 +23873,7 @@ var RelayStateStore = class {
23870
23873
  };
23871
23874
 
23872
23875
  // server.ts
23873
- var VERSION = true ? "0.3.2-staging.0" : createRequire(import.meta.url)("./package.json").version;
23876
+ var VERSION = true ? "0.3.2" : createRequire(import.meta.url)("./package.json").version;
23874
23877
  if (process.argv.includes("--version")) {
23875
23878
  process.stdout.write(`${VERSION}
23876
23879
  `);