@liriraid/agentflow-ai 1.0.22 → 1.0.23
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/package.json +1 -1
- package/src/ink/index.mjs +23 -25
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liriraid/agentflow-ai",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.23",
|
|
4
4
|
"description": "Multi-agent workspace orchestrator with TUI. Coordinates AI coding agents over your real frontend and backend projects.",
|
|
5
5
|
"author": "LiriRaid",
|
|
6
6
|
"homepage": "https://github.com/LiriRaid/agentflow-ai#readme",
|
package/src/ink/index.mjs
CHANGED
|
@@ -100,6 +100,7 @@ let quitRequested = false;
|
|
|
100
100
|
let resizeTimer = null;
|
|
101
101
|
let isResizing = false;
|
|
102
102
|
let lastColumns = process.stdout?.columns ?? 0;
|
|
103
|
+
let isRendering = false;
|
|
103
104
|
|
|
104
105
|
function normalizeInlineMessage(message) {
|
|
105
106
|
return String(message ?? '')
|
|
@@ -324,21 +325,24 @@ function ensureEngine() {
|
|
|
324
325
|
}
|
|
325
326
|
|
|
326
327
|
function refresh() {
|
|
327
|
-
if (isResizing) return;
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
328
|
+
if (isResizing || isRendering) return;
|
|
329
|
+
isRendering = true;
|
|
330
|
+
try {
|
|
331
|
+
const snapshot = buildSnapshot();
|
|
332
|
+
lastRenderedSnapshot = snapshot;
|
|
333
|
+
ensureStateWatcher();
|
|
334
|
+
if (!inkApp) {
|
|
335
|
+
inkApp = render(React.createElement(App, {snapshot, onAction: requestAction}), {
|
|
336
|
+
exitOnCtrlC: false,
|
|
337
|
+
patchConsole: false,
|
|
338
|
+
alternateScreen: true
|
|
339
|
+
});
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
inkApp.rerender(React.createElement(App, {snapshot, onAction: requestAction}));
|
|
343
|
+
} finally {
|
|
344
|
+
isRendering = false;
|
|
339
345
|
}
|
|
340
|
-
|
|
341
|
-
inkApp.rerender(React.createElement(App, {snapshot, onAction: requestAction}));
|
|
342
346
|
}
|
|
343
347
|
|
|
344
348
|
function clearTerminal() {
|
|
@@ -415,31 +419,25 @@ function ensureStateWatcher() {
|
|
|
415
419
|
} catch { stateWatcher = null; }
|
|
416
420
|
}
|
|
417
421
|
|
|
418
|
-
// Tick
|
|
419
|
-
//
|
|
422
|
+
// Tick del reloj: solo actualiza lastRenderedSnapshot en memoria.
|
|
423
|
+
// scheduleRefresh es la única fuente de rerender para evitar renders concurrentes.
|
|
420
424
|
function startClockTick() {
|
|
421
425
|
clockInterval = setInterval(() => {
|
|
422
|
-
if (!
|
|
426
|
+
if (!lastRenderedSnapshot?.startedAt) return;
|
|
423
427
|
const activeSeconds = Math.max(0, Math.round((Date.now() - lastRenderedSnapshot.startedAt) / 1000));
|
|
424
|
-
|
|
428
|
+
lastRenderedSnapshot = {
|
|
425
429
|
...lastRenderedSnapshot,
|
|
426
430
|
activeLabel: formatDuration(activeSeconds),
|
|
427
431
|
timestamp: new Date().toLocaleString(getLocale(), {hour12: false})
|
|
428
432
|
};
|
|
429
|
-
lastRenderedSnapshot = updated;
|
|
430
|
-
inkApp.rerender(React.createElement(App, {snapshot: updated, onAction: requestAction}));
|
|
431
433
|
}, 1000);
|
|
432
434
|
}
|
|
433
435
|
|
|
434
436
|
function scheduleRefresh() {
|
|
435
|
-
const engineState = readEngineState();
|
|
436
|
-
const busy = engineState && Object.values(engineState.agents || {}).some(a => a.status === 'busy');
|
|
437
|
-
const hasWork = engineState && ((engineState.queue || []).length > 0 || (engineState.inProgress || []).length > 0);
|
|
438
|
-
const ms = (busy || hasWork) ? 1000 : 4000;
|
|
439
437
|
refreshTimer = setTimeout(() => {
|
|
440
438
|
refresh();
|
|
441
439
|
scheduleRefresh();
|
|
442
|
-
},
|
|
440
|
+
}, 1000);
|
|
443
441
|
}
|
|
444
442
|
|
|
445
443
|
function mount() {
|