tycono 0.1.96-beta.51 → 0.1.96-beta.52

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.
Files changed (2) hide show
  1. package/bin/tycono.ts +32 -48
  2. package/package.json +1 -1
package/bin/tycono.ts CHANGED
@@ -221,65 +221,49 @@ async function startServerForTui(): Promise<void> {
221
221
  const origStdoutWrite = process.stdout.write.bind(process.stdout);
222
222
  const origLog = (...args: unknown[]) => origStdoutWrite(args.join(' ') + '\n');
223
223
 
224
- // Start API server as a CHILD PROCESS to isolate stdout completely
225
- // This prevents server console.log from corrupting Ink's frame buffer
226
- const { fork } = await import('node:child_process');
227
- const serverScript = path.resolve(__dirname, '..', 'src', 'api', 'src', 'server.ts');
228
-
229
- const child = fork(serverScript, [], {
230
- execArgv: ['--import', 'tsx'],
231
- env: {
232
- ...process.env,
233
- PORT: String(port),
234
- COMPANY_ROOT: process.env.COMPANY_ROOT,
235
- },
236
- stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
237
- });
224
+ // Suppress ALL server output BEFORE importing server code
225
+ // Override console methods globally affects all subsequently imported modules
226
+ const _log = console.log, _err = console.error, _warn = console.warn, _info = console.info;
227
+ console.log = (...a: unknown[]) => logStream.write(a.join(' ') + '\n');
228
+ console.error = (...a: unknown[]) => logStream.write(a.join(' ') + '\n');
229
+ console.warn = (...a: unknown[]) => logStream.write(a.join(' ') + '\n');
230
+ console.info = (...a: unknown[]) => logStream.write(a.join(' ') + '\n');
238
231
 
239
- // Redirect child stdout/stderr to log file
240
- child.stdout?.on('data', (data: Buffer) => { logStream.write(data); });
241
- child.stderr?.on('data', (data: Buffer) => { logStream.write(data); });
242
-
243
- // Wait for server to be ready (poll health endpoint)
244
- const waitForServer = async () => {
245
- const http = await import('node:http');
246
- for (let i = 0; i < 30; i++) {
247
- try {
248
- await new Promise<void>((resolve, reject) => {
249
- const req = http.get(`http://localhost:${port}/api/health`, (res) => {
250
- res.resume();
251
- resolve();
252
- });
253
- req.on('error', reject);
254
- req.setTimeout(1000, () => { req.destroy(); reject(new Error('timeout')); });
255
- });
256
- return true;
257
- } catch {
258
- await new Promise(r => setTimeout(r, 500));
259
- }
260
- }
261
- return false;
262
- };
232
+ const { createHttpServer } = await import('../src/api/src/create-server.js');
233
+ const server = createHttpServer();
263
234
 
264
- const serverReady = await waitForServer();
265
- if (!serverReady) {
266
- origLog(' Failed to start API server. Check logs:', logFile);
267
- process.exit(1);
268
- }
235
+ const host = process.env.HOST || '0.0.0.0';
236
+
237
+ await new Promise<void>((resolve) => {
238
+ server.listen(port, host, () => resolve());
239
+ });
269
240
 
270
241
  origLog(` API server started on port ${port}`);
271
242
  origLog(` Logs: ${logFile}`);
272
243
 
273
- // Graceful shutdown kill child server
244
+ // Now hijack stdout.write AFTER server started but BEFORE Ink
245
+ // Block non-Ink output from reaching terminal
246
+ // Ink always writes ANSI escape sequences — server text output doesn't
247
+ process.stdout.write = ((chunk: any, ...args: any[]) => {
248
+ const str = typeof chunk === 'string' ? chunk : chunk.toString();
249
+ // Ink output: contains ANSI CSI sequences
250
+ if (str.includes('\x1b[') || str.includes('\x1b(')) {
251
+ return origStdoutWrite(chunk, ...args);
252
+ }
253
+ // Non-Ink (server log leaked): redirect to file
254
+ logStream.write(str);
255
+ return true;
256
+ }) as any;
257
+
258
+ // Graceful shutdown
274
259
  const shutdown = () => {
275
- child.kill();
276
- process.exit(0);
260
+ server.close(() => process.exit(0));
261
+ setTimeout(() => process.exit(1), 5000);
277
262
  };
278
263
  process.on('SIGINT', shutdown);
279
264
  process.on('SIGTERM', shutdown);
280
- child.on('exit', () => { process.exit(0); });
281
265
 
282
- // Start TUI — clean stdout, no server interference
266
+ // Start TUI
283
267
  const { startTui } = await import('../src/tui/index.tsx');
284
268
  await startTui({ port });
285
269
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tycono",
3
- "version": "0.1.96-beta.51",
3
+ "version": "0.1.96-beta.52",
4
4
  "description": "Build an AI company. Watch them work.",
5
5
  "type": "module",
6
6
  "bin": {