@bridge4dev/runner 0.27.0 → 0.30.0

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.
@@ -39,6 +39,14 @@ export interface SupervisorOptions {
39
39
  verifyEnabled?: boolean;
40
40
  /** Test seam for the one-shot commit-message run. */
41
41
  proposeCommitMessage?: typeof proposeCommitMessage;
42
+ /**
43
+ * `[checkpoints] enabled` from the runner's own config (ticket #126), by the
44
+ * same rule as `[verify] enabled`: restore points are copies of the working
45
+ * tree kept on this machine, so the machine's owner has the last word on
46
+ * whether they are taken at all. `false` means the capability is not
47
+ * announced and no rewind can be started.
48
+ */
49
+ checkpointsEnabled?: boolean;
42
50
  }
43
51
  export declare class Supervisor {
44
52
  private readonly ws;
@@ -61,6 +69,17 @@ export declare class Supervisor {
61
69
  private readonly authRelay;
62
70
  /** Serialises repo-mutating git commands per workspace repo (QA-99 MAJOR-1). */
63
71
  private readonly repoLocks;
72
+ /**
73
+ * Repo keys with work in flight right now (ticket #126).
74
+ *
75
+ * A checkpoint deliberately does NOT take the repo lock — it only reads the
76
+ * worktree, and queueing a user's message behind a 150-second push would be
77
+ * a plain regression. What it does instead is decline to run while a
78
+ * mutating command holds the repo: a snapshot taken halfway through an apply
79
+ * would be a state that never existed, and offering to restore it is worse
80
+ * than having no restore point for that one message.
81
+ */
82
+ private readonly repoLockDepth;
64
83
  /** An update is installing right now — a second one would fight it. */
65
84
  private selfUpdateInFlight;
66
85
  /** Session 14: one project-recipe run per machine, and its verdict queue. */
@@ -198,6 +217,14 @@ export declare class Supervisor {
198
217
  * slot.
199
218
  */
200
219
  private isParkable;
220
+ /**
221
+ * Stop the agent process but keep the session resumable.
222
+ *
223
+ * `quiet` is for the callers that say it better themselves: a conversation
224
+ * rewind parks the session too, and announcing «the runner switched to
225
+ * another session» there is simply untrue — nothing switched, the user
226
+ * rewound (ticket #126).
227
+ */
201
228
  private park;
202
229
  private forwardEvent;
203
230
  /**
@@ -210,6 +237,16 @@ export declare class Supervisor {
210
237
  */
211
238
  private onQuestionAnswer;
212
239
  private onUserMessage;
240
+ /**
241
+ * Queue a message that no agent can take yet, and say so in the feed
242
+ * (ticket #125).
243
+ *
244
+ * Every queueing decision goes through here so the browser's idea of "this
245
+ * one can still be taken back" cannot drift from the runner's. Records with
246
+ * no seq — orphans, and anything written by a runner older than 0.28.0 —
247
+ * stay silent: they have no name the browser could quote back.
248
+ */
249
+ private queueMessage;
213
250
  /**
214
251
  * Run delivery work for one session, strictly after whatever is already
215
252
  * queued for it. Order is the whole point: two messages typed seconds apart
@@ -235,6 +272,39 @@ export declare class Supervisor {
235
272
  * the message is retired from disk only once an agent has it.
236
273
  */
237
274
  private deliverMessage;
275
+ /**
276
+ * Nothing could take the message: put it back where it came from.
277
+ *
278
+ * Records that were already held keep their identity (and their queued
279
+ * announcement); a first-time refusal mints one and announces it.
280
+ */
281
+ private requeue;
282
+ /**
283
+ * Where this session's conversation stands, live process or not (ticket #126).
284
+ *
285
+ * Reads the running agent when there is one and remembers what it said;
286
+ * falls back to that memory when there is not. The provider session id is
287
+ * checked on the way out rather than on the way in: an anchor minted before
288
+ * a fork is not wrong, it simply belongs to a conversation this session no
289
+ * longer has.
290
+ */
291
+ private currentAnchor;
292
+ /**
293
+ * Take a restore point in front of the work that is about to start
294
+ * (ticket #126).
295
+ *
296
+ * Called from the delivery chain — which is already asynchronous because of
297
+ * attachments — rather than from `deliverMessage`, which is synchronous and
298
+ * has five exits. Never throws and never blocks delivery: a message must
299
+ * reach the agent whether or not a restore point could be taken.
300
+ *
301
+ * Three reasons it declines, and each of them is a state in which a snapshot
302
+ * would be a lie rather than a restore point:
303
+ * - the machine's owner switched checkpoints off;
304
+ * - the agent is mid-turn, so the tree is being written to as we read it;
305
+ * - a repo-mutating command holds the repository.
306
+ */
307
+ private captureCheckpoint;
238
308
  /**
239
309
  * Deliver messages that raced session start (already journaled).
240
310
  *
@@ -247,6 +317,10 @@ export declare class Supervisor {
247
317
  private interruptSession;
248
318
  /** Live model / interaction-mode switch (persisted for the next relaunch). */
249
319
  private applySettings;
320
+ /** Is a turn (or a question the agent is parked on) in flight right now? */
321
+ private isMidTurn;
322
+ /** The three live setters, in the order that lets an explicit pick win. */
323
+ private applyLiveSettings;
250
324
  private stopSession;
251
325
  private reconcile;
252
326
  /**
@@ -263,15 +337,31 @@ export declare class Supervisor {
263
337
  * mark the other session failed (QA-99 MAJOR-1).
264
338
  */
265
339
  private withRepoLock;
340
+ /** Is a repo-mutating command queued or running for this path right now? */
341
+ private isRepoLocked;
266
342
  /**
267
343
  * Same lock, keyed by the shared repository rather than by whichever path the
268
344
  * caller happened to have. A worktree commit and a workspace squash-merge
269
345
  * touch one repo, so they must take one key (see `repoKeyFor`).
270
346
  */
271
347
  private withRepoLockFor;
348
+ /**
349
+ * The live session this command names, or the sentence to refuse it with.
350
+ *
351
+ * A string return is deliberately unmistakable for a session: every caller
352
+ * has to branch on the type, so "I did not check" cannot compile.
353
+ */
354
+ private requireSession;
272
355
  /** A session actively mid-turn in this worktree — git writes must wait. */
273
356
  private isWorktreeBusy;
274
357
  private static readonly EVENT_PAYLOAD_CAP;
358
+ /**
359
+ * Journal an event, put it on the wire, and return it.
360
+ *
361
+ * The return value matters since ticket #125: the seq assigned here is the
362
+ * only name the browser and the runner share for one message, so the caller
363
+ * that echoes a user bubble has to be able to read it back.
364
+ */
275
365
  private sendEvent;
276
366
  private reportStatus;
277
367
  /** Graceful daemon shutdown: kill agents, keep sessions resumable server-side. */