@nac3/forge-cli 1.16.0 → 1.16.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/chat/server.d.ts.map +1 -1
- package/dist/chat/server.js +8 -2
- package/dist/chat/server.js.map +1 -1
- package/dist/relay/in_flight_turn.d.ts +42 -9
- package/dist/relay/in_flight_turn.d.ts.map +1 -1
- package/dist/relay/in_flight_turn.js +57 -13
- package/dist/relay/in_flight_turn.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -33,23 +33,56 @@ export interface InFlightTurn {
|
|
|
33
33
|
started_at: string;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
36
|
+
* Cada cuanto el turno da senal de vida. Es el periodo del latido de actividad
|
|
37
|
+
* del servidor (`startRelayHeartbeat`), que corre SOLO entre el arranque y el
|
|
38
|
+
* cierre del turno.
|
|
38
39
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* Mentir sobre lo que el sistema esta haciendo es peor que no decir nada.
|
|
40
|
+
* Vive aca y no en server.ts a proposito: es la mitad de un par acoplado, y la
|
|
41
|
+
* otra mitad es `SILENCIO_MAX_MS`. El bug anterior nacio de tener dos numeros
|
|
42
|
+
* acoplados en dos archivos distintos sin nada que los ligara.
|
|
43
43
|
*/
|
|
44
|
-
export declare const
|
|
45
|
-
|
|
44
|
+
export declare const PULSO_DE_PROGRESO_MS: number;
|
|
45
|
+
/**
|
|
46
|
+
* Tope de SILENCIO. Un turno que no da senal de vida por mas que esto se
|
|
47
|
+
* considera muerto y deja de anunciarse, aunque nadie lo haya limpiado.
|
|
48
|
+
*
|
|
49
|
+
* ANTES ERA UN TOPE DE EDAD, y eso estaba mal (Pablo, 13-oct-2026: "hay turnos
|
|
50
|
+
* de mas de 3 horas en un desarrollo"). La proteccion que se queria es contra
|
|
51
|
+
* un turno COLGADO -- un proceso que muere a mitad de camino, o una excepcion
|
|
52
|
+
* por un camino que no pasa por `clearInFlightTurn` -- porque mentir sobre lo
|
|
53
|
+
* que el sistema esta haciendo es peor que no decir nada. Pero "colgado" no es
|
|
54
|
+
* "viejo": es "sin progreso". Un tope de edad confunde las dos cosas y castiga
|
|
55
|
+
* justo al turno largo, que es el que mas necesita anunciarse.
|
|
56
|
+
*
|
|
57
|
+
* Medido: un turno de 29 minutos en ADIP-Kikan dejaba al telefono diciendo que
|
|
58
|
+
* no habia nada corriendo durante sus ultimos 19 minutos. Con turnos de 3 horas
|
|
59
|
+
* el anuncio serviria para el 5% del turno.
|
|
60
|
+
*
|
|
61
|
+
* Diez pulsos de margen: tolera que se pierdan nueve latidos seguidos antes de
|
|
62
|
+
* dar por muerto un turno que esta vivo.
|
|
63
|
+
*/
|
|
64
|
+
export declare const SILENCIO_MAX_MS: number;
|
|
65
|
+
export declare function setInFlightTurn(t: InFlightTurn, now?: number): void;
|
|
66
|
+
/**
|
|
67
|
+
* Senal de vida del turno en curso. La llama el latido de actividad del
|
|
68
|
+
* servidor, que corre solo mientras hay turno.
|
|
69
|
+
*
|
|
70
|
+
* No crea nada: si no hay turno registrado, no hace nada. Asi un latido
|
|
71
|
+
* rezagado no puede resucitar un turno ya cerrado.
|
|
72
|
+
*/
|
|
73
|
+
export declare function touchInFlightTurn(now?: number): void;
|
|
46
74
|
/**
|
|
47
75
|
* Limpia el turno en vuelo. Con `id`, SOLO si coincide: dos turnos encadenados
|
|
48
76
|
* pueden cerrar fuera de orden, y un cierre tardio del viejo no tiene que
|
|
49
77
|
* borrar el anuncio del que recien arranco.
|
|
50
78
|
*/
|
|
51
79
|
export declare function clearInFlightTurn(id?: string): void;
|
|
52
|
-
/**
|
|
80
|
+
/**
|
|
81
|
+
* El turno en vuelo, o null si no hay o si se quedo CALLADO.
|
|
82
|
+
*
|
|
83
|
+
* La edad del turno no entra en la decision: un turno de tres horas que sigue
|
|
84
|
+
* latiendo es un turno vivo y se anuncia. Lo que lo saca es el silencio.
|
|
85
|
+
*/
|
|
53
86
|
export declare function inFlightTurn(now?: number): InFlightTurn | null;
|
|
54
87
|
/** Solo para tests. */
|
|
55
88
|
export declare function _resetInFlightTurn(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in_flight_turn.d.ts","sourceRoot":"","sources":["../../src/relay/in_flight_turn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,
|
|
1
|
+
{"version":3,"file":"in_flight_turn.d.ts","sourceRoot":"","sources":["../../src/relay/in_flight_turn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,QAAY,CAAC;AAE9C;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,eAAe,QAA4B,CAAC;AASzD,wBAAgB,eAAe,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,GAAE,MAAmB,GAAG,IAAI,CAQ/E;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAmB,GAAG,IAAI,CAGhE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAInD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAmB,GAAG,YAAY,GAAG,IAAI,CAU1E;AAED,uBAAuB;AACvB,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
|
|
@@ -27,20 +27,57 @@
|
|
|
27
27
|
* ASCII puro.
|
|
28
28
|
*/
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
30
|
+
* Cada cuanto el turno da senal de vida. Es el periodo del latido de actividad
|
|
31
|
+
* del servidor (`startRelayHeartbeat`), que corre SOLO entre el arranque y el
|
|
32
|
+
* cierre del turno.
|
|
32
33
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* Mentir sobre lo que el sistema esta haciendo es peor que no decir nada.
|
|
34
|
+
* Vive aca y no en server.ts a proposito: es la mitad de un par acoplado, y la
|
|
35
|
+
* otra mitad es `SILENCIO_MAX_MS`. El bug anterior nacio de tener dos numeros
|
|
36
|
+
* acoplados en dos archivos distintos sin nada que los ligara.
|
|
37
37
|
*/
|
|
38
|
-
export const
|
|
38
|
+
export const PULSO_DE_PROGRESO_MS = 60 * 1000;
|
|
39
|
+
/**
|
|
40
|
+
* Tope de SILENCIO. Un turno que no da senal de vida por mas que esto se
|
|
41
|
+
* considera muerto y deja de anunciarse, aunque nadie lo haya limpiado.
|
|
42
|
+
*
|
|
43
|
+
* ANTES ERA UN TOPE DE EDAD, y eso estaba mal (Pablo, 13-oct-2026: "hay turnos
|
|
44
|
+
* de mas de 3 horas en un desarrollo"). La proteccion que se queria es contra
|
|
45
|
+
* un turno COLGADO -- un proceso que muere a mitad de camino, o una excepcion
|
|
46
|
+
* por un camino que no pasa por `clearInFlightTurn` -- porque mentir sobre lo
|
|
47
|
+
* que el sistema esta haciendo es peor que no decir nada. Pero "colgado" no es
|
|
48
|
+
* "viejo": es "sin progreso". Un tope de edad confunde las dos cosas y castiga
|
|
49
|
+
* justo al turno largo, que es el que mas necesita anunciarse.
|
|
50
|
+
*
|
|
51
|
+
* Medido: un turno de 29 minutos en ADIP-Kikan dejaba al telefono diciendo que
|
|
52
|
+
* no habia nada corriendo durante sus ultimos 19 minutos. Con turnos de 3 horas
|
|
53
|
+
* el anuncio serviria para el 5% del turno.
|
|
54
|
+
*
|
|
55
|
+
* Diez pulsos de margen: tolera que se pierdan nueve latidos seguidos antes de
|
|
56
|
+
* dar por muerto un turno que esta vivo.
|
|
57
|
+
*/
|
|
58
|
+
export const SILENCIO_MAX_MS = PULSO_DE_PROGRESO_MS * 10;
|
|
39
59
|
let current = null;
|
|
40
|
-
export function setInFlightTurn(t) {
|
|
60
|
+
export function setInFlightTurn(t, now = Date.now()) {
|
|
41
61
|
if (!t || !t.id)
|
|
42
62
|
return;
|
|
43
|
-
current = {
|
|
63
|
+
current = {
|
|
64
|
+
id: String(t.id),
|
|
65
|
+
user: String(t.user || ''),
|
|
66
|
+
started_at: String(t.started_at || new Date(now).toISOString()),
|
|
67
|
+
visto: now,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Senal de vida del turno en curso. La llama el latido de actividad del
|
|
72
|
+
* servidor, que corre solo mientras hay turno.
|
|
73
|
+
*
|
|
74
|
+
* No crea nada: si no hay turno registrado, no hace nada. Asi un latido
|
|
75
|
+
* rezagado no puede resucitar un turno ya cerrado.
|
|
76
|
+
*/
|
|
77
|
+
export function touchInFlightTurn(now = Date.now()) {
|
|
78
|
+
if (!current)
|
|
79
|
+
return;
|
|
80
|
+
current.visto = now;
|
|
44
81
|
}
|
|
45
82
|
/**
|
|
46
83
|
* Limpia el turno en vuelo. Con `id`, SOLO si coincide: dos turnos encadenados
|
|
@@ -54,16 +91,23 @@ export function clearInFlightTurn(id) {
|
|
|
54
91
|
return;
|
|
55
92
|
current = null;
|
|
56
93
|
}
|
|
57
|
-
/**
|
|
94
|
+
/**
|
|
95
|
+
* El turno en vuelo, o null si no hay o si se quedo CALLADO.
|
|
96
|
+
*
|
|
97
|
+
* La edad del turno no entra en la decision: un turno de tres horas que sigue
|
|
98
|
+
* latiendo es un turno vivo y se anuncia. Lo que lo saca es el silencio.
|
|
99
|
+
*/
|
|
58
100
|
export function inFlightTurn(now = Date.now()) {
|
|
59
101
|
if (!current)
|
|
60
102
|
return null;
|
|
61
|
-
|
|
62
|
-
|
|
103
|
+
/* Un reloj que salta hacia atras da silencio negativo: no vence. Preferible
|
|
104
|
+
* anunciar un turno de mas que descartar uno vivo por un salto de NTP. */
|
|
105
|
+
if (now - current.visto > SILENCIO_MAX_MS) {
|
|
63
106
|
current = null;
|
|
64
107
|
return null;
|
|
65
108
|
}
|
|
66
|
-
|
|
109
|
+
const { id, user, started_at } = current;
|
|
110
|
+
return { id, user, started_at };
|
|
67
111
|
}
|
|
68
112
|
/** Solo para tests. */
|
|
69
113
|
export function _resetInFlightTurn() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in_flight_turn.js","sourceRoot":"","sources":["../../src/relay/in_flight_turn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AASH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"in_flight_turn.js","sourceRoot":"","sources":["../../src/relay/in_flight_turn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AASH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,GAAG,IAAI,CAAC;AAE9C;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,oBAAoB,GAAG,EAAE,CAAC;AAOzD,IAAI,OAAO,GAAoB,IAAI,CAAC;AAEpC,MAAM,UAAU,eAAe,CAAC,CAAe,EAAE,MAAc,IAAI,CAAC,GAAG,EAAE;IACvE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,OAAO;IACxB,OAAO,GAAG;QACR,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;QAC1B,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/D,KAAK,EAAE,GAAG;KACX,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc,IAAI,CAAC,GAAG,EAAE;IACxD,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,OAAO,CAAC,KAAK,GAAG,GAAG,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAW;IAC3C,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,IAAI,EAAE,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE;QAAE,OAAO;IACpC,OAAO,GAAG,IAAI,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,IAAI,CAAC,GAAG,EAAE;IACnD,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B;8EAC0E;IAC1E,IAAI,GAAG,GAAG,OAAO,CAAC,KAAK,GAAG,eAAe,EAAE,CAAC;QAC1C,OAAO,GAAG,IAAI,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IACzC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAClC,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,kBAAkB;IAChC,OAAO,GAAG,IAAI,CAAC;AACjB,CAAC"}
|
package/dist/version.d.ts
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* Yujin Forge CLI version. Kept in sync with package.json by the npm
|
|
3
3
|
* "version" lifecycle (scripts/sync_version.mjs) so the two never drift.
|
|
4
4
|
*/
|
|
5
|
-
export declare const VERSION = "1.16.
|
|
5
|
+
export declare const VERSION = "1.16.1";
|
|
6
6
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nac3/forge-cli",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.1",
|
|
4
4
|
"description": "Yujin Forge -- voice-first NAC-3 React development framework. CLI + chat panel + spec ingest + 10-format document reader + voice loop.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Pablo Kuschnirof <pablo@rpaforce.com>",
|