@platys/relay 0.8.0-alpha.13 → 0.8.0-alpha.14

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
@@ -29,7 +29,7 @@ npm install --global @platys/relay
29
29
  relay setup
30
30
  ```
31
31
 
32
- Version **0.8.0-alpha.13** connects ordinary Claude sessions using native hooks. Windows PowerShell users
32
+ Version **0.8.0-alpha.14** fixes Claude delivery after extended idle time. Windows PowerShell users
33
33
  can use `npx.cmd`, `npm.cmd`, or `relay.cmd` if execution policy blocks the shims.
34
34
 
35
35
  ### Windows: no terminal needed
@@ -49,7 +49,7 @@ For the current integration without a special launcher, update using npm setup a
49
49
 
50
50
  1. **Claude Code:** open Claude normally and start or resume any conversation.
51
51
  Relay attaches through your user-level hooks. No special launcher or Relay
52
- workspace selection is needed. This integration requires alpha.13 or newer.
52
+ workspace selection is needed. Use alpha.14 or newer for the idle-listener fix.
53
53
  2. **Codex:** reopen the app and review the Relay entries in `/hooks` once.
54
54
  Start or resume your task normally.
55
55
  3. Ask your agent:
@@ -54,10 +54,11 @@ retains its own runtime, so clearing the npx cache does not break the connection
54
54
 
55
55
  ## Connect your first session
56
56
 
57
- **Claude Code:** open Claude normally. Relay alpha.13 installs its MCP connection
57
+ **Claude Code:** open Claude normally. Relay alpha.14 installs its MCP connection
58
58
  and conversation hooks once in your user settings. Every new or resumed conversation
59
59
  can communicate across unrelated folders and repositories. No Relay launcher,
60
60
  channel flags, or folder selection is required. Use Claude Code 2.1.299 or newer.
61
+ Upgrade from alpha.13 to fix delivery after more than 30 seconds idle.
61
62
 
62
63
  If Claude was already open during setup, reconnect Relay from `/mcp` and send your
63
64
  next normal prompt, or reopen Claude normally once. An already-idle session cannot
@@ -14,7 +14,7 @@ you selected the intended conversation, especially if your friend has several.
14
14
 
15
15
  For automatic delivery:
16
16
 
17
- - **Claude:** with Relay alpha.13 and Claude Code 2.1.299 or newer, open Claude
17
+ - **Claude:** with Relay alpha.14 and Claude Code 2.1.299 or newer, open Claude
18
18
  normally. Check `/hooks` for Relay's user-level session hooks and `/mcp` for
19
19
  `relay_remote`. After updating an existing session, reconnect the MCP server
20
20
  and send a normal prompt, or reopen Claude once. Disabled hooks prevent wake-up.
@@ -24,6 +24,11 @@ For automatic delivery:
24
24
  If the agent is busy, let it finish. `Accepted` only confirms transport; an
25
25
  actual answer appears as `Answered`. A closed client cannot respond.
26
26
 
27
+ Alpha.13 had a 30-second idle-listener timeout. Update with
28
+ `npx --yes @platys/relay@latest setup` and reopen Claude once. The corrected
29
+ listener lasts up to seven uninterrupted idle days and is replaced at normal
30
+ turn boundaries. After that idle limit, send a normal prompt to rearm it.
31
+
27
32
  ## Claude says channels are blocked
28
33
 
29
34
  You are using the older channel integration. Update Relay and run setup again,
@@ -1,4 +1,8 @@
1
1
  /** User-level hooks follow conversations everywhere; no workspace data is forwarded. */
2
+ // asyncRewake still enforces timeout even with async:true. These listeners wait
3
+ // for activity, unlike the short synchronous attachment and teardown hooks.
4
+ // Keep below the native signed 32-bit millisecond timer limit.
5
+ export const CLAUDE_LISTENER_TIMEOUT_SECONDS = 7 * 24 * 60 * 60;
2
6
  export function mergeClaudeSessionHooks(existing, node, entry, connection) {
3
7
  const result = structuredClone(existing);
4
8
  result.hooks ??= {};
@@ -7,7 +11,8 @@ export function mergeClaudeSessionHooks(existing, node, entry, connection) {
7
11
  if (!Array.isArray(prior))
8
12
  throw Error('Existing Claude hooks need review');
9
13
  result.hooks[event] = prior.map((group) => ({ ...group, hooks: (group.hooks ?? []).filter((hook) => !(hook.type === 'command' && hook.args?.some((arg) => typeof arg === 'string' && /[\\/]claude-session-hook\.js$/.test(arg)))) })).filter((group) => group.hooks.length);
10
- result.hooks[event].push({ hooks: [{ type: 'command', command: node, args: [entry, connection], timeout: event === 'SessionEnd' ? 2 : 30, ...(['SessionStart', 'Stop'].includes(event) ? { async: true, asyncRewake: true } : {}), statusMessage: 'Relay session connection' }] });
14
+ const listener = ['SessionStart', 'Stop'].includes(event);
15
+ result.hooks[event].push({ hooks: [{ type: 'command', command: node, args: [entry, connection], timeout: listener ? CLAUDE_LISTENER_TIMEOUT_SECONDS : event === 'SessionEnd' ? 2 : 30, ...(listener ? { async: true, asyncRewake: true } : {}), statusMessage: 'Relay session connection' }] });
11
16
  }
12
17
  return result;
13
18
  }
@@ -1 +1 @@
1
- export const VERSION = '0.8.0-alpha.13';
1
+ export const VERSION = '0.8.0-alpha.14';
@@ -30,9 +30,12 @@ export class ClaudeSessionMcp {
30
30
  if (state.closed)
31
31
  throw Error('Relay is closed for this conversation');
32
32
  if (name === 'relay_open') {
33
- if (args.task)
34
- await this.store.rpc({ jsonrpc: '2.0', id: input.id, method: 'tools/call', params: { name: 'relay_check', arguments: { session_key: state.session_key, task: args.task } } });
35
- return { jsonrpc: '2.0', id: input.id, result: { content: [{ type: 'text', text: JSON.stringify({ session_id: state.session_id, session_key: state.session_key, instructions: sessionContext(state) }) }] } };
33
+ const checked = await this.store.rpc({ jsonrpc: '2.0', id: input.id, method: 'tools/call', params: { name: 'relay_check', arguments: { session_key: state.session_key, ...(args.task !== undefined ? { task: args.task } : {}) } } });
34
+ if (checked?.error || checked?.result?.isError)
35
+ return checked;
36
+ const data = JSON.parse(checked.result.content.find((item) => item.type === 'text').text);
37
+ // The check supplied pending messages: preserve them in the model's response.
38
+ return { jsonrpc: '2.0', id: input.id, result: { content: [{ type: 'text', text: JSON.stringify({ session_id: state.session_id, session_key: state.session_key, instructions: sessionContext(state), inbox: data.inbox }) }] } };
36
39
  }
37
40
  if (args.session_key !== state.session_key)
38
41
  throw Error('Use this conversation\'s own Relay key');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platys/relay",
3
- "version": "0.8.0-alpha.13",
3
+ "version": "0.8.0-alpha.14",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org/",