@rynx-ai/runtime 0.1.11-beta.20 → 0.1.11-beta.21
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/claude/native-integration.d.ts +23 -1
- package/dist/claude/native-integration.js +69 -6
- package/dist/claude/session-status.d.ts +39 -0
- package/dist/claude/session-status.js +163 -0
- package/dist/codex-app-server/forwarder.d.ts +33 -2
- package/dist/codex-app-server/forwarder.js +175 -16
- package/dist/codex-app-server/mapping.d.ts +2 -0
- package/dist/codex-app-server/mapping.js +97 -23
- package/dist/codex-app-server/protocol.d.ts +1 -1
- package/dist/host.d.ts +3 -2
- package/dist/host.js +111 -90
- package/dist/runner/child.js +1 -1
- package/dist/runner/manager.d.ts +26 -11
- package/dist/runner/manager.js +99 -30
- package/dist/runner/protocol.d.ts +5 -11
- package/dist/terminal/tmux.d.ts +15 -0
- package/dist/terminal/tmux.js +50 -0
- package/package.json +2 -2
package/dist/terminal/tmux.d.ts
CHANGED
|
@@ -49,6 +49,19 @@ export declare function resolveTmuxBin(explicit?: string, env?: NodeJS.ProcessEn
|
|
|
49
49
|
* shutdown uses the same mapping when the runner child is too wedged to clean
|
|
50
50
|
* up its own tmux server. */
|
|
51
51
|
export declare function tmuxSocketPath(name: string): string;
|
|
52
|
+
/** Read tmux's own output-activity clock for a private terminal window.
|
|
53
|
+
*
|
|
54
|
+
* `#{window_activity}` is an epoch timestamp updated by tmux whenever the pane
|
|
55
|
+
* emits bytes. It is deliberately queried out-of-process rather than inferred
|
|
56
|
+
* from Rynx's forwarded PTY stream: the forwarder/status path is exactly what
|
|
57
|
+
* may have stalled when the idle reaper needs an independent liveness signal.
|
|
58
|
+
* Missing servers, command failures, timeouts, and unparseable output are all
|
|
59
|
+
* treated as unknown (`null`). */
|
|
60
|
+
export declare function tmuxWindowActivityAt(name: string, tmuxBin?: string): Promise<number | null>;
|
|
61
|
+
/** Whether tmux itself reports an attached client for this private terminal.
|
|
62
|
+
* This remains authoritative if a parent-side attachment bookkeeping edge was
|
|
63
|
+
* missed during a transport failure. */
|
|
64
|
+
export declare function tmuxHasAttachedClient(name: string, tmuxBin?: string): Promise<boolean>;
|
|
52
65
|
/** Kill one private tmux server and verify it no longer answers. Missing
|
|
53
66
|
* sockets are already stopped; an existing socket with an unusable tmux
|
|
54
67
|
* command is unproven and returns false. */
|
|
@@ -113,6 +126,8 @@ export declare class TmuxTerminal {
|
|
|
113
126
|
* terminal appears "stuck"). reference implementation's `_tmux_session_alive` uses an async
|
|
114
127
|
* subprocess + timeout for exactly this reason. */
|
|
115
128
|
isAliveAsync(): Promise<boolean>;
|
|
129
|
+
/** PID of the process currently owning the pane. */
|
|
130
|
+
panePid(): number | undefined;
|
|
116
131
|
/** Type literal text into the pane (agent injection / co-drive from a
|
|
117
132
|
* non-PTY caller). `-l` sends the text literally rather than as key names. */
|
|
118
133
|
sendKeys(text: string): void;
|
package/dist/terminal/tmux.js
CHANGED
|
@@ -42,6 +42,43 @@ export function tmuxSocketPath(name) {
|
|
|
42
42
|
const key = createHash("sha256").update(name).digest("hex").slice(0, 16);
|
|
43
43
|
return join(tmpdir(), "rynx-term", `${key}.sock`);
|
|
44
44
|
}
|
|
45
|
+
/** Read tmux's own output-activity clock for a private terminal window.
|
|
46
|
+
*
|
|
47
|
+
* `#{window_activity}` is an epoch timestamp updated by tmux whenever the pane
|
|
48
|
+
* emits bytes. It is deliberately queried out-of-process rather than inferred
|
|
49
|
+
* from Rynx's forwarded PTY stream: the forwarder/status path is exactly what
|
|
50
|
+
* may have stalled when the idle reaper needs an independent liveness signal.
|
|
51
|
+
* Missing servers, command failures, timeouts, and unparseable output are all
|
|
52
|
+
* treated as unknown (`null`). */
|
|
53
|
+
export function tmuxWindowActivityAt(name, tmuxBin = resolveTmuxBin()) {
|
|
54
|
+
const socketPath = tmuxSocketPath(name);
|
|
55
|
+
return new Promise((resolve) => {
|
|
56
|
+
execFile(tmuxBin, ["-S", socketPath, "display-message", "-p", "-t", TMUX_TARGET, "#{window_activity}"], { timeout: 2_000 }, (error, stdout) => {
|
|
57
|
+
if (error) {
|
|
58
|
+
resolve(null);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const raw = stdout.toString().trim();
|
|
62
|
+
if (!raw) {
|
|
63
|
+
resolve(null);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const value = Number(raw);
|
|
67
|
+
resolve(Number.isFinite(value) ? value : null);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/** Whether tmux itself reports an attached client for this private terminal.
|
|
72
|
+
* This remains authoritative if a parent-side attachment bookkeeping edge was
|
|
73
|
+
* missed during a transport failure. */
|
|
74
|
+
export function tmuxHasAttachedClient(name, tmuxBin = resolveTmuxBin()) {
|
|
75
|
+
const socketPath = tmuxSocketPath(name);
|
|
76
|
+
return new Promise((resolve) => {
|
|
77
|
+
execFile(tmuxBin, ["-S", socketPath, "list-clients", "-t", TMUX_TARGET, "-F", "#{client_name}"], { timeout: 2_000 }, (error, stdout) => {
|
|
78
|
+
resolve(!error && stdout.toString().split("\n").some((line) => line.trim().length > 0));
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
45
82
|
/** Kill one private tmux server and verify it no longer answers. Missing
|
|
46
83
|
* sockets are already stopped; an existing socket with an unusable tmux
|
|
47
84
|
* command is unproven and returns false. */
|
|
@@ -281,6 +318,19 @@ export class TmuxTerminal {
|
|
|
281
318
|
});
|
|
282
319
|
});
|
|
283
320
|
}
|
|
321
|
+
/** PID of the process currently owning the pane. */
|
|
322
|
+
panePid() {
|
|
323
|
+
if (!this.started)
|
|
324
|
+
return undefined;
|
|
325
|
+
try {
|
|
326
|
+
const value = execFileSync(this.tmuxBin, [...this.base(), "list-panes", "-t", TMUX_TARGET, "-F", "#{pane_pid}"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim().split(/\s+/)[0];
|
|
327
|
+
const pid = Number(value);
|
|
328
|
+
return Number.isSafeInteger(pid) && pid > 0 ? pid : undefined;
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
return undefined;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
284
334
|
/** Type literal text into the pane (agent injection / co-drive from a
|
|
285
335
|
* non-PTY caller). `-l` sends the text literally rather than as key names. */
|
|
286
336
|
sendKeys(text) {
|
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.21",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/rynx-ai/rynx.git",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"node-pty": "1.2.0-beta.15",
|
|
28
28
|
"smol-toml": "1.7.1",
|
|
29
29
|
"ws": "^8.21.0",
|
|
30
|
-
"@rynx-ai/core": "0.1.11-beta.
|
|
30
|
+
"@rynx-ai/core": "0.1.11-beta.21"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/ws": "^8.18.1"
|