@nac3/forge-cli 1.8.0 → 1.8.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/bin/yf.js +0 -0
- package/dist/chat/claude.d.ts.map +1 -1
- package/dist/chat/claude.js +5 -5
- package/dist/chat/claude.js.map +1 -1
- package/dist/chat/panel.d.ts.map +1 -1
- package/dist/chat/panel.js +21 -4
- package/dist/chat/panel.js.map +1 -1
- package/dist/chat/project_slug.d.ts +13 -3
- package/dist/chat/project_slug.d.ts.map +1 -1
- package/dist/chat/project_slug.js +32 -25
- package/dist/chat/project_slug.js.map +1 -1
- package/dist/chat/server.d.ts +10 -0
- package/dist/chat/server.d.ts.map +1 -1
- package/dist/chat/server.js +87 -11
- package/dist/chat/server.js.map +1 -1
- package/dist/commands/chat.d.ts.map +1 -1
- package/dist/commands/chat.js +8 -27
- package/dist/commands/chat.js.map +1 -1
- package/dist/core/limits_config.d.ts +34 -0
- package/dist/core/limits_config.d.ts.map +1 -1
- package/dist/core/limits_config.js +49 -5
- package/dist/core/limits_config.js.map +1 -1
- package/dist/llm/deepseek_client.d.ts.map +1 -1
- package/dist/llm/deepseek_client.js +5 -5
- package/dist/llm/deepseek_client.js.map +1 -1
- package/dist/llm/gemini_client.d.ts.map +1 -1
- package/dist/llm/gemini_client.js +0 -0
- package/dist/llm/gemini_client.js.map +1 -1
- package/dist/llm/managed_client.d.ts.map +1 -1
- package/dist/llm/managed_client.js +5 -5
- package/dist/llm/managed_client.js.map +1 -1
- package/dist/llm/ollama_client.d.ts.map +1 -1
- package/dist/llm/ollama_client.js +5 -5
- package/dist/llm/ollama_client.js.map +1 -1
- package/dist/llm/openai_client.d.ts.map +1 -1
- package/dist/llm/openai_client.js +5 -5
- package/dist/llm/openai_client.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +20 -18
package/dist/chat/server.js
CHANGED
|
@@ -131,6 +131,20 @@ export async function startChatServer(opts) {
|
|
|
131
131
|
* CLI + panel converge. */
|
|
132
132
|
const { resolveProjectSlug } = await import('./project_slug.js');
|
|
133
133
|
const projectSlug = await resolveProjectSlug(opts.projectRoot);
|
|
134
|
+
/* Cerebro por instancia (Pablo, 2026-09-30). Habia una sola config para
|
|
135
|
+
* todas: cambiar el cerebro en un `yf chat` lo cambiaba en todos. Este
|
|
136
|
+
* proceso queda atado al cerebro de SU proyecto -- lee el del proyecto si
|
|
137
|
+
* existe y cae al global si no, asi que nada cambia hasta que alguien
|
|
138
|
+
* elige uno aca, y ahi el cambio se queda aca.
|
|
139
|
+
*
|
|
140
|
+
* 2026-10-03 -- esto estaba DESPUES de construir el brain client, asi que
|
|
141
|
+
* la modalidad (Plan/Console) se decidia con el scope todavia sin atar.
|
|
142
|
+
* Va antes de cualquier lectura de brain_config. */
|
|
143
|
+
try {
|
|
144
|
+
const { setBrainConfigScope } = await import('../core/brain_config.js');
|
|
145
|
+
setBrainConfigScope(projectSlug);
|
|
146
|
+
}
|
|
147
|
+
catch { /* sin scope se sigue usando el global, como antes */ }
|
|
134
148
|
/* Director sprint slice 9 -- hydrate ingest sessions from disk
|
|
135
149
|
* for this project so spec extract+plan survive restarts. */
|
|
136
150
|
try {
|
|
@@ -234,9 +248,42 @@ export async function startChatServer(opts) {
|
|
|
234
248
|
}
|
|
235
249
|
return new ClaudeClient();
|
|
236
250
|
}
|
|
251
|
+
/* De donde sale la modalidad cuando el llamador no la fija: la config del
|
|
252
|
+
* cerebro de ESTE proyecto (ya scopeada arriba) y, si no dice nada, el
|
|
253
|
+
* camino que eligio el wizard. Prioridad: --provider > brain_config >
|
|
254
|
+
* wizard_state > anthropic-api.
|
|
255
|
+
*
|
|
256
|
+
* 2026-10-03 -- esto se derivaba en `yf chat` ANTES de arrancar el server,
|
|
257
|
+
* con un scope resuelto por otro camino (resolveProjectSlugSync). Cuando
|
|
258
|
+
* los dos slugs no coincidian, el boot leia la config del proyecto
|
|
259
|
+
* equivocado: el panel mostraba la modalidad correcta (lee la config ya
|
|
260
|
+
* scopeada) y el cerebro vivo era el de arrastre. Ahora la cadena vive
|
|
261
|
+
* aca, que es donde se resuelve el slug autoritativo. */
|
|
262
|
+
async function providerFromBrainConfig() {
|
|
263
|
+
try {
|
|
264
|
+
const { readBrainConfig } = await import('../core/brain_config.js');
|
|
265
|
+
const bc = await readBrainConfig();
|
|
266
|
+
if (bc.anthropic_mode === 'plan')
|
|
267
|
+
return 'claude-code-cli';
|
|
268
|
+
if (bc.anthropic_mode === 'console')
|
|
269
|
+
return 'anthropic-api';
|
|
270
|
+
}
|
|
271
|
+
catch { /* sin config -> probamos el wizard */ }
|
|
272
|
+
try {
|
|
273
|
+
const { readWizardState } = await import('../core/wizard_state.js');
|
|
274
|
+
if ((await readWizardState()).path_chosen === 'claude_plan')
|
|
275
|
+
return 'claude-code-cli';
|
|
276
|
+
}
|
|
277
|
+
catch { /* swallow */ }
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
/* `--provider` -- y el anthropic-api forzado de una sub-sesion agentMode,
|
|
281
|
+
* que es lo que hace que el scope de verbos aplique -- pisan la config y
|
|
282
|
+
* NO se re-derivan: ni al boot ni al cambiar de proyecto. */
|
|
283
|
+
const providerPinned = !!opts.chatProvider;
|
|
237
284
|
/* MUTABLE per-session provider state, so flipping Plan/Console in the
|
|
238
285
|
* panel applies LIVE (mirrors the reanchor pattern). */
|
|
239
|
-
let activeChatProvider = opts.chatProvider ?? 'anthropic-api';
|
|
286
|
+
let activeChatProvider = opts.chatProvider ?? (await providerFromBrainConfig()) ?? 'anthropic-api';
|
|
240
287
|
let claude = opts.claude ?? await buildClaudeClient(activeChatProvider);
|
|
241
288
|
/** Hot-swap the brain provider when the user flips the mode in the
|
|
242
289
|
* panel. 'plan' -> claude-code-cli (subscription); 'console' ->
|
|
@@ -256,6 +303,25 @@ export async function startChatServer(opts) {
|
|
|
256
303
|
catch { /* */ }
|
|
257
304
|
return true;
|
|
258
305
|
}
|
|
306
|
+
/** El cerebro sigue al proyecto activo: despues de un reanchor hay que
|
|
307
|
+
* re-derivar la modalidad del proyecto NUEVO. Sin esto el provider
|
|
308
|
+
* quedaba de arrastre (el del proyecto anterior) mientras el selector del
|
|
309
|
+
* panel -- que lee la config ya re-scopeada -- mostraba la del nuevo, y
|
|
310
|
+
* solo se enderezaba al tocar Plan/Console a mano. */
|
|
311
|
+
async function applyProviderFromBrainConfig() {
|
|
312
|
+
if (providerPinned || opts.claude)
|
|
313
|
+
return false;
|
|
314
|
+
const target = (await providerFromBrainConfig()) ?? 'anthropic-api';
|
|
315
|
+
if (target === activeChatProvider)
|
|
316
|
+
return false;
|
|
317
|
+
claude = await buildClaudeClient(target);
|
|
318
|
+
activeChatProvider = target;
|
|
319
|
+
try {
|
|
320
|
+
console.error('[brain] provider del proyecto activo -> ' + target);
|
|
321
|
+
}
|
|
322
|
+
catch { /* */ }
|
|
323
|
+
return true;
|
|
324
|
+
}
|
|
259
325
|
const voice = opts.voice ?? new VoiceRouter({
|
|
260
326
|
configDir: configDir(),
|
|
261
327
|
registry: buildDefaultRegistry(),
|
|
@@ -289,16 +355,6 @@ export async function startChatServer(opts) {
|
|
|
289
355
|
* handlers (que leen de `session`) pasan a apuntar al nuevo root
|
|
290
356
|
* sin reiniciar el panel. */
|
|
291
357
|
const session = { projectRoot: opts.projectRoot, projectName, projectSlug };
|
|
292
|
-
/* Cerebro por instancia (Pablo, 2026-09-30). Habia una sola config para
|
|
293
|
-
* todas: cambiar el cerebro en un `yf chat` lo cambiaba en todos. Este
|
|
294
|
-
* proceso queda atado al cerebro de SU proyecto -- lee el del proyecto si
|
|
295
|
-
* existe y cae al global si no, asi que nada cambia hasta que alguien
|
|
296
|
-
* elige uno aca, y ahi el cambio se queda aca. */
|
|
297
|
-
try {
|
|
298
|
-
const { setBrainConfigScope } = await import('../core/brain_config.js');
|
|
299
|
-
setBrainConfigScope(projectSlug);
|
|
300
|
-
}
|
|
301
|
-
catch { /* sin scope se sigue usando el global, como antes */ }
|
|
302
358
|
/* Project registry (task #33) -- record the project we just opened in
|
|
303
359
|
* ~/.yujin-forge/projects.json + mark it active, so the project
|
|
304
360
|
* selector (panel + mobile) always lists at least the current one.
|
|
@@ -344,6 +400,15 @@ export async function startChatServer(opts) {
|
|
|
344
400
|
setBrainConfigScope(session.projectSlug);
|
|
345
401
|
}
|
|
346
402
|
catch { /* best-effort */ }
|
|
403
|
+
/* ...y con el scope nuevo, la modalidad (Plan/Console) del proyecto
|
|
404
|
+
* nuevo. Antes se quedaba la del anterior hasta tocarla a mano. */
|
|
405
|
+
try {
|
|
406
|
+
if (await applyProviderFromBrainConfig()) {
|
|
407
|
+
chatLog('Cerebro de este proyecto: '
|
|
408
|
+
+ (activeChatProvider === 'claude-code-cli' ? 'Plan (suscripcion)' : 'Console (API)') + '.');
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
catch { /* best-effort */ }
|
|
347
412
|
/* keep the registry in sync after a hot switch (task #33) */
|
|
348
413
|
try {
|
|
349
414
|
await upsertProject({ slug: session.projectSlug, path: abs });
|
|
@@ -492,6 +557,16 @@ export async function startChatServer(opts) {
|
|
|
492
557
|
};
|
|
493
558
|
tryListen(opts.port);
|
|
494
559
|
});
|
|
560
|
+
/* El puerto REAL, no el pedido (2026-10-03). El retry de EADDRINUSE ya
|
|
561
|
+
* reescribia opts.port, pero un port:0 (liga uno efimero) no pasa por ahi:
|
|
562
|
+
* opts.port se quedaba en 0 y entonces la url, el lock de instancia y el
|
|
563
|
+
* panelBridge del subproceso apuntaban a un puerto que no existe. */
|
|
564
|
+
{
|
|
565
|
+
const addr = server.address();
|
|
566
|
+
if (addr && typeof addr === 'object' && typeof addr.port === 'number' && addr.port > 0) {
|
|
567
|
+
opts.port = addr.port;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
495
570
|
/* Port-race fix (2026-09-01). The eager `claude` client above was built
|
|
496
571
|
* BEFORE the EADDRINUSE retry could finalize opts.port. The CLI client
|
|
497
572
|
* FREEZES panelBridge.port at construction, so when two instances race for
|
|
@@ -605,6 +680,7 @@ export async function startChatServer(opts) {
|
|
|
605
680
|
port: opts.port,
|
|
606
681
|
store,
|
|
607
682
|
bridge: bridgeHandle,
|
|
683
|
+
reanchor,
|
|
608
684
|
close: () => new Promise((resolve) => {
|
|
609
685
|
/* alpha.59w -- stop the component watcher on shutdown so
|
|
610
686
|
* vitest does not hang on lingering fs watchers. */
|