patchcord 0.6.46 → 0.6.47
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/agent-plugin/plugin.json
CHANGED
|
@@ -44,33 +44,53 @@ WAKES YOU: the pipe fills with messages you are never told about, and you
|
|
|
44
44
|
discover them only when the user asks why you did not answer. That has happened
|
|
45
45
|
in production, on jcode, and is the reason this section exists.
|
|
46
46
|
|
|
47
|
-
So, if you have no `Monitor
|
|
47
|
+
So, if you have no `Monitor`, **use `--stall-signal`. It was built for exactly
|
|
48
|
+
this and it is not optional here:**
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
```
|
|
51
|
+
patchcord subscribe --stall-signal | grep --line-buffered '^PATCHCORD:'; exit ${PIPESTATUS[0]}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
run as a background command with your harness's stall wake set to **15
|
|
55
|
+
seconds** (jcode: `stall_wake_seconds: 15`).
|
|
56
|
+
|
|
57
|
+
1. **What `--stall-signal` does.** While idle it writes a `HEARTBEAT:` line
|
|
58
|
+
every 5 s, so the pipe never looks silent and the stall never fires on
|
|
59
|
+
nothing. When a real message arrives it writes the `PATCHCORD:` line and
|
|
60
|
+
then goes QUIET ON PURPOSE for 15 s, so your harness's stall detector fires
|
|
61
|
+
because a message came in. It turns wake-on-silence into wake-on-message
|
|
62
|
+
using only the primitive your harness has.
|
|
63
|
+
|
|
64
|
+
The `grep` drops the `HEARTBEAT:` lines from what you see; they still keep
|
|
65
|
+
the pipe alive, which is their whole job.
|
|
53
66
|
|
|
54
|
-
2. **
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
2. **The two numbers must agree.** Your stall wake MUST equal `--stall-signal`'s
|
|
68
|
+
quiet window. Both default to 15 s, so setting `15` and passing no inline
|
|
69
|
+
value is correct. If you pass a custom triple
|
|
70
|
+
(`--stall-signal keepaliveMs:quietMs:stallMs`), your stall wake must equal
|
|
71
|
+
the `stallMs` you passed. Too short and it fires on nothing; too long and it
|
|
72
|
+
never fires on a real message. **Do not use 30** — that number predates this
|
|
73
|
+
mode and is simply wrong for it, not safer.
|
|
59
74
|
|
|
60
75
|
3. **NEVER read the last `PATCHCORD:` line in the task output as news.** It is
|
|
61
|
-
scrollback
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
scrollback and it may be a line you already handled. Two lines look almost
|
|
77
|
+
alike: a live arrival, and a `... waiting in inbox (snapshot at HH:MM:SS)`
|
|
78
|
+
written once when the listener connected and drained the queue. The
|
|
79
|
+
timestamp on the second is there so you can see it is old — check it. In a
|
|
80
|
+
real jcode session an agent re-announced that same drain line repeatedly and
|
|
81
|
+
missed five actual messages while doing so. On every wake call
|
|
82
|
+
`mcp__patchcord__inbox` and believe only that. If it is empty, say nothing
|
|
83
|
+
and go back to waiting.
|
|
84
|
+
|
|
85
|
+
4. **If the inbox is empty, check the listener is still alive** before assuming
|
|
86
|
+
a harmless false wake. A dead listener produces the same silence. If a
|
|
87
|
+
restart is refused with `already running (pid N)`, the process outlived the
|
|
88
|
+
task that tracked it: restart with `--replace`, which is the only sanctioned
|
|
89
|
+
way to remove a running listener. Never `kill`/`pkill` by hand.
|
|
90
|
+
|
|
91
|
+
**Only if your harness has no stall setting at all** does this degrade to a
|
|
92
|
+
timed poll. Say so plainly to the user in that case — tell them you will check
|
|
93
|
+
regularly, never that you will be woken "as messages arrive".
|
|
74
94
|
|
|
75
95
|
# When a notification fires
|
|
76
96
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "patchcord",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.47",
|
|
4
4
|
"description": "Cross-machine agent messaging for Claude Code and Codex",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"version": "node scripts/sync-plugin-version.mjs && git add .claude-plugin/plugin.json agent-plugin/plugin.json"
|
package/scripts/subscribe.mjs
CHANGED
|
@@ -295,7 +295,20 @@ async function drainQueueOnce(baseUrl, token) {
|
|
|
295
295
|
count = JSON.parse(res.body).pending_count ?? 0;
|
|
296
296
|
} catch (_) {}
|
|
297
297
|
if (count > 0) {
|
|
298
|
-
|
|
298
|
+
// SELF-DATING, DELIBERATELY. This line and a live-arrival line both
|
|
299
|
+
// start with "PATCHCORD:" and both stay in the task output forever.
|
|
300
|
+
// On a harness that wakes on a stall, the agent re-reads the tail of
|
|
301
|
+
// that output on every wake, and an undated snapshot from twenty
|
|
302
|
+
// minutes ago is indistinguishable from a message that just landed -
|
|
303
|
+
// reported in a jcode session where five real messages were missed
|
|
304
|
+
// while the same old line was announced repeatedly as news.
|
|
305
|
+
// The clock is what makes a re-read visibly stale.
|
|
306
|
+
const at = new Date().toTimeString().slice(0, 8);
|
|
307
|
+
await notify(`PATCHCORD: ${count} waiting in inbox (snapshot at ${at})`, {
|
|
308
|
+
count,
|
|
309
|
+
kind: "pending",
|
|
310
|
+
at,
|
|
311
|
+
});
|
|
299
312
|
}
|
|
300
313
|
return;
|
|
301
314
|
} catch (e) {
|
|
@@ -44,33 +44,53 @@ WAKES YOU: the pipe fills with messages you are never told about, and you
|
|
|
44
44
|
discover them only when the user asks why you did not answer. That has happened
|
|
45
45
|
in production, on jcode, and is the reason this section exists.
|
|
46
46
|
|
|
47
|
-
So, if you have no `Monitor
|
|
47
|
+
So, if you have no `Monitor`, **use `--stall-signal`. It was built for exactly
|
|
48
|
+
this and it is not optional here:**
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
```
|
|
51
|
+
patchcord subscribe --stall-signal | grep --line-buffered '^PATCHCORD:'; exit ${PIPESTATUS[0]}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
run as a background command with your harness's stall wake set to **15
|
|
55
|
+
seconds** (jcode: `stall_wake_seconds: 15`).
|
|
56
|
+
|
|
57
|
+
1. **What `--stall-signal` does.** While idle it writes a `HEARTBEAT:` line
|
|
58
|
+
every 5 s, so the pipe never looks silent and the stall never fires on
|
|
59
|
+
nothing. When a real message arrives it writes the `PATCHCORD:` line and
|
|
60
|
+
then goes QUIET ON PURPOSE for 15 s, so your harness's stall detector fires
|
|
61
|
+
because a message came in. It turns wake-on-silence into wake-on-message
|
|
62
|
+
using only the primitive your harness has.
|
|
63
|
+
|
|
64
|
+
The `grep` drops the `HEARTBEAT:` lines from what you see; they still keep
|
|
65
|
+
the pipe alive, which is their whole job.
|
|
53
66
|
|
|
54
|
-
2. **
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
2. **The two numbers must agree.** Your stall wake MUST equal `--stall-signal`'s
|
|
68
|
+
quiet window. Both default to 15 s, so setting `15` and passing no inline
|
|
69
|
+
value is correct. If you pass a custom triple
|
|
70
|
+
(`--stall-signal keepaliveMs:quietMs:stallMs`), your stall wake must equal
|
|
71
|
+
the `stallMs` you passed. Too short and it fires on nothing; too long and it
|
|
72
|
+
never fires on a real message. **Do not use 30** — that number predates this
|
|
73
|
+
mode and is simply wrong for it, not safer.
|
|
59
74
|
|
|
60
75
|
3. **NEVER read the last `PATCHCORD:` line in the task output as news.** It is
|
|
61
|
-
scrollback
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
scrollback and it may be a line you already handled. Two lines look almost
|
|
77
|
+
alike: a live arrival, and a `... waiting in inbox (snapshot at HH:MM:SS)`
|
|
78
|
+
written once when the listener connected and drained the queue. The
|
|
79
|
+
timestamp on the second is there so you can see it is old — check it. In a
|
|
80
|
+
real jcode session an agent re-announced that same drain line repeatedly and
|
|
81
|
+
missed five actual messages while doing so. On every wake call
|
|
82
|
+
`mcp__patchcord__inbox` and believe only that. If it is empty, say nothing
|
|
83
|
+
and go back to waiting.
|
|
84
|
+
|
|
85
|
+
4. **If the inbox is empty, check the listener is still alive** before assuming
|
|
86
|
+
a harmless false wake. A dead listener produces the same silence. If a
|
|
87
|
+
restart is refused with `already running (pid N)`, the process outlived the
|
|
88
|
+
task that tracked it: restart with `--replace`, which is the only sanctioned
|
|
89
|
+
way to remove a running listener. Never `kill`/`pkill` by hand.
|
|
90
|
+
|
|
91
|
+
**Only if your harness has no stall setting at all** does this degrade to a
|
|
92
|
+
timed poll. Say so plainly to the user in that case — tell them you will check
|
|
93
|
+
regularly, never that you will be woken "as messages arrive".
|
|
74
94
|
|
|
75
95
|
# When a notification fires
|
|
76
96
|
|