@rynx-ai/runtime 0.1.11-beta.42 → 0.1.11-beta.44
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/dist/host.d.ts +5 -4
- package/dist/host.js +15 -7
- package/dist/runner/child.d.ts +8 -0
- package/dist/runner/child.js +149 -10
- package/package.json +2 -2
package/dist/host.d.ts
CHANGED
|
@@ -275,8 +275,8 @@ export declare class LocalAgentHost implements CodexCapabilities {
|
|
|
275
275
|
/** Structured phase + concrete cause used by the runner wire protocol. */
|
|
276
276
|
liveSessionFailure(localThreadId: string): LiveSessionFailure | undefined;
|
|
277
277
|
/** Publish the background TUI/thread discovery failure so an executor
|
|
278
|
-
* already waiting in
|
|
279
|
-
*
|
|
278
|
+
* already waiting in its runtime-specific bridge window exits immediately
|
|
279
|
+
* with the exact discovery cause. */
|
|
280
280
|
failLiveStartup(localThreadId: string, error: Error): boolean;
|
|
281
281
|
/**
|
|
282
282
|
* Inject a user turn into a session's live codex thread — reference implementation's
|
|
@@ -288,8 +288,9 @@ export declare class LocalAgentHost implements CodexCapabilities {
|
|
|
288
288
|
* Returns an {@link InjectResult}: `notLive` when this session has no live
|
|
289
289
|
* forwarder (caller may use the run path); `notReady`/`failed` are hard errors
|
|
290
290
|
* the caller reports WITHOUT re-running (re-running double-writes alongside the
|
|
291
|
-
* forwarder). Park
|
|
292
|
-
*
|
|
291
|
+
* forwarder). Park until the runtime's discovery window expires, aligning
|
|
292
|
+
* reference implementation's executor waiting for the bridge instead of a
|
|
293
|
+
* short race that falls back to a second output path.
|
|
293
294
|
*/
|
|
294
295
|
injectMessage(localThreadId: string, input: RuntimeUserInput | string, options?: RuntimeTurnOptions): Promise<InjectResult>;
|
|
295
296
|
/**
|
package/dist/host.js
CHANGED
|
@@ -208,6 +208,9 @@ export class SpawnCodexCommandRunner {
|
|
|
208
208
|
const CONTEXT_WARN_RATIO = 0.8;
|
|
209
209
|
/** Wait for native bridge/thread binding before injection gives up. */
|
|
210
210
|
const CODEX_BRIDGE_READY_TIMEOUT_MS = 60_000;
|
|
211
|
+
/** Match RunnerSession's hard cap when Traex is visibly updating. Its ordinary
|
|
212
|
+
* 30-second startup failure still resolves readiness before this deadline. */
|
|
213
|
+
const TRAEX_BRIDGE_READY_TIMEOUT_MS = 2 * 60_000;
|
|
211
214
|
function providerPluginSkillName(namespace, name) {
|
|
212
215
|
const candidate = `${namespace}-${name}`;
|
|
213
216
|
if (candidate.length <= 128)
|
|
@@ -1769,8 +1772,8 @@ export class LocalAgentHost {
|
|
|
1769
1772
|
: undefined;
|
|
1770
1773
|
}
|
|
1771
1774
|
/** Publish the background TUI/thread discovery failure so an executor
|
|
1772
|
-
* already waiting in
|
|
1773
|
-
*
|
|
1775
|
+
* already waiting in its runtime-specific bridge window exits immediately
|
|
1776
|
+
* with the exact discovery cause. */
|
|
1774
1777
|
failLiveStartup(localThreadId, error) {
|
|
1775
1778
|
const live = this.liveSessions.get(localThreadId);
|
|
1776
1779
|
if (!live || live.threadId || live.stopped)
|
|
@@ -1793,8 +1796,9 @@ export class LocalAgentHost {
|
|
|
1793
1796
|
* Returns an {@link InjectResult}: `notLive` when this session has no live
|
|
1794
1797
|
* forwarder (caller may use the run path); `notReady`/`failed` are hard errors
|
|
1795
1798
|
* the caller reports WITHOUT re-running (re-running double-writes alongside the
|
|
1796
|
-
* forwarder). Park
|
|
1797
|
-
*
|
|
1799
|
+
* forwarder). Park until the runtime's discovery window expires, aligning
|
|
1800
|
+
* reference implementation's executor waiting for the bridge instead of a
|
|
1801
|
+
* short race that falls back to a second output path.
|
|
1798
1802
|
*/
|
|
1799
1803
|
async injectMessage(localThreadId, input, options) {
|
|
1800
1804
|
const runtimeInput = typeof input === "string"
|
|
@@ -1853,9 +1857,13 @@ export class LocalAgentHost {
|
|
|
1853
1857
|
const run = live.injectLock.then(async () => {
|
|
1854
1858
|
if (live.rotationPending || live.stopped)
|
|
1855
1859
|
return { outcome: "failed" };
|
|
1856
|
-
// Park until the thread binds
|
|
1857
|
-
//
|
|
1858
|
-
|
|
1860
|
+
// Park until the thread binds, not a short race that lets the caller
|
|
1861
|
+
// re-run on a second path. Traex gets the update-aware Runner deadline;
|
|
1862
|
+
// its ordinary 30s startup failure still wakes this wait immediately.
|
|
1863
|
+
const readyTimeoutMs = live.runtime === "traex"
|
|
1864
|
+
? TRAEX_BRIDGE_READY_TIMEOUT_MS
|
|
1865
|
+
: CODEX_BRIDGE_READY_TIMEOUT_MS;
|
|
1866
|
+
const bound = await this.waitLiveReady(localThreadId, readyTimeoutMs);
|
|
1859
1867
|
const threadId = live.threadId ?? live.forwarder.threadId();
|
|
1860
1868
|
if (!bound || !threadId)
|
|
1861
1869
|
return { outcome: "notReady" };
|
package/dist/runner/child.d.ts
CHANGED
|
@@ -97,6 +97,8 @@ export declare class RunnerSession {
|
|
|
97
97
|
private readonly attachmentRoles;
|
|
98
98
|
private readonly traexStartupWatchers;
|
|
99
99
|
private readonly traexStartupGates;
|
|
100
|
+
private readonly traexUpdateWatchers;
|
|
101
|
+
private readonly traexStartupUpdateActivity;
|
|
100
102
|
private readonly codexStartupMonitors;
|
|
101
103
|
private readonly terminalWatchers;
|
|
102
104
|
/** Opens are async; a close received before attach resolves tombstones the id. */
|
|
@@ -153,6 +155,7 @@ export declare class RunnerSession {
|
|
|
153
155
|
*/
|
|
154
156
|
private ensureLive;
|
|
155
157
|
private monitorCodexThreadStartup;
|
|
158
|
+
private waitForTraexThreadStartup;
|
|
156
159
|
/** Discovery failure is terminal for this partial native launch. Publish the
|
|
157
160
|
* exact cause first so an in-flight injection wakes, then drop the observer
|
|
158
161
|
* and TUI so a later task retry creates a clean launch instead of reusing an
|
|
@@ -168,6 +171,11 @@ export declare class RunnerSession {
|
|
|
168
171
|
private launchCodexPane;
|
|
169
172
|
private watchNativeTerminal;
|
|
170
173
|
private cancelTraexStartupWatcher;
|
|
174
|
+
private cancelTraexUpdateWatcher;
|
|
175
|
+
/** Observe update-only startup screens independently from prompt handling.
|
|
176
|
+
* The low-frequency capture spans the full normal discovery window and only
|
|
177
|
+
* remains alive longer after a positively identified update. */
|
|
178
|
+
private watchTraexStartupUpdates;
|
|
171
179
|
private skipTraexStartupPrompts;
|
|
172
180
|
private stopLive;
|
|
173
181
|
/** Stop event forwarding, kill native terminals/hooks, then synchronously
|
package/dist/runner/child.js
CHANGED
|
@@ -18,6 +18,10 @@ import { RunnerTransportWriteError, } from "./transport.js";
|
|
|
18
18
|
const TERMINAL_PREPARATION_TTL_MS = 30_000;
|
|
19
19
|
/** Maximum time for a fresh Codex-lineage TUI to publish its native thread. */
|
|
20
20
|
const CODEX_THREAD_START_TIMEOUT_MS = 30_000;
|
|
21
|
+
/** Traex may spend most of the normal discovery window installing an update.
|
|
22
|
+
* Keep one fresh discovery window after visible update activity, but never let
|
|
23
|
+
* a stuck updater hold the partial native launch indefinitely. */
|
|
24
|
+
const TRAEX_UPDATE_THREAD_START_MAX_MS = 2 * 60_000;
|
|
21
25
|
function providerDisplayName(runtime) {
|
|
22
26
|
return runtime === "traex" ? "Traex" : runtime === "claude" ? "Claude" : "Codex";
|
|
23
27
|
}
|
|
@@ -51,6 +55,7 @@ function terminalFailureDetail(pane) {
|
|
|
51
55
|
const TRAEX_STARTUP_WATCH_MS = 20_000;
|
|
52
56
|
const TRAEX_STARTUP_DISCOVERY_MS = 5_000;
|
|
53
57
|
const TRAEX_STARTUP_POLL_MS = 100;
|
|
58
|
+
const TRAEX_UPDATE_POLL_MS = 1_000;
|
|
54
59
|
const TRAEX_AUTHORIZATION_POLL_MS = 500;
|
|
55
60
|
const TRAEX_AUTHORIZATION_WAIT_MS = 15 * 60_000;
|
|
56
61
|
const TRAEX_ESCAPE_CONFIRM_MS = 1_000;
|
|
@@ -128,7 +133,14 @@ function isTraexAuthorizationPending(pane) {
|
|
|
128
133
|
pane.includes("press esc to cancel");
|
|
129
134
|
}
|
|
130
135
|
function isTraexStartupActivity(pane) {
|
|
131
|
-
|
|
136
|
+
// The visible pane can include old conversation text. A mounted composer is
|
|
137
|
+
// evidence that an update phrase belongs to history rather than the active
|
|
138
|
+
// startup screen.
|
|
139
|
+
const composerReady = pane.includes("❯") &&
|
|
140
|
+
pane.includes("context ") &&
|
|
141
|
+
pane.includes(" left");
|
|
142
|
+
return !composerReady &&
|
|
143
|
+
(pane.includes("updating traecode cli") || pane.includes("updating trae cli"));
|
|
132
144
|
}
|
|
133
145
|
function isTerminalProtocolResponse(input) {
|
|
134
146
|
// xterm answers terminal queries through the same onData channel as real
|
|
@@ -191,6 +203,8 @@ export class RunnerSession {
|
|
|
191
203
|
attachmentRoles = new Map();
|
|
192
204
|
traexStartupWatchers = new Map();
|
|
193
205
|
traexStartupGates = new Map();
|
|
206
|
+
traexUpdateWatchers = new Map();
|
|
207
|
+
traexStartupUpdateActivity = new Map();
|
|
194
208
|
codexStartupMonitors = new Map();
|
|
195
209
|
terminalWatchers = new Map();
|
|
196
210
|
/** Opens are async; a close received before attach resolves tombstones the id. */
|
|
@@ -1061,8 +1075,8 @@ export class RunnerSession {
|
|
|
1061
1075
|
}
|
|
1062
1076
|
let ready = true;
|
|
1063
1077
|
if (runtime === "codex" || runtime === "traex") {
|
|
1064
|
-
// Discover thread/started in the background
|
|
1065
|
-
//
|
|
1078
|
+
// Discover thread/started in the background while injection waits for
|
|
1079
|
+
// either bridge readiness or the runtime-specific startup deadline.
|
|
1066
1080
|
// Do not serialize the two waits here.
|
|
1067
1081
|
this.monitorCodexThreadStartup(msg.localThreadId, runtime, provider);
|
|
1068
1082
|
}
|
|
@@ -1117,12 +1131,20 @@ export class RunnerSession {
|
|
|
1117
1131
|
this.terminals.get(`${localThreadId}-main`) !== expectedTerminal)
|
|
1118
1132
|
return false;
|
|
1119
1133
|
this.codexStartupMonitors.delete(localThreadId);
|
|
1134
|
+
if (runtime === "traex") {
|
|
1135
|
+
this.cancelTraexUpdateWatcher(localThreadId);
|
|
1136
|
+
this.traexStartupUpdateActivity.delete(localThreadId);
|
|
1137
|
+
}
|
|
1120
1138
|
return true;
|
|
1121
1139
|
};
|
|
1122
|
-
|
|
1123
|
-
if (ready) {
|
|
1140
|
+
const handleResult = (result) => {
|
|
1141
|
+
if (result.ready) {
|
|
1124
1142
|
if (this.codexStartupMonitors.get(localThreadId) === monitor) {
|
|
1125
1143
|
this.codexStartupMonitors.delete(localThreadId);
|
|
1144
|
+
if (runtime === "traex") {
|
|
1145
|
+
this.cancelTraexUpdateWatcher(localThreadId);
|
|
1146
|
+
this.traexStartupUpdateActivity.delete(localThreadId);
|
|
1147
|
+
}
|
|
1126
1148
|
}
|
|
1127
1149
|
return;
|
|
1128
1150
|
}
|
|
@@ -1142,16 +1164,81 @@ export class RunnerSession {
|
|
|
1142
1164
|
const detail = provider.liveSessionError?.(localThreadId)
|
|
1143
1165
|
?? (paneFailure
|
|
1144
1166
|
? `${providerDisplayName(runtime)} Terminal exited before native session discovery: ${paneFailure}`
|
|
1145
|
-
:
|
|
1167
|
+
: result.updateObserved
|
|
1168
|
+
? `Traex TUI did not publish thread/started before its update-aware startup deadline (${Math.ceil(result.elapsedMs / 1_000)}s elapsed)`
|
|
1169
|
+
: `${runtime === "traex" ? "Traex" : "Codex"} TUI did not publish thread/started within ${CODEX_THREAD_START_TIMEOUT_MS / 1_000}s after app-server and observer readiness`);
|
|
1146
1170
|
this.failCodexThreadStartup(localThreadId, provider, new AgentRuntimeError(detail, 503, paneFailure
|
|
1147
1171
|
? "native_terminal_exited_before_session"
|
|
1148
1172
|
: "native_thread_discovery_timeout"), expectedTerminal);
|
|
1149
|
-
}
|
|
1173
|
+
};
|
|
1174
|
+
const handleError = (error) => {
|
|
1150
1175
|
if (!claimCurrentLaunch())
|
|
1151
1176
|
return;
|
|
1152
1177
|
this.failCodexThreadStartup(localThreadId, provider, error instanceof AgentRuntimeError
|
|
1153
1178
|
? error
|
|
1154
1179
|
: nativePhaseError(runtime, "native_thread_discovery_failed", "native session discovery failed", error), expectedTerminal);
|
|
1180
|
+
};
|
|
1181
|
+
if (runtime === "traex") {
|
|
1182
|
+
void this.waitForTraexThreadStartup(localThreadId, provider, expectedTerminal, monitor).then(handleResult).catch(handleError);
|
|
1183
|
+
return;
|
|
1184
|
+
}
|
|
1185
|
+
void provider.waitLiveReady(localThreadId, CODEX_THREAD_START_TIMEOUT_MS).then((ready) => {
|
|
1186
|
+
handleResult({
|
|
1187
|
+
ready,
|
|
1188
|
+
updateObserved: false,
|
|
1189
|
+
elapsedMs: CODEX_THREAD_START_TIMEOUT_MS,
|
|
1190
|
+
});
|
|
1191
|
+
}).catch(handleError);
|
|
1192
|
+
}
|
|
1193
|
+
async waitForTraexThreadStartup(localThreadId, provider, expectedTerminal, monitor) {
|
|
1194
|
+
const startedAt = Date.now();
|
|
1195
|
+
const hardDeadline = startedAt + TRAEX_UPDATE_THREAD_START_MAX_MS;
|
|
1196
|
+
let deadline = startedAt + CODEX_THREAD_START_TIMEOUT_MS;
|
|
1197
|
+
let updateObserved = false;
|
|
1198
|
+
const readiness = provider.waitLiveReady(localThreadId, null);
|
|
1199
|
+
return await new Promise((resolve, reject) => {
|
|
1200
|
+
let settled = false;
|
|
1201
|
+
let timer;
|
|
1202
|
+
const finish = (ready, now = Date.now()) => {
|
|
1203
|
+
if (settled)
|
|
1204
|
+
return;
|
|
1205
|
+
settled = true;
|
|
1206
|
+
if (timer)
|
|
1207
|
+
clearTimeout(timer);
|
|
1208
|
+
resolve({ ready, updateObserved, elapsedMs: now - startedAt });
|
|
1209
|
+
};
|
|
1210
|
+
const checkDeadline = () => {
|
|
1211
|
+
if (this.codexStartupMonitors.get(localThreadId) !== monitor ||
|
|
1212
|
+
this.terminals.get(`${localThreadId}-main`) !== expectedTerminal) {
|
|
1213
|
+
finish(false);
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
const now = Date.now();
|
|
1217
|
+
const updateObservedAt = this.traexStartupUpdateActivity.get(localThreadId);
|
|
1218
|
+
if (updateObservedAt !== undefined) {
|
|
1219
|
+
if (!updateObserved) {
|
|
1220
|
+
console.info(`[runner] session=${localThreadId} Traex startup update detected; extending native thread discovery up to ${TRAEX_UPDATE_THREAD_START_MAX_MS / 1_000}s`);
|
|
1221
|
+
}
|
|
1222
|
+
updateObserved = true;
|
|
1223
|
+
deadline = Math.min(hardDeadline, updateObservedAt + CODEX_THREAD_START_TIMEOUT_MS);
|
|
1224
|
+
}
|
|
1225
|
+
const remainingMs = Math.min(deadline, hardDeadline) - now;
|
|
1226
|
+
if (remainingMs <= 0) {
|
|
1227
|
+
finish(false, now);
|
|
1228
|
+
return;
|
|
1229
|
+
}
|
|
1230
|
+
timer = setTimeout(checkDeadline, Math.min(TRAEX_STARTUP_POLL_MS, remainingMs));
|
|
1231
|
+
timer.unref?.();
|
|
1232
|
+
};
|
|
1233
|
+
void readiness.then((ready) => finish(ready), (error) => {
|
|
1234
|
+
if (settled)
|
|
1235
|
+
return;
|
|
1236
|
+
settled = true;
|
|
1237
|
+
if (timer)
|
|
1238
|
+
clearTimeout(timer);
|
|
1239
|
+
reject(error);
|
|
1240
|
+
});
|
|
1241
|
+
checkDeadline();
|
|
1155
1242
|
});
|
|
1156
1243
|
}
|
|
1157
1244
|
/** Discovery failure is terminal for this partial native launch. Publish the
|
|
@@ -1167,6 +1254,8 @@ export class RunnerSession {
|
|
|
1167
1254
|
clearInterval(watcher);
|
|
1168
1255
|
this.terminalWatchers.delete(localThreadId);
|
|
1169
1256
|
this.cancelTraexStartupWatcher(localThreadId);
|
|
1257
|
+
this.cancelTraexUpdateWatcher(localThreadId);
|
|
1258
|
+
this.traexStartupUpdateActivity.delete(localThreadId);
|
|
1170
1259
|
try {
|
|
1171
1260
|
this.terminals.close(`${localThreadId}-main`, expectedTerminal);
|
|
1172
1261
|
}
|
|
@@ -1272,6 +1361,7 @@ export class RunnerSession {
|
|
|
1272
1361
|
clearInterval(watcher);
|
|
1273
1362
|
this.terminalWatchers.delete(msg.localThreadId);
|
|
1274
1363
|
this.cancelTraexStartupWatcher(msg.localThreadId);
|
|
1364
|
+
this.cancelTraexUpdateWatcher(msg.localThreadId);
|
|
1275
1365
|
for (const [attachId, sessionId] of this.attachmentThreadIds) {
|
|
1276
1366
|
if (sessionId !== msg.localThreadId)
|
|
1277
1367
|
continue;
|
|
@@ -1328,9 +1418,13 @@ export class RunnerSession {
|
|
|
1328
1418
|
: { keepAliveAfterExit: spec.keepAliveAfterExit }),
|
|
1329
1419
|
});
|
|
1330
1420
|
if (spec.skipTraexStartupPrompts) {
|
|
1331
|
-
const watcher = Symbol(localThreadId);
|
|
1421
|
+
const watcher = Symbol(`${localThreadId}:prompts`);
|
|
1422
|
+
const updateWatcher = Symbol(`${localThreadId}:updates`);
|
|
1423
|
+
this.traexStartupUpdateActivity.delete(localThreadId);
|
|
1332
1424
|
this.traexStartupWatchers.set(localThreadId, watcher);
|
|
1425
|
+
this.traexUpdateWatchers.set(localThreadId, updateWatcher);
|
|
1333
1426
|
const gate = this.skipTraexStartupPrompts(localThreadId, term, watcher);
|
|
1427
|
+
void this.watchTraexStartupUpdates(localThreadId, term, updateWatcher);
|
|
1334
1428
|
this.traexStartupGates.set(localThreadId, gate);
|
|
1335
1429
|
void gate.finally(() => {
|
|
1336
1430
|
if (this.traexStartupGates.get(localThreadId) === gate) {
|
|
@@ -1367,6 +1461,7 @@ export class RunnerSession {
|
|
|
1367
1461
|
clearInterval(timer);
|
|
1368
1462
|
this.terminalWatchers.delete(localThreadId);
|
|
1369
1463
|
this.cancelTraexStartupWatcher(localThreadId);
|
|
1464
|
+
this.cancelTraexUpdateWatcher(localThreadId);
|
|
1370
1465
|
const runtime = this.liveRuntimes.get(localThreadId);
|
|
1371
1466
|
const lifecycle = this.terminals.lifecycle(terminalId);
|
|
1372
1467
|
const paneFailure = terminalFailureDetail(terminal.capturePane?.() ?? "");
|
|
@@ -1414,6 +1509,47 @@ export class RunnerSession {
|
|
|
1414
1509
|
if (localThreadId)
|
|
1415
1510
|
this.traexStartupWatchers.delete(localThreadId);
|
|
1416
1511
|
}
|
|
1512
|
+
cancelTraexUpdateWatcher(localThreadId) {
|
|
1513
|
+
if (localThreadId)
|
|
1514
|
+
this.traexUpdateWatchers.delete(localThreadId);
|
|
1515
|
+
}
|
|
1516
|
+
/** Observe update-only startup screens independently from prompt handling.
|
|
1517
|
+
* The low-frequency capture spans the full normal discovery window and only
|
|
1518
|
+
* remains alive longer after a positively identified update. */
|
|
1519
|
+
async watchTraexStartupUpdates(localThreadId, terminal, watcher) {
|
|
1520
|
+
const startedAt = Date.now();
|
|
1521
|
+
const hardDeadline = startedAt + TRAEX_UPDATE_THREAD_START_MAX_MS;
|
|
1522
|
+
let deadline = startedAt + CODEX_THREAD_START_TIMEOUT_MS;
|
|
1523
|
+
const terminalId = `${localThreadId}-main`;
|
|
1524
|
+
while (!this.shuttingDown &&
|
|
1525
|
+
this.traexUpdateWatchers.get(localThreadId) === watcher &&
|
|
1526
|
+
this.terminals.get(terminalId) === terminal) {
|
|
1527
|
+
const now = Date.now();
|
|
1528
|
+
if (now > deadline)
|
|
1529
|
+
break;
|
|
1530
|
+
try {
|
|
1531
|
+
const pane = normalizeTraexPane(terminal.capturePane());
|
|
1532
|
+
if (isTraexStartupActivity(pane)) {
|
|
1533
|
+
this.traexStartupUpdateActivity.set(localThreadId, now);
|
|
1534
|
+
deadline = Math.min(hardDeadline, now + CODEX_THREAD_START_TIMEOUT_MS);
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
catch {
|
|
1538
|
+
// A concurrent terminal teardown owns the lifecycle failure. Keep the
|
|
1539
|
+
// bounded observer alive until that path invalidates this watcher.
|
|
1540
|
+
}
|
|
1541
|
+
const remainingMs = deadline - Date.now();
|
|
1542
|
+
if (remainingMs <= 0)
|
|
1543
|
+
break;
|
|
1544
|
+
await new Promise((resolve) => {
|
|
1545
|
+
const timer = setTimeout(resolve, Math.min(TRAEX_UPDATE_POLL_MS, remainingMs));
|
|
1546
|
+
timer.unref();
|
|
1547
|
+
});
|
|
1548
|
+
}
|
|
1549
|
+
if (this.traexUpdateWatchers.get(localThreadId) === watcher) {
|
|
1550
|
+
this.traexUpdateWatchers.delete(localThreadId);
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1417
1553
|
async skipTraexStartupPrompts(localThreadId, terminal, watcher) {
|
|
1418
1554
|
const prompts = [
|
|
1419
1555
|
{
|
|
@@ -1459,7 +1595,8 @@ export class RunnerSession {
|
|
|
1459
1595
|
const prompt = prompts.find((candidate) => candidate.matches(pane));
|
|
1460
1596
|
const now = Date.now();
|
|
1461
1597
|
const authorizationPending = isTraexAuthorizationPending(pane);
|
|
1462
|
-
|
|
1598
|
+
const updateActive = isTraexStartupActivity(pane);
|
|
1599
|
+
if (updateActive) {
|
|
1463
1600
|
discoveryDeadline = now + TRAEX_STARTUP_DISCOVERY_MS;
|
|
1464
1601
|
}
|
|
1465
1602
|
// Human device authorization routinely takes longer than the normal
|
|
@@ -1483,7 +1620,7 @@ export class RunnerSession {
|
|
|
1483
1620
|
// updater keeps the full startup window because prompts may follow it.
|
|
1484
1621
|
if (now >= discoveryDeadline &&
|
|
1485
1622
|
!authorizationPending &&
|
|
1486
|
-
!
|
|
1623
|
+
!updateActive)
|
|
1487
1624
|
break;
|
|
1488
1625
|
}
|
|
1489
1626
|
else if (!prompt.requiresEscapeConfirmation) {
|
|
@@ -1542,6 +1679,8 @@ export class RunnerSession {
|
|
|
1542
1679
|
clearInterval(timer);
|
|
1543
1680
|
this.terminalWatchers.clear();
|
|
1544
1681
|
this.codexStartupMonitors.clear();
|
|
1682
|
+
this.traexUpdateWatchers.clear();
|
|
1683
|
+
this.traexStartupUpdateActivity.clear();
|
|
1545
1684
|
for (const id of this.liveIds) {
|
|
1546
1685
|
this.liveProvider.stopLiveCodexSession?.(id, {
|
|
1547
1686
|
deferClaudeInteractionCleanup: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rynx-ai/runtime",
|
|
3
|
-
"version": "0.1.11-beta.
|
|
3
|
+
"version": "0.1.11-beta.44",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/rynx-ai/rynx.git",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"smol-toml": "1.7.1",
|
|
28
28
|
"ws": "^8.21.0",
|
|
29
|
-
"@rynx-ai/core": "0.1.11-beta.
|
|
29
|
+
"@rynx-ai/core": "0.1.11-beta.44"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/ws": "^8.18.1"
|