@astrosheep/square 0.4.4 → 0.4.6

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.
Files changed (100) hide show
  1. package/dist/artifact-store.d.ts +1 -1
  2. package/dist/artifact-store.js +32 -15
  3. package/dist/artifact.d.ts +1 -4
  4. package/dist/artifact.js +0 -28
  5. package/dist/attention-presentation.js +1 -1
  6. package/dist/boundary-presentation.js +2 -2
  7. package/dist/claude-boundary-state.d.ts +6 -6
  8. package/dist/claude-boundary-state.js +13 -13
  9. package/dist/claude-hook.js +25 -24
  10. package/dist/claude-mcp-context.d.ts +2 -2
  11. package/dist/claude-mcp-context.js +6 -6
  12. package/dist/cli/context.js +3 -6
  13. package/dist/cli/json.js +1 -1
  14. package/dist/cli/mcp-server-command.js +3 -3
  15. package/dist/cli/observation-commands.d.ts +2 -2
  16. package/dist/cli/observation-commands.js +23 -51
  17. package/dist/cli/perceive-presentation.d.ts +3 -0
  18. package/dist/cli/{catch-presentation.js → perceive-presentation.js} +3 -3
  19. package/dist/cli/registry.js +2 -2
  20. package/dist/codex-address.d.ts +3 -0
  21. package/dist/codex-address.js +7 -0
  22. package/dist/codex-hook.d.ts +1 -1
  23. package/dist/codex-hook.js +11 -8
  24. package/dist/codex-queue.d.ts +3 -2
  25. package/dist/codex-queue.js +8 -11
  26. package/dist/codex-watch.d.ts +6 -1
  27. package/dist/codex-watch.js +27 -29
  28. package/dist/delivery-ledger-sqlite.d.ts +25 -20
  29. package/dist/delivery-ledger-sqlite.js +76 -61
  30. package/dist/delivery-ledger.d.ts +24 -19
  31. package/dist/delivery-ledger.js +150 -81
  32. package/dist/delivery-lifetime.d.ts +2 -2
  33. package/dist/delivery-lifetime.js +6 -18
  34. package/dist/help.js +12 -12
  35. package/dist/hints.d.ts +2 -2
  36. package/dist/hints.js +7 -7
  37. package/dist/index.d.ts +1 -1
  38. package/dist/index.js +1 -1
  39. package/dist/list.d.ts +2 -2
  40. package/dist/list.js +4 -3
  41. package/dist/mcp.d.ts +2 -2
  42. package/dist/mcp.js +8 -32
  43. package/dist/neutral.d.ts +5 -5
  44. package/dist/notifications.js +12 -6
  45. package/dist/operation-presentation.d.ts +8 -3
  46. package/dist/operation-presentation.js +50 -12
  47. package/dist/packages/agent-delivery/src/file-lock.js +4 -1
  48. package/dist/perceive-decisions.d.ts +28 -0
  49. package/dist/{catch-decisions.js → perceive-decisions.js} +24 -24
  50. package/dist/{catch-selection.d.ts → perceive-selection.d.ts} +2 -2
  51. package/dist/{catch-selection.js → perceive-selection.js} +3 -3
  52. package/dist/plugins/opencode/index.js +4 -4
  53. package/dist/plugins/opencode-shared/delivery.d.ts +6 -6
  54. package/dist/plugins/opencode-shared/delivery.js +27 -21
  55. package/dist/plugins/opencode-v1/runtime.js +3 -3
  56. package/dist/ports.d.ts +0 -4
  57. package/dist/presentation.d.ts +1 -1
  58. package/dist/presentation.js +13 -13
  59. package/dist/session-lifecycle.d.ts +2 -2
  60. package/dist/session-lifecycle.js +11 -11
  61. package/dist/sqlite-square.d.ts +2 -4
  62. package/dist/sqlite-square.js +47 -54
  63. package/dist/sqlite-transaction.d.ts +2 -0
  64. package/dist/sqlite-transaction.js +25 -3
  65. package/dist/square-api.d.ts +1 -1
  66. package/dist/square-api.js +1 -1
  67. package/dist/square-domain.js +1 -1
  68. package/dist/square-facade.d.ts +15 -13
  69. package/dist/square-location.js +1 -1
  70. package/dist/square-posting.d.ts +5 -5
  71. package/dist/square-posting.js +39 -38
  72. package/dist/square-tools.d.ts +15 -4
  73. package/dist/square-tools.js +35 -17
  74. package/dist/views.d.ts +7 -3
  75. package/dist/views.js +6 -3
  76. package/guides/architect.md +2 -2
  77. package/guides/change-waits.md +1 -1
  78. package/guides/codex-delivery.md +40 -35
  79. package/guides/delivery-primitives.md +22 -7
  80. package/guides/mcp.md +4 -2
  81. package/guides/operation-cancellation.md +11 -3
  82. package/guides/pi-native-delivery.md +1 -1
  83. package/guides/pi-tools.md +11 -6
  84. package/guides/receive-primitive.md +3 -3
  85. package/guides/square-api.md +15 -8
  86. package/package.json +2 -2
  87. package/plugins/claude/.claude-plugin/plugin.json +1 -1
  88. package/plugins/claude/skills/square/SKILL.md +10 -10
  89. package/plugins/codex/.codex-plugin/plugin.json +2 -2
  90. package/plugins/codex/hooks/hooks.json +3 -0
  91. package/plugins/opencode/index.ts +4 -4
  92. package/plugins/opencode-shared/delivery.ts +27 -21
  93. package/plugins/opencode-v1/runtime.ts +3 -3
  94. package/plugins/paseo/client/markdown.tsx +9 -26
  95. package/plugins/paseo/client/square-message.tsx +10 -14
  96. package/plugins/pi/square-pi.js +100 -20
  97. package/skills/square/SKILL.md +10 -10
  98. package/dist/catch-decisions.d.ts +0 -28
  99. package/dist/cli/catch-presentation.d.ts +0 -3
  100. package/guides/mcp-connection-lifetime.md +0 -22
