tycono 0.1.111 → 0.1.113
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
CHANGED
|
@@ -338,36 +338,44 @@ class SupervisorHeartbeat {
|
|
|
338
338
|
if (waveCeoSessions.length === 0) return '';
|
|
339
339
|
|
|
340
340
|
const exchanges: Array<{ role: 'ceo' | 'supervisor'; text: string }> = [];
|
|
341
|
-
for (const ses of waveCeoSessions.slice(-3)) {
|
|
341
|
+
for (const ses of waveCeoSessions.slice(-3)) {
|
|
342
342
|
if (!ActivityStream.exists(ses.id)) continue;
|
|
343
343
|
const events = ActivityStream.readAll(ses.id);
|
|
344
344
|
|
|
345
|
-
let
|
|
345
|
+
let currentText = '';
|
|
346
346
|
for (const e of events) {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
347
|
+
// New turn starts — flush accumulated text from previous turn
|
|
348
|
+
if (e.type === 'msg:start') {
|
|
349
|
+
if (currentText.trim()) {
|
|
350
|
+
exchanges.push({ role: 'supervisor', text: currentText.trim().slice(0, 100) });
|
|
351
|
+
currentText = '';
|
|
352
|
+
}
|
|
353
|
+
// Extract CEO directive
|
|
354
|
+
const task = String(e.data.task ?? '');
|
|
355
|
+
const match = task.match(/\[CEO (?:Supervisor|Question)\]\s*(.*?)(?:\n|$)/);
|
|
356
|
+
if (match) {
|
|
357
|
+
exchanges.push({ role: 'ceo', text: match[1].slice(0, 80) });
|
|
357
358
|
}
|
|
358
359
|
}
|
|
359
|
-
// Accumulate
|
|
360
|
+
// Accumulate supervisor response text
|
|
360
361
|
if (e.type === 'text' && e.roleId === 'ceo') {
|
|
361
362
|
const text = String(e.data.text ?? '').trim();
|
|
362
363
|
if (text && !text.startsWith('#') && !text.startsWith('\u26D4')) {
|
|
363
|
-
|
|
364
|
+
currentText += text + ' ';
|
|
364
365
|
}
|
|
365
366
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
367
|
+
// Turn boundary — flush
|
|
368
|
+
if (e.type === 'msg:done' || e.type === 'msg:awaiting_input' || e.type === 'msg:error') {
|
|
369
|
+
if (currentText.trim()) {
|
|
370
|
+
exchanges.push({ role: 'supervisor', text: currentText.trim().slice(0, 100) });
|
|
371
|
+
currentText = '';
|
|
372
|
+
}
|
|
369
373
|
}
|
|
370
374
|
}
|
|
375
|
+
// Flush any remaining text
|
|
376
|
+
if (currentText.trim()) {
|
|
377
|
+
exchanges.push({ role: 'supervisor', text: currentText.trim().slice(0, 100) });
|
|
378
|
+
}
|
|
371
379
|
}
|
|
372
380
|
|
|
373
381
|
if (exchanges.length === 0) return '';
|
package/src/tui/app.tsx
CHANGED
|
@@ -293,8 +293,10 @@ export const App: React.FC = () => {
|
|
|
293
293
|
directive: pw.directive || '',
|
|
294
294
|
startedAt: pw.startedAt ? new Date(pw.startedAt).getTime() : 0,
|
|
295
295
|
}));
|
|
296
|
+
// Sort by startedAt ascending (oldest first = Wave 1)
|
|
297
|
+
pastEntries.sort((a, b) => a.startedAt - b.startedAt);
|
|
296
298
|
setWaves(pastEntries);
|
|
297
|
-
// Focus
|
|
299
|
+
// Focus most recent wave (last in sorted list)
|
|
298
300
|
setFocusedWaveId(pastEntries[pastEntries.length - 1]?.waveId ?? null);
|
|
299
301
|
} else if (api.loaded) {
|
|
300
302
|
// No active waves, no past waves — fresh start
|