tycono 0.3.14-beta.11 → 0.3.14-beta.12
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/tui/components/PanelMode.tsx +66 -67
package/package.json
CHANGED
|
@@ -383,80 +383,79 @@ const PanelModeInner: React.FC<PanelModeProps> = ({
|
|
|
383
383
|
|
|
384
384
|
const leftWidth = 28;
|
|
385
385
|
const termCols = process.stdout.columns || 120;
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
//
|
|
389
|
-
//
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
lines.push(`${(waveSessionCount + ' sessions').padEnd(leftWidth)} \u2502`);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// OrgTree (left) + Stream (right) side by side
|
|
408
|
-
const ceoIcon = waveScopedStatuses['ceo'] === 'working' ? '\u25CF' : waveScopedStatuses['ceo'] === 'done' ? '\u2713' : '\u25CB';
|
|
409
|
-
const treeLines = [`\u2500\u2500 Org Tree \u2500\u2500`, `${ceoIcon} CEO`];
|
|
410
|
-
const flatEntries = flattenTreeForText(waveScopedTree);
|
|
411
|
-
treeLines.push(...flatEntries);
|
|
412
|
-
|
|
413
|
-
// Stream lines (right side)
|
|
414
|
-
const streamLines: string[] = [];
|
|
415
|
-
if (rightTab === 'stream') {
|
|
416
|
-
const maxEv = Math.min(termHeight - 8, 20);
|
|
417
|
-
const visible = (selectedRoleId ? events.filter(e => e.roleId === selectedRoleId) : events).slice(-maxEv);
|
|
418
|
-
for (const ev of visible) {
|
|
419
|
-
const line = eventToOneLiner(ev);
|
|
420
|
-
if (line) streamLines.push(line.slice(0, rightWidth));
|
|
421
|
-
}
|
|
422
|
-
if (streamLines.length === 0) {
|
|
423
|
-
streamLines.push(waveId ? 'Waiting for events...' : 'No active stream.');
|
|
424
|
-
}
|
|
425
|
-
} else if (rightTab === 'info') {
|
|
426
|
-
streamLines.push(`Wave: ${focusedWave?.waveId ?? 'none'}`);
|
|
427
|
-
streamLines.push(`Directive: ${focusedWave?.directive || '(idle)'}`);
|
|
428
|
-
streamLines.push(`Sessions: ${waveSessionCount}`);
|
|
429
|
-
streamLines.push(`SSE events: ${events.length}`);
|
|
430
|
-
} else {
|
|
431
|
-
streamLines.push('(Docs tab — press h/l to switch)');
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
// Merge left + right
|
|
435
|
-
const maxLines = Math.max(treeLines.length, streamLines.length);
|
|
436
|
-
for (let i = 0; i < maxLines; i++) {
|
|
437
|
-
const left = (treeLines[i] ?? '').padEnd(leftWidth);
|
|
438
|
-
const right = streamLines[i] ?? '';
|
|
439
|
-
lines.push(`${left} \u2502 ${right}`);
|
|
386
|
+
const rightWidth = Math.max(40, termCols - leftWidth - 3);
|
|
387
|
+
|
|
388
|
+
// === Build panel as line arrays, render each line as <Text> ===
|
|
389
|
+
// yoga-layout OOMs with nested Box on 245+ columns.
|
|
390
|
+
// Solution: flat list of <Text> elements (1 yoga node per line, no nesting)
|
|
391
|
+
|
|
392
|
+
// Left: OrgTree
|
|
393
|
+
const ceoIcon = waveScopedStatuses['ceo'] === 'working' ? '\u25CF' : waveScopedStatuses['ceo'] === 'done' ? '\u2713' : '\u25CB';
|
|
394
|
+
const treeLines = [`${ceoIcon} CEO`, ...flattenTreeForText(waveScopedTree)];
|
|
395
|
+
|
|
396
|
+
// Right: Stream/Info content
|
|
397
|
+
const rightLines: string[] = [];
|
|
398
|
+
if (rightTab === 'stream') {
|
|
399
|
+
const maxEv = Math.min(termHeight - 8, 20);
|
|
400
|
+
const visible = (selectedRoleId ? events.filter(e => e.roleId === selectedRoleId) : events).slice(-maxEv);
|
|
401
|
+
for (const ev of visible) {
|
|
402
|
+
const line = eventToOneLiner(ev);
|
|
403
|
+
if (line) rightLines.push(line.slice(0, rightWidth));
|
|
440
404
|
}
|
|
405
|
+
if (rightLines.length === 0) rightLines.push(waveId ? 'Waiting for events...' : 'No active stream.');
|
|
406
|
+
} else if (rightTab === 'info') {
|
|
407
|
+
rightLines.push(`Wave: ${focusedWave?.waveId ?? 'none'}`);
|
|
408
|
+
if (wavePreset) rightLines.push(`Preset: ${wavePreset}`);
|
|
409
|
+
rightLines.push(`Directive: ${focusedWave?.directive?.slice(0, 60) || '(idle)'}`);
|
|
410
|
+
rightLines.push(`Sessions: ${waveSessionCount} Events: ${events.length}`);
|
|
411
|
+
} else {
|
|
412
|
+
rightLines.push('Docs tab (h/l to switch)');
|
|
413
|
+
}
|
|
441
414
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
}
|
|
415
|
+
// Merge into display lines
|
|
416
|
+
const maxRows = Math.max(treeLines.length, rightLines.length);
|
|
417
|
+
const mergedLines: Array<{ left: string; right: string }> = [];
|
|
418
|
+
for (let i = 0; i < maxRows; i++) {
|
|
419
|
+
mergedLines.push({
|
|
420
|
+
left: (treeLines[i] ?? '').padEnd(leftWidth).slice(0, leftWidth),
|
|
421
|
+
right: (rightLines[i] ?? ''),
|
|
422
|
+
});
|
|
423
|
+
}
|
|
450
424
|
|
|
451
|
-
|
|
452
|
-
|
|
425
|
+
// Tab bar
|
|
426
|
+
const tabLabels = ['Stream', 'Docs', 'Info'];
|
|
427
|
+
const tabBar = tabLabels.map(t => t.toLowerCase() === rightTab ? `[${t}]` : ` ${t} `).join(' ');
|
|
453
428
|
|
|
454
|
-
//
|
|
455
|
-
const
|
|
429
|
+
// Wave tabs
|
|
430
|
+
const waveTabs = waves.length > 1
|
|
431
|
+
? waves.map((w, i) => w.waveId === focusedWaveId ? `[${i + 1}]` : ` ${i + 1} `).join(' ')
|
|
432
|
+
: '';
|
|
456
433
|
|
|
457
434
|
return (
|
|
458
435
|
<Box flexDirection="column">
|
|
459
|
-
|
|
436
|
+
{/* Header */}
|
|
437
|
+
<Text>
|
|
438
|
+
<Text color="green" bold>W{focusedWaveIndex}</Text>
|
|
439
|
+
<Text color="white"> {focusedWave?.directive?.slice(0, leftWidth - 6) || '(idle)'}</Text>
|
|
440
|
+
<Text color="gray"> \u2502 </Text>
|
|
441
|
+
<Text color="cyan" bold>{tabBar}</Text>
|
|
442
|
+
</Text>
|
|
443
|
+
{waveSessionCount > 0 && <Text color="gray">{waveSessionCount} sessions</Text>}
|
|
444
|
+
<Text color="gray">\u2500\u2500 Org Tree \u2500\u2500</Text>
|
|
445
|
+
|
|
446
|
+
{/* Merged left|right lines — each line = 1 Text = 1 yoga node */}
|
|
447
|
+
{mergedLines.map((line, i) => (
|
|
448
|
+
<Text key={i}>
|
|
449
|
+
<Text color="white">{line.left}</Text>
|
|
450
|
+
<Text color="gray"> \u2502 </Text>
|
|
451
|
+
<Text color="white">{line.right}</Text>
|
|
452
|
+
</Text>
|
|
453
|
+
))}
|
|
454
|
+
|
|
455
|
+
{/* Wave tabs */}
|
|
456
|
+
{waveTabs && <Text color="gray">{waveTabs}</Text>}
|
|
457
|
+
|
|
458
|
+
{/* Footer */}
|
|
460
459
|
<Text color="gray" dimColor>
|
|
461
460
|
[h/l] tab [j/k] role {waves.length > 1 ? '[1-9] wave ' : ''}[Esc] command
|
|
462
461
|
</Text>
|