@nac3/forge-cli 1.11.0 → 1.13.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.
- package/dist/chat/persistence.d.ts +6 -0
- package/dist/chat/persistence.d.ts.map +1 -1
- package/dist/chat/persistence.js +16 -0
- package/dist/chat/persistence.js.map +1 -1
- package/dist/chat/server.d.ts.map +1 -1
- package/dist/chat/server.js +48 -1
- package/dist/chat/server.js.map +1 -1
- package/dist/chat/tools/pending.d.ts.map +1 -1
- package/dist/chat/tools/pending.js +55 -0
- package/dist/chat/tools/pending.js.map +1 -1
- package/dist/nac3/internal_manifest.d.ts.map +1 -1
- package/dist/nac3/internal_manifest.js +4 -1
- package/dist/nac3/internal_manifest.js.map +1 -1
- package/dist/relay/in_flight_turn.d.ts +56 -0
- package/dist/relay/in_flight_turn.d.ts.map +1 -0
- package/dist/relay/in_flight_turn.js +72 -0
- package/dist/relay/in_flight_turn.js.map +1 -0
- package/dist/relay/relay_publisher.d.ts +10 -1
- package/dist/relay/relay_publisher.d.ts.map +1 -1
- package/dist/relay/relay_publisher.js +31 -1
- package/dist/relay/relay_publisher.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -19,6 +19,10 @@ export declare class TranscriptStore {
|
|
|
19
19
|
private transcript;
|
|
20
20
|
private dirty;
|
|
21
21
|
private writeQueue;
|
|
22
|
+
/** Motivo del ultimo fallo de escritura, o null. Lo expone `lastError()`
|
|
23
|
+
* para que un llamador que SI espera el flush pueda enterarse: el catch de
|
|
24
|
+
* la cadena evita que mate el proceso, no que el fallo importe. */
|
|
25
|
+
private lastWriteError;
|
|
22
26
|
constructor(projectRoot: string, forgeVersion: string, filename?: string);
|
|
23
27
|
append(message: ChatMessage): void;
|
|
24
28
|
/**
|
|
@@ -29,6 +33,8 @@ export declare class TranscriptStore {
|
|
|
29
33
|
* an upstream fire-and-forget already enqueued a write).
|
|
30
34
|
*/
|
|
31
35
|
flush(): Promise<void>;
|
|
36
|
+
/** El ultimo fallo de escritura, o null si la ultima escritura fue bien. */
|
|
37
|
+
lastError(): string | null;
|
|
32
38
|
/** Total messages currently in the transcript (excl. system). */
|
|
33
39
|
size(): number;
|
|
34
40
|
/** Return a shallow copy of the messages for downstream send. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../src/chat/persistence.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,MAAM,WAAW,cAAc;IAC7B,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,eAAe,CAAC,EAAE,GAAE,IAAiB,GAAG,MAAM,CAc7D;AAED,qBAAa,eAAe;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,UAAU,CAAoC;
|
|
1
|
+
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../src/chat/persistence.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,MAAM,WAAW,cAAc;IAC7B,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,eAAe,CAAC,EAAE,GAAE,IAAiB,GAAG,MAAM,CAc7D;AAED,qBAAa,eAAe;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,UAAU,CAAoC;IACtD;;wEAEoE;IACpE,OAAO,CAAC,cAAc,CAAuB;gBAEjC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAaxE,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAYlC;;;;;;OAMG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA+B5B,4EAA4E;IAC5E,SAAS,IAAI,MAAM,GAAG,IAAI;IAE1B,iEAAiE;IACjE,IAAI,IAAI,MAAM;IAId,iEAAiE;IACjE,QAAQ,IAAI,WAAW,EAAE;CAG1B"}
|
package/dist/chat/persistence.js
CHANGED
|
@@ -39,6 +39,10 @@ export class TranscriptStore {
|
|
|
39
39
|
transcript;
|
|
40
40
|
dirty = false;
|
|
41
41
|
writeQueue = Promise.resolve();
|
|
42
|
+
/** Motivo del ultimo fallo de escritura, o null. Lo expone `lastError()`
|
|
43
|
+
* para que un llamador que SI espera el flush pueda enterarse: el catch de
|
|
44
|
+
* la cadena evita que mate el proceso, no que el fallo importe. */
|
|
45
|
+
lastWriteError = null;
|
|
42
46
|
constructor(projectRoot, forgeVersion, filename) {
|
|
43
47
|
this.projectRoot = projectRoot;
|
|
44
48
|
this.filePath = path.join(cacheDir(projectRoot), filename ?? sessionFilename());
|
|
@@ -78,6 +82,14 @@ export class TranscriptStore {
|
|
|
78
82
|
* cola esperando su turno. La meta tambien se redacta, por si el
|
|
79
83
|
* projectRoot trae algo. */
|
|
80
84
|
this.dirty = false;
|
|
85
|
+
/* La cadena se encadena con un catch PROPIO: quien hace
|
|
86
|
+
* `void store.flush()` (server.ts, al cerrar el turno) no espera la
|
|
87
|
+
* promesa, asi que una escritura fallida se volvia una unhandled
|
|
88
|
+
* rejection -- y en Node eso TUMBA el proceso. Encontrado porque la
|
|
89
|
+
* bateria completa salia con error aunque los 4495 tests pasaran: un
|
|
90
|
+
* test borraba su temp mientras un flush seguia en vuelo (2026-10-11).
|
|
91
|
+
* Fallar la escritura del transcript no puede matar la sesion, y
|
|
92
|
+
* tampoco puede desaparecer en silencio (SQ 0.3): se loguea. */
|
|
81
93
|
this.writeQueue = this.writeQueue.then(async () => {
|
|
82
94
|
const snapshot = JSON.stringify({
|
|
83
95
|
meta: redactDeep(this.transcript.meta),
|
|
@@ -85,10 +97,14 @@ export class TranscriptStore {
|
|
|
85
97
|
}, null, 2);
|
|
86
98
|
await fs.mkdir(path.dirname(this.filePath), { recursive: true });
|
|
87
99
|
await fs.writeFile(this.filePath, snapshot, 'utf-8');
|
|
100
|
+
}).catch((e) => {
|
|
101
|
+
this.lastWriteError = e instanceof Error ? e.message : String(e);
|
|
88
102
|
});
|
|
89
103
|
}
|
|
90
104
|
await this.writeQueue;
|
|
91
105
|
}
|
|
106
|
+
/** El ultimo fallo de escritura, o null si la ultima escritura fue bien. */
|
|
107
|
+
lastError() { return this.lastWriteError; }
|
|
92
108
|
/** Total messages currently in the transcript (excl. system). */
|
|
93
109
|
size() {
|
|
94
110
|
return this.transcript.messages.length;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persistence.js","sourceRoot":"","sources":["../../src/chat/persistence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAgBlD,MAAM,UAAU,QAAQ,CAAC,WAAmB;IAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAW,IAAI,IAAI,EAAE;IACnD,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,EAAE,CAAC,cAAc,EAAE;UAC7B,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;UAC/B,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC;UAC1B,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;UAC3B,GAAG,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;UACvB,GAAG,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,CAAC;IAC5B,qEAAqE;IACrE,kEAAkE;IAClE,mEAAmE;IACnE,gEAAgE;IAChE,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO,KAAK,GAAG,GAAG,GAAG,MAAM,GAAG,OAAO,CAAC;AACxC,CAAC;AAED,MAAM,OAAO,eAAe;IACjB,WAAW,CAAS;IACpB,QAAQ,CAAS;IAClB,UAAU,CAAa;IACvB,KAAK,GAAG,KAAK,CAAC;IACd,UAAU,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"persistence.js","sourceRoot":"","sources":["../../src/chat/persistence.ts"],"names":[],"mappings":"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"}
|
|
@@ -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;
|
|
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
|
@@ -47,6 +47,7 @@ import { checkMutatingRequest, publicOrigins } from '../core/public_origin.js';
|
|
|
47
47
|
import { isAllowedSlot, listAllowedSlots } from '../core/provider_keys.js';
|
|
48
48
|
import { toolStatusSection, startToolStatusRefresh, environmentLines } from './tool_status.js';
|
|
49
49
|
import { RelayPublisher } from '../relay/relay_publisher.js';
|
|
50
|
+
import { setInFlightTurn, clearInFlightTurn, inFlightTurn } from '../relay/in_flight_turn.js';
|
|
50
51
|
import { getInstanceIdentity } from '../relay/instance_identity.js';
|
|
51
52
|
import { isMobilePaired, relayGate } from '../core/mobile_pairing_state.js';
|
|
52
53
|
import { relayPoll } from '../relay/relay_client.js';
|
|
@@ -1136,7 +1137,11 @@ function startDesktopCommandConsumer(port, coord = {}) {
|
|
|
1136
1137
|
return;
|
|
1137
1138
|
const idn = getInstanceIdentity();
|
|
1138
1139
|
const slug = _relayBoardCtx?.slug ?? null;
|
|
1139
|
-
pub.presence({
|
|
1140
|
+
pub.presence({
|
|
1141
|
+
hostname: idn.hostname, pid: idn.pid, port,
|
|
1142
|
+
...(slug ? { project_slug: slug, project_name: slug } : {}),
|
|
1143
|
+
turn: inFlightTurn(),
|
|
1144
|
+
});
|
|
1140
1145
|
void pub.flush();
|
|
1141
1146
|
}
|
|
1142
1147
|
catch { /* best-effort */ }
|
|
@@ -5466,6 +5471,11 @@ async function handleChat(req, res, ctx) {
|
|
|
5466
5471
|
* mid-flight. Declared out here so the outer try's finally can
|
|
5467
5472
|
* clear it on every exit path. */
|
|
5468
5473
|
let turnId = null;
|
|
5474
|
+
/* El eco del turno para el movil. Se declara ACA, fuera del try, porque el
|
|
5475
|
+
* catch y el finally tienen que poder anunciar el error y limpiar el estado
|
|
5476
|
+
* del turno en vuelo -- y lo que se declara dentro del try no se ve desde
|
|
5477
|
+
* ahi. Mismo motivo por el que turnId vive en este nivel. */
|
|
5478
|
+
let turnEcho = null;
|
|
5469
5479
|
/* alpha.59e -- SSE streaming mode. Client opts in via
|
|
5470
5480
|
* body.stream=true. We keep the response open + emit events
|
|
5471
5481
|
* during the tool loop instead of bundling everything in a
|
|
@@ -5605,6 +5615,13 @@ async function handleChat(req, res, ctx) {
|
|
|
5605
5615
|
* the END remoteTurn (same id) fills the reply. Old phones ignore
|
|
5606
5616
|
* the extra fields and keep their current end-of-turn behavior. */
|
|
5607
5617
|
const _xTurnId = (body.origin === 'mobile' ? 'mb-' : body.origin === 'bridge' ? 'br-' : 'dt-') + Date.now().toString(36);
|
|
5618
|
+
/* Queda registrado como ESTADO para que el latido de presencia lo
|
|
5619
|
+
* repita: ver el comentario largo en RelayPublisher.presence(). */
|
|
5620
|
+
if (sessionId === DEFAULT_SESSION_ID && lastUserText
|
|
5621
|
+
&& body.origin !== 'mobile' && body.origin !== 'bridge') {
|
|
5622
|
+
setInFlightTurn({ id: _xTurnId, user: lastUserText, started_at: new Date().toISOString() });
|
|
5623
|
+
turnEcho = { id: _xTurnId, user: lastUserText };
|
|
5624
|
+
}
|
|
5608
5625
|
if (sessionId === DEFAULT_SESSION_ID && lastUserText) {
|
|
5609
5626
|
if (body.origin === 'mobile' || body.origin === 'bridge') {
|
|
5610
5627
|
try {
|
|
@@ -6609,6 +6626,11 @@ async function handleChat(req, res, ctx) {
|
|
|
6609
6626
|
* reflects it too. Mobile-origin turns are skipped (the phone already
|
|
6610
6627
|
* has them as its own bubbles). Same id as the start 'working' echo so
|
|
6611
6628
|
* a new phone replaces its pending bubble instead of appending. */
|
|
6629
|
+
/* Se limpia ANTES de publicar el remoteTurn para que un latido que caiga
|
|
6630
|
+
* en el medio no vuelva a anunciar como "en curso" algo que ya tiene
|
|
6631
|
+
* respuesta. El finally lo limpia igual -- esto es el caso normal, el
|
|
6632
|
+
* finally es la garantia de que ningun camino lo deje colgado. */
|
|
6633
|
+
clearInFlightTurn(_xTurnId);
|
|
6612
6634
|
if (body.origin !== 'mobile' && body.origin !== 'bridge' && sessionId === DEFAULT_SESSION_ID
|
|
6613
6635
|
&& !reply.interrupted) {
|
|
6614
6636
|
try {
|
|
@@ -6704,6 +6726,24 @@ async function handleChat(req, res, ctx) {
|
|
|
6704
6726
|
}
|
|
6705
6727
|
}
|
|
6706
6728
|
catch (err) {
|
|
6729
|
+
/* El movil se entera del corte. Va al TOPE del catch y no en cada rama
|
|
6730
|
+
* porque las tres ramas retornan, y repetirlo seria tres copias de la
|
|
6731
|
+
* misma regla (y la tercera se olvidaria). El codigo distingue el motivo
|
|
6732
|
+
* para que la pantalla pueda decir algo util en vez de "fallo". */
|
|
6733
|
+
try {
|
|
6734
|
+
if (turnEcho) {
|
|
6735
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6736
|
+
const code = err instanceof ConfigurationError ? 'no_api_key'
|
|
6737
|
+
: (err instanceof ClaudeApiError || (err instanceof Error && /ApiError$/.test(err.name))) ? 'brain_error'
|
|
6738
|
+
: 'internal';
|
|
6739
|
+
const pub = getRelayPublisher();
|
|
6740
|
+
if (pub) {
|
|
6741
|
+
pub.remoteTurn(turnEcho.id, turnEcho.user, '', { error: msg, code });
|
|
6742
|
+
void pub.flush();
|
|
6743
|
+
}
|
|
6744
|
+
}
|
|
6745
|
+
}
|
|
6746
|
+
catch { /* best-effort: anunciar el error no puede provocar otro */ }
|
|
6707
6747
|
if (err instanceof ConfigurationError) {
|
|
6708
6748
|
flushSteering();
|
|
6709
6749
|
sseEmit('error', { kind: 'no_api_key', message: err.message });
|
|
@@ -6751,6 +6791,13 @@ async function handleChat(req, res, ctx) {
|
|
|
6751
6791
|
}
|
|
6752
6792
|
}
|
|
6753
6793
|
finally {
|
|
6794
|
+
/* El turno en vuelo se limpia ACA, no en el camino feliz. Lo tenia solo
|
|
6795
|
+
* antes del remoteTurn de exito, asi que un turno que reventaba dejaba al
|
|
6796
|
+
* telefono anunciando "en curso" algo ya muerto hasta que expiraba a los
|
|
6797
|
+
* 10 minutos (Pablo 2026-10-11). Pasa por el id para no borrar el anuncio
|
|
6798
|
+
* de un turno que ya arranco despues. */
|
|
6799
|
+
if (turnEcho)
|
|
6800
|
+
clearInFlightTurn(turnEcho.id);
|
|
6754
6801
|
/* Interrupt (task #27): always clear this turn from the active
|
|
6755
6802
|
* registry, no matter how the turn exits. endTurn is a no-op if a
|
|
6756
6803
|
* newer turn has already replaced us, so it never clobbers a
|