tycono 0.1.96-beta.27 → 0.1.96-beta.29
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/api.ts +8 -0
- package/src/tui/app.tsx +31 -7
- package/src/tui/hooks/useCommand.ts +26 -2
package/package.json
CHANGED
package/src/tui/api.ts
CHANGED
|
@@ -180,6 +180,14 @@ export async function fetchActiveSessions(): Promise<ActiveSessionsResponse> {
|
|
|
180
180
|
return fetchJson<ActiveSessionsResponse>('/api/active-sessions');
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
export async function killSession(sessionId: string): Promise<{ ok: boolean }> {
|
|
184
|
+
return fetchJson<{ ok: boolean }>(`/api/active-sessions/${sessionId}`, { method: 'DELETE' });
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export async function cleanupSessions(): Promise<{ cleaned: number; remaining: number }> {
|
|
188
|
+
return fetchJson<{ cleaned: number; remaining: number }>('/api/active-sessions/cleanup', { method: 'POST' });
|
|
189
|
+
}
|
|
190
|
+
|
|
183
191
|
/* ─── Setup API calls ─── */
|
|
184
192
|
|
|
185
193
|
export interface TeamTemplate {
|
package/src/tui/app.tsx
CHANGED
|
@@ -326,6 +326,28 @@ export const App: React.FC = () => {
|
|
|
326
326
|
addSystemLines(lines);
|
|
327
327
|
break;
|
|
328
328
|
}
|
|
329
|
+
case 'sessions': {
|
|
330
|
+
if (api.activeSessions.length === 0) {
|
|
331
|
+
addSystemMessage('No active sessions.', 'gray');
|
|
332
|
+
} else {
|
|
333
|
+
addSystemMessage(`Sessions (${api.activeSessions.length}):`, 'cyan');
|
|
334
|
+
for (const s of api.activeSessions) {
|
|
335
|
+
const alive = s.alive === false ? ' DEAD' : s.pid ? ` PID:${s.pid}` : '';
|
|
336
|
+
const wave = s.waveId ? ` wave=${String(s.waveId).replace('wave-', 'W')}` : '';
|
|
337
|
+
addSystemMessage(
|
|
338
|
+
` ${s.sessionId.slice(0, 25).padEnd(26)} ${s.roleId.padEnd(12)} API:${s.ports.api} ${s.status}${alive}${wave}`,
|
|
339
|
+
s.alive === false ? 'red' : s.status === 'active' ? 'green' : 'gray'
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
addSystemMessage(' /kill <sessionId> to stop | /cleanup to remove dead', 'gray');
|
|
343
|
+
}
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
case 'cleanup': {
|
|
347
|
+
addSystemMessage(result.message, 'yellow');
|
|
348
|
+
api.refresh();
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
329
351
|
case 'error':
|
|
330
352
|
addSystemMessage(result.message, 'red');
|
|
331
353
|
break;
|
|
@@ -337,6 +359,9 @@ export const App: React.FC = () => {
|
|
|
337
359
|
addSystemMessage(' /focus <n> Switch to wave n', 'white');
|
|
338
360
|
addSystemMessage(' /agents Agent tree + resources', 'white');
|
|
339
361
|
addSystemMessage(' /ports Port allocations', 'white');
|
|
362
|
+
addSystemMessage(' /sessions All sessions (kill/cleanup)', 'white');
|
|
363
|
+
addSystemMessage(' /kill <id> Kill a session', 'white');
|
|
364
|
+
addSystemMessage(' /cleanup Remove dead sessions', 'white');
|
|
340
365
|
addSystemMessage(' /status Show current status', 'white');
|
|
341
366
|
addSystemMessage(' /assign <role> <task> Assign task to role', 'white');
|
|
342
367
|
addSystemMessage(' /roles Org tree (Panel Mode)', 'white');
|
|
@@ -364,17 +389,16 @@ export const App: React.FC = () => {
|
|
|
364
389
|
}
|
|
365
390
|
}, [execute, addSystemMessage, addSystemLines, focusedWaveId, focusedWaveIndex, derivedWaveStatus, api.sessions.length, activeCount, waves, api.activeSessions, api.portSummary]);
|
|
366
391
|
|
|
367
|
-
// Global key handler: Tab to toggle mode, Ctrl+C
|
|
392
|
+
// Global key handler: Tab to toggle mode, Ctrl+C always exits
|
|
368
393
|
useInput((input, key) => {
|
|
369
|
-
if (mode === 'command' && key.tab) {
|
|
370
|
-
setMode('panel');
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
// Ctrl+C in command mode: exit
|
|
374
394
|
if (key.ctrl && input === 'c') {
|
|
375
395
|
exit();
|
|
396
|
+
return;
|
|
376
397
|
}
|
|
377
|
-
|
|
398
|
+
if (mode === 'command' && key.tab) {
|
|
399
|
+
setMode('panel');
|
|
400
|
+
}
|
|
401
|
+
});
|
|
378
402
|
|
|
379
403
|
// Loading state
|
|
380
404
|
if (view === 'loading') {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { useCallback } from 'react';
|
|
19
|
-
import { dispatchWave, sendDirective, fetchJson } from '../api';
|
|
19
|
+
import { dispatchWave, sendDirective, fetchJson, killSession, cleanupSessions } from '../api';
|
|
20
20
|
|
|
21
21
|
export interface WaveInfo {
|
|
22
22
|
waveId: string;
|
|
@@ -25,7 +25,7 @@ export interface WaveInfo {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export interface CommandResult {
|
|
28
|
-
type: 'success' | 'error' | 'info' | 'wave_started' | 'directive_sent' | 'stopped' | 'quit' | 'help' | 'panel' | 'waves_list' | 'focus_changed' | 'agents' | 'ports';
|
|
28
|
+
type: 'success' | 'error' | 'info' | 'wave_started' | 'directive_sent' | 'stopped' | 'quit' | 'help' | 'panel' | 'waves_list' | 'focus_changed' | 'agents' | 'ports' | 'sessions' | 'cleanup';
|
|
29
29
|
message: string;
|
|
30
30
|
waveId?: string;
|
|
31
31
|
}
|
|
@@ -99,6 +99,30 @@ export function useCommand(options: UseCommandOptions) {
|
|
|
99
99
|
case 'ports':
|
|
100
100
|
return { type: 'ports', message: '__ports__' };
|
|
101
101
|
|
|
102
|
+
case 'sessions':
|
|
103
|
+
return { type: 'sessions', message: '__sessions__' };
|
|
104
|
+
|
|
105
|
+
case 'kill': {
|
|
106
|
+
if (!args) {
|
|
107
|
+
return { type: 'error', message: 'Usage: /kill <sessionId>' };
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
await killSession(args);
|
|
111
|
+
return { type: 'success', message: `Session ${args} killed` };
|
|
112
|
+
} catch (err) {
|
|
113
|
+
return { type: 'error', message: `Kill failed: ${err instanceof Error ? err.message : 'unknown'}` };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
case 'cleanup': {
|
|
118
|
+
try {
|
|
119
|
+
const result = await cleanupSessions();
|
|
120
|
+
return { type: 'cleanup', message: `Cleaned ${result.cleaned} dead sessions. ${result.remaining} remaining.` };
|
|
121
|
+
} catch (err) {
|
|
122
|
+
return { type: 'error', message: `Cleanup failed: ${err instanceof Error ? err.message : 'unknown'}` };
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
102
126
|
case 'status':
|
|
103
127
|
return { type: 'info', message: '__status__' };
|
|
104
128
|
|