@triflux/remote 10.44.0 → 10.46.0

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 (40) hide show
  1. package/hub/pipe.mjs +10 -15
  2. package/hub/schema.sql +1 -0
  3. package/hub/server.mjs +172 -93
  4. package/hub/store.mjs +127 -61
  5. package/hub/team/backend.mjs +4 -2
  6. package/hub/team/claude-daemon-control.mjs +2 -0
  7. package/hub/team/cli/commands/start/start-headless.mjs +2 -0
  8. package/hub/team/cli/commands/start/start-mux.mjs +24 -3
  9. package/hub/team/cli/services/runtime-mode.mjs +23 -9
  10. package/hub/team/conductor.mjs +80 -24
  11. package/hub/team/cto-auto-collect.mjs +2 -6
  12. package/hub/team/cto-pull.mjs +4 -0
  13. package/hub/team/dashboard-open.mjs +1 -0
  14. package/hub/team/execution-mode.mjs +38 -2
  15. package/hub/team/headless.mjs +493 -82
  16. package/hub/team/interactive-tui-transport.mjs +15 -1
  17. package/hub/team/launcher-template.mjs +17 -1
  18. package/hub/team/orchestrator.mjs +36 -9
  19. package/hub/team/pane.mjs +176 -14
  20. package/hub/team/psmux.mjs +79 -70
  21. package/hub/team/retry-state-machine.mjs +47 -16
  22. package/hub/team/session.mjs +57 -0
  23. package/hub/team/synapse-http.mjs +149 -4
  24. package/hub/team/terminal-opener.mjs +68 -13
  25. package/hub/team/tui-viewer.mjs +65 -14
  26. package/hub/team/uds-orchestrator.mjs +384 -83
  27. package/hub/tools.mjs +10 -1
  28. package/hub/workers/codex-mcp.mjs +9 -4
  29. package/hub/workers/delegator-mcp.mjs +1 -1
  30. package/package.json +1 -1
  31. package/scripts/lib/agent-route-policy.mjs +99 -38
  32. package/scripts/lib/cli-agy.mjs +24 -4
  33. package/scripts/lib/cli-codex.mjs +2 -0
  34. package/scripts/lib/codex-profile-config.mjs +45 -13
  35. package/scripts/lib/codex-recovery.sh +19 -0
  36. package/scripts/lib/gemini-profiles.mjs +113 -29
  37. package/scripts/lib/keyword-rules.mjs +12 -0
  38. package/scripts/lib/logger.mjs +60 -43
  39. package/scripts/lib/machine-profile.mjs +293 -0
  40. package/scripts/lib/mcp-health.mjs +44 -18
@@ -345,6 +345,35 @@ function isValidInitResponse(line) {
345
345
  }
346
346
  }
347
347
 
348
+ function validateHttpInitResponse(msg) {
349
+ if (msg?.jsonrpc !== "2.0") return "http:not-jsonrpc";
350
+ if (msg.id !== 1 && msg.id !== "1") return "http:id-mismatch";
351
+ if (msg.result === undefined && msg.error === undefined) {
352
+ return "http:no-result";
353
+ }
354
+ return null;
355
+ }
356
+
357
+ function parseSseInitResponse(body) {
358
+ let failureReason = "http:no-jsonrpc-body";
359
+ for (const event of body.split(/\r?\n\r?\n/)) {
360
+ const data = event
361
+ .split(/\r?\n/)
362
+ .filter((line) => line.startsWith("data:"))
363
+ .map((line) => line.slice("data:".length).replace(/^\s/, ""))
364
+ .join("\n");
365
+ if (!data) continue;
366
+ try {
367
+ const reason = validateHttpInitResponse(JSON.parse(data));
368
+ if (!reason) return null;
369
+ failureReason = reason;
370
+ } catch {
371
+ failureReason = "http:invalid-json";
372
+ }
373
+ }
374
+ return failureReason;
375
+ }
376
+
348
377
  export function probeStdio(def, timeoutMs = DEFAULT_PROBE_TIMEOUT_MS) {
349
378
  return new Promise((resolve) => {
350
379
  const start = Date.now();
@@ -431,7 +460,10 @@ export async function probeHttp(url, timeoutMs = DEFAULT_PROBE_TIMEOUT_MS) {
431
460
  try {
432
461
  const res = await fetch(url, {
433
462
  method: "POST",
434
- headers: { "content-type": "application/json" },
463
+ headers: {
464
+ accept: "application/json, text/event-stream",
465
+ "content-type": "application/json",
466
+ },
435
467
  body: makeInitializeRequest().trim(),
436
468
  signal: AbortSignal.timeout(timeoutMs),
437
469
  });
@@ -445,26 +477,20 @@ export async function probeHttp(url, timeoutMs = DEFAULT_PROBE_TIMEOUT_MS) {
445
477
  } catch {
446
478
  return { alive: false, reason: "http:body-read-failed", ms };
447
479
  }
448
- // SSE / ndjson 환경 대비 — 첫 JSON-RPC envelope 하나만 찾으면 충분.
449
- const envelope = body
450
- .split(/\r?\n/)
451
- .map((chunk) => chunk.replace(/^data:\s*/, "").trim())
452
- .find((chunk) => chunk.startsWith("{"));
453
- if (!envelope) {
480
+ const contentType = (res.headers.get("content-type") || "")
481
+ .split(";", 1)[0]
482
+ .trim()
483
+ .toLowerCase();
484
+ if (contentType === "text/event-stream") {
485
+ const reason = parseSseInitResponse(body);
486
+ return reason ? { alive: false, reason, ms } : { alive: true, ms };
487
+ }
488
+ if (contentType !== "application/json") {
454
489
  return { alive: false, reason: "http:no-jsonrpc-body", ms };
455
490
  }
456
491
  try {
457
- const msg = JSON.parse(envelope);
458
- if (msg.jsonrpc !== "2.0") {
459
- return { alive: false, reason: "http:not-jsonrpc", ms };
460
- }
461
- if (msg.id !== 1 && msg.id !== "1") {
462
- return { alive: false, reason: "http:id-mismatch", ms };
463
- }
464
- if (msg.result === undefined && msg.error === undefined) {
465
- return { alive: false, reason: "http:no-result", ms };
466
- }
467
- return { alive: true, ms };
492
+ const reason = validateHttpInitResponse(JSON.parse(body));
493
+ return reason ? { alive: false, reason, ms } : { alive: true, ms };
468
494
  } catch {
469
495
  return { alive: false, reason: "http:invalid-json", ms };
470
496
  }