@@ -22,7 +22,7 @@ export const { DatabaseSync } = await (process.versions.bun
22
22
  },
23
23
  }))
24
24
  : import('node:sqlite'));
25
- import { inSqliteTransaction } from './sqlite-transaction.js';
25
+ import { inSqliteTransaction, retrySqliteBusy, awaitSqliteQueue } from './sqlite-transaction.js';
26
26
  import { validateSchema } from './sqlite-framing.js';
27
27
  const FORMAT = 3;
28
28
  const APPLICATION_ID = 0x444c4752;
@@ -70,12 +70,16 @@ export class LedgerStore {
70
70
  clock;
71
71
  pending = Promise.resolve();
72
72
  closed = false;
73
+ cancellation = new AbortController();
74
+ ordinaryCancellation = new AbortController();
75
+ closing;
73
76
  constructor(location, db, clock) {
74
77
  this.location = location;
75
78
  this.db = db;
76
79
  this.clock = clock;
77
80
  }
78
- static async open(location, clock) {
81
+ static async open(location, clock, signal) {
82
+ signal?.throwIfAborted();
79
83
  try {
80
84
  await fs.access(location);
81
85
  }
@@ -87,14 +91,15 @@ export class LedgerStore {
87
91
  let initial;
88
92
  try {
89
93
  await (await fs.open(temporary, 'wx', 0o600)).close();
90
- initial = new DatabaseSync(temporary);
94
+ initial = await retrySqliteBusy(() => new DatabaseSync(temporary), signal);
91
95
  await inSqliteTransaction(initial, true, () => undefined, () => {
92
96
  initial.exec(SCHEMA);
93
97
  initial.prepare('INSERT INTO meta VALUES(?,1)').run(FORMAT);
94
98
  initial.exec(`PRAGMA application_id=${APPLICATION_ID}; PRAGMA user_version=${FORMAT}`);
95
- });
99
+ }, signal);
96
100
  initial.close();
97
101
  initial = undefined;
102
+ signal?.throwIfAborted();
98
103
  try {
99
104
  await fs.link(temporary, location);
100
105
  }
@@ -109,16 +114,16 @@ export class LedgerStore {
109
114
  }
110
115
  }
111
116
  // Existing formats are inspected on a read-only connection before any writable open.
112
- const probe = new DatabaseSync(location, { readOnly: true });
117
+ const probe = await retrySqliteBusy(() => new DatabaseSync(location, { readOnly: true }), signal);
113
118
  try {
114
- validate(probe, location);
119
+ await retrySqliteBusy(() => validate(probe, location), signal);
115
120
  }
116
121
  finally {
117
122
  probe.close();
118
123
  }
119
- const db = new DatabaseSync(location);
124
+ const db = await retrySqliteBusy(() => new DatabaseSync(location), signal);
120
125
  try {
121
- validate(db, location);
126
+ await retrySqliteBusy(() => { validate(db, location); db.exec('PRAGMA busy_timeout=0; PRAGMA synchronous=FULL'); }, signal);
122
127
  return new LedgerStore(location, db, clock);
123
128
  }
124
129
  catch (error) {
@@ -126,27 +131,37 @@ export class LedgerStore {
126
131
  throw error;
127
132
  }
128
133
  }
134
+ /** Stop ordinary work while captured effects retain access to settlement. */
135
+ retire() { this.ordinaryCancellation.abort(new Error('Delivery ledger is closed')); }
129
136
  close() {
137
+ this.retire();
130
138
  this.closed = true;
131
- return this.pending.then(() => this.db.close());
139
+ this.cancellation.abort(new Error('Delivery ledger is closed'));
140
+ return this.closing ??= this.pending.then(() => this.db.close());
132
141
  }
133
- transaction(write, change, signal) {
134
- if (this.closed)
142
+ transaction(write, change, signal, settlement = false) {
143
+ if (this.closed || !settlement && this.ordinaryCancellation.signal.aborted)
135
144
  return Promise.reject(new Error('Delivery ledger is closed'));
136
- const result = this.pending.then(() => inSqliteTransaction(this.db, write, () => validate(this.db, this.location), () => {
137
- const now = this.clock();
138
- if (!Number.isFinite(now))
139
- throw new TypeError('Expected finite ledger time');
140
- const changes = Number(this.db.prepare('SELECT total_changes() AS n').get().n);
141
- const result = change(now);
142
- if (write && Number(this.db.prepare('SELECT total_changes() AS n').get().n) > changes) {
143
- this.normalize(now);
144
- this.gc(now);
145
- }
146
- return result;
147
- }, signal));
145
+ signal = AbortSignal.any([this.cancellation.signal, ...(!settlement ? [this.ordinaryCancellation.signal] : []), ...(signal ? [signal] : [])]);
146
+ let started = false;
147
+ const result = this.pending.then(() => {
148
+ signal.throwIfAborted();
149
+ started = true;
150
+ return inSqliteTransaction(this.db, write, () => validate(this.db, this.location), () => {
151
+ const now = this.clock();
152
+ if (!Number.isFinite(now))
153
+ throw new TypeError('Expected finite ledger time');
154
+ const changes = Number(this.db.prepare('SELECT total_changes() AS n').get().n);
155
+ const result = change(now);
156
+ if (write && Number(this.db.prepare('SELECT total_changes() AS n').get().n) > changes) {
157
+ this.normalize(now);
158
+ this.gc(now);
159
+ }
160
+ return result;
161
+ }, signal);
162
+ });
148
163
  this.pending = result.catch(() => undefined);
149
- return result;
164
+ return awaitSqliteQueue(result, signal, () => started);
150
165
  }
151
166
  getSession(owner) {
152
167
  return session(this.db.prepare('SELECT * FROM sessions WHERE owner=?').get(owner));
@@ -215,19 +230,19 @@ export class LedgerStore {
215
230
  this.deleteCard(row.seq, now);
216
231
  this.db.prepare('DELETE FROM receipts WHERE rowid IN (SELECT rowid FROM receipts WHERE at<? ORDER BY at LIMIT 100)').run(cutoff);
217
232
  }
218
- session(owner) { return this.transaction(false, () => this.getSession(owner)); }
219
- sessions() {
220
- return this.transaction(false, () => this.db.prepare('SELECT * FROM sessions ORDER BY owner').all().map(row => session(row)));
233
+ session(owner, signal) { return this.transaction(false, () => this.getSession(owner), signal); }
234
+ sessions(signal) {
235
+ return this.transaction(false, () => this.db.prepare('SELECT * FROM sessions ORDER BY owner').all().map(row => session(row)), signal);
221
236
  }
222
- pendingCards(owner, generation) {
237
+ pendingCards(owner, generation, signal) {
223
238
  return this.transaction(false, now => this.attached(owner, generation)
224
- ? this.db.prepare('SELECT * FROM cards WHERE owner=? ORDER BY seq').all(owner).filter(row => this.eligible(row, now)).map(card) : []);
239
+ ? this.db.prepare('SELECT * FROM cards WHERE owner=? ORDER BY seq').all(owner).filter(row => this.eligible(row, now)).map(card) : [], signal);
225
240
  }
226
- handoffs(owner, generation) {
241
+ handoffs(owner, generation, signal) {
227
242
  return this.transaction(false, () => this.db.prepare(`SELECT a.* FROM attempts a JOIN cards c ON c.seq=a.seq
228
- WHERE c.owner=? AND a.generation=? AND a.track='handoff' ORDER BY a.rowid`).all(owner, generation).map(attempt));
243
+ WHERE c.owner=? AND a.generation=? AND a.track='handoff' ORDER BY a.rowid`).all(owner, generation).map(attempt), signal);
229
244
  }
230
- attach(input) {
245
+ attach(input, signal) {
231
246
  const encoded = JSON.stringify(input.routes);
232
247
  return this.transaction(true, now => {
233
248
  const previous = this.getSession(input.owner);
@@ -237,27 +252,27 @@ export class LedgerStore {
237
252
  this.db.prepare(`INSERT INTO sessions VALUES(?,?,'attached',?,?) ON CONFLICT(owner)
238
253
  DO UPDATE SET generation=excluded.generation,state=excluded.state,routes_json=excluded.routes_json,at=excluded.at`).run(input.owner, generation, encoded, now);
239
254
  return this.getSession(input.owner);
240
- });
255
+ }, signal);
241
256
  }
242
- updateRoutes(input) {
257
+ updateRoutes(input, signal) {
243
258
  const encoded = JSON.stringify(input.routes);
244
259
  return this.transaction(true, now => {
245
260
  if (!this.attached(input.owner, input.generation))
246
261
  return false;
247
262
  this.db.prepare('UPDATE sessions SET routes_json=?,at=? WHERE owner=?').run(encoded, now, input.owner);
248
263
  return true;
249
- });
264
+ }, signal);
250
265
  }
251
- lifecycle(input, state) {
266
+ lifecycle(input, state, signal) {
252
267
  return this.transaction(true, now => {
253
268
  const s = this.getSession(input.owner);
254
269
  if (!s || s.generation !== input.generation || s.state === 'deleted')
255
270
  return false;
256
271
  this.db.prepare('UPDATE sessions SET state=?,at=? WHERE owner=?').run(state, now, input.owner);
257
272
  return true;
258
- });
273
+ }, signal);
259
274
  }
260
- post(input) {
275
+ post(input, signal) {
261
276
  return this.transaction(true, now => {
262
277
  const s = this.getSession(input.owner);
263
278
  if (!s)
@@ -279,9 +294,9 @@ export class LedgerStore {
279
294
  this.db.prepare('UPDATE meta SET next_seq=?').run(seq + 1);
280
295
  this.db.prepare('INSERT INTO cards VALUES(?,?,?,?,?,?)').run(seq, input.owner, input.key, input.text, input.details, now);
281
296
  return { status: suppressed ? 'suppressed' : 'posted' };
282
- });
297
+ }, signal);
283
298
  }
284
- suppress(input) {
299
+ suppress(input, signal) {
285
300
  return this.transaction(true, now => {
286
301
  const permanentId = input.scope === 'exact' && input.expiresAt === undefined
287
302
  ? this.db.prepare("SELECT id FROM suppressions WHERE owner=? AND key=? AND scope='exact' AND expires_at IS NULL").get(input.owner, input.key)?.id
@@ -298,22 +313,22 @@ export class LedgerStore {
298
313
  this.deleteCard(row.seq);
299
314
  }
300
315
  return { id, status: inCustody ? 'in-custody' : 'suppressed' };
301
- });
316
+ }, signal);
302
317
  }
303
- renewSuppression(input) {
304
- return this.transaction(true, now => this.db.prepare('UPDATE suppressions SET expires_at=? WHERE owner=? AND id=? AND (expires_at IS NULL OR expires_at>?)').run(input.expiresAt, input.owner, input.id, now).changes > 0);
318
+ renewSuppression(input, signal) {
319
+ return this.transaction(true, now => this.db.prepare('UPDATE suppressions SET expires_at=? WHERE owner=? AND id=? AND (expires_at IS NULL OR expires_at>?)').run(input.expiresAt, input.owner, input.id, now).changes > 0, signal);
305
320
  }
306
- releaseSuppression(input) {
307
- return this.transaction(true, () => this.db.prepare('DELETE FROM suppressions WHERE owner=? AND id=?').run(input.owner, input.id).changes > 0);
321
+ releaseSuppression(input, signal) {
322
+ return this.transaction(true, () => this.db.prepare('DELETE FROM suppressions WHERE owner=? AND id=?').run(input.owner, input.id).changes > 0, signal);
308
323
  }
309
- cancel(input) {
324
+ cancel(input, signal) {
310
325
  return this.transaction(true, () => {
311
326
  if (!this.attached(input.owner, input.generation))
312
327
  return false;
313
328
  this.db.prepare(`INSERT INTO cancellations VALUES(?,?,(SELECT next_seq-1 FROM meta))
314
329
  ON CONFLICT(owner) DO UPDATE SET generation=excluded.generation,through_seq=MAX(through_seq,excluded.through_seq)`).run(input.owner, input.generation);
315
330
  return true;
316
- });
331
+ }, signal);
317
332
  }
318
333
  isSuppressed(owner, key, now) {
319
334
  return !!this.db.prepare(`SELECT 1 FROM suppressions WHERE owner=? AND (expires_at IS NULL OR expires_at>?)
@@ -413,7 +428,7 @@ export class LedgerStore {
413
428
  this.receipt(handoff.seq, now);
414
429
  return true;
415
430
  }
416
- settle(tokens, outcome) {
431
+ settle(tokens, outcome, signal) {
417
432
  return this.transaction(true, now => {
418
433
  const attempts = tokens.map(token => this.getAttempt(token));
419
434
  if (attempts.some(a => !a || a.track === 'presentation' && outcome === 'accepted'
@@ -440,7 +455,7 @@ export class LedgerStore {
440
455
  }
441
456
  }
442
457
  return true;
443
- });
458
+ }, signal, true);
444
459
  }
445
460
  handoffFacts(token) {
446
461
  const a = this.getAttempt(token);
@@ -463,16 +478,16 @@ export class LedgerStore {
463
478
  const s = this.attached(facts.ref.owner, facts.ref.generation);
464
479
  return facts.attempt.expiresAt > now && !!s && s.routes.some(route => route.kind === facts.ref.routeKind) && this.eligible(facts.row, now);
465
480
  }
466
- handoff(token) {
467
- return this.transaction(false, () => this.handoffFacts(token)?.ref);
481
+ handoff(token, signal) {
482
+ return this.transaction(false, () => this.handoffFacts(token)?.ref, signal);
468
483
  }
469
- guardHandoff(ref) {
484
+ guardHandoff(ref, signal) {
470
485
  return this.transaction(false, now => {
471
486
  const facts = this.matchingHandoff(ref);
472
487
  return !!facts && ['dispatching', 'unknown'].includes(facts.attempt.outcome) && this.currentHandoff(facts, now);
473
- });
488
+ }, signal);
474
489
  }
475
- acceptHandoff(ref) {
490
+ acceptHandoff(ref, signal) {
476
491
  return this.transaction(true, now => {
477
492
  const a = this.matchingHandoff(ref)?.attempt;
478
493
  if (!a || !['dispatching', 'unknown', 'accepted'].includes(a.outcome))
@@ -480,9 +495,9 @@ export class LedgerStore {
480
495
  if (a.outcome !== 'accepted')
481
496
  this.db.prepare("UPDATE attempts SET outcome='accepted',settled_at=? WHERE token=?").run(now, a.token);
482
497
  return true;
483
- });
498
+ }, signal);
484
499
  }
485
- observePresentation(handoff, options) {
500
+ observePresentation(handoff, options, signal) {
486
501
  return this.transaction(true, now => {
487
502
  const facts = typeof handoff === 'string' ? undefined : this.matchingHandoff(handoff);
488
503
  if (options?.requireCurrent) {
@@ -494,14 +509,14 @@ export class LedgerStore {
494
509
  }
495
510
  const a = typeof handoff === 'string' ? this.getAttempt(handoff) : facts?.attempt;
496
511
  return a ? this.confirm(a, now) : false;
497
- });
512
+ }, signal);
498
513
  }
499
- receipts(owner, options) {
514
+ receipts(owner, options, signal) {
500
515
  return this.transaction(false, () => this.db.prepare('SELECT * FROM receipts WHERE owner=? AND at>=? ORDER BY at,key').all(owner, options.since ?? -Number.MAX_VALUE)
501
516
  .filter(row => options.keys === undefined || options.keys.includes(row.key))
502
- .map(row => ({ owner: row.owner, key: row.key, at: row.at })));
517
+ .map(row => ({ owner: row.owner, key: row.key, at: row.at })), signal);
503
518
  }
504
- health(owner) {
519
+ health(owner, signal) {
505
520
  return this.transaction(false, now => {
506
521
  const all = this.db.prepare('SELECT a.* FROM attempts a JOIN cards c ON c.seq=a.seq WHERE (? IS NULL OR c.owner=?) ORDER BY a.started_at,a.token').all(owner ?? null, owner ?? null).map(attempt);
507
522
  const repeatedFailures = this.db.prepare(`SELECT c.owner,c.key,COUNT(*) AS count FROM attempts a JOIN cards c ON c.seq=a.seq
@@ -511,6 +526,6 @@ export class LedgerStore {
511
526
  return { unknownAttempts: all.filter(a => a.outcome === 'unknown' || a.outcome === 'dispatching' && a.expiresAt <= now)
512
527
  .map(a => a.outcome === 'dispatching' ? { ...a, outcome: 'unknown' } : a), repeatedFailures,
513
528
  sessionsWithoutRoute: sessions.filter(s => s.routes.length === 0).map(s => s.owner) };
514
- });
529
+ }, signal);
515
530
  }
516
531
  }
@@ -109,83 +109,88 @@ export declare function deliveryLedgerLocation(env?: NodeJS.ProcessEnv, homeDir?
109
109
  export declare class DeliveryLedger {
110
110
  private readonly store;
111
111
  private readonly leaseMs;
112
+ private readonly settlements;
113
+ private retired;
112
114
  private constructor();
113
115
  static open(options?: {
114
116
  readonly location?: string;
115
117
  readonly clock?: () => number;
116
118
  readonly leaseMs?: number;
119
+ readonly signal?: AbortSignal;
117
120
  }): Promise<DeliveryLedger>;
118
121
  close(): Promise<void>;
122
+ private retainSettlement;
123
+ private diagnose;
119
124
  attach(input: {
120
125
  readonly owner: Owner;
121
126
  readonly expectedGeneration: string | null;
122
127
  readonly routes: readonly DeliveryRoute[];
123
- }): Promise<DeliverySession | false>;
128
+ }, signal?: AbortSignal): Promise<DeliverySession | false>;
124
129
  updateRoutes(input: {
125
130
  readonly owner: Owner;
126
131
  readonly generation: string;
127
132
  readonly routes: readonly DeliveryRoute[];
128
- }): Promise<boolean>;
133
+ }, signal?: AbortSignal): Promise<boolean>;
129
134
  detach(input: {
130
135
  readonly owner: Owner;
131
136
  readonly generation: string;
132
- }): Promise<boolean>;
137
+ }, signal?: AbortSignal): Promise<boolean>;
133
138
  markDeleted(input: {
134
139
  readonly owner: Owner;
135
140
  readonly generation: string;
136
- }): Promise<boolean>;
141
+ }, signal?: AbortSignal): Promise<boolean>;
137
142
  private lifecycle;
138
- session(owner: Owner): Promise<DeliverySession | undefined>;
139
- sessions(): Promise<readonly DeliverySession[]>;
143
+ session(owner: Owner, signal?: AbortSignal): Promise<DeliverySession | undefined>;
144
+ sessions(signal?: AbortSignal): Promise<readonly DeliverySession[]>;
140
145
  pending(owner: Owner, options: {
141
146
  readonly generation: string;
142
- }): Promise<readonly DeliveryCard[]>;
147
+ }, signal?: AbortSignal): Promise<readonly DeliveryCard[]>;
143
148
  handoffs(owner: Owner, options: {
144
149
  readonly generation: string;
145
- }): Promise<readonly DeliveryAttempt[]>;
150
+ }, signal?: AbortSignal): Promise<readonly DeliveryAttempt[]>;
146
151
  post(input: {
147
152
  readonly owner: Owner;
148
153
  readonly key: string;
149
154
  readonly text: string;
150
155
  readonly details?: Readonly<Record<string, unknown>>;
151
- }): Promise<PostResult>;
156
+ }, signal?: AbortSignal): Promise<PostResult>;
152
157
  suppress(input: {
153
158
  readonly owner: Owner;
154
159
  readonly key: string;
155
160
  readonly scope: 'exact' | 'prefix';
156
161
  readonly expiresAt?: number;
157
- }): Promise<SuppressionResult>;
162
+ }, signal?: AbortSignal): Promise<SuppressionResult>;
158
163
  renewSuppression(input: {
159
164
  readonly owner: Owner;
160
165
  readonly id: string;
161
166
  readonly expiresAt: number;
162
- }): Promise<boolean>;
167
+ }, signal?: AbortSignal): Promise<boolean>;
163
168
  releaseSuppression(input: {
164
169
  readonly owner: Owner;
165
170
  readonly id: string;
166
- }): Promise<boolean>;
171
+ }, signal?: AbortSignal): Promise<boolean>;
167
172
  cancel(input: {
168
173
  readonly owner: Owner;
169
174
  readonly generation: string;
170
- }): Promise<boolean>;
175
+ }, signal?: AbortSignal): Promise<boolean>;
171
176
  receipts(owner: Owner, options?: {
172
177
  readonly keys?: readonly string[];
173
178
  readonly since?: number;
174
- }): Promise<readonly DeliveryReceipt[]>;
179
+ }, signal?: AbortSignal): Promise<readonly DeliveryReceipt[]>;
175
180
  claimPresentation(owner: Owner, options: {
176
181
  readonly generation: string;
177
182
  readonly budgetChars: number;
178
183
  readonly signal?: AbortSignal;
179
184
  }): Promise<PresentationClaim | undefined>;
180
185
  /** Resolve the original prepared handoff, including its stored route kind. */
181
- handoff(token: string): Promise<DeliveryHandoffRef | undefined>;
182
- guardHandoff(ref: DeliveryHandoffRef): Promise<boolean>;
183
- acceptHandoff(ref: DeliveryHandoffRef): Promise<boolean>;
186
+ handoff(token: string, signal?: AbortSignal): Promise<DeliveryHandoffRef | undefined>;
187
+ guardHandoff(ref: DeliveryHandoffRef, signal?: AbortSignal): Promise<boolean>;
188
+ acceptHandoff(ref: DeliveryHandoffRef, signal?: AbortSignal): Promise<boolean>;
184
189
  /** Confirms the exact existing external effect; never sends or returns text. */
185
190
  observePresentation(handoff: string | DeliveryHandoffRef, options?: {
186
191
  readonly requireCurrent?: boolean;
187
- }): Promise<boolean>;
188
- health(owner?: Owner): Promise<DeliveryHealth>;
192
+ }, signal?: AbortSignal): Promise<boolean>;
193
+ health(owner?: Owner, signal?: AbortSignal): Promise<DeliveryHealth>;
189
194
  /** Subscribe first; read the returned version, inspect state, then await changed(version,...). */
190
195
  observe(owner: Owner): Promise<VersionObserver<string>>;
191
196
  dispatchHandoff(owner: Owner, key: string, transport: DeliveryTransport, options: {