tycono 0.1.107-beta.0 → 0.1.107-beta.1

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tycono",
3
- "version": "0.1.107-beta.0",
3
+ "version": "0.1.107-beta.1",
4
4
  "description": "Build an AI company. Watch them work.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/tui/api.ts CHANGED
@@ -159,6 +159,19 @@ export async function fetchActiveWaves(): Promise<{ waves: Array<{ waveId: strin
159
159
  return fetchJson('/api/waves/active');
160
160
  }
161
161
 
162
+ export interface PastWaveInfo {
163
+ id: string;
164
+ directive: string;
165
+ rolesCount: number;
166
+ startedAt: string;
167
+ sessionIds?: string[];
168
+ }
169
+
170
+ export async function fetchPastWaves(limit = 20): Promise<PastWaveInfo[]> {
171
+ const all = await fetchJson<PastWaveInfo[]>('/api/operations/waves');
172
+ return all.slice(0, limit);
173
+ }
174
+
162
175
  /* ─── Active Sessions (port/worktree visibility) ─── */
163
176
 
164
177
  export interface ActiveSessionInfo {
package/src/tui/app.tsx CHANGED
@@ -263,17 +263,53 @@ export const App: React.FC = () => {
263
263
  if (view !== 'dashboard' || autoWaveCreated.current) return;
264
264
 
265
265
  if (api.activeWaves.length > 0) {
266
- // Attach to existing waves from API
266
+ // Attach to existing active waves from API
267
267
  const apiWaves: WaveInfo[] = api.activeWaves.map(w => ({
268
268
  waveId: w.waveId,
269
269
  directive: w.directive ?? '',
270
270
  startedAt: w.startedAt ?? Date.now(),
271
271
  }));
272
- setWaves(apiWaves);
272
+
273
+ // Also append past waves (completed) that aren't already in active list
274
+ const activeIds = new Set(apiWaves.map(w => w.waveId));
275
+ const pastEntries: WaveInfo[] = api.pastWaves
276
+ .filter(pw => !activeIds.has(pw.id))
277
+ .slice(0, 10)
278
+ .map(pw => ({
279
+ waveId: pw.id,
280
+ directive: pw.directive || '',
281
+ startedAt: pw.startedAt ? new Date(pw.startedAt).getTime() : 0,
282
+ }));
283
+
284
+ const allWaves = [...pastEntries, ...apiWaves];
285
+ setWaves(allWaves);
273
286
  setFocusedWaveId(apiWaves[apiWaves.length - 1].waveId);
274
287
  autoWaveCreated.current = true;
288
+ } else if (api.loaded && api.pastWaves.length > 0) {
289
+ // No active waves, but past waves exist — load them + create a new one
290
+ autoWaveCreated.current = true;
291
+ const pastEntries: WaveInfo[] = api.pastWaves.slice(0, 10).map(pw => ({
292
+ waveId: pw.id,
293
+ directive: pw.directive || '',
294
+ startedAt: pw.startedAt ? new Date(pw.startedAt).getTime() : 0,
295
+ }));
296
+
297
+ dispatchWave().then(result => {
298
+ const newWave: WaveInfo = {
299
+ waveId: result.waveId,
300
+ directive: '',
301
+ startedAt: Date.now(),
302
+ };
303
+ setWaves([...pastEntries, newWave]);
304
+ setFocusedWaveId(result.waveId);
305
+ }).catch(() => {
306
+ // Even if new wave fails, show past waves
307
+ setWaves(pastEntries);
308
+ setFocusedWaveId(pastEntries[pastEntries.length - 1]?.waveId ?? null);
309
+ autoWaveCreated.current = true;
310
+ });
275
311
  } else if (api.loaded) {
276
- // Create a new empty wave
312
+ // No active waves, no past waves — fresh start
277
313
  autoWaveCreated.current = true;
278
314
  dispatchWave().then(result => {
279
315
  const newWave: WaveInfo = {
@@ -284,11 +320,10 @@ export const App: React.FC = () => {
284
320
  setWaves([newWave]);
285
321
  setFocusedWaveId(result.waveId);
286
322
  }).catch(() => {
287
- // If empty wave creation fails, still proceed — user can /new
288
323
  autoWaveCreated.current = true;
289
324
  });
290
325
  }
291
- }, [view, api.activeWaves, api.loaded]);
326
+ }, [view, api.activeWaves, api.pastWaves, api.loaded]);
292
327
 
293
328
  // SSE subscription to focused wave
294
329
  const sse = useSSE(focusedWaveId);
@@ -10,11 +10,13 @@ import {
10
10
  fetchActiveWaves,
11
11
  fetchActiveSessions,
12
12
  fetchKnowledgeDocs,
13
+ fetchPastWaves,
13
14
  type CompanyInfo,
14
15
  type SessionInfo,
15
16
  type ExecStatus,
16
17
  type ActiveSessionInfo,
17
18
  type KnowledgeDoc,
19
+ type PastWaveInfo,
18
20
  } from '../api';
19
21
 
20
22
  const POLL_INTERVAL = 5000; // 5 seconds (reduce re-renders)
@@ -31,6 +33,7 @@ export interface ApiState {
31
33
  sessions: SessionInfo[];
32
34
  execStatus: ExecStatus | null;
33
35
  activeWaves: ActiveWaveInfo[];
36
+ pastWaves: PastWaveInfo[];
34
37
  activeSessions: ActiveSessionInfo[];
35
38
  portSummary: { active: number; totalPorts: number };
36
39
  knowledgeDocs: KnowledgeDoc[];
@@ -44,6 +47,8 @@ export function useApi(): ApiState {
44
47
  const [sessions, setSessions] = useState<SessionInfo[]>([]);
45
48
  const [execStatus, setExecStatus] = useState<ExecStatus | null>(null);
46
49
  const [activeWaves, setActiveWaves] = useState<ActiveWaveInfo[]>([]);
50
+ const [pastWaves, setPastWaves] = useState<PastWaveInfo[]>([]);
51
+ const pastWavesLoadedRef = useRef(false);
47
52
  const [activeSessions, setActiveSessions] = useState<ActiveSessionInfo[]>([]);
48
53
  const [portSummary, setPortSummary] = useState<{ active: number; totalPorts: number }>({ active: 0, totalPorts: 0 });
49
54
  const [knowledgeDocs, setKnowledgeDocs] = useState<KnowledgeDoc[]>([]);
@@ -88,6 +93,14 @@ export function useApi(): ApiState {
88
93
  }).catch(() => {});
89
94
  }
90
95
 
96
+ // Past waves (load once)
97
+ if (!pastWavesLoadedRef.current) {
98
+ pastWavesLoadedRef.current = true;
99
+ fetchPastWaves(20).then(pw => {
100
+ if (mountedRef.current) setPastWaves(pw);
101
+ }).catch(() => {});
102
+ }
103
+
91
104
  setError(null);
92
105
  setLoaded(true);
93
106
  } catch (err) {
@@ -108,5 +121,5 @@ export function useApi(): ApiState {
108
121
  };
109
122
  }, [refresh]);
110
123
 
111
- return { company, sessions, execStatus, activeWaves, activeSessions, portSummary, knowledgeDocs, error, loaded, refresh };
124
+ return { company, sessions, execStatus, activeWaves, pastWaves, activeSessions, portSummary, knowledgeDocs, error, loaded, refresh };
112
125
  }