tycono 0.1.100 → 0.1.101

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/bin/tycono.ts CHANGED
@@ -237,6 +237,30 @@ async function startServerForTui(): Promise<void> {
237
237
  }) as any;
238
238
 
239
239
  const { createHttpServer } = await import('../src/api/src/create-server.js');
240
+
241
+ // Startup orphan scan — mark stale 'active' sessions as interrupted
242
+ // (server.ts does this for standalone mode, but TUI mode uses create-server directly)
243
+ try {
244
+ const { listSessions, updateSession } = await import('../src/api/src/services/session-store.js');
245
+ const { ActivityStream } = await import('../src/api/src/services/activity-stream.js');
246
+ let orphaned = 0;
247
+ for (const ses of listSessions()) {
248
+ if (ses.status !== 'active') continue;
249
+ if (ActivityStream.exists(ses.id)) {
250
+ const events = ActivityStream.readFrom(ses.id, 0);
251
+ const tail = events.slice(-5);
252
+ if (tail.some((e: any) => e.type === 'msg:done' || e.type === 'msg:error')) {
253
+ updateSession(ses.id, { status: 'done' });
254
+ orphaned++;
255
+ continue;
256
+ }
257
+ }
258
+ updateSession(ses.id, { status: 'interrupted' as any });
259
+ orphaned++;
260
+ }
261
+ if (orphaned > 0) logStream.write(`[STARTUP] Cleaned ${orphaned} orphaned sessions\n`);
262
+ } catch { /* ignore if session-store not ready */ }
263
+
240
264
  const server = createHttpServer();
241
265
 
242
266
  await new Promise<void>((resolve) => {
@@ -246,8 +270,15 @@ async function startServerForTui(): Promise<void> {
246
270
  origLog(` API server started on port ${port}`);
247
271
  origLog(` Logs: ${logFile}`);
248
272
 
249
- // Graceful shutdown
273
+ // Graceful shutdown — mark active sessions as interrupted
250
274
  const shutdown = () => {
275
+ try {
276
+ import('../src/api/src/services/session-store.js').then(({ listSessions, updateSession }) => {
277
+ for (const ses of listSessions()) {
278
+ if (ses.status === 'active') updateSession(ses.id, { status: 'interrupted' as any });
279
+ }
280
+ }).catch(() => {});
281
+ } catch {}
251
282
  server.close(() => process.exit(0));
252
283
  setTimeout(() => process.exit(1), 5000);
253
284
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tycono",
3
- "version": "0.1.100",
3
+ "version": "0.1.101",
4
4
  "description": "Build an AI company. Watch them work.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,13 +33,19 @@ interface CommandModeProps {
33
33
 
34
34
  let lineCounter = 0;
35
35
 
36
- /** Filter out only truly internal system prompt fragments */
36
+ /** Filter out internal system prompt fragments and context leakage */
37
37
  function isSystemNoise(text: string): boolean {
38
38
  const t = text.trim();
39
39
  if (!t) return true;
40
- // Only filter the injected supervisor system prompt header
40
+ // Injected supervisor system prompt header
41
41
  if (t.startsWith('[CEO Supervisor]') && t.includes('Your Role')) return true;
42
42
  if (t.startsWith('\u26D4 AKB Rule:')) return true;
43
+ // System prompt fragments
44
+ if (/^##\s*Your Role/i.test(t)) return true;
45
+ if (t.includes('무엇을 도와드릴까요')) return true;
46
+ // Conversation context leakage
47
+ if (t.startsWith('[Previous execution]')) return true;
48
+ if (/^Tools used:/i.test(t)) return true;
43
49
  return false;
44
50
  }
45
51
 
@@ -157,13 +163,8 @@ export function summarizeEvent(event: SSEEvent, allRoleIds: string[]): StreamLin
157
163
  case 'msg:start': {
158
164
  const task = ((event.data.task as string) ?? '');
159
165
  const cleanTask = task.replace(/\u26D4[^\u26D4]*\u26D4[^"]*/g, '').trim().slice(0, 60);
160
- if (isSupervisor) {
161
- return {
162
- id: ++lineCounter,
163
- text: `\u25B6 Supervisor started${cleanTask ? ': ' + cleanTask : ''}`,
164
- color: 'cyan',
165
- };
166
- }
166
+ // Hide supervisor started message (internal noise)
167
+ if (isSupervisor) return null;
167
168
  return {
168
169
  id: ++lineCounter,
169
170
  prefix: event.roleId,
@@ -313,7 +314,7 @@ export const CommandMode: React.FC<CommandModeProps> = ({
313
314
  setUserInputs(prev => [...prev.slice(-10), {
314
315
  id: ++lineCounter,
315
316
  text: `> ${trimmed}`,
316
- color: 'yellow',
317
+ color: 'green',
317
318
  }]);
318
319
  onSubmit(trimmed);
319
320
  }