@nac3/forge-cli 1.23.3 → 1.23.4
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/bin/yf.js +0 -0
- package/dist/chat/server.d.ts.map +1 -1
- package/dist/chat/server.js +72 -19
- package/dist/chat/server.js.map +1 -1
- package/dist/relay/in_flight_turn.d.ts +52 -11
- package/dist/relay/in_flight_turn.d.ts.map +1 -1
- package/dist/relay/in_flight_turn.js +98 -30
- 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 +20 -18
|
@@ -24,6 +24,32 @@
|
|
|
24
24
|
* refresco a mano -- cae sobre un latido reciente y reconstruye que esta
|
|
25
25
|
* corriendo, incluso si el telefono no estaba conectado cuando arranco.
|
|
26
26
|
*
|
|
27
|
+
* POR QUE ES UN REGISTRO Y NO UNA VARIABLE (PND-237, 30-oct-2026).
|
|
28
|
+
*
|
|
29
|
+
* Esto era UN solo slot (`let current`), y un panel corre turnos SOLAPADOS: el
|
|
30
|
+
* dueno manda un pedido mientras el anterior sigue, o entra uno por el puente.
|
|
31
|
+
* Con un solo slot el segundo pisaba al primero, y `clearInFlightTurn(id)` --
|
|
32
|
+
* que NO limpia si el id no coincide, y eso esta bien, porque un cierre tardio
|
|
33
|
+
* no tiene que borrar el anuncio del que recien arranco -- dejaba al pisado
|
|
34
|
+
* SIN NINGUN camino de salida. Peor: `touchInFlightTurn()` refrescaba lo que
|
|
35
|
+
* hubiera en el slot sin mirar el id, asi que el latido de cualquier turno
|
|
36
|
+
* POSTERIOR mantenia vivo al huerfano y el tope de silencio no vencia nunca.
|
|
37
|
+
*
|
|
38
|
+
* Medido en produccion (D1, 30-oct-2026 13:25 UTC): el panel de adip-kikan
|
|
39
|
+
* venia anunciando `dt-mvuyvonj` -- arrancado 12:47:13 -- durante 152 latidos
|
|
40
|
+
* y 38 minutos, mientras el MISMO panel ya habia publicado los remote_turn
|
|
41
|
+
* completos de dos turnos que arrancaron a su lado (12:46:39 y 12:47:40: los
|
|
42
|
+
* tres se solapan en 61 segundos). El telefono mostraba la burbuja "trabajando"
|
|
43
|
+
* con el texto viejo, y como su guarda es por id, el turno REAL no recibia
|
|
44
|
+
* burbuja: el dueno veia una sesion trabajando sin su pedido a la vista.
|
|
45
|
+
*
|
|
46
|
+
* Las dos reglas que lo cierran, y que son el contrato de este modulo:
|
|
47
|
+
* - un turno es una ENTRADA propia, identificada por su id. Nadie pisa a
|
|
48
|
+
* nadie, y cada uno sale por su propio cierre o por su propio silencio.
|
|
49
|
+
* - la SENAL DE VIDA esta ligada al id que la produce (touchInFlightTurn(id)).
|
|
50
|
+
* Un latido solo puede hablar por SU turno. Eso es lo que le devuelve el
|
|
51
|
+
* poder al tope de silencio: un huerfano deja de ser tocado y vence.
|
|
52
|
+
*
|
|
27
53
|
* ASCII puro.
|
|
28
54
|
*/
|
|
29
55
|
export interface InFlightTurn {
|
|
@@ -60,30 +86,45 @@ export declare const PULSO_DE_PROGRESO_MS: number;
|
|
|
60
86
|
*
|
|
61
87
|
* Diez pulsos de margen: tolera que se pierdan nueve latidos seguidos antes de
|
|
62
88
|
* dar por muerto un turno que esta vivo.
|
|
89
|
+
*
|
|
90
|
+
* PND-237: esta garantia solo existe de verdad desde que la senal de vida va
|
|
91
|
+
* por id. Mientras `touch()` refrescaba el slot entero, el latido de un turno
|
|
92
|
+
* nuevo reseteaba el reloj del huerfano y este tope era letra muerta.
|
|
63
93
|
*/
|
|
64
94
|
export declare const SILENCIO_MAX_MS: number;
|
|
65
95
|
export declare function setInFlightTurn(t: InFlightTurn, now?: number): void;
|
|
66
96
|
/**
|
|
67
|
-
* Senal de vida
|
|
68
|
-
*
|
|
97
|
+
* Senal de vida de UN turno. La llama el latido de actividad de ese turno,
|
|
98
|
+
* que corre solo mientras el turno vive.
|
|
69
99
|
*
|
|
70
|
-
* No crea nada: si no
|
|
71
|
-
* rezagado no puede resucitar un turno ya cerrado
|
|
100
|
+
* No crea nada: si ese id no esta registrado, no hace nada. Asi un latido
|
|
101
|
+
* rezagado no puede resucitar un turno ya cerrado -- y, desde PND-237, no
|
|
102
|
+
* puede tampoco mantener vivo el anuncio de OTRO turno, que era el agujero
|
|
103
|
+
* por el que un huerfano se anunciaba para siempre.
|
|
72
104
|
*/
|
|
73
|
-
export declare function touchInFlightTurn(now?: number): void;
|
|
105
|
+
export declare function touchInFlightTurn(id: string, now?: number): void;
|
|
74
106
|
/**
|
|
75
|
-
* Limpia el turno en vuelo. Con `id`, SOLO
|
|
76
|
-
*
|
|
77
|
-
*
|
|
107
|
+
* Limpia el turno en vuelo. Con `id`, SOLO ese: dos turnos encadenados pueden
|
|
108
|
+
* cerrar fuera de orden, y un cierre tardio del viejo no tiene que borrar el
|
|
109
|
+
* anuncio del que recien arranco. Sin `id`, TODOS (apagado del servidor).
|
|
78
110
|
*/
|
|
79
111
|
export declare function clearInFlightTurn(id?: string): void;
|
|
80
112
|
/**
|
|
81
|
-
* El turno
|
|
113
|
+
* El turno que se ANUNCIA, o null si no hay ninguno vivo.
|
|
114
|
+
*
|
|
115
|
+
* El latido de presencia lleva UN turno (contrato del relay), asi que entre
|
|
116
|
+
* varios solapados hay que elegir, y se elige el que arranco ULTIMO: es el
|
|
117
|
+
* pedido que el dueno acaba de hacer y que esta esperando ver. Era justo el
|
|
118
|
+
* que se perdia -- con el slot unico, el que quedaba anunciado podia ser
|
|
119
|
+
* cualquiera, y si era un huerfano la guarda por id del telefono dejaba al
|
|
120
|
+
* pedido nuevo sin burbuja (PND-237, sintoma 6).
|
|
82
121
|
*
|
|
83
|
-
* La edad del turno no entra en la decision: un turno de tres horas
|
|
84
|
-
* latiendo es un turno vivo
|
|
122
|
+
* La edad del turno no entra en la decision de VIDA: un turno de tres horas
|
|
123
|
+
* que sigue latiendo es un turno vivo. Lo que lo saca es el silencio.
|
|
85
124
|
*/
|
|
86
125
|
export declare function inFlightTurn(now?: number): InFlightTurn | null;
|
|
126
|
+
/** Cuantos turnos vivos declara este panel (diagnostico / tests). */
|
|
127
|
+
export declare function inFlightCount(now?: number): number;
|
|
87
128
|
/** Solo para tests. */
|
|
88
129
|
export declare function _resetInFlightTurn(): void;
|
|
89
130
|
//# sourceMappingURL=in_flight_turn.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in_flight_turn.d.ts","sourceRoot":"","sources":["../../src/relay/in_flight_turn.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"in_flight_turn.d.ts","sourceRoot":"","sources":["../../src/relay/in_flight_turn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;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;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,eAAe,QAA4B,CAAC;AAUzD,wBAAgB,eAAe,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,GAAE,MAAmB,GAAG,IAAI,CAS/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,IAAI,CAK5E;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAGnD;AAWD;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAmB,GAAG,YAAY,GAAG,IAAI,CAiB1E;AAED,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,GAAG,GAAE,MAAmB,GAAG,MAAM,CAG9D;AAED,uBAAuB;AACvB,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
|
|
@@ -24,6 +24,32 @@
|
|
|
24
24
|
* refresco a mano -- cae sobre un latido reciente y reconstruye que esta
|
|
25
25
|
* corriendo, incluso si el telefono no estaba conectado cuando arranco.
|
|
26
26
|
*
|
|
27
|
+
* POR QUE ES UN REGISTRO Y NO UNA VARIABLE (PND-237, 30-oct-2026).
|
|
28
|
+
*
|
|
29
|
+
* Esto era UN solo slot (`let current`), y un panel corre turnos SOLAPADOS: el
|
|
30
|
+
* dueno manda un pedido mientras el anterior sigue, o entra uno por el puente.
|
|
31
|
+
* Con un solo slot el segundo pisaba al primero, y `clearInFlightTurn(id)` --
|
|
32
|
+
* que NO limpia si el id no coincide, y eso esta bien, porque un cierre tardio
|
|
33
|
+
* no tiene que borrar el anuncio del que recien arranco -- dejaba al pisado
|
|
34
|
+
* SIN NINGUN camino de salida. Peor: `touchInFlightTurn()` refrescaba lo que
|
|
35
|
+
* hubiera en el slot sin mirar el id, asi que el latido de cualquier turno
|
|
36
|
+
* POSTERIOR mantenia vivo al huerfano y el tope de silencio no vencia nunca.
|
|
37
|
+
*
|
|
38
|
+
* Medido en produccion (D1, 30-oct-2026 13:25 UTC): el panel de adip-kikan
|
|
39
|
+
* venia anunciando `dt-mvuyvonj` -- arrancado 12:47:13 -- durante 152 latidos
|
|
40
|
+
* y 38 minutos, mientras el MISMO panel ya habia publicado los remote_turn
|
|
41
|
+
* completos de dos turnos que arrancaron a su lado (12:46:39 y 12:47:40: los
|
|
42
|
+
* tres se solapan en 61 segundos). El telefono mostraba la burbuja "trabajando"
|
|
43
|
+
* con el texto viejo, y como su guarda es por id, el turno REAL no recibia
|
|
44
|
+
* burbuja: el dueno veia una sesion trabajando sin su pedido a la vista.
|
|
45
|
+
*
|
|
46
|
+
* Las dos reglas que lo cierran, y que son el contrato de este modulo:
|
|
47
|
+
* - un turno es una ENTRADA propia, identificada por su id. Nadie pisa a
|
|
48
|
+
* nadie, y cada uno sale por su propio cierre o por su propio silencio.
|
|
49
|
+
* - la SENAL DE VIDA esta ligada al id que la produce (touchInFlightTurn(id)).
|
|
50
|
+
* Un latido solo puede hablar por SU turno. Eso es lo que le devuelve el
|
|
51
|
+
* poder al tope de silencio: un huerfano deja de ser tocado y vence.
|
|
52
|
+
*
|
|
27
53
|
* ASCII puro.
|
|
28
54
|
*/
|
|
29
55
|
/**
|
|
@@ -54,63 +80,105 @@ export const PULSO_DE_PROGRESO_MS = 60 * 1000;
|
|
|
54
80
|
*
|
|
55
81
|
* Diez pulsos de margen: tolera que se pierdan nueve latidos seguidos antes de
|
|
56
82
|
* dar por muerto un turno que esta vivo.
|
|
83
|
+
*
|
|
84
|
+
* PND-237: esta garantia solo existe de verdad desde que la senal de vida va
|
|
85
|
+
* por id. Mientras `touch()` refrescaba el slot entero, el latido de un turno
|
|
86
|
+
* nuevo reseteaba el reloj del huerfano y este tope era letra muerta.
|
|
57
87
|
*/
|
|
58
88
|
export const SILENCIO_MAX_MS = PULSO_DE_PROGRESO_MS * 10;
|
|
59
|
-
|
|
89
|
+
/** Los turnos vivos de ESTE panel, por id. Varios a la vez es lo normal. */
|
|
90
|
+
const vivos = new Map();
|
|
60
91
|
export function setInFlightTurn(t, now = Date.now()) {
|
|
61
92
|
if (!t || !t.id)
|
|
62
93
|
return;
|
|
63
|
-
|
|
64
|
-
|
|
94
|
+
const id = String(t.id);
|
|
95
|
+
vivos.set(id, {
|
|
96
|
+
id,
|
|
65
97
|
user: String(t.user || ''),
|
|
66
98
|
started_at: String(t.started_at || new Date(now).toISOString()),
|
|
67
99
|
visto: now,
|
|
68
|
-
};
|
|
100
|
+
});
|
|
69
101
|
}
|
|
70
102
|
/**
|
|
71
|
-
* Senal de vida
|
|
72
|
-
*
|
|
103
|
+
* Senal de vida de UN turno. La llama el latido de actividad de ese turno,
|
|
104
|
+
* que corre solo mientras el turno vive.
|
|
73
105
|
*
|
|
74
|
-
* No crea nada: si no
|
|
75
|
-
* rezagado no puede resucitar un turno ya cerrado
|
|
106
|
+
* No crea nada: si ese id no esta registrado, no hace nada. Asi un latido
|
|
107
|
+
* rezagado no puede resucitar un turno ya cerrado -- y, desde PND-237, no
|
|
108
|
+
* puede tampoco mantener vivo el anuncio de OTRO turno, que era el agujero
|
|
109
|
+
* por el que un huerfano se anunciaba para siempre.
|
|
76
110
|
*/
|
|
77
|
-
export function touchInFlightTurn(now = Date.now()) {
|
|
78
|
-
if (!
|
|
111
|
+
export function touchInFlightTurn(id, now = Date.now()) {
|
|
112
|
+
if (!id)
|
|
113
|
+
return;
|
|
114
|
+
const r = vivos.get(String(id));
|
|
115
|
+
if (!r)
|
|
79
116
|
return;
|
|
80
|
-
|
|
117
|
+
r.visto = now;
|
|
81
118
|
}
|
|
82
119
|
/**
|
|
83
|
-
* Limpia el turno en vuelo. Con `id`, SOLO
|
|
84
|
-
*
|
|
85
|
-
*
|
|
120
|
+
* Limpia el turno en vuelo. Con `id`, SOLO ese: dos turnos encadenados pueden
|
|
121
|
+
* cerrar fuera de orden, y un cierre tardio del viejo no tiene que borrar el
|
|
122
|
+
* anuncio del que recien arranco. Sin `id`, TODOS (apagado del servidor).
|
|
86
123
|
*/
|
|
87
124
|
export function clearInFlightTurn(id) {
|
|
88
|
-
if (!
|
|
125
|
+
if (!id) {
|
|
126
|
+
vivos.clear();
|
|
89
127
|
return;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
128
|
+
}
|
|
129
|
+
vivos.delete(String(id));
|
|
130
|
+
}
|
|
131
|
+
/** Poda las entradas que se quedaron CALLADAS. */
|
|
132
|
+
function podar(now) {
|
|
133
|
+
for (const [id, r] of vivos) {
|
|
134
|
+
/* Un reloj que salta hacia atras da silencio negativo: no vence. Preferible
|
|
135
|
+
* anunciar un turno de mas que descartar uno vivo por un salto de NTP. */
|
|
136
|
+
if (now - r.visto > SILENCIO_MAX_MS)
|
|
137
|
+
vivos.delete(id);
|
|
138
|
+
}
|
|
93
139
|
}
|
|
94
140
|
/**
|
|
95
|
-
* El turno
|
|
141
|
+
* El turno que se ANUNCIA, o null si no hay ninguno vivo.
|
|
96
142
|
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
143
|
+
* El latido de presencia lleva UN turno (contrato del relay), asi que entre
|
|
144
|
+
* varios solapados hay que elegir, y se elige el que arranco ULTIMO: es el
|
|
145
|
+
* pedido que el dueno acaba de hacer y que esta esperando ver. Era justo el
|
|
146
|
+
* que se perdia -- con el slot unico, el que quedaba anunciado podia ser
|
|
147
|
+
* cualquiera, y si era un huerfano la guarda por id del telefono dejaba al
|
|
148
|
+
* pedido nuevo sin burbuja (PND-237, sintoma 6).
|
|
149
|
+
*
|
|
150
|
+
* La edad del turno no entra en la decision de VIDA: un turno de tres horas
|
|
151
|
+
* que sigue latiendo es un turno vivo. Lo que lo saca es el silencio.
|
|
99
152
|
*/
|
|
100
153
|
export function inFlightTurn(now = Date.now()) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
154
|
+
podar(now);
|
|
155
|
+
let elegido = null;
|
|
156
|
+
let mejor = -Infinity;
|
|
157
|
+
for (const r of vivos.values()) {
|
|
158
|
+
/* Un started_at ilegible NO puede ganar la eleccion. Date.parse devuelve
|
|
159
|
+
* NaN y toda comparacion con NaN es false, asi que comparando en crudo el
|
|
160
|
+
* primero de la iteracion se quedaba con el anuncio para siempre -- el
|
|
161
|
+
* mismo sintoma que estamos arreglando, por otra puerta. Vale -Infinity:
|
|
162
|
+
* se anuncia solo si es el unico que hay. */
|
|
163
|
+
const t = Date.parse(r.started_at);
|
|
164
|
+
const orden = Number.isFinite(t) ? t : -Infinity;
|
|
165
|
+
if (!elegido || orden > mejor) {
|
|
166
|
+
elegido = r;
|
|
167
|
+
mejor = orden;
|
|
168
|
+
}
|
|
108
169
|
}
|
|
109
|
-
|
|
170
|
+
if (!elegido)
|
|
171
|
+
return null;
|
|
172
|
+
const { id, user, started_at } = elegido;
|
|
110
173
|
return { id, user, started_at };
|
|
111
174
|
}
|
|
175
|
+
/** Cuantos turnos vivos declara este panel (diagnostico / tests). */
|
|
176
|
+
export function inFlightCount(now = Date.now()) {
|
|
177
|
+
podar(now);
|
|
178
|
+
return vivos.size;
|
|
179
|
+
}
|
|
112
180
|
/** Solo para tests. */
|
|
113
181
|
export function _resetInFlightTurn() {
|
|
114
|
-
|
|
182
|
+
vivos.clear();
|
|
115
183
|
}
|
|
116
184
|
//# sourceMappingURL=in_flight_turn.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in_flight_turn.js","sourceRoot":"","sources":["../../src/relay/in_flight_turn.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"in_flight_turn.js","sourceRoot":"","sources":["../../src/relay/in_flight_turn.ts"],"names":[],"mappings":"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"}
|
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.23.
|
|
5
|
+
export declare const VERSION = "1.23.4";
|
|
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.23.
|
|
3
|
+
"version": "1.23.4",
|
|
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>",
|
|
@@ -15,6 +15,23 @@
|
|
|
15
15
|
"exports": {
|
|
16
16
|
".": "./dist/index.js"
|
|
17
17
|
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"version": "node scripts/sync_version.mjs && git add src/version.ts",
|
|
20
|
+
"build": "node scripts/clean_dist.mjs && tsc && node scripts/copy_qa_assets.mjs",
|
|
21
|
+
"dev": "tsx watch src/bin/yf.ts",
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"typecheck:all": "pnpm typecheck && pnpm --filter @yujin/hito4-server typecheck && pnpm --filter @yujin/forge-mobile typecheck",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest",
|
|
26
|
+
"lint": "tsc --noEmit",
|
|
27
|
+
"yf": "tsx src/bin/yf.ts",
|
|
28
|
+
"catalog:lint": "node scripts/catalog_lint.mjs",
|
|
29
|
+
"pairing:check": "node scripts/check_pairing_sync.mjs",
|
|
30
|
+
"brain-matrix:gate": "node scripts/brain_matrix_gate.mjs",
|
|
31
|
+
"hito4:lint": "node scripts/hito4_lint_bundle.mjs",
|
|
32
|
+
"publish-alpha-emergency": "node scripts/publish_alpha_emergency.mjs",
|
|
33
|
+
"prepublishOnly": "pnpm run build && pnpm run typecheck && pnpm run catalog:lint && pnpm run test && pnpm run brain-matrix:gate && pnpm run hito4:lint"
|
|
34
|
+
},
|
|
18
35
|
"dependencies": {
|
|
19
36
|
"@anthropic-ai/sdk": "^0.32.1",
|
|
20
37
|
"@aws-sdk/client-ecs": "^3.1053.0",
|
|
@@ -51,6 +68,7 @@
|
|
|
51
68
|
"node": ">=18.17",
|
|
52
69
|
"pnpm": ">=9"
|
|
53
70
|
},
|
|
71
|
+
"packageManager": "pnpm@11.3.0",
|
|
54
72
|
"files": [
|
|
55
73
|
"dist",
|
|
56
74
|
"templates",
|
|
@@ -95,21 +113,5 @@
|
|
|
95
113
|
"publishConfig": {
|
|
96
114
|
"access": "public",
|
|
97
115
|
"tag": "latest"
|
|
98
|
-
},
|
|
99
|
-
"scripts": {
|
|
100
|
-
"version": "node scripts/sync_version.mjs && git add src/version.ts",
|
|
101
|
-
"build": "node scripts/clean_dist.mjs && tsc && node scripts/copy_qa_assets.mjs",
|
|
102
|
-
"dev": "tsx watch src/bin/yf.ts",
|
|
103
|
-
"typecheck": "tsc --noEmit",
|
|
104
|
-
"typecheck:all": "pnpm typecheck && pnpm --filter @yujin/hito4-server typecheck && pnpm --filter @yujin/forge-mobile typecheck",
|
|
105
|
-
"test": "vitest run",
|
|
106
|
-
"test:watch": "vitest",
|
|
107
|
-
"lint": "tsc --noEmit",
|
|
108
|
-
"yf": "tsx src/bin/yf.ts",
|
|
109
|
-
"catalog:lint": "node scripts/catalog_lint.mjs",
|
|
110
|
-
"pairing:check": "node scripts/check_pairing_sync.mjs",
|
|
111
|
-
"brain-matrix:gate": "node scripts/brain_matrix_gate.mjs",
|
|
112
|
-
"hito4:lint": "node scripts/hito4_lint_bundle.mjs",
|
|
113
|
-
"publish-alpha-emergency": "node scripts/publish_alpha_emergency.mjs"
|
|
114
116
|
}
|
|
115
|
-
}
|
|
117
|
+
}
|