tycono 0.1.91 → 0.1.92
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/api/src/create-server.ts +7 -0
- package/src/api/src/routes/execute.ts +6 -0
- package/src/api/src/services/wave-multiplexer.ts +54 -0
- package/src/web/dist/assets/{index--pQ-Ce3E.js → index-HiHZjTU-.js} +24 -24
- package/src/web/dist/assets/{preview-app-B2p8z-M8.js → preview-app-DmFg3Yi9.js} +1 -1
- package/src/web/dist/index.html +1 -1
package/package.json
CHANGED
|
@@ -119,6 +119,13 @@ export function createHttpServer(): http.Server {
|
|
|
119
119
|
const url = req.url ?? '';
|
|
120
120
|
const method = req.method ?? '';
|
|
121
121
|
|
|
122
|
+
// GET /api/waves/active — restore active waves after refresh
|
|
123
|
+
if (url === '/api/waves/active' && method === 'GET') {
|
|
124
|
+
setExecCors(req, res);
|
|
125
|
+
handleExecRequest(req, res);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
122
129
|
// SSE multiplexed wave stream (GET /api/waves/:waveId/stream)
|
|
123
130
|
if (url.match(/^\/api\/waves\/[^/]+\/stream/) && method === 'GET') {
|
|
124
131
|
setExecCors(req, res);
|
|
@@ -48,6 +48,12 @@ export function handleExecRequest(req: IncomingMessage, res: ServerResponse): vo
|
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
// ── /api/waves/active — restore active waves after refresh ──
|
|
52
|
+
if (method === 'GET' && url === '/api/waves/active') {
|
|
53
|
+
jsonResponse(res, 200, { waves: waveMultiplexer.getActiveWaves() });
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
51
57
|
// ── /api/waves/save ──
|
|
52
58
|
if (method === 'POST' && url === '/api/waves/save') {
|
|
53
59
|
readBody(req).then((body) => handleSaveWave(body, res));
|
|
@@ -255,6 +255,60 @@ class WaveMultiplexer {
|
|
|
255
255
|
const jobs = this.waveJobs.get(waveId);
|
|
256
256
|
return jobs ? Array.from(jobs.keys()) : [];
|
|
257
257
|
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Return all waves that have at least one active (running/awaiting_input) job.
|
|
261
|
+
* Used to restore waveCenterWaves after page refresh.
|
|
262
|
+
*/
|
|
263
|
+
getActiveWaves(): Array<{
|
|
264
|
+
id: string;
|
|
265
|
+
directive: string;
|
|
266
|
+
rootJobs: Array<{ sessionId: string; roleId: string; roleName: string; jobId: string }>;
|
|
267
|
+
startedAt: number;
|
|
268
|
+
sessionIds: string[];
|
|
269
|
+
}> {
|
|
270
|
+
const result: Array<{
|
|
271
|
+
id: string;
|
|
272
|
+
directive: string;
|
|
273
|
+
rootJobs: Array<{ sessionId: string; roleId: string; roleName: string; jobId: string }>;
|
|
274
|
+
startedAt: number;
|
|
275
|
+
sessionIds: string[];
|
|
276
|
+
}> = [];
|
|
277
|
+
|
|
278
|
+
for (const [waveId, jobs] of this.waveJobs) {
|
|
279
|
+
const hasActive = Array.from(jobs.values()).some(j => isJobActive(j.status));
|
|
280
|
+
if (!hasActive) continue;
|
|
281
|
+
|
|
282
|
+
// Extract wave info from root jobs (jobs without parentJobId in this wave)
|
|
283
|
+
const rootJobs = Array.from(jobs.values())
|
|
284
|
+
.filter(j => !j.parentJobId || !jobs.has(j.parentJobId))
|
|
285
|
+
.map(j => ({
|
|
286
|
+
sessionId: j.sessionId ?? '',
|
|
287
|
+
roleId: j.roleId,
|
|
288
|
+
roleName: j.roleId.toUpperCase(),
|
|
289
|
+
jobId: j.id,
|
|
290
|
+
}));
|
|
291
|
+
|
|
292
|
+
// Directive from first root job's task (strip "[CEO Wave] " prefix)
|
|
293
|
+
const firstJob = rootJobs.length > 0
|
|
294
|
+
? Array.from(jobs.values()).find(j => j.id === rootJobs[0].jobId)
|
|
295
|
+
: undefined;
|
|
296
|
+
const directive = firstJob?.task.replace(/^\[CEO Wave\]\s*/, '') ?? '';
|
|
297
|
+
|
|
298
|
+
// StartedAt from earliest job
|
|
299
|
+
const startedAt = Math.min(
|
|
300
|
+
...Array.from(jobs.values()).map(j => new Date(j.createdAt).getTime())
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
const sessionIds = Array.from(jobs.values())
|
|
304
|
+
.map(j => j.sessionId)
|
|
305
|
+
.filter((s): s is string => !!s);
|
|
306
|
+
|
|
307
|
+
result.push({ id: waveId, directive, rootJobs, startedAt, sessionIds });
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return result;
|
|
311
|
+
}
|
|
258
312
|
}
|
|
259
313
|
|
|
260
314
|
/* ─── Helpers ────────────────────────────── */
|