@standardagents/code 0.11.0 → 0.11.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/dist/index.js CHANGED
@@ -451,14 +451,6 @@ var ApiClient = class {
451
451
  })
452
452
  );
453
453
  }
454
- async steerInput(threadId, mutation) {
455
- return parseSharedMessagingSnapshot(
456
- await this.json(this.messagingPath(threadId, "/steer"), {
457
- method: "POST",
458
- body: JSON.stringify(mutation)
459
- })
460
- );
461
- }
462
454
  async updatePendingInput(threadId, pendingId, mutation) {
463
455
  return parseSharedMessagingSnapshot(
464
456
  await this.json(this.messagingPath(threadId, `/pending/${encodeURIComponent(pendingId)}`), {
@@ -499,13 +491,23 @@ var ApiClient = class {
499
491
  })
500
492
  );
501
493
  }
502
- async requestSharedStop(threadId, origin2) {
503
- return parseSharedMessagingSnapshot(
504
- await this.json(this.messagingPath(threadId, "/stop"), {
505
- method: "POST",
506
- body: JSON.stringify(origin2)
507
- })
508
- );
494
+ /**
495
+ * Immediately halt a thread: the instance aborts the in-flight LLM
496
+ * request(s), marks dangling tool calls failed, and holds new turns until
497
+ * the next user message. This is Escape's HARD stop — not the old
498
+ * cooperative "stop at the next safe boundary" intent, which deferred the
499
+ * halt until the current step finished.
500
+ */
501
+ async stopThread(threadId) {
502
+ await this.json(`/api/threads/${threadId}/stop`, { method: "POST" });
503
+ }
504
+ /**
505
+ * Resume a stopped thread's execution loop. Used after a hard stop when a
506
+ * queued (steered) message should play immediately instead of waiting for
507
+ * the user's next direct send.
508
+ */
509
+ async continueThread(threadId) {
510
+ await this.json(`/api/threads/${threadId}/continue`, { method: "POST" });
509
511
  }
510
512
  async getMessages(threadId, limit = 50, order) {
511
513
  const orderParam = order ? `&order=${order}` : "";
@@ -9316,7 +9318,7 @@ why: ${req.requestPermission}` : ""}`,
9316
9318
  const sessionEnded = new Promise((r) => endSession = r);
9317
9319
  const quit = async () => {
9318
9320
  tui.end();
9319
- const stopped2 = bridge?.isOwner ?? false ? api.requestSharedStop(threadId, messagingOrigin).catch(() => {
9321
+ const stopped2 = bridge?.isOwner ?? false ? api.stopThread(threadId).catch(() => {
9320
9322
  }) : Promise.resolve();
9321
9323
  const procsStopped2 = host ? host.stopAllLocalProcesses().catch(() => 0) : Promise.resolve(0);
9322
9324
  bridge?.close();
@@ -9442,11 +9444,6 @@ why: ${req.requestPermission}` : ""}`,
9442
9444
  attachments: [...refs, ...toSharedAttachments(images)],
9443
9445
  ...messagingOrigin
9444
9446
  }));
9445
- const steerSharedInput = (text, images, refs = []) => applySharedMutation(api.steerInput(threadId, {
9446
- content: text,
9447
- attachments: [...refs, ...toSharedAttachments(images)],
9448
- ...messagingOrigin
9449
- }));
9450
9447
  const editSharedPending = (item, text, images, refs) => applySharedMutation(api.updatePendingInput(threadId, item.id, {
9451
9448
  content: text,
9452
9449
  attachments: [
@@ -9456,7 +9453,21 @@ why: ${req.requestPermission}` : ""}`,
9456
9453
  ...messagingOrigin
9457
9454
  }));
9458
9455
  const dismissSharedPending = (item) => applySharedMutation(api.dismissPendingInput(threadId, item.id, messagingOrigin));
9459
- const promoteSharedPending = (item) => applySharedMutation(api.steerPendingInput(threadId, item.id, messagingOrigin));
9456
+ const promoteSharedPending = async (item) => {
9457
+ if (busy) {
9458
+ await Promise.all([
9459
+ api.stopThread(threadId).catch(() => {
9460
+ }),
9461
+ ...[...activeSubagents.keys()].map((childId) => api.stopThread(childId).catch(() => {
9462
+ }))
9463
+ ]);
9464
+ const promoted = await applySharedMutation(api.steerPendingInput(threadId, item.id, messagingOrigin));
9465
+ if (promoted) await api.continueThread(threadId).catch(() => {
9466
+ });
9467
+ return promoted;
9468
+ }
9469
+ return applySharedMutation(api.steerPendingInput(threadId, item.id, messagingOrigin));
9470
+ };
9460
9471
  const sendNow = async (text, images = [], refs = []) => {
9461
9472
  lastSent = { text, images, refs };
9462
9473
  tui.printUserMessage(text || `\u{1F4CE} ${refs.length + images.length} attachment(s)`);
@@ -9797,7 +9808,7 @@ ${c4.gray}Close another session (its slot frees within ~90s), then resend your m
9797
9808
  return;
9798
9809
  }
9799
9810
  const updated = await editSharedPending(item, text, images, draftRefs);
9800
- const promoted = !steer || !updated ? updated : await applySharedMutation(api.steerPendingInput(threadId, pendingId, messagingOrigin));
9811
+ const promoted = !steer || !updated ? updated : await promoteSharedPending({ ...item, id: pendingId });
9801
9812
  if (!promoted) {
9802
9813
  mirroredDraftRefs = item.attachments.filter(isSharedAttachmentRef);
9803
9814
  tui.setExternalAttachmentNames(mirroredDraftRefs.map((attachment) => attachment.name));
@@ -9806,8 +9817,14 @@ ${c4.gray}Close another session (its slot frees within ~90s), then resend your m
9806
9817
  return;
9807
9818
  }
9808
9819
  if (steer) {
9809
- tui.print(`${c4.yellow}\u21AA steering at the next safe model boundary:${c4.reset} ${text}`);
9810
- if (!await steerSharedInput(text, images, draftRefs)) {
9820
+ tui.print(`${c4.yellow}\u21AA steering now \u2014 stopping the current step${c4.reset}`);
9821
+ await Promise.all([
9822
+ api.stopThread(threadId).catch(() => {
9823
+ }),
9824
+ ...[...activeSubagents.keys()].map((childId) => api.stopThread(childId).catch(() => {
9825
+ }))
9826
+ ]);
9827
+ if (!await sendNow(text, images, draftRefs)) {
9811
9828
  mirroredDraftRefs = draftRefs;
9812
9829
  tui.setExternalAttachmentNames(draftRefs.map((attachment) => attachment.name));
9813
9830
  tui.setInput(text, images);
@@ -9844,13 +9861,15 @@ ${c4.gray}Close another session (its slot frees within ~90s), then resend your m
9844
9861
  return;
9845
9862
  }
9846
9863
  if (busy) {
9847
- if (!sharedMessagingReady) {
9848
- tui.print(`${c4.dim}Shared messaging is not connected; the session was not stopped.${c4.reset}`);
9849
- return;
9864
+ const queued = sharedMessaging.pending.items.length;
9865
+ tui.print(`${c4.yellow}\u25A0 stopping now${queued > 0 ? ` \u2014 ${queued} queued message${queued === 1 ? "" : "s"} kept` : ""}${c4.reset}`);
9866
+ const stops = [api.stopThread(threadId).catch(() => {
9867
+ })];
9868
+ for (const childId of activeSubagents.keys()) {
9869
+ stops.push(api.stopThread(childId).catch(() => {
9870
+ }));
9850
9871
  }
9851
- const advancing = sharedMessaging.pending.items.length > 0;
9852
- tui.print(`${c4.yellow}${advancing ? "[stopping; next pending message will run]" : "[stopping at the next safe boundary]"}${c4.reset}`);
9853
- void applySharedMutation(api.requestSharedStop(threadId, messagingOrigin));
9872
+ void Promise.all(stops);
9854
9873
  }
9855
9874
  };
9856
9875
  tui.onBgBadge = () => {
@@ -10061,7 +10080,7 @@ ${c4.dim}runs on ${request.machine || runnerName}${c4.reset}`,
10061
10080
  clearInterval(pollTimer);
10062
10081
  clearInterval(heartbeatPoll);
10063
10082
  process.off("SIGCONT", onTerminalResume);
10064
- const stopped = bridge?.isOwner ?? false ? api.requestSharedStop(threadId, messagingOrigin).catch(() => {
10083
+ const stopped = bridge?.isOwner ?? false ? api.stopThread(threadId).catch(() => {
10065
10084
  }) : Promise.resolve();
10066
10085
  const procsStopped = host ? host.stopAllLocalProcesses().catch(() => 0) : Promise.resolve(0);
10067
10086
  bridge?.close();
@@ -10328,7 +10347,7 @@ function showKeybindings(tui) {
10328
10347
  tui.print(`${c4.gray}shortcuts:${c4.reset}`);
10329
10348
  tui.print(`${c4.gray} shift-tab${c4.reset} cycle auto-accept level (1\u20135)`);
10330
10349
  tui.print(`${c4.gray} shift-\u23CE${c4.reset} insert a newline (multiline input)`);
10331
- tui.print(`${c4.gray} option-\u23CE${c4.reset} steer the working agent at the next safe boundary`);
10350
+ tui.print(`${c4.gray} option-\u23CE${c4.reset} steer now \u2014 stops the current step and plays your message`);
10332
10351
  tui.print(`${c4.gray} /${c4.reset} open the command palette (type to filter)`);
10333
10352
  tui.print(`${c4.gray} !cmd${c4.reset} run a shell command on the session's machine (e.g. !ls); !! to send a literal !`);
10334
10353
  tui.print(`${c4.gray} ctrl-v${c4.reset} paste an image from the clipboard ([#Image 1])`);