@astrosheep/square 0.3.48 → 0.3.49
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/dist/codex-hook.js
CHANGED
|
@@ -17,9 +17,11 @@ export async function codexHookResponse(input, lookup = sessionInbox, env = proc
|
|
|
17
17
|
if (hookEventName === undefined)
|
|
18
18
|
return undefined;
|
|
19
19
|
await recordCodexBoundary(input.session_id, hookEventName === 'Stop' ? 'Stop' : 'non-stop', env);
|
|
20
|
-
|
|
21
|
-
?
|
|
22
|
-
|
|
20
|
+
if (hookEventName === 'Stop') {
|
|
21
|
+
await sweepPrivilegedPending(typeof input.cwd === 'string' ? input.cwd : process.cwd(), env, deliveryAdapters, sweepDeadline).catch(() => undefined);
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
const response = await presentPendingAtBoundary(input.session_id, (context) => ({ hookSpecificOutput: { hookEventName: 'PostToolUse', additionalContext: context } }), lookup, env);
|
|
23
25
|
await sweepPrivilegedPending(typeof input.cwd === 'string' ? input.cwd : process.cwd(), env, deliveryAdapters, sweepDeadline).catch(() => undefined);
|
|
24
26
|
return response;
|
|
25
27
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { Square } from './square-wiring.js';
|
|
2
2
|
export { SquareError } from './model.js';
|
|
3
3
|
export { bindCurrentParticipant, squareAssignedParticipantName, unbindCurrentParticipant } from './registry.js';
|
|
4
|
+
export { createDefaultWakeTransport } from './notifications.js';
|
|
4
5
|
export { createHostLedgerPort, FileHostLedgerPort } from './host-ledger-file-adapter.js';
|
|
5
6
|
export type { HostLedgerPort, PresenceRecord, EvidenceRecord } from './host-ledger.js';
|
|
6
7
|
export type { PresentationSinkPort } from './ports.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { Square } from './square-wiring.js';
|
|
2
2
|
export { SquareError } from './model.js';
|
|
3
3
|
export { bindCurrentParticipant, squareAssignedParticipantName, unbindCurrentParticipant } from './registry.js';
|
|
4
|
+
export { createDefaultWakeTransport } from './notifications.js';
|
|
4
5
|
export { createHostLedgerPort, FileHostLedgerPort } from './host-ledger-file-adapter.js';
|
package/extensions/square-pi.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { presentPendingAtBoundary, renderPendingAtBoundary } from '../dist/boundary-presentation.js';
|
|
2
2
|
import { automaticSessionEnd, automaticSessionStart } from '../dist/automatic-session.js';
|
|
3
|
-
import { waitForSessionPending } from '../dist/inbox.js';
|
|
3
|
+
import { sessionInbox, waitForSessionPending } from '../dist/inbox.js';
|
|
4
4
|
import { projectSessionBindings } from '../dist/square-projections.js';
|
|
5
5
|
import { createHostLedgerPort } from '../dist/host-ledger-file-adapter.js';
|
|
6
6
|
|
|
@@ -37,34 +37,24 @@ export default function squarePiExtension(pi) {
|
|
|
37
37
|
let watcherAbort;
|
|
38
38
|
let generation = 0;
|
|
39
39
|
const handledPending = new Set();
|
|
40
|
+
const observedPending = new Set();
|
|
40
41
|
const landingAcks = new Map();
|
|
41
42
|
let retryAfterChange = false;
|
|
42
43
|
let retryWait;
|
|
43
44
|
let turnIndex = 0;
|
|
44
45
|
let activeTurn;
|
|
45
46
|
let currentRunSignal;
|
|
46
|
-
|
|
47
|
+
let detachRunAbort;
|
|
48
|
+
let cancelledRun = false;
|
|
47
49
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const abort = () => {
|
|
57
|
-
deferredSteers.delete(deferred);
|
|
58
|
-
signal.removeEventListener('abort', abort);
|
|
59
|
-
reject(signal.reason || new Error('Pi native injection aborted'));
|
|
60
|
-
};
|
|
61
|
-
deferredSteers.add(deferred);
|
|
62
|
-
if (signal.aborted) abort();
|
|
63
|
-
else signal.addEventListener('abort', abort, { once: true });
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
const releaseDeferredSteers = () => {
|
|
67
|
-
for (const deferred of [...deferredSteers]) deferred.release();
|
|
50
|
+
const cancelRunDelivery = () => {
|
|
51
|
+
cancelledRun = true;
|
|
52
|
+
for (const key of observedPending) handledPending.add(key);
|
|
53
|
+
generation += 1;
|
|
54
|
+
stopWatcher();
|
|
55
|
+
failAcks(new Error('Pi notification delivery cancelled'));
|
|
56
|
+
retryAfterChange = false;
|
|
57
|
+
retryWait = undefined;
|
|
68
58
|
};
|
|
69
59
|
|
|
70
60
|
const failAcks = (error) => {
|
|
@@ -87,7 +77,6 @@ export default function squarePiExtension(pi) {
|
|
|
87
77
|
kind,
|
|
88
78
|
sentAfterTurn: turnIndex,
|
|
89
79
|
emptyTurnWindows: 0,
|
|
90
|
-
dropAfterSettled: false,
|
|
91
80
|
settle(error) {
|
|
92
81
|
if (ack.settled) return;
|
|
93
82
|
ack.settled = true;
|
|
@@ -180,6 +169,7 @@ export default function squarePiExtension(pi) {
|
|
|
180
169
|
retryWait = undefined;
|
|
181
170
|
|
|
182
171
|
const keys = inboxKeys(pending);
|
|
172
|
+
for (const key of keys) observedPending.add(key);
|
|
183
173
|
const deferred = armDeferredRetry();
|
|
184
174
|
const retryArmed = await deferred.armed;
|
|
185
175
|
if (!retryArmed) {
|
|
@@ -191,7 +181,7 @@ export default function squarePiExtension(pi) {
|
|
|
191
181
|
await presentPendingAtBoundary(
|
|
192
182
|
sessionId,
|
|
193
183
|
async (content) => {
|
|
194
|
-
if (currentRunSignal?.aborted)
|
|
184
|
+
if (signal.aborted || currentRunSignal?.aborted) throw new Error('Pi notification delivery cancelled');
|
|
195
185
|
const landing = waitForLanding(content, signal, 'steer');
|
|
196
186
|
try {
|
|
197
187
|
Promise.resolve(pi.sendMessage(
|
|
@@ -203,12 +193,23 @@ export default function squarePiExtension(pi) {
|
|
|
203
193
|
}
|
|
204
194
|
return landing.promise;
|
|
205
195
|
},
|
|
206
|
-
|
|
196
|
+
async (id, env) => {
|
|
197
|
+
const inbox = await sessionInbox(id, env);
|
|
198
|
+
if (signal.aborted || token !== generation) return [];
|
|
199
|
+
for (const key of inboxKeys(inbox)) observedPending.add(key);
|
|
200
|
+
return inbox.map((membership) => ({
|
|
201
|
+
...membership,
|
|
202
|
+
notifications: membership.notifications.filter((note) => !handledPending.has(
|
|
203
|
+
`${membership.squarePath}\u0000${membership.name.toLocaleLowerCase()}\u0000${note.actIndex}`,
|
|
204
|
+
)),
|
|
205
|
+
}));
|
|
206
|
+
},
|
|
207
207
|
undefined,
|
|
208
208
|
signal,
|
|
209
209
|
);
|
|
210
210
|
for (const key of keys) handledPending.add(key);
|
|
211
211
|
} catch (error) {
|
|
212
|
+
if (signal.aborted || token !== generation) return;
|
|
212
213
|
if (error instanceof PiDeliveryDroppedError) {
|
|
213
214
|
deferred.cancel();
|
|
214
215
|
continue;
|
|
@@ -224,10 +225,13 @@ export default function squarePiExtension(pi) {
|
|
|
224
225
|
};
|
|
225
226
|
|
|
226
227
|
pi.on('session_start', async (_event, ctx) => {
|
|
228
|
+
detachRunAbort?.();
|
|
229
|
+
cancelledRun = false;
|
|
227
230
|
generation += 1;
|
|
228
231
|
failAcks(new Error('Pi session replaced'));
|
|
229
232
|
stopWatcher();
|
|
230
233
|
handledPending.clear();
|
|
234
|
+
observedPending.clear();
|
|
231
235
|
retryAfterChange = false;
|
|
232
236
|
retryWait = undefined;
|
|
233
237
|
turnIndex = 0;
|
|
@@ -258,7 +262,13 @@ export default function squarePiExtension(pi) {
|
|
|
258
262
|
});
|
|
259
263
|
|
|
260
264
|
pi.on('agent_start', async (_event, ctx) => {
|
|
265
|
+
detachRunAbort?.();
|
|
261
266
|
currentRunSignal = ctx?.getSignal?.();
|
|
267
|
+
if (ctx?.mode !== 'tui' || currentRunSignal === undefined) return;
|
|
268
|
+
const runSignal = currentRunSignal;
|
|
269
|
+
detachRunAbort = () => runSignal.removeEventListener('abort', cancelRunDelivery);
|
|
270
|
+
if (runSignal.aborted) cancelRunDelivery();
|
|
271
|
+
else runSignal.addEventListener('abort', cancelRunDelivery, { once: true });
|
|
262
272
|
});
|
|
263
273
|
|
|
264
274
|
pi.on('message_end', async (event) => {
|
|
@@ -277,15 +287,13 @@ export default function squarePiExtension(pi) {
|
|
|
277
287
|
const turn = activeTurn;
|
|
278
288
|
activeTurn = undefined;
|
|
279
289
|
const acks = [...landingAcks.values()].flatMap((waiters) => [...waiters]);
|
|
280
|
-
if (event.message?.stopReason === 'aborted' && ctx?.mode === 'tui'
|
|
281
|
-
|
|
282
|
-
if (ack.kind === 'steer') ack.dropAfterSettled = true;
|
|
283
|
-
}
|
|
290
|
+
if (event.message?.stopReason === 'aborted' && ctx?.mode === 'tui') {
|
|
291
|
+
if (!cancelledRun) cancelRunDelivery();
|
|
284
292
|
return;
|
|
285
293
|
}
|
|
286
294
|
if (turn === undefined) return;
|
|
287
295
|
for (const ack of acks) {
|
|
288
|
-
if (ack.kind !== 'steer' ||
|
|
296
|
+
if (ack.kind !== 'steer' || turn.index <= ack.sentAfterTurn) continue;
|
|
289
297
|
if (turn.hasInput) {
|
|
290
298
|
ack.emptyTurnWindows = 0;
|
|
291
299
|
} else {
|
|
@@ -296,15 +304,25 @@ export default function squarePiExtension(pi) {
|
|
|
296
304
|
});
|
|
297
305
|
|
|
298
306
|
pi.on('agent_settled', async () => {
|
|
307
|
+
detachRunAbort?.();
|
|
308
|
+
detachRunAbort = undefined;
|
|
299
309
|
currentRunSignal = undefined;
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
310
|
+
if (!cancelledRun || sessionId === undefined) return;
|
|
311
|
+
const token = generation;
|
|
312
|
+
// Cancel the entire pending batch, including entries not yet sent to Pi.
|
|
313
|
+
// This is local suppression, never evidence that the model saw the activity.
|
|
314
|
+
const cancelled = await sessionInbox(sessionId);
|
|
315
|
+
if (token !== generation || sessionId === undefined) return;
|
|
316
|
+
for (const key of inboxKeys(cancelled)) handledPending.add(key);
|
|
317
|
+
cancelledRun = false;
|
|
318
|
+
watcherAbort = new AbortController();
|
|
319
|
+
watcher = wake(token, watcherAbort.signal).catch(() => undefined);
|
|
305
320
|
});
|
|
306
321
|
|
|
307
322
|
pi.on('session_shutdown', async () => {
|
|
323
|
+
detachRunAbort?.();
|
|
324
|
+
detachRunAbort = undefined;
|
|
325
|
+
cancelledRun = false;
|
|
308
326
|
generation += 1;
|
|
309
327
|
failAcks(new Error('Pi session ended'));
|
|
310
328
|
stopWatcher();
|