@rynx-ai/runtime 0.1.11-beta.4 → 0.1.11-beta.41
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/executor.d.ts +19 -5
- package/dist/claude/executor.js +56 -12
- package/dist/claude/models.d.ts +0 -5
- package/dist/claude/models.js +1 -7
- package/dist/claude/native-bridge.d.ts +103 -1
- package/dist/claude/native-bridge.js +445 -30
- package/dist/claude/native-hook-main.js +81 -1
- package/dist/claude/native-hooks.js +7 -0
- package/dist/claude/native-integration.d.ts +178 -26
- package/dist/claude/native-integration.js +1528 -170
- package/dist/claude/session-status.d.ts +39 -0
- package/dist/claude/session-status.js +163 -0
- package/dist/claude/transcript-clone.d.ts +18 -0
- package/dist/claude/transcript-clone.js +497 -0
- package/dist/claude/transcript.d.ts +27 -4
- package/dist/claude/transcript.js +158 -47
- package/dist/codex-app-server/client.d.ts +10 -6
- package/dist/codex-app-server/client.js +67 -15
- package/dist/codex-app-server/forwarder.d.ts +92 -3
- package/dist/codex-app-server/forwarder.js +532 -57
- package/dist/codex-app-server/mapping.d.ts +3 -6
- package/dist/codex-app-server/mapping.js +206 -36
- package/dist/codex-app-server/mcp-startup.d.ts +13 -0
- package/dist/codex-app-server/mcp-startup.js +63 -0
- package/dist/codex-app-server/process-registry.d.ts +36 -0
- package/dist/codex-app-server/process-registry.js +320 -0
- package/dist/codex-app-server/protocol.d.ts +64 -7
- package/dist/codex-app-server/ws-channel.d.ts +7 -0
- package/dist/codex-app-server/ws-channel.js +104 -28
- package/dist/codex-home.d.ts +35 -3
- package/dist/codex-home.js +323 -18
- package/dist/codex-session-store.d.ts +23 -0
- package/dist/codex-session-store.js +21 -0
- package/dist/host.d.ts +103 -46
- package/dist/host.js +1988 -634
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/input-resources.d.ts +4 -0
- package/dist/input-resources.js +21 -5
- package/dist/models-catalog.d.ts +2 -1
- package/dist/models-catalog.js +94 -6
- package/dist/runner/child.d.ts +97 -28
- package/dist/runner/child.js +1486 -100
- package/dist/runner/manager.d.ts +110 -29
- package/dist/runner/manager.js +1481 -246
- package/dist/runner/protocol.d.ts +212 -24
- package/dist/runner/protocol.js +5 -0
- package/dist/runner/startup-policy.d.ts +7 -0
- package/dist/runner/startup-policy.js +10 -0
- package/dist/runner/transport.d.ts +18 -2
- package/dist/runner/transport.js +82 -3
- package/dist/runner-main.js +8 -3
- package/dist/terminal/claude-tui.d.ts +3 -1
- package/dist/terminal/claude-tui.js +3 -1
- package/dist/terminal/codex-tui.d.ts +4 -0
- package/dist/terminal/codex-tui.js +5 -0
- package/dist/terminal/control-parser.d.ts +39 -0
- package/dist/terminal/control-parser.js +172 -0
- package/dist/terminal/registry.d.ts +18 -15
- package/dist/terminal/registry.js +44 -23
- package/dist/terminal/spool.d.ts +47 -0
- package/dist/terminal/spool.js +231 -0
- package/dist/terminal/tmux.d.ts +126 -74
- package/dist/terminal/tmux.js +807 -211
- package/package.json +4 -4
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type ClaudeRunnerStatus = "running" | "idle";
|
|
2
|
+
export interface ClaudeSessionStatus {
|
|
3
|
+
runnerStatus: ClaudeRunnerStatus;
|
|
4
|
+
rawStatus: string;
|
|
5
|
+
statusUpdatedAt?: number;
|
|
6
|
+
blockedOn?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function claudeSessionsDir(configDir?: string): string;
|
|
9
|
+
export declare function resolveClaudeSessionStatusFile({ panePid, expectedSessionId, configDir, now, }: {
|
|
10
|
+
panePid?: number;
|
|
11
|
+
expectedSessionId?: string;
|
|
12
|
+
configDir?: string;
|
|
13
|
+
now?: number;
|
|
14
|
+
}): string | undefined;
|
|
15
|
+
export declare function readClaudeSessionStatus(path: string): ClaudeSessionStatus | undefined;
|
|
16
|
+
export declare class ClaudeSessionStatusPoller {
|
|
17
|
+
private readonly options;
|
|
18
|
+
private path?;
|
|
19
|
+
private attempts;
|
|
20
|
+
private exhausted;
|
|
21
|
+
private lastMtime?;
|
|
22
|
+
private lastEdge?;
|
|
23
|
+
private lastStatus?;
|
|
24
|
+
constructor(options: {
|
|
25
|
+
onStatus: (status: ClaudeSessionStatus) => void;
|
|
26
|
+
panePid: () => number | undefined;
|
|
27
|
+
sessionId: () => string | undefined;
|
|
28
|
+
configDir?: string;
|
|
29
|
+
maxResolveAttempts?: number;
|
|
30
|
+
now?: () => number;
|
|
31
|
+
});
|
|
32
|
+
get active(): boolean;
|
|
33
|
+
get status(): ClaudeSessionStatus | undefined;
|
|
34
|
+
tick(): void;
|
|
35
|
+
retire(): void;
|
|
36
|
+
resync(): void;
|
|
37
|
+
private tryResolve;
|
|
38
|
+
private readAndPublish;
|
|
39
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
const STATUS_TO_RUNNER = {
|
|
5
|
+
busy: "running",
|
|
6
|
+
waiting: "running",
|
|
7
|
+
idle: "idle",
|
|
8
|
+
shell: "idle",
|
|
9
|
+
running: "running",
|
|
10
|
+
completed: "idle",
|
|
11
|
+
failed: "idle",
|
|
12
|
+
error: "idle",
|
|
13
|
+
done: "idle",
|
|
14
|
+
};
|
|
15
|
+
const SCAN_FRESHNESS_MS = 120_000;
|
|
16
|
+
const DEFAULT_MAX_RESOLVE_ATTEMPTS = 40;
|
|
17
|
+
function isRecord(value) {
|
|
18
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
19
|
+
}
|
|
20
|
+
function readJsonRecord(path) {
|
|
21
|
+
try {
|
|
22
|
+
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
23
|
+
return isRecord(parsed) ? parsed : undefined;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function matchesSession(record, expectedSessionId) {
|
|
30
|
+
if (record.kind !== "interactive")
|
|
31
|
+
return false;
|
|
32
|
+
return expectedSessionId === undefined || record.sessionId === expectedSessionId;
|
|
33
|
+
}
|
|
34
|
+
export function claudeSessionsDir(configDir = process.env.CLAUDE_CONFIG_DIR?.trim() || join(homedir(), ".claude")) {
|
|
35
|
+
return join(configDir, "sessions");
|
|
36
|
+
}
|
|
37
|
+
export function resolveClaudeSessionStatusFile({ panePid, expectedSessionId, configDir, now = Date.now(), }) {
|
|
38
|
+
const directory = claudeSessionsDir(configDir);
|
|
39
|
+
if (panePid !== undefined) {
|
|
40
|
+
const candidate = join(directory, `${panePid}.json`);
|
|
41
|
+
const record = readJsonRecord(candidate);
|
|
42
|
+
if (record && matchesSession(record, expectedSessionId))
|
|
43
|
+
return candidate;
|
|
44
|
+
}
|
|
45
|
+
if (!expectedSessionId)
|
|
46
|
+
return undefined;
|
|
47
|
+
try {
|
|
48
|
+
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
49
|
+
if (!entry.isFile() || !entry.name.endsWith(".json"))
|
|
50
|
+
continue;
|
|
51
|
+
const candidate = join(directory, entry.name);
|
|
52
|
+
let modifiedAt;
|
|
53
|
+
try {
|
|
54
|
+
modifiedAt = statSync(candidate).mtimeMs;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (now - modifiedAt > SCAN_FRESHNESS_MS)
|
|
60
|
+
continue;
|
|
61
|
+
const record = readJsonRecord(candidate);
|
|
62
|
+
if (record && matchesSession(record, expectedSessionId))
|
|
63
|
+
return candidate;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
export function readClaudeSessionStatus(path) {
|
|
72
|
+
const record = readJsonRecord(path);
|
|
73
|
+
if (!record || typeof record.status !== "string")
|
|
74
|
+
return undefined;
|
|
75
|
+
const runnerStatus = STATUS_TO_RUNNER[record.status];
|
|
76
|
+
if (!runnerStatus)
|
|
77
|
+
return undefined;
|
|
78
|
+
const updatedAt = record.statusUpdatedAt;
|
|
79
|
+
const waitingFor = record.status === "waiting" ? record.waitingFor : undefined;
|
|
80
|
+
return {
|
|
81
|
+
runnerStatus,
|
|
82
|
+
rawStatus: record.status,
|
|
83
|
+
...(Number.isSafeInteger(updatedAt) ? { statusUpdatedAt: updatedAt } : {}),
|
|
84
|
+
...(typeof waitingFor === "string" && waitingFor ? { blockedOn: waitingFor } : {}),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export class ClaudeSessionStatusPoller {
|
|
88
|
+
options;
|
|
89
|
+
path;
|
|
90
|
+
attempts = 0;
|
|
91
|
+
exhausted = false;
|
|
92
|
+
lastMtime;
|
|
93
|
+
lastEdge;
|
|
94
|
+
lastStatus;
|
|
95
|
+
constructor(options) {
|
|
96
|
+
this.options = options;
|
|
97
|
+
}
|
|
98
|
+
get active() {
|
|
99
|
+
return this.path !== undefined && !this.exhausted;
|
|
100
|
+
}
|
|
101
|
+
get status() {
|
|
102
|
+
return this.lastStatus;
|
|
103
|
+
}
|
|
104
|
+
tick() {
|
|
105
|
+
if (this.exhausted)
|
|
106
|
+
return;
|
|
107
|
+
if (!this.path) {
|
|
108
|
+
this.tryResolve();
|
|
109
|
+
if (!this.path)
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
this.readAndPublish();
|
|
113
|
+
}
|
|
114
|
+
retire() {
|
|
115
|
+
this.exhausted = true;
|
|
116
|
+
}
|
|
117
|
+
resync() {
|
|
118
|
+
if (!this.active)
|
|
119
|
+
return;
|
|
120
|
+
this.lastMtime = undefined;
|
|
121
|
+
this.lastEdge = undefined;
|
|
122
|
+
}
|
|
123
|
+
tryResolve() {
|
|
124
|
+
this.attempts += 1;
|
|
125
|
+
this.path = resolveClaudeSessionStatusFile({
|
|
126
|
+
panePid: this.options.panePid(),
|
|
127
|
+
expectedSessionId: this.options.sessionId(),
|
|
128
|
+
...(this.options.configDir ? { configDir: this.options.configDir } : {}),
|
|
129
|
+
now: this.options.now?.() ?? Date.now(),
|
|
130
|
+
});
|
|
131
|
+
if (!this.path &&
|
|
132
|
+
this.attempts >= (this.options.maxResolveAttempts ?? DEFAULT_MAX_RESOLVE_ATTEMPTS)) {
|
|
133
|
+
this.exhausted = true;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
readAndPublish() {
|
|
137
|
+
if (!this.path)
|
|
138
|
+
return;
|
|
139
|
+
let mtime;
|
|
140
|
+
try {
|
|
141
|
+
mtime = statSync(this.path).mtimeMs;
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
this.exhausted = true;
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (this.lastMtime === mtime)
|
|
148
|
+
return;
|
|
149
|
+
this.lastMtime = mtime;
|
|
150
|
+
const status = readClaudeSessionStatus(this.path);
|
|
151
|
+
if (!status) {
|
|
152
|
+
this.lastStatus = undefined;
|
|
153
|
+
this.lastEdge = undefined;
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
this.lastStatus = status;
|
|
157
|
+
const edge = `${status.runnerStatus}\0${status.blockedOn ?? ""}`;
|
|
158
|
+
if (edge === this.lastEdge)
|
|
159
|
+
return;
|
|
160
|
+
this.lastEdge = edge;
|
|
161
|
+
this.options.onStatus(status);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface ClonedClaudeTranscript {
|
|
2
|
+
transcriptPath: string;
|
|
3
|
+
prefixBytes?: number;
|
|
4
|
+
}
|
|
5
|
+
/** Claude names a project's transcript directory by replacing every
|
|
6
|
+
* non-alphanumeric character in its absolute cwd with `-`. */
|
|
7
|
+
export declare function claudeProjectDirectoryName(cwd: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Copy an existing Claude transcript into the target workspace under the
|
|
10
|
+
* target native Session id. The copy is fully committed before Claude starts,
|
|
11
|
+
* so the caller can seed its forwarder at the returned exact byte boundary.
|
|
12
|
+
*/
|
|
13
|
+
export declare function cloneClaudeTranscript({ sourceClaudeSessionId, targetClaudeSessionId, targetCwd, projectsRoot, }: {
|
|
14
|
+
sourceClaudeSessionId: string;
|
|
15
|
+
targetClaudeSessionId: string;
|
|
16
|
+
targetCwd: string;
|
|
17
|
+
projectsRoot?: string;
|
|
18
|
+
}): Promise<ClonedClaudeTranscript | null>;
|