@north-light/crouter 0.3.158 → 0.3.159

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.
@@ -501,9 +501,12 @@ export async function runCoreView(core, tui, text, opts = {}) {
501
501
  setMode(mode) { chrome.mode = mode; },
502
502
  quit() { finish(); },
503
503
  };
504
- // The single-flight busy lane lives in the external FIFO. Key input still
505
- // drops while busy; refresh timers still skip while busy; ctx.dispatch from
506
- // inside an intent runs inline so chained intents do not deadlock.
504
+ // The single-flight busy lane lives in the external FIFO. Refresh timers skip
505
+ // while busy; ctx.dispatch from inside an intent runs inline so chained intents
506
+ // do not deadlock. Keystrokes QUEUE behind an in-flight intent (up to a small
507
+ // depth) rather than vanishing: a view whose auto-refresh shells out is busy a
508
+ // real fraction of the time, and silently swallowing a `y` confirmation or a
509
+ // cursor move is the difference between a live surface and a deaf one.
507
510
  const streams = new Set();
508
511
  let busy = false;
509
512
  let dispatching = false;
@@ -627,6 +630,9 @@ export async function runCoreView(core, tui, text, opts = {}) {
627
630
  render();
628
631
  if (core.intents['refresh'])
629
632
  await enqueueDispatch('refresh');
633
+ // Keystroke-dispatch backlog depth (see onData).
634
+ const MAX_QUEUED_KEYS = 2;
635
+ let queuedKeys = 0;
630
636
  // Capture-mode buffer: the host's line-editor draft while a `capture` binding's
631
637
  // when(state) is true; reset to '' whenever no capture binding is active.
632
638
  let captureBuf = '';
@@ -650,8 +656,10 @@ export async function runCoreView(core, tui, text, opts = {}) {
650
656
  finish();
651
657
  return;
652
658
  }
653
- // Drop keystrokes while an async intent is in flight (paces fetch/send).
654
- if (busy)
659
+ // Queue behind an in-flight intent, but shallowly: past a couple of pending
660
+ // keys the user is hammering a stuck view, and replaying the backlog later
661
+ // would act on a screen they never saw.
662
+ if (busy && queuedKeys >= MAX_QUEUED_KEYS)
655
663
  return;
656
664
  // Text-capture: while a capture binding is active, printable/backspace edit
657
665
  // the host buffer and dispatch capture(nextDraft); other keys (return/escape)
@@ -673,8 +681,15 @@ export async function runCoreView(core, tui, text, opts = {}) {
673
681
  captureBuf = '';
674
682
  }
675
683
  const m = matchViewBinding(tui.keymap, bindings, input, key, state, raw);
676
- if (m)
684
+ if (!m)
685
+ return;
686
+ queuedKeys += 1;
687
+ try {
677
688
  await enqueueDispatch(m.intent, m.payload);
689
+ }
690
+ finally {
691
+ queuedKeys -= 1;
692
+ }
678
693
  };
679
694
  process.stdin.on('data', (d) => { void onData(d); });
680
695
  // Resize → repaint from current state (never re-enter an in-flight intent).
@@ -244,6 +244,11 @@ export function createValveOperations(nodeId, contextDir) {
244
244
  finish(() => reject(err));
245
245
  });
246
246
  pgid = child.pid;
247
+ // The detached supervisor IS the group leader, so its pid is the pgid.
248
+ // Persisting it is what lets a human stop the job from the Inspector
249
+ // later; the agent's own handoff notice quotes the same number.
250
+ if (pgid !== undefined)
251
+ writeFileSync(paths.jobPgid, String(pgid));
247
252
  child.unref();
248
253
  interval = setInterval(() => {
249
254
  offset = tailOnce(paths.jobLog, offset, onData);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.158",
3
+ "version": "0.3.159",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/runtime.lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.158",
3
+ "version": "0.3.159",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@north-light/crouter",
9
- "version": "0.3.158",
9
+ "version": "0.3.159",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "dependencies": {