@modelprofile.com/mcp-crossharness 5.3.0 → 5.5.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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.codexappserverclient.d.ts +3 -0
- package/dist_ts/classes.codexappserverclient.js +17 -7
- package/dist_ts/functions.codexunixsocket.d.ts +25 -0
- package/dist_ts/functions.codexunixsocket.js +94 -0
- package/dist_ts/index.d.ts +1 -0
- package/dist_ts/index.js +2 -1
- package/dist_ts/plugins.d.ts +4 -1
- package/dist_ts/plugins.js +5 -2
- package/package.json +5 -5
- package/readme.md +59 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.codexappserverclient.ts +18 -6
- package/ts/functions.codexunixsocket.ts +119 -0
- package/ts/index.ts +1 -0
- package/ts/plugins.ts +4 -1
- package/readme.hints.md +0 -52
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@modelprofile.com/mcp-crossharness',
|
|
6
|
-
version: '5.
|
|
6
|
+
version: '5.5.0',
|
|
7
7
|
description: 'Connection-first MCP server for explicit OpenCode HTTP and Codex WebSocket session servers'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxvQ0FBb0M7SUFDMUMsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLDRGQUE0RjtDQUMxRyxDQUFBIn0=
|
|
@@ -43,6 +43,11 @@ export class CodexAppServerClient {
|
|
|
43
43
|
throw new Error('Codex app-server requires an explicit ws/wss URL without credentials or fragment');
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
+
if (options.transport.type === 'unix' && (typeof options.transport.socketPath !== 'string'
|
|
47
|
+
|| !options.transport.socketPath.startsWith('/')
|
|
48
|
+
|| options.transport.socketPath.includes('\0')
|
|
49
|
+
|| Buffer.byteLength(options.transport.socketPath, 'utf8') > 4096))
|
|
50
|
+
throw new Error('Codex app-server requires an absolute Unix socket path of at most 4096 bytes');
|
|
46
51
|
}
|
|
47
52
|
async connect() {
|
|
48
53
|
if (this.started || this.state === 'closed')
|
|
@@ -50,12 +55,17 @@ export class CodexAppServerClient {
|
|
|
50
55
|
this.started = true;
|
|
51
56
|
try {
|
|
52
57
|
const transport = this.options.transport;
|
|
53
|
-
if (transport.type
|
|
54
|
-
const socket = new plugins.WsWebSocket(transport.url, {
|
|
58
|
+
if (transport.type !== 'stdio') {
|
|
59
|
+
const socket = new plugins.WsWebSocket(transport.type === 'websocket' ? transport.url : 'ws://localhost/', {
|
|
55
60
|
perMessageDeflate: false,
|
|
56
61
|
followRedirects: false,
|
|
57
62
|
maxPayload: this.maxMessageBytes,
|
|
58
|
-
headers: transport.
|
|
63
|
+
headers: transport.type === 'websocket' && transport.token
|
|
64
|
+
? { authorization: `Bearer ${transport.token}` } : {},
|
|
65
|
+
...(transport.type === 'unix' ? {
|
|
66
|
+
// Keep the path out of URL parsing: valid socket names may contain :, # or %.
|
|
67
|
+
createConnection: () => plugins.net.createConnection({ path: transport.socketPath }),
|
|
68
|
+
} : {}),
|
|
59
69
|
});
|
|
60
70
|
this.socket = socket;
|
|
61
71
|
socket.on('message', (data) => this.receive(data.toString()));
|
|
@@ -160,7 +170,7 @@ export class CodexAppServerClient {
|
|
|
160
170
|
this.finishServerRequest(id);
|
|
161
171
|
this.inputBuffer = Buffer.alloc(0);
|
|
162
172
|
const transport = this.options.transport;
|
|
163
|
-
if (transport.type
|
|
173
|
+
if (transport.type !== 'stdio') {
|
|
164
174
|
if (this.socket && this.socket.readyState !== plugins.WsWebSocket.CLOSED)
|
|
165
175
|
this.socket.terminate();
|
|
166
176
|
}
|
|
@@ -201,7 +211,7 @@ export class CodexAppServerClient {
|
|
|
201
211
|
const payload = JSON.stringify(frameArg);
|
|
202
212
|
const payloadBytes = Buffer.byteLength(payload, 'utf8');
|
|
203
213
|
const transport = this.options.transport;
|
|
204
|
-
const buffered = transport.type
|
|
214
|
+
const buffered = transport.type !== 'stdio'
|
|
205
215
|
? this.socket?.bufferedAmount ?? 0 : transport.writable.writableLength;
|
|
206
216
|
if (this.state === 'closed')
|
|
207
217
|
throw new Error('Codex server connection is closed');
|
|
@@ -210,7 +220,7 @@ export class CodexAppServerClient {
|
|
|
210
220
|
this.close(error.message);
|
|
211
221
|
throw error;
|
|
212
222
|
}
|
|
213
|
-
if (transport.type
|
|
223
|
+
if (transport.type !== 'stdio') {
|
|
214
224
|
if (!this.socket || this.socket.readyState !== plugins.WsWebSocket.OPEN) {
|
|
215
225
|
throw new Error('Codex server WebSocket is not open');
|
|
216
226
|
}
|
|
@@ -301,4 +311,4 @@ export class CodexAppServerClient {
|
|
|
301
311
|
return new CodexAppServerRequestError(signalArg.reason instanceof Error ? signalArg.reason.message : 'operation cancelled', dispatchedArg, undefined, { cause: signalArg.reason });
|
|
302
312
|
}
|
|
303
313
|
}
|
|
304
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jb2RleGFwcHNlcnZlcmNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuY29kZXhhcHBzZXJ2ZXJjbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUEwQ3hDLG9GQUFvRjtBQUNwRixNQUFNLE9BQU8sMEJBQTJCLFNBQVEsS0FBSztJQUdqQztJQUNBO0lBSGxCLFlBQ0UsVUFBa0IsRUFDRixVQUFtQixFQUNuQixJQUFhLEVBQzdCLFVBQXlCO1FBRXpCLEtBQUssQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFKZCxlQUFVLEdBQVYsVUFBVSxDQUFTO1FBQ25CLFNBQUksR0FBSixJQUFJLENBQVM7UUFJN0IsSUFBSSxDQUFDLElBQUksR0FBRyw0QkFBNEIsQ0FBQztJQUMzQyxDQUFDO0NBQ0Y7QUFFRCxzR0FBc0c7QUFDdEcsTUFBTSxPQUFPLG9CQUFvQjtJQVlGO0lBWHRCLEtBQUssR0FBMEMsWUFBWSxDQUFDO0lBQzVELGFBQWEsQ0FBVTtJQUN0QixNQUFNLENBQTRDO0lBQ2xELE9BQU8sR0FBRyxLQUFLLENBQUM7SUFDaEIsY0FBYyxHQUFHLENBQUMsQ0FBQztJQUNWLGVBQWUsR0FBRyxJQUFJLEdBQUcsRUFBMkIsQ0FBQztJQUNyRCxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQTZDLENBQUM7SUFDdEUsZUFBZSxDQUFTO0lBQ2pDLFdBQVcsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JCLGdCQUFnQixHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBRXBELFlBQTZCLE9BQXFDO1FBQXJDLFlBQU8sR0FBUCxPQUFPLENBQThCO1FBQ2hFLElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxDQUFDLGVBQWUsSUFB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
|
|
314
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jb2RleGFwcHNlcnZlcmNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuY29kZXhhcHBzZXJ2ZXJjbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUEyQ3hDLG9GQUFvRjtBQUNwRixNQUFNLE9BQU8sMEJBQTJCLFNBQVEsS0FBSztJQUdqQztJQUNBO0lBSGxCLFlBQ0UsVUFBa0IsRUFDRixVQUFtQixFQUNuQixJQUFhLEVBQzdCLFVBQXlCO1FBRXpCLEtBQUssQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFKZCxlQUFVLEdBQVYsVUFBVSxDQUFTO1FBQ25CLFNBQUksR0FBSixJQUFJLENBQVM7UUFJN0IsSUFBSSxDQUFDLElBQUksR0FBRyw0QkFBNEIsQ0FBQztJQUMzQyxDQUFDO0NBQ0Y7QUFFRCxzR0FBc0c7QUFDdEcsTUFBTSxPQUFPLG9CQUFvQjtJQVlGO0lBWHRCLEtBQUssR0FBMEMsWUFBWSxDQUFDO0lBQzVELGFBQWEsQ0FBVTtJQUN0QixNQUFNLENBQTRDO0lBQ2xELE9BQU8sR0FBRyxLQUFLLENBQUM7SUFDaEIsY0FBYyxHQUFHLENBQUMsQ0FBQztJQUNWLGVBQWUsR0FBRyxJQUFJLEdBQUcsRUFBMkIsQ0FBQztJQUNyRCxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQTZDLENBQUM7SUFDdEUsZUFBZSxDQUFTO0lBQ2pDLFdBQVcsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JCLGdCQUFnQixHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBRXBELFlBQTZCLE9BQXFDO1FBQXJDLFlBQU8sR0FBUCxPQUFPLENBQThCO1FBQ2hFLElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxDQUFDLGVBQWUsSUFB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
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex's `--listen unix://PATH` contract since Codex 0.156.0 (codex-rs/app-server-transport,
|
|
3
|
+
* `protected_socket_path`): the socket is bound in the fixed per-user directory
|
|
4
|
+
* `<realpath /tmp>/codex-daemon-<euid>` under the SHA-256 of PATH with its parent canonicalised,
|
|
5
|
+
* and PATH itself is only a symlink to it. Earlier releases bound PATH directly; that layout is
|
|
6
|
+
* not this contract and is refused like any other foreign entry.
|
|
7
|
+
*/
|
|
8
|
+
export interface ICodexUnixSocketOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Codex's per-user socket directory. Defaults to `<realpath /tmp>/codex-daemon-<euid>`, which
|
|
11
|
+
* Codex derives without HOME, TMPDIR or CODEX_HOME; override it only for fixtures.
|
|
12
|
+
*/
|
|
13
|
+
daemonDirectory?: string;
|
|
14
|
+
}
|
|
15
|
+
/** `absent`: nothing exists at the path. `published`: Codex's own alias to a private socket. */
|
|
16
|
+
export type TCodexUnixSocketPublication = 'absent' | 'published';
|
|
17
|
+
/** Where Codex binds the socket it publishes at `socketPathArg`. The parent directory must exist. */
|
|
18
|
+
export declare const codexUnixSocketTarget: (socketPathArg: string, optionsArg?: ICodexUnixSocketOptions) => Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Reports whether Codex has published an app-server socket at `socketPathArg`. Anything present
|
|
21
|
+
* must be exactly Codex's own same-user link to its target, in a parent other users cannot
|
|
22
|
+
* rewrite (Codex's own startup condition), pointing at a same-user socket in a 0700 same-user
|
|
23
|
+
* directory; every other entry throws instead of being connected to.
|
|
24
|
+
*/
|
|
25
|
+
export declare const observeCodexUnixSocket: (socketPathArg: string, optionsArg?: ICodexUnixSocketOptions) => Promise<TCodexUnixSocketPublication>;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import * as helpers from './helpers.js';
|
|
3
|
+
const assertNormalizedAbsolute = (pathArg, messageArg) => {
|
|
4
|
+
if (typeof pathArg !== 'string' || !plugins.path.isAbsolute(pathArg) || pathArg.includes('\0')
|
|
5
|
+
|| plugins.path.normalize(pathArg) !== pathArg) {
|
|
6
|
+
throw new Error(messageArg);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Codex splits PATH into parent and file name with Rust's `Path`, which drops `.` components and
|
|
11
|
+
* has no file name for `..`; a normalized path without a trailing separator splits identically here.
|
|
12
|
+
*/
|
|
13
|
+
const assertSocketPath = (socketPathArg) => {
|
|
14
|
+
const message = 'Codex Unix socket path must be a normalized absolute file path';
|
|
15
|
+
assertNormalizedAbsolute(socketPathArg, message);
|
|
16
|
+
if (socketPathArg.endsWith(plugins.path.sep))
|
|
17
|
+
throw new Error(message);
|
|
18
|
+
};
|
|
19
|
+
/** Codex keys its directory and checks every entry by the effective uid, so this module does too. */
|
|
20
|
+
const effectiveUserId = () => {
|
|
21
|
+
const euid = process.geteuid?.();
|
|
22
|
+
if (euid === undefined)
|
|
23
|
+
throw new Error('Codex Unix socket inspection requires a POSIX effective user id');
|
|
24
|
+
return euid;
|
|
25
|
+
};
|
|
26
|
+
/** A malformed root is a caller error, so it throws whatever exists at the socket path. */
|
|
27
|
+
const assertOptions = (optionsArg) => {
|
|
28
|
+
if (optionsArg.daemonDirectory !== undefined) {
|
|
29
|
+
assertNormalizedAbsolute(optionsArg.daemonDirectory, 'Codex daemon socket directory must be a normalized absolute path');
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const daemonDirectoryFor = async (optionsArg, euidArg) => {
|
|
33
|
+
if (optionsArg.daemonDirectory !== undefined)
|
|
34
|
+
return optionsArg.daemonDirectory;
|
|
35
|
+
return plugins.path.join(await plugins.fs.promises.realpath('/tmp'), `codex-daemon-${euidArg}`);
|
|
36
|
+
};
|
|
37
|
+
const isMissing = (errorArg) => helpers.isRecord(errorArg) && errorArg.code === 'ENOENT';
|
|
38
|
+
/** Where Codex binds the socket it publishes at `socketPathArg`. The parent directory must exist. */
|
|
39
|
+
export const codexUnixSocketTarget = async (socketPathArg, optionsArg = {}) => {
|
|
40
|
+
assertSocketPath(socketPathArg);
|
|
41
|
+
assertOptions(optionsArg);
|
|
42
|
+
const euid = effectiveUserId();
|
|
43
|
+
const directory = await daemonDirectoryFor(optionsArg, euid);
|
|
44
|
+
const canonical = plugins.path.join(await plugins.fs.promises.realpath(plugins.path.dirname(socketPathArg)), plugins.path.basename(socketPathArg));
|
|
45
|
+
return plugins.path.join(directory, plugins.crypto.createHash('sha256').update(canonical).digest('hex'));
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Reports whether Codex has published an app-server socket at `socketPathArg`. Anything present
|
|
49
|
+
* must be exactly Codex's own same-user link to its target, in a parent other users cannot
|
|
50
|
+
* rewrite (Codex's own startup condition), pointing at a same-user socket in a 0700 same-user
|
|
51
|
+
* directory; every other entry throws instead of being connected to.
|
|
52
|
+
*/
|
|
53
|
+
export const observeCodexUnixSocket = async (socketPathArg, optionsArg = {}) => {
|
|
54
|
+
assertSocketPath(socketPathArg);
|
|
55
|
+
assertOptions(optionsArg);
|
|
56
|
+
const euid = effectiveUserId();
|
|
57
|
+
let alias;
|
|
58
|
+
try {
|
|
59
|
+
alias = await plugins.fs.promises.lstat(socketPathArg);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (isMissing(error))
|
|
63
|
+
return 'absent';
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
const target = await codexUnixSocketTarget(socketPathArg, optionsArg);
|
|
67
|
+
if (!alias.isSymbolicLink() || alias.uid !== euid || await plugins.fs.promises.readlink(socketPathArg) !== target) {
|
|
68
|
+
throw new Error('Codex Unix socket path is not the alias Codex publishes');
|
|
69
|
+
}
|
|
70
|
+
const parent = await plugins.fs.promises.stat(plugins.path.dirname(socketPathArg));
|
|
71
|
+
if (!parent.isDirectory() || (parent.uid !== 0 && parent.uid !== euid)
|
|
72
|
+
|| ((parent.mode & 0o022) !== 0 && (parent.mode & 0o1000) === 0)) {
|
|
73
|
+
throw new Error('Codex Unix socket parent directory lets other users replace its entries');
|
|
74
|
+
}
|
|
75
|
+
let directory;
|
|
76
|
+
let socket;
|
|
77
|
+
try {
|
|
78
|
+
directory = await plugins.fs.promises.lstat(plugins.path.dirname(target));
|
|
79
|
+
socket = await plugins.fs.promises.lstat(target);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (isMissing(error))
|
|
83
|
+
throw new Error('Codex Unix socket alias has no socket behind it');
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
if (!directory.isDirectory() || directory.uid !== euid || (directory.mode & 0o777) !== 0o700) {
|
|
87
|
+
throw new Error('Codex Unix socket directory is not private to the current user');
|
|
88
|
+
}
|
|
89
|
+
if (!socket.isSocket() || socket.uid !== euid) {
|
|
90
|
+
throw new Error('Codex Unix socket is not a socket owned by the current user');
|
|
91
|
+
}
|
|
92
|
+
return 'published';
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnVuY3Rpb25zLmNvZGV4dW5peHNvY2tldC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2Z1bmN0aW9ucy5jb2RleHVuaXhzb2NrZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFvQnhDLE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxPQUFlLEVBQUUsVUFBa0IsRUFBUSxFQUFFO0lBQzdFLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7V0FDekYsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLEtBQUssT0FBTyxFQUFFLENBQUM7UUFDakQsTUFBTSxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUM5QixDQUFDO0FBQ0gsQ0FBQyxDQUFDO0FBRUY7OztHQUdHO0FBQ0gsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLGFBQXFCLEVBQVEsRUFBRTtJQUN2RCxNQUFNLE9BQU8sR0FBRyxnRUFBZ0UsQ0FBQztJQUNqRix3QkFBd0IsQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDakQsSUFBSSxhQUFhLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUN6RSxDQUFDLENBQUM7QUFFRixxR0FBcUc7QUFDckcsTUFBTSxlQUFlLEdBQUcsR0FBVyxFQUFFO0lBQ25DLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO0lBQ2pDLElBQUksSUFBSSxLQUFLLFNBQVM7UUFBRSxNQUFNLElBQUksS0FB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
|
package/dist_ts/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './interfaces.js';
|
|
2
2
|
export * from './classes.codexappserverclient.js';
|
|
3
|
+
export * from './functions.codexunixsocket.js';
|
|
3
4
|
export * from './classes.connectionregistry.js';
|
|
4
5
|
export * from './classes.dispatchregistry.js';
|
|
5
6
|
export * from './classes.mcptoolregistrar.js';
|
package/dist_ts/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './interfaces.js';
|
|
2
2
|
export * from './classes.codexappserverclient.js';
|
|
3
|
+
export * from './functions.codexunixsocket.js';
|
|
3
4
|
export * from './classes.connectionregistry.js';
|
|
4
5
|
export * from './classes.dispatchregistry.js';
|
|
5
6
|
export * from './classes.mcptoolregistrar.js';
|
|
@@ -8,4 +9,4 @@ import { CrossHarnessMcpServer } from './classes.mcpserver.js';
|
|
|
8
9
|
export const runCli = async () => {
|
|
9
10
|
await new CrossHarnessMcpServer().start();
|
|
10
11
|
};
|
|
11
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMsbUNBQW1DLENBQUM7QUFDbEQsY0FBYyxnQ0FBZ0MsQ0FBQztBQUMvQyxjQUFjLGlDQUFpQyxDQUFDO0FBQ2hELGNBQWMsK0JBQStCLENBQUM7QUFDOUMsY0FBYywrQkFBK0IsQ0FBQztBQUM5QyxjQUFjLHdCQUF3QixDQUFDO0FBRXZDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRS9ELE1BQU0sQ0FBQyxNQUFNLE1BQU0sR0FBRyxLQUFLLElBQW1CLEVBQUU7SUFDOUMsTUFBTSxJQUFJLHFCQUFxQixFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDNUMsQ0FBQyxDQUFDIn0=
|
package/dist_ts/plugins.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as crypto from 'node:crypto';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
2
3
|
import * as http from 'node:http';
|
|
4
|
+
import * as net from 'node:net';
|
|
5
|
+
import * as path from 'node:path';
|
|
3
6
|
import * as stream from 'node:stream';
|
|
4
7
|
import type { AddressInfo } from 'node:net';
|
|
5
|
-
export { crypto, http, stream };
|
|
8
|
+
export { crypto, fs, http, net, path, stream };
|
|
6
9
|
export type { AddressInfo };
|
|
7
10
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
8
11
|
import type { RegisteredTool } from '@modelcontextprotocol/sdk/server/mcp.js';
|
package/dist_ts/plugins.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
// Node native modules
|
|
2
2
|
import * as crypto from 'node:crypto';
|
|
3
|
+
import * as fs from 'node:fs';
|
|
3
4
|
import * as http from 'node:http';
|
|
5
|
+
import * as net from 'node:net';
|
|
6
|
+
import * as path from 'node:path';
|
|
4
7
|
import * as stream from 'node:stream';
|
|
5
|
-
export { crypto, http, stream };
|
|
8
|
+
export { crypto, fs, http, net, path, stream };
|
|
6
9
|
// Third-party modules
|
|
7
10
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
8
11
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
@@ -11,4 +14,4 @@ import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
|
|
|
11
14
|
import { WebSocket as WsWebSocket, WebSocketServer } from 'ws';
|
|
12
15
|
import { z } from 'zod';
|
|
13
16
|
export { InMemoryTransport, McpClient, McpServer, StdioServerTransport, WebSocketServer, WsWebSocket, z, };
|
|
14
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
17
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsc0JBQXNCO0FBQ3RCLE9BQU8sS0FBSyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxHQUFHLE1BQU0sVUFBVSxDQUFDO0FBQ2hDLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBR3RDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDO0FBRy9DLHNCQUFzQjtBQUN0QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFFcEUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFDakYsT0FBTyxFQUFFLE1BQU0sSUFBSSxTQUFTLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUNoRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUUxRSxPQUFPLEVBQUUsU0FBUyxJQUFJLFdBQVcsRUFBRSxlQUFlLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFFL0QsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUV4QixPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxTQUFTLEVBQ1Qsb0JBQW9CLEVBQ3BCLGVBQWUsRUFDZixXQUFXLEVBQ1gsQ0FBQyxHQUNGLENBQUMifQ==
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modelprofile.com/mcp-crossharness",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Connection-first MCP server for explicit OpenCode HTTP and Codex WebSocket session servers",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
"mcp-crossharness": "./cli.js"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@git.zone/tsbuild": "^
|
|
27
|
-
"@git.zone/tsrun": "^
|
|
28
|
-
"@git.zone/tstest": "^
|
|
29
|
-
"@types/node": "^26.
|
|
26
|
+
"@git.zone/tsbuild": "^5.0.0",
|
|
27
|
+
"@git.zone/tsrun": "^3.0.0",
|
|
28
|
+
"@git.zone/tstest": "^6.2.1",
|
|
29
|
+
"@types/node": "^26.6.1",
|
|
30
30
|
"@types/ws": "^8.18.1"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
package/readme.md
CHANGED
|
@@ -143,7 +143,7 @@ Register the `mcp-crossharness` binary as a stdio MCP server in your client.
|
|
|
143
143
|
### Native Codex app-server client
|
|
144
144
|
|
|
145
145
|
`CodexAppServerClient` exposes the underlying app-server protocol independently of the MCP
|
|
146
|
-
chat tools. It accepts an explicit WebSocket endpoint or caller-owned JSONL stdio streams;
|
|
146
|
+
chat tools. It accepts an explicit WebSocket endpoint, a Unix socket, or caller-owned JSONL stdio streams;
|
|
147
147
|
it never discovers or spawns a server. The embedding application owns process lifecycle,
|
|
148
148
|
session authorization, history projection, and human approval policy.
|
|
149
149
|
|
|
@@ -166,6 +166,14 @@ client.close();
|
|
|
166
166
|
```
|
|
167
167
|
|
|
168
168
|
For WebSocket transport use `{ type: 'websocket', url: approvedServerUrl, token: bearerToken }`.
|
|
169
|
+
|
|
170
|
+
To join an existing local Codex daemon, use
|
|
171
|
+
`{ type: 'unix', socketPath: absoluteSocketPath }`. This performs a WebSocket handshake
|
|
172
|
+
over the exact Unix socket, with the same deadlines, message limits and request lifecycle
|
|
173
|
+
as the network transport. The client does not discover, start, restart or stop the daemon;
|
|
174
|
+
closing it closes only its own connection. Socket paths remain filesystem paths, including
|
|
175
|
+
spaces and URL punctuation. Callers choose a trusted socket and own discovery and process
|
|
176
|
+
policy. Codex's `app-server proxy` forwards raw socket bytes; its stdio is not JSONL.
|
|
169
177
|
The caller must authorize the destination before supplying credentials. The client follows no
|
|
170
178
|
redirects and reads no credential environment variables. MCP tools retain their existing
|
|
171
179
|
allowlist and credential policy.
|
|
@@ -189,6 +197,56 @@ client never grants or automatically declines a permission. `close()` ends the s
|
|
|
189
197
|
stdio streams but never kills a subprocess. The existing MCP Codex adapter delegates to
|
|
190
198
|
this client and retains its conservative automatic rejection policy.
|
|
191
199
|
|
|
200
|
+
### Codex Unix socket alias
|
|
201
|
+
|
|
202
|
+
Since Codex 0.156.0, `codex app-server --listen unix://PATH` does not bind PATH. Codex binds
|
|
203
|
+
the socket in its fixed per-user directory, `<realpath /tmp>/codex-daemon-<euid>` (mode 0700),
|
|
204
|
+
under the SHA-256 of PATH with its parent directory canonicalised, and publishes PATH as a
|
|
205
|
+
symlink to it. Its shared local daemon socket, `$CODEX_HOME/app-server-control/app-server-control.sock`,
|
|
206
|
+
is published the same way. The unix transport connects through that link like any other
|
|
207
|
+
path; these two functions let a caller check, before connecting, that the entry really is
|
|
208
|
+
Codex's own:
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
import { CodexAppServerClient, codexUnixSocketTarget, observeCodexUnixSocket } from '@modelprofile.com/mcp-crossharness';
|
|
212
|
+
|
|
213
|
+
const target = await codexUnixSocketTarget(socketPath); // where Codex binds PATH
|
|
214
|
+
if (await observeCodexUnixSocket(socketPath) === 'published') {
|
|
215
|
+
const client = new CodexAppServerClient({
|
|
216
|
+
transport: { type: 'unix', socketPath },
|
|
217
|
+
clientInfo: { name: 'my-app', title: 'My App', version: '1.0.0' },
|
|
218
|
+
});
|
|
219
|
+
await client.connect();
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
`observeCodexUnixSocket(socketPath)` returns `'absent'` when nothing exists at the path and
|
|
224
|
+
`'published'` only when the path is a link owned by the effective user whose text is exactly
|
|
225
|
+
the derived target, in a parent directory other users cannot rewrite (owned by the user or
|
|
226
|
+
root, and not group- or world-writable unless sticky, which is Codex's own startup condition),
|
|
227
|
+
pointing at a socket owned by the effective user in a directory owned by that user with mode
|
|
228
|
+
0700. Every other entry throws, and nothing is created, removed or connected to. Ownership is
|
|
229
|
+
compared with the effective uid because Codex keys the directory by and checks against it.
|
|
230
|
+
A socket bound directly at the path, as Codex 0.155 and earlier did, is not this contract
|
|
231
|
+
and is refused like any other foreign entry.
|
|
232
|
+
|
|
233
|
+
Both functions take an optional `{ daemonDirectory }` that replaces the per-user directory for
|
|
234
|
+
fixtures; `codexUnixSocketTarget` needs the socket's parent directory to exist. They throw
|
|
235
|
+
plain `Error`s with these exact messages:
|
|
236
|
+
|
|
237
|
+
| Message | Cause |
|
|
238
|
+
| --- | --- |
|
|
239
|
+
| `Codex Unix socket path must be a normalized absolute file path` | relative, non-normalized, trailing-separator or NUL-containing path |
|
|
240
|
+
| `Codex daemon socket directory must be a normalized absolute path` | invalid `daemonDirectory` |
|
|
241
|
+
| `Codex Unix socket inspection requires a POSIX effective user id` | no `process.geteuid` (Windows) |
|
|
242
|
+
| `Codex Unix socket path is not the alias Codex publishes` | a regular file, a direct socket, another user's link, or a link to any other target |
|
|
243
|
+
| `Codex Unix socket parent directory lets other users replace its entries` | the path's parent is not safe for a published alias |
|
|
244
|
+
| `Codex Unix socket alias has no socket behind it` | Codex's own link whose target is gone (a stale publication) |
|
|
245
|
+
| `Codex Unix socket directory is not private to the current user` | the per-user directory is not the user's own 0700 directory |
|
|
246
|
+
| `Codex Unix socket is not a socket owned by the current user` | the target is not a socket, or is another user's |
|
|
247
|
+
|
|
248
|
+
Filesystem errors other than a missing path propagate unchanged.
|
|
249
|
+
|
|
192
250
|
### Composable tool registration
|
|
193
251
|
|
|
194
252
|
`CrossHarnessMcpToolRegistrar` registers the same nine Crossharness tools used by the standalone
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -15,6 +15,7 @@ export interface ICodexAppServerRequest extends ICodexAppServerNotification {
|
|
|
15
15
|
|
|
16
16
|
export type TCodexAppServerTransport =
|
|
17
17
|
| { type: 'websocket'; url: string; token?: string }
|
|
18
|
+
| { type: 'unix'; socketPath: string }
|
|
18
19
|
| { type: 'stdio'; readable: plugins.stream.Readable; writable: plugins.stream.Writable };
|
|
19
20
|
|
|
20
21
|
export interface ICodexAppServerClientOptions {
|
|
@@ -85,6 +86,12 @@ export class CodexAppServerClient {
|
|
|
85
86
|
throw new Error('Codex app-server requires an explicit ws/wss URL without credentials or fragment');
|
|
86
87
|
}
|
|
87
88
|
}
|
|
89
|
+
if (options.transport.type === 'unix' && (
|
|
90
|
+
typeof options.transport.socketPath !== 'string'
|
|
91
|
+
|| !options.transport.socketPath.startsWith('/')
|
|
92
|
+
|| options.transport.socketPath.includes('\0')
|
|
93
|
+
|| Buffer.byteLength(options.transport.socketPath, 'utf8') > 4096
|
|
94
|
+
)) throw new Error('Codex app-server requires an absolute Unix socket path of at most 4096 bytes');
|
|
88
95
|
}
|
|
89
96
|
|
|
90
97
|
public async connect(): Promise<void> {
|
|
@@ -92,12 +99,17 @@ export class CodexAppServerClient {
|
|
|
92
99
|
this.started = true;
|
|
93
100
|
try {
|
|
94
101
|
const transport = this.options.transport;
|
|
95
|
-
if (transport.type
|
|
96
|
-
const socket = new plugins.WsWebSocket(transport.url, {
|
|
102
|
+
if (transport.type !== 'stdio') {
|
|
103
|
+
const socket = new plugins.WsWebSocket(transport.type === 'websocket' ? transport.url : 'ws://localhost/', {
|
|
97
104
|
perMessageDeflate: false,
|
|
98
105
|
followRedirects: false,
|
|
99
106
|
maxPayload: this.maxMessageBytes,
|
|
100
|
-
headers: transport.
|
|
107
|
+
headers: transport.type === 'websocket' && transport.token
|
|
108
|
+
? { authorization: `Bearer ${transport.token}` } : {},
|
|
109
|
+
...(transport.type === 'unix' ? {
|
|
110
|
+
// Keep the path out of URL parsing: valid socket names may contain :, # or %.
|
|
111
|
+
createConnection: () => plugins.net.createConnection({ path: transport.socketPath }),
|
|
112
|
+
} : {}),
|
|
101
113
|
});
|
|
102
114
|
this.socket = socket;
|
|
103
115
|
socket.on('message', (data) => this.receive(data.toString()));
|
|
@@ -211,7 +223,7 @@ export class CodexAppServerClient {
|
|
|
211
223
|
for (const id of this.serverRequests.keys()) this.finishServerRequest(id);
|
|
212
224
|
this.inputBuffer = Buffer.alloc(0);
|
|
213
225
|
const transport = this.options.transport;
|
|
214
|
-
if (transport.type
|
|
226
|
+
if (transport.type !== 'stdio') {
|
|
215
227
|
if (this.socket && this.socket.readyState !== plugins.WsWebSocket.CLOSED) this.socket.terminate();
|
|
216
228
|
} else {
|
|
217
229
|
transport.readable.off('data', this.handleData);
|
|
@@ -250,7 +262,7 @@ export class CodexAppServerClient {
|
|
|
250
262
|
const payload = JSON.stringify(frameArg);
|
|
251
263
|
const payloadBytes = Buffer.byteLength(payload, 'utf8');
|
|
252
264
|
const transport = this.options.transport;
|
|
253
|
-
const buffered = transport.type
|
|
265
|
+
const buffered = transport.type !== 'stdio'
|
|
254
266
|
? this.socket?.bufferedAmount ?? 0 : transport.writable.writableLength;
|
|
255
267
|
if (this.state === 'closed') throw new Error('Codex server connection is closed');
|
|
256
268
|
if (buffered + payloadBytes + 1 > this.maxBufferedBytes) {
|
|
@@ -258,7 +270,7 @@ export class CodexAppServerClient {
|
|
|
258
270
|
this.close(error.message);
|
|
259
271
|
throw error;
|
|
260
272
|
}
|
|
261
|
-
if (transport.type
|
|
273
|
+
if (transport.type !== 'stdio') {
|
|
262
274
|
if (!this.socket || this.socket.readyState !== plugins.WsWebSocket.OPEN) {
|
|
263
275
|
throw new Error('Codex server WebSocket is not open');
|
|
264
276
|
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import * as helpers from './helpers.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Codex's `--listen unix://PATH` contract since Codex 0.156.0 (codex-rs/app-server-transport,
|
|
6
|
+
* `protected_socket_path`): the socket is bound in the fixed per-user directory
|
|
7
|
+
* `<realpath /tmp>/codex-daemon-<euid>` under the SHA-256 of PATH with its parent canonicalised,
|
|
8
|
+
* and PATH itself is only a symlink to it. Earlier releases bound PATH directly; that layout is
|
|
9
|
+
* not this contract and is refused like any other foreign entry.
|
|
10
|
+
*/
|
|
11
|
+
export interface ICodexUnixSocketOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Codex's per-user socket directory. Defaults to `<realpath /tmp>/codex-daemon-<euid>`, which
|
|
14
|
+
* Codex derives without HOME, TMPDIR or CODEX_HOME; override it only for fixtures.
|
|
15
|
+
*/
|
|
16
|
+
daemonDirectory?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** `absent`: nothing exists at the path. `published`: Codex's own alias to a private socket. */
|
|
20
|
+
export type TCodexUnixSocketPublication = 'absent' | 'published';
|
|
21
|
+
|
|
22
|
+
const assertNormalizedAbsolute = (pathArg: string, messageArg: string): void => {
|
|
23
|
+
if (typeof pathArg !== 'string' || !plugins.path.isAbsolute(pathArg) || pathArg.includes('\0')
|
|
24
|
+
|| plugins.path.normalize(pathArg) !== pathArg) {
|
|
25
|
+
throw new Error(messageArg);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Codex splits PATH into parent and file name with Rust's `Path`, which drops `.` components and
|
|
31
|
+
* has no file name for `..`; a normalized path without a trailing separator splits identically here.
|
|
32
|
+
*/
|
|
33
|
+
const assertSocketPath = (socketPathArg: string): void => {
|
|
34
|
+
const message = 'Codex Unix socket path must be a normalized absolute file path';
|
|
35
|
+
assertNormalizedAbsolute(socketPathArg, message);
|
|
36
|
+
if (socketPathArg.endsWith(plugins.path.sep)) throw new Error(message);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/** Codex keys its directory and checks every entry by the effective uid, so this module does too. */
|
|
40
|
+
const effectiveUserId = (): number => {
|
|
41
|
+
const euid = process.geteuid?.();
|
|
42
|
+
if (euid === undefined) throw new Error('Codex Unix socket inspection requires a POSIX effective user id');
|
|
43
|
+
return euid;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/** A malformed root is a caller error, so it throws whatever exists at the socket path. */
|
|
47
|
+
const assertOptions = (optionsArg: ICodexUnixSocketOptions): void => {
|
|
48
|
+
if (optionsArg.daemonDirectory !== undefined) {
|
|
49
|
+
assertNormalizedAbsolute(optionsArg.daemonDirectory, 'Codex daemon socket directory must be a normalized absolute path');
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const daemonDirectoryFor = async (optionsArg: ICodexUnixSocketOptions, euidArg: number): Promise<string> => {
|
|
54
|
+
if (optionsArg.daemonDirectory !== undefined) return optionsArg.daemonDirectory;
|
|
55
|
+
return plugins.path.join(await plugins.fs.promises.realpath('/tmp'), `codex-daemon-${euidArg}`);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const isMissing = (errorArg: unknown): boolean => helpers.isRecord(errorArg) && errorArg.code === 'ENOENT';
|
|
59
|
+
|
|
60
|
+
/** Where Codex binds the socket it publishes at `socketPathArg`. The parent directory must exist. */
|
|
61
|
+
export const codexUnixSocketTarget = async (
|
|
62
|
+
socketPathArg: string,
|
|
63
|
+
optionsArg: ICodexUnixSocketOptions = {},
|
|
64
|
+
): Promise<string> => {
|
|
65
|
+
assertSocketPath(socketPathArg);
|
|
66
|
+
assertOptions(optionsArg);
|
|
67
|
+
const euid = effectiveUserId();
|
|
68
|
+
const directory = await daemonDirectoryFor(optionsArg, euid);
|
|
69
|
+
const canonical = plugins.path.join(await plugins.fs.promises.realpath(plugins.path.dirname(socketPathArg)),
|
|
70
|
+
plugins.path.basename(socketPathArg));
|
|
71
|
+
return plugins.path.join(directory, plugins.crypto.createHash('sha256').update(canonical).digest('hex'));
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Reports whether Codex has published an app-server socket at `socketPathArg`. Anything present
|
|
76
|
+
* must be exactly Codex's own same-user link to its target, in a parent other users cannot
|
|
77
|
+
* rewrite (Codex's own startup condition), pointing at a same-user socket in a 0700 same-user
|
|
78
|
+
* directory; every other entry throws instead of being connected to.
|
|
79
|
+
*/
|
|
80
|
+
export const observeCodexUnixSocket = async (
|
|
81
|
+
socketPathArg: string,
|
|
82
|
+
optionsArg: ICodexUnixSocketOptions = {},
|
|
83
|
+
): Promise<TCodexUnixSocketPublication> => {
|
|
84
|
+
assertSocketPath(socketPathArg);
|
|
85
|
+
assertOptions(optionsArg);
|
|
86
|
+
const euid = effectiveUserId();
|
|
87
|
+
let alias: plugins.fs.Stats;
|
|
88
|
+
try {
|
|
89
|
+
alias = await plugins.fs.promises.lstat(socketPathArg);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
if (isMissing(error)) return 'absent';
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
const target = await codexUnixSocketTarget(socketPathArg, optionsArg);
|
|
95
|
+
if (!alias.isSymbolicLink() || alias.uid !== euid || await plugins.fs.promises.readlink(socketPathArg) !== target) {
|
|
96
|
+
throw new Error('Codex Unix socket path is not the alias Codex publishes');
|
|
97
|
+
}
|
|
98
|
+
const parent = await plugins.fs.promises.stat(plugins.path.dirname(socketPathArg));
|
|
99
|
+
if (!parent.isDirectory() || (parent.uid !== 0 && parent.uid !== euid)
|
|
100
|
+
|| ((parent.mode & 0o022) !== 0 && (parent.mode & 0o1000) === 0)) {
|
|
101
|
+
throw new Error('Codex Unix socket parent directory lets other users replace its entries');
|
|
102
|
+
}
|
|
103
|
+
let directory: plugins.fs.Stats;
|
|
104
|
+
let socket: plugins.fs.Stats;
|
|
105
|
+
try {
|
|
106
|
+
directory = await plugins.fs.promises.lstat(plugins.path.dirname(target));
|
|
107
|
+
socket = await plugins.fs.promises.lstat(target);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
if (isMissing(error)) throw new Error('Codex Unix socket alias has no socket behind it');
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
if (!directory.isDirectory() || directory.uid !== euid || (directory.mode & 0o777) !== 0o700) {
|
|
113
|
+
throw new Error('Codex Unix socket directory is not private to the current user');
|
|
114
|
+
}
|
|
115
|
+
if (!socket.isSocket() || socket.uid !== euid) {
|
|
116
|
+
throw new Error('Codex Unix socket is not a socket owned by the current user');
|
|
117
|
+
}
|
|
118
|
+
return 'published';
|
|
119
|
+
};
|
package/ts/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './interfaces.js';
|
|
2
2
|
export * from './classes.codexappserverclient.js';
|
|
3
|
+
export * from './functions.codexunixsocket.js';
|
|
3
4
|
export * from './classes.connectionregistry.js';
|
|
4
5
|
export * from './classes.dispatchregistry.js';
|
|
5
6
|
export * from './classes.mcptoolregistrar.js';
|
package/ts/plugins.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
// Node native modules
|
|
2
2
|
import * as crypto from 'node:crypto';
|
|
3
|
+
import * as fs from 'node:fs';
|
|
3
4
|
import * as http from 'node:http';
|
|
5
|
+
import * as net from 'node:net';
|
|
6
|
+
import * as path from 'node:path';
|
|
4
7
|
import * as stream from 'node:stream';
|
|
5
8
|
import type { AddressInfo } from 'node:net';
|
|
6
9
|
|
|
7
|
-
export { crypto, http, stream };
|
|
10
|
+
export { crypto, fs, http, net, path, stream };
|
|
8
11
|
export type { AddressInfo };
|
|
9
12
|
|
|
10
13
|
// Third-party modules
|
package/readme.hints.md
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# readme.hints.md
|
|
2
|
-
|
|
3
|
-
Implementation findings for mcp-crossharness.
|
|
4
|
-
|
|
5
|
-
## Server-only architecture
|
|
6
|
-
|
|
7
|
-
- Every harness operation after connection setup is scoped to an opaque connection established from an explicit server origin and remote absolute directory; `list_connections` remains global.
|
|
8
|
-
- Duplicate harness/origin/directory bindings are rejected and each registry is capped at 32 connections.
|
|
9
|
-
- `CROSSHARNESS_ALLOWED_SERVER_URLS` is an exact-origin allowlist. Credentials are fixed environment variables, never tool inputs.
|
|
10
|
-
- URLs reject user info, query strings, fragments, and non-root paths. OpenCode fetch calls use `redirect: 'error'`.
|
|
11
|
-
- No production source reads harness stores, invokes harness CLIs, starts or stops processes, or discovers endpoints.
|
|
12
|
-
|
|
13
|
-
## OpenCode server API
|
|
14
|
-
|
|
15
|
-
Verified against OpenCode 1.18.13 docs, source, and generated SDK.
|
|
16
|
-
|
|
17
|
-
- Health: `GET /global/health`.
|
|
18
|
-
- Session list: `GET /session?directory=...&scope=project&roots=true&limit=...`.
|
|
19
|
-
- Session ownership: `GET /session/:id?directory=...`, then verify returned `directory` exactly.
|
|
20
|
-
- Transcript: `GET /session/:id/message?directory=...&limit=...`.
|
|
21
|
-
- Send: `POST /session/:id/message?directory=...` with a generated `messageID` and text part.
|
|
22
|
-
- OpenCode owns queuing. Crossharness intentionally does not serialize HTTP sends, subscribe to permission events, or issue session-wide aborts.
|
|
23
|
-
- Aborting a fetch does not prove that a queued/running server turn stopped, so timeout errors state the ambiguity and no retry occurs.
|
|
24
|
-
- Successful JSON response bodies are capped at 16 MiB; error bodies are capped at 64 KiB and only the first 2,000 characters are surfaced.
|
|
25
|
-
|
|
26
|
-
## Codex app-server API
|
|
27
|
-
|
|
28
|
-
Verified against Codex 0.146.0 using `codex app-server generate-ts` and official app-server documentation.
|
|
29
|
-
|
|
30
|
-
- Explicit transports are `ws://` and `wss://`; one initialized WebSocket is owned per Crossharness connection.
|
|
31
|
-
- Flow: `initialize` -> `initialized`; `thread/list`; `thread/read`; `thread/resume`; `turn/start`; correlated notifications; optional `turn/interrupt` on timeout.
|
|
32
|
-
- `thread/list` supports exact `cwd` filtering. `thread/read` results are still verified against the connection directory before reading or sending.
|
|
33
|
-
- Request responses are correlated by JSON-RPC id. Turn events are correlated by `threadId` and `turnId`; events can arrive before `turn/start` resolves, so one unbound turn per thread may claim the early id.
|
|
34
|
-
- Sends to one thread are sequenced; different threads remain concurrent.
|
|
35
|
-
- Codex send queues are bounded globally and per thread, outbound WebSocket buffering is capped at 4 MiB, and a send's timeout includes time spent waiting in the same-thread queue.
|
|
36
|
-
- Turn output is bounded by text size and delta count, including empty streaming deltas.
|
|
37
|
-
- Foreground MCP cancellation aborts the operation-scoped OpenCode request or safely interrupts the correlated Codex turn; asynchronous dispatches remain independent after acceptance.
|
|
38
|
-
- A timed-out send keeps its thread queue locked until `turn/interrupt` is acknowledged and `turn/completed` reports terminal state. Missing turn correlation or incomplete interruption closes the connection fail-closed.
|
|
39
|
-
- Socket close rejects all pending requests and turns. Disconnect removes the connection before closing so no new work can enter.
|
|
40
|
-
- Stdio EOF closes the MCP transport and every active or handshaking connection.
|
|
41
|
-
- Server requests are never ignored: command/file approvals decline, tool input returns empty answers, MCP elicitation declines, permission-profile requests grant no extra permissions for the turn, legacy approvals abort, and unknown requests receive `-32601`.
|
|
42
|
-
|
|
43
|
-
## Claude Code
|
|
44
|
-
|
|
45
|
-
Claude Code 2.1.219 and the current Agent SDK expose local CLI/library interfaces, not a URL-addressable session server. `connect_harness` rejects `claudecode` until such a server exists.
|
|
46
|
-
|
|
47
|
-
## Testing
|
|
48
|
-
|
|
49
|
-
- HTTP fixtures cover required Basic auth, allowlisting, redirect rejection, directory ownership, concurrent OpenCode sends, and disconnect state.
|
|
50
|
-
- WebSocket fixtures cover initialization, list/read/send, interleaved turns, bounded deltas and send buffering, safe server-request responses, timeout interruption, directory ownership, and disconnect failure propagation.
|
|
51
|
-
- Registry fixtures cover pending-connect shutdown and bounded dispatch admission before send invocation.
|
|
52
|
-
- Timeout fixtures cover OpenCode validation, Codex same-thread queueing, interruption completion, malformed terminal events, and stdio EOF cleanup.
|