pendingyou 0.31.1 → 0.32.1
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/CHANGELOG.md +16 -0
- package/dist/apps/codex-wake.js +1 -1
- package/dist/confirm.js +1 -1
- package/dist/version.js +1 -1
- package/mod/.claude-plugin/plugin.json +1 -1
- package/mod/README.md +1 -1
- package/mod/hooks/register.js +12 -3
- package/mod/hooks/wake.js +16 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.32.1 (2026-10-08)
|
|
4
|
+
|
|
5
|
+
- The Claude Code wake mod never announces a card that's already picked up. It checks cards while a turn runs but tells
|
|
6
|
+
only once the session is idle, and it told what it had read then: a card the agent picked up in that turn (by posting
|
|
7
|
+
the next card with `follows`, or with `ack_answer`) was announced minutes later as “your person answered …”. It now
|
|
8
|
+
reads each card again just before telling it, unless it read it in the last 10 seconds; never tells a card picked up,
|
|
9
|
+
whichever way; and takes the card a new card follows as heard. A card withdrawn under the agent is still told once.
|
|
10
|
+
|
|
11
|
+
## 0.32.0 (2026-10-08)
|
|
12
|
+
|
|
13
|
+
- Follow-ups are new cards that follow the one before (threads, guide 2.48). The Codex wake and the Claude Code wake mod
|
|
14
|
+
no longer say "reply_in_thread with reopen": when the person answered and the agent needs more, or the next step, they
|
|
15
|
+
say "If you need more from them, or the next step, post a new card with follows: that card’s requestId; never
|
|
16
|
+
reopen." The stop hook's reminder for words asked for in the terminal says to post the card with follows after a
|
|
17
|
+
card the person answered, instead of reopening it. Publish before guide 2.48 is deployed.
|
|
18
|
+
|
|
3
19
|
## 0.31.1 (2026-10-08)
|
|
4
20
|
|
|
5
21
|
- Your words on a card that's closed reach its assistant. "Write to …" (threads) writes on a thread's newest card even
|
package/dist/apps/codex-wake.js
CHANGED
|
@@ -442,7 +442,7 @@ export function wakeMessage(ready) {
|
|
|
442
442
|
return null;
|
|
443
443
|
const asked = lines.some(({ heard }) => heard.turn === 'agent' && heard.status !== 'expired' && !noticeOf(heard) && !handledOf(heard));
|
|
444
444
|
const reopen = asked
|
|
445
|
-
? ' If
|
|
445
|
+
? ' If you need more from them, or the next step, post a new card with follows: that card’s requestId; never reopen.'
|
|
446
446
|
: '';
|
|
447
447
|
if (lines.length === 1) {
|
|
448
448
|
const [happened, todo] = lines[0].said;
|
package/dist/confirm.js
CHANGED
|
@@ -159,5 +159,5 @@ export function confirmReason(words, link, app = 'Claude Code') {
|
|
|
159
159
|
: chars.join('');
|
|
160
160
|
const asked = shown ? `to type “${shown}” here` : 'to confirm here';
|
|
161
161
|
const what = shown ? 'those exact words' : 'the words to type';
|
|
162
|
-
return `You asked them ${asked}, but no open Pending You card says so: post an action card “Confirm in ${app} on <computer>: <step>” with ${what} as a step command, where ${app} on <computer>${link ? `, ${link}` : ''}, done what you’ll do (a card they answered:
|
|
162
|
+
return `You asked them ${asked}, but no open Pending You card says so: post an action card “Confirm in ${app} on <computer>: <step>” with ${what} as a step command, where ${app} on <computer>${link ? `, ${link}` : ''}, done what you’ll do (after a card they answered: with follows, its requestId).`;
|
|
163
163
|
}
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.
|
|
1
|
+
export const VERSION = '0.32.1';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pendingyou-wake",
|
|
3
3
|
"displayName": "Pending You",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.48.1",
|
|
5
5
|
"description": "Wakes Claude Code when your person answers a Pending You card it posted, even while it sits idle. Installed by `npx pendingyou init`.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "RecordPlane",
|
package/mod/README.md
CHANGED
|
@@ -4,4 +4,4 @@ The pendingyou command line’s copy of the Pending You plugin’s wake mod, for
|
|
|
4
4
|
|
|
5
5
|
In each session it learns the cards the session posts to Pending You, checks them through the session’s own Pending You connection, and starts a turn when your person answers, writes back or a fallback comes due, or hands the session a question from another of their assistants (CLI 0.14.0), even while it sits idle. It answers `npx pendingyou hold` itself, so nothing waits in the background, and shows “2 waiting on you” under the prompt, after the plugin’s name. With the Pending You plugin installed too, only one copy acts.
|
|
6
6
|
|
|
7
|
-
Generated from recordplane/pendingyou (packages/claude-plugin/src/wake) with Pending You’s guide 2.
|
|
7
|
+
Generated from recordplane/pendingyou (packages/claude-plugin/src/wake) with Pending You’s guide 2.48.1; send changes there.
|
package/mod/hooks/register.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Generated from packages/claude-plugin/src/wake/register.ts in recordplane/pendingyou: edit that, then run
|
|
2
2
|
// `pnpm --filter @pendingyou/claude-plugin generate`.
|
|
3
3
|
|
|
4
|
-
import { argumentsOf, blockedNote, CLAIM_PREFIX, CLI_COPY, cardTool, checked, claimLease, cliConfigOf, connectionOf, dueCards, emptyBook, failed, folderOf, HANDED_FAST_MS, HANDED_READS, HERDR_EVERY_MS, HERDR_RUN_MS, handedDue, handedNext, handedOf, handedText, handedView, herdrArgv, herdrPayload, holdOf, holdReply, inHerdr, isRefusal, isStale, isWaitingOnYou, KEEP_MS, learn, leaseHolder, loadedNote, loadedPath, momentOf, originOf, PRESENCE_EVERY_MS, PRESENCE_RUN_MS, presenceArgv, prompted, put, readBook, readClaim, readSetup, readSince, resultObject, SETUP_AFTER_MS, SETUP_RETRY_MS, SETUP_SERVER, SETUP_TRIES, settle, setUpOf, setupNeeded, setupPrompt, stateOf, statusText, TICK_MS, takesHanded, told, toTell, untold, wakeText, } from "./wake.js";
|
|
4
|
+
import { argumentsOf, blockedNote, CLAIM_PREFIX, CLI_COPY, cardTool, checked, claimLease, cliConfigOf, connectionOf, dueCards, emptyBook, failed, folderOf, HANDED_FAST_MS, HANDED_READS, HERDR_EVERY_MS, HERDR_RUN_MS, handedDue, handedNext, handedOf, handedText, handedView, herdrArgv, herdrPayload, holdOf, holdReply, inHerdr, isFresh, isRefusal, isStale, isWaitingOnYou, KEEP_MS, learn, leaseHolder, loadedNote, loadedPath, momentOf, originOf, PRESENCE_EVERY_MS, PRESENCE_RUN_MS, presenceArgv, prompted, put, readBook, readClaim, readSetup, readSince, resultObject, SETUP_AFTER_MS, SETUP_RETRY_MS, SETUP_SERVER, SETUP_TRIES, settle, setUpOf, setupNeeded, setupPrompt, stateOf, statusText, TICK_MS, takesHanded, told, toTell, untold, wakeText, } from "./wake.js";
|
|
5
5
|
const RETRY_MS = 60_000;
|
|
6
6
|
const live = {
|
|
7
7
|
me: '',
|
|
@@ -141,11 +141,20 @@ async function check($, requestId) {
|
|
|
141
141
|
async function deliver($) {
|
|
142
142
|
if (live.busy)
|
|
143
143
|
return false;
|
|
144
|
-
|
|
145
|
-
if (cards.length === 0 || (await $.clock.now()) < live.quietUntil)
|
|
144
|
+
if (toTell(live.book).length === 0 || (await $.clock.now()) < live.quietUntil)
|
|
146
145
|
return false;
|
|
147
146
|
if (!(await claim($)))
|
|
148
147
|
return false;
|
|
148
|
+
const before = await $.clock.now();
|
|
149
|
+
for (const card of toTell(live.book))
|
|
150
|
+
if (!isFresh(card, before))
|
|
151
|
+
await check($, card.requestId);
|
|
152
|
+
if (live.busy)
|
|
153
|
+
return false;
|
|
154
|
+
const now = await $.clock.now();
|
|
155
|
+
const cards = toTell(live.book).filter((card) => isFresh(card, now));
|
|
156
|
+
if (cards.length === 0)
|
|
157
|
+
return false;
|
|
149
158
|
live.book = told(live.book, cards);
|
|
150
159
|
await save($);
|
|
151
160
|
$.prompt.submit({ text: wakeText(cards) }).catch(async () => {
|
package/mod/hooks/wake.js
CHANGED
|
@@ -8,6 +8,7 @@ export const RECENT_MS = 30 * 60_000;
|
|
|
8
8
|
export const MAX_BACKOFF_MS = 15 * 60_000;
|
|
9
9
|
export const HINT_FLOOR_MS = 5000;
|
|
10
10
|
export const BLOCKED_MS = 60_000;
|
|
11
|
+
export const FRESH_MS = 10_000;
|
|
11
12
|
export const KEEP_MS = 7 * 24 * 60 * 60_000;
|
|
12
13
|
export const MAX_CARDS = 50;
|
|
13
14
|
export const LEASE_MS = 60_000;
|
|
@@ -231,6 +232,13 @@ function tracked(book, facts, now) {
|
|
|
231
232
|
nextAt: now + FAST_MS,
|
|
232
233
|
});
|
|
233
234
|
}
|
|
235
|
+
function followedUp(book, follows, now) {
|
|
236
|
+
const card = follows ? book.cards[follows] : undefined;
|
|
237
|
+
if (!card)
|
|
238
|
+
return book;
|
|
239
|
+
const heard = card.state && isReady(card.state) ? { seen: momentOf(card.state) } : {};
|
|
240
|
+
return put(book, { ...card, ...heard, nextAt: now });
|
|
241
|
+
}
|
|
234
242
|
export function learn(book, call, now) {
|
|
235
243
|
const { server, tool, input, output } = call;
|
|
236
244
|
if (!output)
|
|
@@ -251,7 +259,7 @@ export function learn(book, call, now) {
|
|
|
251
259
|
if (!status || !OPEN.has(status) || version === undefined)
|
|
252
260
|
return next;
|
|
253
261
|
const title = text(input.title, 400);
|
|
254
|
-
|
|
262
|
+
const posted = tracked(next, {
|
|
255
263
|
requestId,
|
|
256
264
|
server,
|
|
257
265
|
...(name ? { name } : {}),
|
|
@@ -259,6 +267,7 @@ export function learn(book, call, now) {
|
|
|
259
267
|
pressing: pressingFrom(tool, input, card),
|
|
260
268
|
state: { status, turn: 'you', version, cursor: card?.state?.cursor ?? '' },
|
|
261
269
|
}, now);
|
|
270
|
+
return tool === 'post_request' ? followedUp(posted, requestIdOf(input.follows), now) : posted;
|
|
262
271
|
}
|
|
263
272
|
case 'reply_in_thread': {
|
|
264
273
|
const reopen = isObject(input.reopen) ? input.reopen : null;
|
|
@@ -311,7 +320,7 @@ export function checked(card, output, now) {
|
|
|
311
320
|
if (!isReady(state) && pollAfter !== undefined && pollAfter * 1000 < wait)
|
|
312
321
|
wait = Math.max(HINT_FLOOR_MS, pollAfter * 1000 + 1000);
|
|
313
322
|
const { failures: _failures, ...rest } = card;
|
|
314
|
-
return { ...rest, state, changedAt, nextAt: now + wait };
|
|
323
|
+
return { ...rest, state, changedAt, nextAt: now + wait, checkedAt: now };
|
|
315
324
|
}
|
|
316
325
|
export function failed(card, now, blocked) {
|
|
317
326
|
if (blocked)
|
|
@@ -332,13 +341,16 @@ export function needsTelling(card) {
|
|
|
332
341
|
const state = card.state;
|
|
333
342
|
if (!state || !isReady(state))
|
|
334
343
|
return false;
|
|
344
|
+
if (state.status === 'resolved')
|
|
345
|
+
return false;
|
|
335
346
|
const moment = momentOf(state);
|
|
336
347
|
if (moment === card.told || moment === card.seen)
|
|
337
348
|
return false;
|
|
338
|
-
if (
|
|
349
|
+
if (state.status === 'cancelled' && (card.told || card.seen))
|
|
339
350
|
return false;
|
|
340
351
|
return true;
|
|
341
352
|
}
|
|
353
|
+
export const isFresh = (card, now) => card.checkedAt !== undefined && now - card.checkedAt <= FRESH_MS;
|
|
342
354
|
export const toTell = (book) => Object.values(book.cards)
|
|
343
355
|
.filter(needsTelling)
|
|
344
356
|
.sort((a, b) => a.changedAt - b.changedAt);
|
|
@@ -385,8 +397,6 @@ function line(card) {
|
|
|
385
397
|
];
|
|
386
398
|
case 'cancelled':
|
|
387
399
|
return [`${titled(card)} was withdrawn`, 'nothing to do'];
|
|
388
|
-
case 'resolved':
|
|
389
|
-
return [`${titled(card)} is already handled`, 'nothing to do'];
|
|
390
400
|
case 'answered':
|
|
391
401
|
if (state.handled === 'self')
|
|
392
402
|
return [
|
|
@@ -421,7 +431,7 @@ export function wakeText(cards) {
|
|
|
421
431
|
card.state.status !== 'delegated' &&
|
|
422
432
|
!card.state.handled);
|
|
423
433
|
const reopen = asked
|
|
424
|
-
? ' If
|
|
434
|
+
? ' If you need more from them, or the next step, post a new card with follows: that card’s requestId; never reopen.'
|
|
425
435
|
: '';
|
|
426
436
|
if (cards.length === 1) {
|
|
427
437
|
const [happened, todo] = line(cards[0]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pendingyou",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.1",
|
|
4
4
|
"description": "Pending You for your coding agents: one command sets up Claude Code, Codex, OpenCode and Pi to ask you through Pending You and hear your answers, even while they sit idle.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://www.pendingyou.com",
|