@mmmbuto/nexuscrew 0.8.46 → 0.8.47

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.
@@ -25,6 +25,7 @@ const {
25
25
  waitAlive, waitStablePane, injectPrompt,
26
26
  redactSecrets, sanitizeEarlyDiagnostic,
27
27
  } = require('./launch.js');
28
+ const { waitDeliveryReport, actionRequiredFor } = require('./prompt-delivery.js');
28
29
 
29
30
  // TTL della cache status (ms): scaduto, status rilegge tmux + defs da disco.
30
31
  const STATUS_TTL_MS = 2000;
@@ -209,6 +210,12 @@ function createBuiltinRuntime(ctx) {
209
210
  tmuxSession: cell.tmuxSession,
210
211
  prompt: cell.prompt,
211
212
  readyMs: Math.max(0, Math.min(30000, Number(cfg.sendKeysReadyMs) || readyMs)),
213
+ // Solo gli engine managed Kimi (kimi.native / claude.kimi-code) hanno
214
+ // la delivery classificata at-most-once ai restart; gli engine custom
215
+ // send-keys conservano il reinject legacy senza Enter (0.8.47 G4).
216
+ client: engine.managed && engine.managed.client === 'kimi' ? 'kimi'
217
+ : (engine.managed && engine.managed.provider === 'kimi-code' ? 'claude' : ''),
218
+ readyWaitMs: Math.max(0, Math.min(120000, Number(cfg.bootstrapReadyWaitMs) || 15000)),
212
219
  },
213
220
  } : {}),
214
221
  });
@@ -396,20 +403,52 @@ function createBuiltinRuntime(ctx) {
396
403
  };
397
404
  }
398
405
 
399
- // (6) prompt send-keys: bracketed-paste best-effort, target = pane id esatto
400
- // (fallback al nome sessione con match esatto '=' se tmux non ha stampato l'id).
406
+ // (6) prompt: due percorsi distinti (0.8.47, R2 single-owner).
407
+ // - managed kimi.native / claude.kimi-code: la consegna e' posseduta SOLO
408
+ // dal supervisore (cell-exec) per TUTTE le generazioni; qui si legge
409
+ // l'esito bounded (@nc_delivery sul pane) con attesa bounded. Mai paste/
410
+ // Enter dal runtime: niente doppia delivery se gen0 muore durante
411
+ // l'attesa e gen1 parte sotto il supervisore.
412
+ // - engine custom promptMode 'send-keys': injectPrompt legacy (bracketed
413
+ // paste SENZA Enter, contratto invariato — G4), target %N esatto.
401
414
  let prompt = null;
415
+ let actionRequired = null;
402
416
  if (launchEngine.promptMode === 'send-keys' && cell.prompt) {
403
- const target = paneId.startsWith('%') ? paneId : `=${cell.tmuxSession}`;
404
- prompt = await injectPrompt(tmuxBin, cell.tmuxSession, cell.prompt, {
405
- env: minimalEnv(),
406
- readyMs: cfg.sendKeysReadyMs != null ? cfg.sendKeysReadyMs : readyMs,
407
- target,
408
- engine: launchEngine, cell, // per la redazione del reason se paste-buffer fallisce (§9h)
409
- });
417
+ const managedClient = engine.managed && typeof engine.managed.client === 'string' ? engine.managed.client : '';
418
+ const managedProvider = engine.managed && typeof engine.managed.provider === 'string' ? engine.managed.provider : '';
419
+ const classified = managedClient === 'kimi' || managedProvider === 'kimi-code';
420
+ if (classified) {
421
+ const readyWaitMs = Math.max(0, Math.min(120000, Number(cfg.bootstrapReadyWaitMs) || 15000));
422
+ const reportWaitMs = Math.max(100, Math.min(150000,
423
+ (Number(cfg.sendKeysReadyMs) || readyMs) + readyWaitMs + 2000));
424
+ const report = await waitDeliveryReport(tmuxBin,
425
+ paneId.startsWith('%') ? paneId : `=${cell.tmuxSession}`,
426
+ { env: minimalEnv(), timeoutMs: reportWaitMs });
427
+ const delivery = report || {
428
+ delivered: false, state: 'report-timeout', notReady: '', attempts: 0, reason: 'report-timeout',
429
+ };
430
+ prompt = {
431
+ injected: delivery.delivered,
432
+ delivered: delivery.delivered,
433
+ state: delivery.state,
434
+ reason: delivery.reason,
435
+ };
436
+ actionRequired = actionRequiredFor(managedClient, managedProvider, delivery);
437
+ } else {
438
+ const target = paneId.startsWith('%') ? paneId : `=${cell.tmuxSession}`;
439
+ prompt = await injectPrompt(tmuxBin, cell.tmuxSession, cell.prompt, {
440
+ env: minimalEnv(),
441
+ readyMs: cfg.sendKeysReadyMs != null ? cfg.sendKeysReadyMs : readyMs,
442
+ target,
443
+ engine: launchEngine, cell, // per la redazione del reason se paste-buffer fallisce (§9h)
444
+ });
445
+ }
410
446
  }
411
447
  cache = { ...cache, at: 0 }; // invalida: prossimo status rilegge tmux
412
- return { ok: true, cell: cellId, session: cell.tmuxSession, prompt };
448
+ return {
449
+ ok: true, cell: cellId, session: cell.tmuxSession, prompt,
450
+ ...(actionRequired ? { actionRequired } : {}),
451
+ };
413
452
  }
414
453
 
415
454
  async function down(cellId /* , opts */) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmmbuto/nexuscrew",
3
- "version": "0.8.46",
3
+ "version": "0.8.47",
4
4
  "description": "Faithful browser tmux client — attach to live sessions over a real PTY, localhost-only, mobile-easy",
5
5
  "main": "lib/server.js",
6
6
  "bin": {