@nac3/forge-cli 1.7.2 → 1.7.3
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/chat/server.d.ts.map +1 -1
- package/dist/chat/server.js +43 -10
- package/dist/chat/server.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/chat/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAA2D,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAKjG,OAAO,EAAoD,KAAK,aAAa,EAAoB,MAAM,aAAa,CAAC;AAErH,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,EAEL,KAAK,SAAS,EACf,MAAM,iBAAiB,CAAC;AAczB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAsBjD,OAAO,EAAyD,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAsB1H,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB;;;;;;;;wDAQoD;IACpD,YAAY,CAAC,EAAE,eAAe,GAAG,iBAAiB,CAAC;IACnD;;2DAEuD;IACvD,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B;+CAC2C;IAC3C,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;;kEAG8D;IAC9D,OAAO,CAAC,EAAE,OAAO,sBAAsB,EAAE,OAAO,CAAC;IACjD;;;;;;;iDAO6C;IAC7C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;oDAEgD;IAChD,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ;qEACiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B;;;oCAGgC;IAChC,MAAM,CAAC,EAAE,OAAO,aAAa,EAAE,YAAY,GAAG,IAAI,CAAC;CACpD;AAqBD,wBAAsB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAwehF;AAED,UAAU,GAAG;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,eAAe,CAAC;IAIvB,OAAO,CAAC,EAAE,OAAO,sBAAsB,EAAE,OAAO,CAAC;IAMjD,YAAY,CAAC,EAAE,eAAe,GAAG,iBAAiB,CAAC;IAKnD,cAAc,CAAC,EAAE,MAAM,CAAC;IAGxB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAG3G,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAGlE,MAAM,CAAC,EAAE,OAAO,aAAa,EAAE,YAAY,GAAG,IAAI,CAAC;CACpD;AAwCD;;;;+EAI+E;AAC/E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAOV;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/chat/server.ts"],"names":[],"mappings":"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"}
|
package/dist/chat/server.js
CHANGED
|
@@ -5227,7 +5227,18 @@ async function handleChat(req, res, ctx) {
|
|
|
5227
5227
|
'connection': 'keep-alive',
|
|
5228
5228
|
'x-accel-buffering': 'no',
|
|
5229
5229
|
});
|
|
5230
|
+
/* Escribir en una respuesta YA cerrada no tira una excepcion que se
|
|
5231
|
+
* pueda atrapar aca: Node captura el stack en este punto pero emite el
|
|
5232
|
+
* error en el tick siguiente, como evento 'error' del stream. Sin
|
|
5233
|
+
* listener eso es un uncaughtException. Paso en vivo el 2026-09-29
|
|
5234
|
+
* (dos por turno, ERR_STREAM_WRITE_AFTER_END desde sseWrite) porque el
|
|
5235
|
+
* finally emitia steer_unclaimed despues del res.end(). Por eso: guarda
|
|
5236
|
+
* antes de escribir Y listener para el resto de los casos (el navegador
|
|
5237
|
+
* que se va a mitad de escritura -> EPIPE / ECONNRESET). */
|
|
5238
|
+
res.on('error', () => { });
|
|
5230
5239
|
sseWrite = (event, data) => {
|
|
5240
|
+
if (res.writableEnded || res.destroyed)
|
|
5241
|
+
return;
|
|
5231
5242
|
try {
|
|
5232
5243
|
const payload = JSON.stringify(data ?? {});
|
|
5233
5244
|
res.write('event: ' + event + '\n');
|
|
@@ -5249,6 +5260,30 @@ async function handleChat(req, res, ctx) {
|
|
|
5249
5260
|
sseWrite(event, data);
|
|
5250
5261
|
relayForward(event, data);
|
|
5251
5262
|
};
|
|
5263
|
+
/* Steering mid-turno: devolver al panel lo que quedo SIN entregar (el
|
|
5264
|
+
* turno termino antes de llegar a otra frontera de ronda) para que salga
|
|
5265
|
+
* como turno nuevo.
|
|
5266
|
+
*
|
|
5267
|
+
* Tiene que correr ANTES de cerrar el stream. Al principio esto vivia solo
|
|
5268
|
+
* en el finally, que en modo SSE corre DESPUES del res.end(): el evento no
|
|
5269
|
+
* llegaba nunca y encima reventaba con ERR_STREAM_WRITE_AFTER_END (visto en
|
|
5270
|
+
* vivo el 2026-09-29). Y tiene que llegar antes de turn_complete, porque es
|
|
5271
|
+
* ahi donde el panel vacia su cola: si el sobrante entra despues, se queda
|
|
5272
|
+
* esperando el proximo turno.
|
|
5273
|
+
*
|
|
5274
|
+
* Idempotente: closeSteering vacia el buzon, asi que la segunda llamada (la
|
|
5275
|
+
* red del finally) no hace nada. */
|
|
5276
|
+
const flushSteering = () => {
|
|
5277
|
+
if (!turnId)
|
|
5278
|
+
return;
|
|
5279
|
+
const sobrantes = closeSteering(turnId);
|
|
5280
|
+
if (!sobrantes.length)
|
|
5281
|
+
return;
|
|
5282
|
+
try {
|
|
5283
|
+
sseEmit('steer_unclaimed', { items: sobrantes.map((x) => x.text) });
|
|
5284
|
+
}
|
|
5285
|
+
catch { /* el panel lo reintenta igual por su cola */ }
|
|
5286
|
+
};
|
|
5252
5287
|
/* Register this live emitter so out-of-turn producers -- notably the CLI/Plan
|
|
5253
5288
|
* bridge dispatching verbs from the subprocess -- can push events (e.g.
|
|
5254
5289
|
* approval_required to open the R8 modal) to the panel. Unregister on
|
|
@@ -6368,6 +6403,7 @@ async function handleChat(req, res, ctx) {
|
|
|
6368
6403
|
};
|
|
6369
6404
|
}),
|
|
6370
6405
|
};
|
|
6406
|
+
flushSteering();
|
|
6371
6407
|
sseEmit('turn_complete', responsePayload);
|
|
6372
6408
|
if (sseWrite) {
|
|
6373
6409
|
res.end();
|
|
@@ -6378,6 +6414,7 @@ async function handleChat(req, res, ctx) {
|
|
|
6378
6414
|
}
|
|
6379
6415
|
catch (err) {
|
|
6380
6416
|
if (err instanceof ConfigurationError) {
|
|
6417
|
+
flushSteering();
|
|
6381
6418
|
sseEmit('error', { kind: 'no_api_key', message: err.message });
|
|
6382
6419
|
if (sseWrite) {
|
|
6383
6420
|
res.end();
|
|
@@ -6396,6 +6433,7 @@ async function handleChat(req, res, ctx) {
|
|
|
6396
6433
|
* "fetch failed" internal (PND-155). */
|
|
6397
6434
|
if (err instanceof ClaudeApiError || (err instanceof Error && /ApiError$/.test(err.name))) {
|
|
6398
6435
|
const message = err instanceof Error ? err.message : String(err);
|
|
6436
|
+
flushSteering();
|
|
6399
6437
|
sseEmit('error', { kind: 'claude_api_error', message });
|
|
6400
6438
|
if (sseWrite) {
|
|
6401
6439
|
res.end();
|
|
@@ -6409,6 +6447,7 @@ async function handleChat(req, res, ctx) {
|
|
|
6409
6447
|
}
|
|
6410
6448
|
return;
|
|
6411
6449
|
}
|
|
6450
|
+
flushSteering();
|
|
6412
6451
|
sseEmit('error', { kind: 'internal', message: err instanceof Error ? err.message : String(err) });
|
|
6413
6452
|
if (sseWrite) {
|
|
6414
6453
|
res.end();
|
|
@@ -6427,16 +6466,10 @@ async function handleChat(req, res, ctx) {
|
|
|
6427
6466
|
* concurrent turn's registration. */
|
|
6428
6467
|
if (turnId) {
|
|
6429
6468
|
endTurn(turnId);
|
|
6430
|
-
/*
|
|
6431
|
-
*
|
|
6432
|
-
*
|
|
6433
|
-
|
|
6434
|
-
if (sobrantes.length) {
|
|
6435
|
-
try {
|
|
6436
|
-
sseEmit('steer_unclaimed', { items: sobrantes.map((x) => x.text) });
|
|
6437
|
-
}
|
|
6438
|
-
catch { /* el panel lo reintenta igual por su cola */ }
|
|
6439
|
-
}
|
|
6469
|
+
/* Red: los caminos normales ya llamaron a flushSteering() con el stream
|
|
6470
|
+
* abierto. Esto solo cubre una salida que no paso por ahi -- el modo
|
|
6471
|
+
* NO-SSE (mobile / relay), donde no hay stream que cerrar. */
|
|
6472
|
+
flushSteering();
|
|
6440
6473
|
}
|
|
6441
6474
|
}
|
|
6442
6475
|
}
|