@hua-labs/tap 0.5.0 → 0.5.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/README.md +9 -0
- package/dist/bridges/codex-app-server-bridge.d.mts +236 -5
- package/dist/bridges/codex-app-server-bridge.mjs +1168 -722
- package/dist/bridges/codex-app-server-bridge.mjs.map +1 -1
- package/dist/bridges/codex-bridge-runner.d.mts +2 -1
- package/dist/bridges/codex-bridge-runner.mjs +10 -2
- package/dist/bridges/codex-bridge-runner.mjs.map +1 -1
- package/dist/bridges/gemini-ide-companion-runner.mjs +0 -0
- package/dist/cli.mjs +353 -192
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +208 -68
- package/dist/index.mjs.map +1 -1
- package/dist/mcp-server.mjs +267 -19
- package/dist/mcp-server.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -1388,13 +1388,14 @@ function startWindowsDetachedProcess(command, args, repoRoot, logPath, env = pro
|
|
|
1388
1388
|
}
|
|
1389
1389
|
return pid;
|
|
1390
1390
|
}
|
|
1391
|
-
function startWindowsCodexAppServer(command, url, repoRoot, logPath) {
|
|
1391
|
+
function startWindowsCodexAppServer(command, url, repoRoot, logPath, env = process.env) {
|
|
1392
1392
|
const { command: exe, prefixArgs } = splitResolvedCommand(command);
|
|
1393
1393
|
return startWindowsDetachedProcess(
|
|
1394
1394
|
exe,
|
|
1395
1395
|
[...prefixArgs, "app-server", "--listen", url],
|
|
1396
1396
|
repoRoot,
|
|
1397
|
-
logPath
|
|
1397
|
+
logPath,
|
|
1398
|
+
env
|
|
1398
1399
|
);
|
|
1399
1400
|
}
|
|
1400
1401
|
function findListeningProcessId(url, platform) {
|
|
@@ -1514,14 +1515,14 @@ function startUnixDetachedProcess(command, args, repoRoot, logPath, env = proces
|
|
|
1514
1515
|
}
|
|
1515
1516
|
}
|
|
1516
1517
|
}
|
|
1517
|
-
function startUnixCodexAppServer(command, url, repoRoot, logPath, platform = DEFAULT_UNIX_PLATFORM) {
|
|
1518
|
+
function startUnixCodexAppServer(command, url, repoRoot, logPath, env = process.env, platform = DEFAULT_UNIX_PLATFORM) {
|
|
1518
1519
|
const { command: exe, prefixArgs } = splitResolvedCommand(command);
|
|
1519
1520
|
return startUnixDetachedProcess(
|
|
1520
1521
|
exe,
|
|
1521
1522
|
[...prefixArgs, "app-server", "--listen", url],
|
|
1522
1523
|
repoRoot,
|
|
1523
1524
|
logPath,
|
|
1524
|
-
|
|
1525
|
+
env,
|
|
1525
1526
|
platform
|
|
1526
1527
|
);
|
|
1527
1528
|
}
|
|
@@ -2337,6 +2338,19 @@ var init_bridge_app_server_auth = __esm({
|
|
|
2337
2338
|
// src/engine/bridge-app-server-lifecycle.ts
|
|
2338
2339
|
import * as fs18 from "fs";
|
|
2339
2340
|
import * as path17 from "path";
|
|
2341
|
+
function buildCodexAppServerEnv(options) {
|
|
2342
|
+
return {
|
|
2343
|
+
...process.env,
|
|
2344
|
+
TAP_COMMS_DIR: options.commsDir,
|
|
2345
|
+
TAP_STATE_DIR: options.stateDir,
|
|
2346
|
+
TAP_RUNTIME_STATE_DIR: options.runtimeStateDir,
|
|
2347
|
+
TAP_REPO_ROOT: options.repoRoot,
|
|
2348
|
+
TAP_BRIDGE_INSTANCE_ID: options.instanceId,
|
|
2349
|
+
TAP_AGENT_ID: options.instanceId,
|
|
2350
|
+
TAP_AGENT_NAME: options.agentName,
|
|
2351
|
+
CODEX_TAP_AGENT_NAME: options.agentName
|
|
2352
|
+
};
|
|
2353
|
+
}
|
|
2340
2354
|
function isAppServerUsedByOtherBridge(stateDir, excludeInstanceId, appServer) {
|
|
2341
2355
|
const pidDir = path17.join(stateDir, "pids");
|
|
2342
2356
|
if (!fs18.existsSync(pidDir)) return false;
|
|
@@ -2440,6 +2454,7 @@ Start the app-server manually:
|
|
|
2440
2454
|
const logPath = appServerLogFilePath(options.stateDir, options.instanceId);
|
|
2441
2455
|
fs18.mkdirSync(path17.dirname(logPath), { recursive: true });
|
|
2442
2456
|
rotateLog(logPath);
|
|
2457
|
+
const appServerEnv = buildCodexAppServerEnv(options);
|
|
2443
2458
|
if (options.noAuth) {
|
|
2444
2459
|
const manualCommand2 = formatCodexAppServerCommand("codex", effectiveUrl);
|
|
2445
2460
|
let pid2;
|
|
@@ -2449,7 +2464,8 @@ Start the app-server manually:
|
|
|
2449
2464
|
resolvedCommand,
|
|
2450
2465
|
effectiveUrl,
|
|
2451
2466
|
options.repoRoot,
|
|
2452
|
-
logPath
|
|
2467
|
+
logPath,
|
|
2468
|
+
appServerEnv
|
|
2453
2469
|
);
|
|
2454
2470
|
} catch (err) {
|
|
2455
2471
|
throw new Error(
|
|
@@ -2466,6 +2482,7 @@ Start it manually:
|
|
|
2466
2482
|
effectiveUrl,
|
|
2467
2483
|
options.repoRoot,
|
|
2468
2484
|
logPath,
|
|
2485
|
+
appServerEnv,
|
|
2469
2486
|
options.platform
|
|
2470
2487
|
);
|
|
2471
2488
|
} catch (err) {
|
|
@@ -2526,7 +2543,8 @@ Or start it manually:
|
|
|
2526
2543
|
resolvedCommand,
|
|
2527
2544
|
auth.upstreamUrl,
|
|
2528
2545
|
options.repoRoot,
|
|
2529
|
-
logPath
|
|
2546
|
+
logPath,
|
|
2547
|
+
appServerEnv
|
|
2530
2548
|
);
|
|
2531
2549
|
} catch (err) {
|
|
2532
2550
|
if (auth.gatewayPid != null) {
|
|
@@ -2547,6 +2565,7 @@ Start it manually:
|
|
|
2547
2565
|
auth.upstreamUrl,
|
|
2548
2566
|
options.repoRoot,
|
|
2549
2567
|
logPath,
|
|
2568
|
+
appServerEnv,
|
|
2550
2569
|
options.platform
|
|
2551
2570
|
);
|
|
2552
2571
|
} catch (err) {
|
|
@@ -2777,9 +2796,12 @@ async function startBridge(options) {
|
|
|
2777
2796
|
appServer = await ensureCodexAppServer({
|
|
2778
2797
|
instanceId,
|
|
2779
2798
|
stateDir,
|
|
2799
|
+
runtimeStateDir,
|
|
2800
|
+
commsDir,
|
|
2780
2801
|
repoRoot,
|
|
2781
2802
|
platform: options.platform,
|
|
2782
2803
|
appServerUrl: effectiveAppServerUrl,
|
|
2804
|
+
agentName: resolvedAgent,
|
|
2783
2805
|
existingAppServer: previousAppServer,
|
|
2784
2806
|
noAuth: options.noAuth
|
|
2785
2807
|
});
|
|
@@ -2800,7 +2822,9 @@ async function startBridge(options) {
|
|
|
2800
2822
|
const bridgeEnv = {
|
|
2801
2823
|
...runtimeEnv,
|
|
2802
2824
|
TAP_COMMS_DIR: commsDir,
|
|
2803
|
-
TAP_STATE_DIR:
|
|
2825
|
+
TAP_STATE_DIR: stateDir,
|
|
2826
|
+
TAP_RUNTIME_STATE_DIR: runtimeStateDir,
|
|
2827
|
+
TAP_REPO_ROOT: repoRoot,
|
|
2804
2828
|
TAP_BRIDGE_RUNTIME: runtime,
|
|
2805
2829
|
TAP_BRIDGE_INSTANCE_ID: instanceId,
|
|
2806
2830
|
TAP_AGENT_ID: instanceId,
|
|
@@ -4354,8 +4378,24 @@ function resolveTuiConnectUrl(appServer) {
|
|
|
4354
4378
|
function quoteCliArg(value) {
|
|
4355
4379
|
return `"${value.replace(/"/g, '\\"')}"`;
|
|
4356
4380
|
}
|
|
4357
|
-
function
|
|
4358
|
-
|
|
4381
|
+
function quoteShellEnvValue(value) {
|
|
4382
|
+
if (process.platform === "win32") {
|
|
4383
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
4384
|
+
}
|
|
4385
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
4386
|
+
}
|
|
4387
|
+
function formatCodexTuiAttachCommand(tuiConnectUrl, cwd, env = {}) {
|
|
4388
|
+
const base = `codex --enable tui_app_server --remote ${quoteCliArg(tuiConnectUrl)} --cd ${quoteCliArg(cwd)}`;
|
|
4389
|
+
const entries = Object.entries(env).filter(([, value]) => value.length > 0);
|
|
4390
|
+
if (entries.length === 0) {
|
|
4391
|
+
return base;
|
|
4392
|
+
}
|
|
4393
|
+
if (process.platform === "win32") {
|
|
4394
|
+
const envPrefix2 = entries.map(([key, value]) => `$env:${key} = ${quoteShellEnvValue(value)}`).join("; ");
|
|
4395
|
+
return `${envPrefix2}; ${base}`;
|
|
4396
|
+
}
|
|
4397
|
+
const envPrefix = entries.map(([key, value]) => `${key}=${quoteShellEnvValue(value)}`).join(" ");
|
|
4398
|
+
return `${envPrefix} ${base}`;
|
|
4359
4399
|
}
|
|
4360
4400
|
function resolveTuiAttachCwd(repoRoot, stateRepoRoot, runtimeThreadCwd, savedThreadCwd) {
|
|
4361
4401
|
return runtimeThreadCwd ?? savedThreadCwd ?? stateRepoRoot ?? repoRoot;
|
|
@@ -5352,8 +5392,62 @@ var init_bridge_watch = __esm({
|
|
|
5352
5392
|
}
|
|
5353
5393
|
});
|
|
5354
5394
|
|
|
5355
|
-
// src/
|
|
5395
|
+
// src/engine/health-monitor.ts
|
|
5396
|
+
import * as fs26 from "fs";
|
|
5356
5397
|
import * as path28 from "path";
|
|
5398
|
+
function getHeartbeatActivityMs2(record) {
|
|
5399
|
+
const timestamp = new Date(record.lastActivity ?? record.timestamp ?? 0).getTime();
|
|
5400
|
+
return Number.isFinite(timestamp) ? timestamp : null;
|
|
5401
|
+
}
|
|
5402
|
+
function isSameInstanceHeartbeat2(key, heartbeat, instanceId) {
|
|
5403
|
+
if (heartbeat.instanceId === instanceId) return true;
|
|
5404
|
+
if (heartbeat.connectHash === `instance:${instanceId}`) return true;
|
|
5405
|
+
return key === instanceId || key.replace(/_/g, "-") === instanceId || key.replace(/-/g, "_") === instanceId;
|
|
5406
|
+
}
|
|
5407
|
+
function loadLiveDispatchEvidence(commsDir, instanceId) {
|
|
5408
|
+
const heartbeatsPath = path28.join(commsDir, "heartbeats.json");
|
|
5409
|
+
if (!fs26.existsSync(heartbeatsPath)) return null;
|
|
5410
|
+
try {
|
|
5411
|
+
const store = JSON.parse(
|
|
5412
|
+
fs26.readFileSync(heartbeatsPath, "utf-8")
|
|
5413
|
+
);
|
|
5414
|
+
let best = null;
|
|
5415
|
+
let bestActivityMs = -1;
|
|
5416
|
+
for (const [key, heartbeat] of Object.entries(store)) {
|
|
5417
|
+
if (!isSameInstanceHeartbeat2(key, heartbeat, instanceId)) continue;
|
|
5418
|
+
if (heartbeat.source !== "bridge-dispatch") continue;
|
|
5419
|
+
if (heartbeat.bridgePid == null || !isProcessAlive(heartbeat.bridgePid)) {
|
|
5420
|
+
continue;
|
|
5421
|
+
}
|
|
5422
|
+
const activityMs = getHeartbeatActivityMs2(heartbeat);
|
|
5423
|
+
if (activityMs == null || Date.now() - activityMs > DISPATCH_EVIDENCE_FRESH_THRESHOLD_MS) {
|
|
5424
|
+
continue;
|
|
5425
|
+
}
|
|
5426
|
+
if (activityMs > bestActivityMs) {
|
|
5427
|
+
bestActivityMs = activityMs;
|
|
5428
|
+
best = {
|
|
5429
|
+
bridgePid: heartbeat.bridgePid,
|
|
5430
|
+
lastActivity: heartbeat.lastActivity ?? heartbeat.timestamp ?? new Date(activityMs).toISOString()
|
|
5431
|
+
};
|
|
5432
|
+
}
|
|
5433
|
+
}
|
|
5434
|
+
return best;
|
|
5435
|
+
} catch {
|
|
5436
|
+
return null;
|
|
5437
|
+
}
|
|
5438
|
+
}
|
|
5439
|
+
var DISPATCH_EVIDENCE_FRESH_THRESHOLD_MS, HEARTBEAT_FRESH_THRESHOLD_MS;
|
|
5440
|
+
var init_health_monitor = __esm({
|
|
5441
|
+
"src/engine/health-monitor.ts"() {
|
|
5442
|
+
"use strict";
|
|
5443
|
+
init_bridge_process_control();
|
|
5444
|
+
DISPATCH_EVIDENCE_FRESH_THRESHOLD_MS = 2 * 60 * 1e3;
|
|
5445
|
+
HEARTBEAT_FRESH_THRESHOLD_MS = 2 * 60 * 1e3;
|
|
5446
|
+
}
|
|
5447
|
+
});
|
|
5448
|
+
|
|
5449
|
+
// src/commands/bridge-status.ts
|
|
5450
|
+
import * as path29 from "path";
|
|
5357
5451
|
function bridgeStatusAll() {
|
|
5358
5452
|
const repoRoot = findRepoRoot();
|
|
5359
5453
|
const state = loadState(repoRoot);
|
|
@@ -5402,23 +5496,26 @@ function bridgeStatusAll() {
|
|
|
5402
5496
|
};
|
|
5403
5497
|
continue;
|
|
5404
5498
|
}
|
|
5405
|
-
const
|
|
5499
|
+
const rawStatus = getBridgeStatus(stateDir, instanceId);
|
|
5406
5500
|
const bridgeState = loadBridgeState(stateDir, instanceId) ?? inst.bridge;
|
|
5407
|
-
const
|
|
5408
|
-
const
|
|
5409
|
-
const
|
|
5410
|
-
|
|
5501
|
+
const liveDispatch = rawStatus === "running" ? null : loadLiveDispatchEvidence(state.commsDir, instanceId);
|
|
5502
|
+
const surfaceBridgeState = liveDispatch ? null : bridgeState;
|
|
5503
|
+
const runtimeHeartbeat = loadRuntimeBridgeHeartbeat(surfaceBridgeState);
|
|
5504
|
+
const savedThread = loadRuntimeBridgeThreadState(surfaceBridgeState);
|
|
5505
|
+
const status = liveDispatch ? "dispatch-live" : rawStatus;
|
|
5506
|
+
const lifecycle = liveDispatch ? deriveBridgeLifecycleState({ bridgeStatus: "stopped" }) : deriveBridgeLifecycleState({
|
|
5507
|
+
bridgeStatus: rawStatus,
|
|
5411
5508
|
bridgeState,
|
|
5412
5509
|
runtimeHeartbeat,
|
|
5413
5510
|
savedThread,
|
|
5414
5511
|
persistedLifecycle: inst.bridgeLifecycle ?? bridgeState?.lifecycle ?? null
|
|
5415
5512
|
});
|
|
5416
|
-
const session =
|
|
5513
|
+
const session = rawStatus === "running" || liveDispatch ? deriveCodexSessionState({
|
|
5417
5514
|
runtimeHeartbeat,
|
|
5418
|
-
runtimeStateDir:
|
|
5515
|
+
runtimeStateDir: surfaceBridgeState?.runtimeStateDir ?? null
|
|
5419
5516
|
}) : null;
|
|
5420
|
-
const age = getHeartbeatAge(stateDir, instanceId);
|
|
5421
|
-
if (
|
|
5517
|
+
const age = liveDispatch ? null : getHeartbeatAge(stateDir, instanceId);
|
|
5518
|
+
if (rawStatus === "stale" && inst.bridge) {
|
|
5422
5519
|
state.instances[instanceId] = {
|
|
5423
5520
|
...inst,
|
|
5424
5521
|
bridge: null,
|
|
@@ -5430,22 +5527,22 @@ function bridgeStatusAll() {
|
|
|
5430
5527
|
};
|
|
5431
5528
|
stateChanged = true;
|
|
5432
5529
|
}
|
|
5433
|
-
const pid =
|
|
5434
|
-
const heartbeat = getBridgeHeartbeatTimestamp(stateDir, instanceId);
|
|
5530
|
+
const pid = surfaceBridgeState?.pid ?? null;
|
|
5531
|
+
const heartbeat = liveDispatch ? null : getBridgeHeartbeatTimestamp(stateDir, instanceId);
|
|
5435
5532
|
const pidStr = pid ? String(pid) : "-";
|
|
5436
5533
|
const portStr = inst.port ? String(inst.port) : "-";
|
|
5437
5534
|
const ageStr = age !== null ? formatAge(age) : "-";
|
|
5438
5535
|
log(
|
|
5439
5536
|
`${instanceId.padEnd(20)} ${inst.runtime.padEnd(8)} ${status.padEnd(10)} ${lifecycle.status.padEnd(20)} ${(session?.status ?? "-").padEnd(18)} ${pidStr.padEnd(8)} ${portStr.padEnd(6)} ${ageStr}`
|
|
5440
5537
|
);
|
|
5441
|
-
if (
|
|
5442
|
-
log(` App server: ${formatAppServerState(
|
|
5443
|
-
if (
|
|
5444
|
-
log(` Server log: ${
|
|
5538
|
+
if (surfaceBridgeState?.appServer) {
|
|
5539
|
+
log(` App server: ${formatAppServerState(surfaceBridgeState.appServer)}`);
|
|
5540
|
+
if (surfaceBridgeState.appServer.logPath) {
|
|
5541
|
+
log(` Server log: ${surfaceBridgeState.appServer.logPath}`);
|
|
5445
5542
|
}
|
|
5446
|
-
if (
|
|
5543
|
+
if (surfaceBridgeState.appServer.auth) {
|
|
5447
5544
|
log(
|
|
5448
|
-
` Protected: ${redactProtectedUrl(
|
|
5545
|
+
` Protected: ${redactProtectedUrl(surfaceBridgeState.appServer.auth.protectedUrl)}`
|
|
5449
5546
|
);
|
|
5450
5547
|
}
|
|
5451
5548
|
}
|
|
@@ -5463,6 +5560,11 @@ function bridgeStatusAll() {
|
|
|
5463
5560
|
if (transition) {
|
|
5464
5561
|
log(` Transition: ${transition}`);
|
|
5465
5562
|
}
|
|
5563
|
+
if (liveDispatch) {
|
|
5564
|
+
log(
|
|
5565
|
+
` Drift: fresh bridge-dispatch heartbeat from PID ${liveDispatch.bridgePid} without bridge pid state`
|
|
5566
|
+
);
|
|
5567
|
+
}
|
|
5466
5568
|
const turnInfo = getTurnInfo(stateDir, instanceId);
|
|
5467
5569
|
if (turnInfo?.activeTurnId) {
|
|
5468
5570
|
const ageStr2 = turnInfo.ageSeconds != null ? formatAge(turnInfo.ageSeconds) : "?";
|
|
@@ -5488,7 +5590,7 @@ function bridgeStatusAll() {
|
|
|
5488
5590
|
threadCwd: runtimeHeartbeat?.threadCwd ?? null,
|
|
5489
5591
|
savedThreadId: savedThread?.threadId ?? null,
|
|
5490
5592
|
savedThreadCwd: savedThread?.cwd ?? null,
|
|
5491
|
-
appServer:
|
|
5593
|
+
appServer: surfaceBridgeState?.appServer ?? null
|
|
5492
5594
|
};
|
|
5493
5595
|
}
|
|
5494
5596
|
if (instanceIds.length === 0) {
|
|
@@ -5585,14 +5687,17 @@ function bridgeStatusOne(identifier) {
|
|
|
5585
5687
|
}
|
|
5586
5688
|
const { config: resolvedCfg2 } = resolveConfig({}, repoRoot);
|
|
5587
5689
|
const stateDir = resolvedCfg2.stateDir;
|
|
5588
|
-
const
|
|
5690
|
+
const rawStatus = getBridgeStatus(stateDir, instanceId);
|
|
5589
5691
|
const bridgeState = loadBridgeState(stateDir, instanceId) ?? inst.bridge;
|
|
5590
|
-
const
|
|
5591
|
-
const
|
|
5592
|
-
const
|
|
5593
|
-
const
|
|
5594
|
-
const
|
|
5595
|
-
|
|
5692
|
+
const liveDispatch = rawStatus === "running" ? null : loadLiveDispatchEvidence(state.commsDir, instanceId);
|
|
5693
|
+
const surfaceBridgeState = liveDispatch ? null : bridgeState;
|
|
5694
|
+
const runtimeHeartbeat = loadRuntimeBridgeHeartbeat(surfaceBridgeState);
|
|
5695
|
+
const savedThread = loadRuntimeBridgeThreadState(surfaceBridgeState);
|
|
5696
|
+
const age = liveDispatch ? null : getHeartbeatAge(stateDir, instanceId);
|
|
5697
|
+
const heartbeat = liveDispatch ? null : getBridgeHeartbeatTimestamp(stateDir, instanceId);
|
|
5698
|
+
const status = liveDispatch ? "dispatch-live" : rawStatus;
|
|
5699
|
+
const lifecycle = liveDispatch ? deriveBridgeLifecycleState({ bridgeStatus: "stopped" }) : deriveBridgeLifecycleState({
|
|
5700
|
+
bridgeStatus: rawStatus,
|
|
5596
5701
|
bridgeState,
|
|
5597
5702
|
runtimeHeartbeat,
|
|
5598
5703
|
savedThread,
|
|
@@ -5600,13 +5705,25 @@ function bridgeStatusOne(identifier) {
|
|
|
5600
5705
|
});
|
|
5601
5706
|
const session = deriveCodexSessionState({
|
|
5602
5707
|
runtimeHeartbeat,
|
|
5603
|
-
runtimeStateDir:
|
|
5708
|
+
runtimeStateDir: surfaceBridgeState?.runtimeStateDir ?? null
|
|
5604
5709
|
});
|
|
5605
5710
|
log(`Status: ${status}`);
|
|
5606
5711
|
log(`Lifecycle: ${lifecycle.summary}`);
|
|
5607
5712
|
log(`Session: ${session.summary}`);
|
|
5608
|
-
if (
|
|
5609
|
-
|
|
5713
|
+
if (rawStatus === "stale" && inst.bridge) {
|
|
5714
|
+
state.instances[instanceId] = {
|
|
5715
|
+
...inst,
|
|
5716
|
+
bridge: null,
|
|
5717
|
+
bridgeLifecycle: transitionBridgeLifecycle(
|
|
5718
|
+
inst.bridgeLifecycle ?? inst.bridge?.lifecycle ?? null,
|
|
5719
|
+
"crashed",
|
|
5720
|
+
"bridge pid not alive"
|
|
5721
|
+
)
|
|
5722
|
+
};
|
|
5723
|
+
saveState(repoRoot, state);
|
|
5724
|
+
}
|
|
5725
|
+
if (surfaceBridgeState) {
|
|
5726
|
+
log(`PID: ${surfaceBridgeState.pid}`);
|
|
5610
5727
|
log(
|
|
5611
5728
|
`Heartbeat: ${heartbeat ?? "-"}${age !== null ? ` (${formatAge(age)})` : ""}`
|
|
5612
5729
|
);
|
|
@@ -5621,35 +5738,35 @@ function bridgeStatusOne(identifier) {
|
|
|
5621
5738
|
);
|
|
5622
5739
|
}
|
|
5623
5740
|
log(
|
|
5624
|
-
`Log: ${
|
|
5741
|
+
`Log: ${path29.join(stateDir, "logs", `bridge-${instanceId}.log`)}`
|
|
5625
5742
|
);
|
|
5626
|
-
if (
|
|
5627
|
-
log(`App server: ${
|
|
5628
|
-
log(`Server PID: ${
|
|
5743
|
+
if (surfaceBridgeState.appServer) {
|
|
5744
|
+
log(`App server: ${surfaceBridgeState.appServer.url}`);
|
|
5745
|
+
log(`Server PID: ${surfaceBridgeState.appServer.pid ?? "-"}`);
|
|
5629
5746
|
log(
|
|
5630
|
-
`Server mode: ${
|
|
5747
|
+
`Server mode: ${surfaceBridgeState.appServer.managed ? "managed" : "external"}`
|
|
5631
5748
|
);
|
|
5632
5749
|
log(
|
|
5633
|
-
`Health: ${
|
|
5750
|
+
`Health: ${surfaceBridgeState.appServer.healthy ? "healthy" : "unhealthy"}`
|
|
5634
5751
|
);
|
|
5635
|
-
log(`Checked: ${
|
|
5636
|
-
if (
|
|
5637
|
-
log(`Server log: ${
|
|
5752
|
+
log(`Checked: ${surfaceBridgeState.appServer.lastCheckedAt}`);
|
|
5753
|
+
if (surfaceBridgeState.appServer.logPath) {
|
|
5754
|
+
log(`Server log: ${surfaceBridgeState.appServer.logPath}`);
|
|
5638
5755
|
}
|
|
5639
|
-
if (
|
|
5640
|
-
log(`Auth: ${
|
|
5756
|
+
if (surfaceBridgeState.appServer.auth) {
|
|
5757
|
+
log(`Auth: ${surfaceBridgeState.appServer.auth.mode}`);
|
|
5641
5758
|
log(
|
|
5642
|
-
`Protected: ${redactProtectedUrl(
|
|
5759
|
+
`Protected: ${redactProtectedUrl(surfaceBridgeState.appServer.auth.protectedUrl)}`
|
|
5643
5760
|
);
|
|
5644
|
-
log(`Upstream: ${
|
|
5645
|
-
log(`TUI connect: ${
|
|
5646
|
-
log(`Gateway PID: ${
|
|
5647
|
-
if (
|
|
5648
|
-
log(`Gateway log: ${
|
|
5761
|
+
log(`Upstream: ${surfaceBridgeState.appServer.auth.upstreamUrl}`);
|
|
5762
|
+
log(`TUI connect: ${surfaceBridgeState.appServer.auth.upstreamUrl}`);
|
|
5763
|
+
log(`Gateway PID: ${surfaceBridgeState.appServer.auth.gatewayPid ?? "-"}`);
|
|
5764
|
+
if (surfaceBridgeState.appServer.auth.gatewayLogPath) {
|
|
5765
|
+
log(`Gateway log: ${surfaceBridgeState.appServer.auth.gatewayLogPath}`);
|
|
5649
5766
|
}
|
|
5650
|
-
} else if (
|
|
5767
|
+
} else if (surfaceBridgeState.appServer.managed) {
|
|
5651
5768
|
log(`Auth: none (--no-auth)`);
|
|
5652
|
-
log(`TUI connect: ${
|
|
5769
|
+
log(`TUI connect: ${surfaceBridgeState.appServer.url}`);
|
|
5653
5770
|
}
|
|
5654
5771
|
}
|
|
5655
5772
|
}
|
|
@@ -5657,6 +5774,11 @@ function bridgeStatusOne(identifier) {
|
|
|
5657
5774
|
if (transition) {
|
|
5658
5775
|
log(`Transition: ${transition}`);
|
|
5659
5776
|
}
|
|
5777
|
+
if (liveDispatch) {
|
|
5778
|
+
log(
|
|
5779
|
+
`Drift: fresh bridge-dispatch heartbeat from PID ${liveDispatch.bridgePid} without bridge pid state`
|
|
5780
|
+
);
|
|
5781
|
+
}
|
|
5660
5782
|
log("");
|
|
5661
5783
|
return {
|
|
5662
5784
|
ok: true,
|
|
@@ -5686,14 +5808,14 @@ function bridgeStatusOne(identifier) {
|
|
|
5686
5808
|
lastDispatchAt: session.lastDispatchAt
|
|
5687
5809
|
},
|
|
5688
5810
|
bridgeMode: inst.bridgeMode,
|
|
5689
|
-
pid:
|
|
5811
|
+
pid: surfaceBridgeState?.pid ?? null,
|
|
5690
5812
|
port: inst.port,
|
|
5691
5813
|
lastHeartbeat: heartbeat,
|
|
5692
5814
|
threadId: runtimeHeartbeat?.threadId ?? null,
|
|
5693
5815
|
threadCwd: runtimeHeartbeat?.threadCwd ?? null,
|
|
5694
5816
|
savedThreadId: savedThread?.threadId ?? null,
|
|
5695
5817
|
savedThreadCwd: savedThread?.cwd ?? null,
|
|
5696
|
-
appServer:
|
|
5818
|
+
appServer: surfaceBridgeState?.appServer ?? null
|
|
5697
5819
|
}
|
|
5698
5820
|
};
|
|
5699
5821
|
}
|
|
@@ -5702,6 +5824,7 @@ var init_bridge_status = __esm({
|
|
|
5702
5824
|
"use strict";
|
|
5703
5825
|
init_state();
|
|
5704
5826
|
init_bridge();
|
|
5827
|
+
init_health_monitor();
|
|
5705
5828
|
init_config();
|
|
5706
5829
|
init_utils();
|
|
5707
5830
|
init_bridge_helpers();
|
|
@@ -5796,7 +5919,23 @@ function bridgeTuiOne(identifier) {
|
|
|
5796
5919
|
runtimeHeartbeat?.threadCwd,
|
|
5797
5920
|
savedThread?.cwd
|
|
5798
5921
|
);
|
|
5799
|
-
const
|
|
5922
|
+
const attachEnv = {
|
|
5923
|
+
TAP_BRIDGE_INSTANCE_ID: instanceId,
|
|
5924
|
+
TAP_AGENT_ID: instanceId,
|
|
5925
|
+
TAP_COMMS_DIR: resolvedConfig.commsDir,
|
|
5926
|
+
TAP_STATE_DIR: stateDir,
|
|
5927
|
+
TAP_RUNTIME_STATE_DIR: bridgeState?.runtimeStateDir ?? getBridgeRuntimeStateDir(repoRoot, instanceId),
|
|
5928
|
+
TAP_REPO_ROOT: repoRoot
|
|
5929
|
+
};
|
|
5930
|
+
if (typeof inst.agentName === "string" && inst.agentName.trim()) {
|
|
5931
|
+
attachEnv.TAP_AGENT_NAME = inst.agentName;
|
|
5932
|
+
attachEnv.CODEX_TAP_AGENT_NAME = inst.agentName;
|
|
5933
|
+
}
|
|
5934
|
+
const attachCommand = formatCodexTuiAttachCommand(
|
|
5935
|
+
tuiConnectUrl,
|
|
5936
|
+
attachCwd,
|
|
5937
|
+
attachEnv
|
|
5938
|
+
);
|
|
5800
5939
|
const warnings = appServer.auth != null ? [
|
|
5801
5940
|
"Use the upstream TUI URL, not the protected gateway URL. The protected URL is bridge-only."
|
|
5802
5941
|
] : [];
|
|
@@ -5821,6 +5960,7 @@ function bridgeTuiOne(identifier) {
|
|
|
5821
5960
|
tuiConnectUrl,
|
|
5822
5961
|
attachCwd,
|
|
5823
5962
|
attachCommand,
|
|
5963
|
+
attachEnv,
|
|
5824
5964
|
appServer
|
|
5825
5965
|
}
|
|
5826
5966
|
};
|
|
@@ -6856,8 +6996,8 @@ init_dashboard();
|
|
|
6856
6996
|
init_utils();
|
|
6857
6997
|
init_config();
|
|
6858
6998
|
init_state();
|
|
6859
|
-
import * as
|
|
6860
|
-
import * as
|
|
6999
|
+
import * as fs27 from "fs";
|
|
7000
|
+
import * as path30 from "path";
|
|
6861
7001
|
function getDashboardSnapshot(options) {
|
|
6862
7002
|
const repoRoot = options?.repoRoot ?? findRepoRoot();
|
|
6863
7003
|
return collectDashboardSnapshot(repoRoot, options?.commsDir);
|
|
@@ -6919,9 +7059,9 @@ function getHealthReport(options) {
|
|
|
6919
7059
|
}
|
|
6920
7060
|
}
|
|
6921
7061
|
}
|
|
6922
|
-
const tmpDir =
|
|
6923
|
-
if (
|
|
6924
|
-
for (const dir of
|
|
7062
|
+
const tmpDir = path30.join(repoRoot, ".tmp");
|
|
7063
|
+
if (fs27.existsSync(tmpDir)) {
|
|
7064
|
+
for (const dir of fs27.readdirSync(tmpDir)) {
|
|
6925
7065
|
if (!dir.startsWith("codex-app-server-bridge")) continue;
|
|
6926
7066
|
const suffix = dir.replace("codex-app-server-bridge-", "");
|
|
6927
7067
|
if (activeMatchers.size > 0) {
|
|
@@ -6934,10 +7074,10 @@ function getHealthReport(options) {
|
|
|
6934
7074
|
}
|
|
6935
7075
|
if (!matched) continue;
|
|
6936
7076
|
}
|
|
6937
|
-
const hsPath =
|
|
6938
|
-
if (!
|
|
7077
|
+
const hsPath = path30.join(tmpDir, dir, "headless-state.json");
|
|
7078
|
+
if (!fs27.existsSync(hsPath)) continue;
|
|
6939
7079
|
try {
|
|
6940
|
-
const hs = JSON.parse(
|
|
7080
|
+
const hs = JSON.parse(fs27.readFileSync(hsPath, "utf-8"));
|
|
6941
7081
|
headlessStates.push({ instanceDir: dir, ...hs });
|
|
6942
7082
|
} catch {
|
|
6943
7083
|
}
|