@shuind/dsh-codex-harness 0.1.7
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/LICENSE +21 -0
- package/README.md +100 -0
- package/README.zh.md +100 -0
- package/cordis.patch.yml +5 -0
- package/lib/index.js +843 -0
- package/lib/installer.js +59 -0
- package/lib/invariant.js +23 -0
- package/lib/types/exec.d.ts +43 -0
- package/lib/types/exec.js +251 -0
- package/lib/types/index.d.ts +28 -0
- package/lib/types/index.js +321 -0
- package/lib/types/installer.d.ts +23 -0
- package/lib/types/installer.js +64 -0
- package/lib/types/invariant.d.ts +16 -0
- package/lib/types/invariant.js +22 -0
- package/lib/types/patch.d.ts +36 -0
- package/lib/types/patch.js +186 -0
- package/package.json +114 -0
- package/presets/codex/agent.cordis.yml +44 -0
- package/presets/codex/preset.yml +3 -0
package/lib/installer.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, mkdtempSync, renameSync, rmSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
//#region lib/types/installer.js
|
|
6
|
+
/** Install the user-visible Codex agent preset supplied by this bundle. */
|
|
7
|
+
const PRESET_ID = "codex";
|
|
8
|
+
const PRESET_FILES = ["agent.cordis.yml", "preset.yml"];
|
|
9
|
+
const SOURCE_PRESET_DIR = fileURLToPath(new URL("../presets/codex/", import.meta.url));
|
|
10
|
+
function dshHomePath(...segments) {
|
|
11
|
+
const configured = process.env.DSH_HOME?.trim();
|
|
12
|
+
const expanded = configured === void 0 || configured.length === 0 ? join(homedir(), ".dsh") : configured === "~" ? homedir() : configured.startsWith("~/") || configured.startsWith("~\\") ? join(homedir(), configured.slice(2)) : configured;
|
|
13
|
+
return join(resolve(expanded), ...segments);
|
|
14
|
+
}
|
|
15
|
+
/** Bundle plugin name for the preset installer. */
|
|
16
|
+
const name = "codex-preset-installer";
|
|
17
|
+
/**
|
|
18
|
+
* Install the shipped Codex preset only when the user has not authored one.
|
|
19
|
+
*
|
|
20
|
+
* The directory is committed with a staging rename so a failed copy cannot
|
|
21
|
+
* leave a half-written preset that hides the mode from the roster. Existing
|
|
22
|
+
* directories are intentionally preserved, including user customizations.
|
|
23
|
+
*
|
|
24
|
+
* @param targetDir - destination preset directory.
|
|
25
|
+
* @param sourceDir - directory containing the packaged preset files.
|
|
26
|
+
*/
|
|
27
|
+
function installCodexPreset(targetDir = dshHomePath(".agent-presets", PRESET_ID), sourceDir = SOURCE_PRESET_DIR) {
|
|
28
|
+
if (existsSync(targetDir)) return;
|
|
29
|
+
const parentDir = dirname(targetDir);
|
|
30
|
+
mkdirSync(parentDir, { recursive: true });
|
|
31
|
+
const stagingDir = mkdtempSync(join(parentDir, `.${PRESET_ID}-`));
|
|
32
|
+
try {
|
|
33
|
+
for (const file of PRESET_FILES) copyFileSync(join(sourceDir, file), join(stagingDir, file));
|
|
34
|
+
try {
|
|
35
|
+
renameSync(stagingDir, targetDir);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
if (!existsSync(targetDir)) throw error;
|
|
38
|
+
}
|
|
39
|
+
} finally {
|
|
40
|
+
if (existsSync(stagingDir)) rmSync(stagingDir, {
|
|
41
|
+
recursive: true,
|
|
42
|
+
force: true
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** Install the preset during profile boot without changing the host tool catalog. */
|
|
47
|
+
function apply(ctx) {
|
|
48
|
+
try {
|
|
49
|
+
installCodexPreset();
|
|
50
|
+
} catch (error) {
|
|
51
|
+
ctx.logger.warn(`dsh-codex: could not install the Codex preset: ${String(error)}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
var installer_default = {
|
|
55
|
+
name,
|
|
56
|
+
apply
|
|
57
|
+
};
|
|
58
|
+
//#endregion
|
|
59
|
+
export { apply, installer_default as default, installCodexPreset, name };
|
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region lib/types/invariant.js
|
|
2
|
+
/**
|
|
3
|
+
* Package-owned invariant companion for `@shuind/dsh-codex-harness`.
|
|
4
|
+
* @module @shuind/dsh-codex-harness/invariant
|
|
5
|
+
*/
|
|
6
|
+
const PACKAGE_NAME = "@shuind/dsh-codex-harness";
|
|
7
|
+
/** Codex companion plugin name. */
|
|
8
|
+
const name = "codex-invariant";
|
|
9
|
+
/** Service required before the companion can reserve package ownership. */
|
|
10
|
+
const inject = ["invariants"];
|
|
11
|
+
/**
|
|
12
|
+
* Codex has no independent lifecycle stream: its model-visible state is owned
|
|
13
|
+
* by the tool registry and session projection services it consumes.
|
|
14
|
+
*/
|
|
15
|
+
const install = () => {};
|
|
16
|
+
/**
|
|
17
|
+
* Register this package's invariant companion.
|
|
18
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
19
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
20
|
+
*/
|
|
21
|
+
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
22
|
+
//#endregion
|
|
23
|
+
export { apply, inject, name };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** Codex `exec_command` and `write_stdin` execution over dsh capability seams. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import type { ToolExecution } from '@deepseek-ai/dsh-tools';
|
|
4
|
+
/** The exact model-facing argument vocabulary of Codex's unified exec tool. */
|
|
5
|
+
export interface ExecCommandArgs {
|
|
6
|
+
cmd: string;
|
|
7
|
+
workdir?: string;
|
|
8
|
+
tty?: boolean;
|
|
9
|
+
yield_time_ms?: number;
|
|
10
|
+
max_output_tokens?: number;
|
|
11
|
+
shell?: string;
|
|
12
|
+
login?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** The exact model-facing argument vocabulary of Codex's stdin poll tool. */
|
|
15
|
+
export interface WriteStdinArgs {
|
|
16
|
+
session_id: number;
|
|
17
|
+
chars?: string;
|
|
18
|
+
yield_time_ms?: number;
|
|
19
|
+
max_output_tokens?: number;
|
|
20
|
+
}
|
|
21
|
+
/** Canonical result fields shared by both unified exec tools. */
|
|
22
|
+
export interface ExecResult {
|
|
23
|
+
chunk_id?: string;
|
|
24
|
+
wall_time_seconds: number;
|
|
25
|
+
output: string;
|
|
26
|
+
session_id?: number;
|
|
27
|
+
exit_code?: number;
|
|
28
|
+
original_token_count?: number;
|
|
29
|
+
}
|
|
30
|
+
/** Render the ordinary Responses tool result text used by Codex's unified exec tools. */
|
|
31
|
+
export declare function renderExecResult(result: ExecResult): string;
|
|
32
|
+
/** Execute one Codex command through the configured pipe or PTY capability. */
|
|
33
|
+
export declare function runExecCommand(ctx: Context, args: ExecCommandArgs, exec: ToolExecution, config: {
|
|
34
|
+
defaultYieldTimeMs: number;
|
|
35
|
+
maxOutputBytes: number;
|
|
36
|
+
}): Promise<ExecResult>;
|
|
37
|
+
/** Poll or write to one session returned by {@link runExecCommand}. */
|
|
38
|
+
export declare function runWriteStdin(ctx: Context, args: WriteStdinArgs, exec: ToolExecution, config: {
|
|
39
|
+
pollYieldTimeMs: number;
|
|
40
|
+
writeYieldTimeMs: number;
|
|
41
|
+
maxOutputBytes: number;
|
|
42
|
+
}): Promise<ExecResult>;
|
|
43
|
+
//# sourceMappingURL=exec.d.ts.map
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/** Codex `exec_command` and `write_stdin` execution over dsh capability seams. */
|
|
2
|
+
import { randomBytes } from 'node:crypto';
|
|
3
|
+
import { resolve as resolvePath } from 'node:path';
|
|
4
|
+
const STATES = new WeakMap();
|
|
5
|
+
function stateFor(agent) {
|
|
6
|
+
const current = STATES.get(agent);
|
|
7
|
+
if (current !== undefined)
|
|
8
|
+
return current;
|
|
9
|
+
const created = { nextId: 0, sessions: new Map() };
|
|
10
|
+
STATES.set(agent, created);
|
|
11
|
+
return created;
|
|
12
|
+
}
|
|
13
|
+
function positiveFinite(name, value) {
|
|
14
|
+
if (value !== undefined && (!Number.isFinite(value) || value < 0)) {
|
|
15
|
+
throw new Error(`${name} must be a non-negative finite number`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function waitMs(value, fallback) {
|
|
19
|
+
return Math.max(0, Math.min(30_000, Math.trunc(value ?? fallback)));
|
|
20
|
+
}
|
|
21
|
+
function outputLimit(maxOutputBytes, maxOutputTokens) {
|
|
22
|
+
if (maxOutputTokens === undefined)
|
|
23
|
+
return maxOutputBytes;
|
|
24
|
+
positiveFinite('max_output_tokens', maxOutputTokens);
|
|
25
|
+
return Math.max(1, Math.min(maxOutputBytes, Math.trunc(maxOutputTokens * 4)));
|
|
26
|
+
}
|
|
27
|
+
function limitOutput(text, maxBytes) {
|
|
28
|
+
if (Buffer.byteLength(text, 'utf8') <= maxBytes)
|
|
29
|
+
return text;
|
|
30
|
+
let end = Math.min(text.length, maxBytes);
|
|
31
|
+
while (end > 0 && Buffer.byteLength(text.slice(0, end), 'utf8') > maxBytes)
|
|
32
|
+
end--;
|
|
33
|
+
return `${text.slice(0, end)}\n[output truncated]`;
|
|
34
|
+
}
|
|
35
|
+
function newChunkId() {
|
|
36
|
+
return randomBytes(3).toString('hex');
|
|
37
|
+
}
|
|
38
|
+
function withChunkId(result) {
|
|
39
|
+
return { chunk_id: newChunkId(), ...result };
|
|
40
|
+
}
|
|
41
|
+
/** Render the ordinary Responses tool result text used by Codex's unified exec tools. */
|
|
42
|
+
export function renderExecResult(result) {
|
|
43
|
+
const sections = [];
|
|
44
|
+
if (result.chunk_id !== undefined)
|
|
45
|
+
sections.push(`Chunk ID: ${result.chunk_id}`);
|
|
46
|
+
sections.push(`Wall time: ${result.wall_time_seconds.toFixed(4)} seconds`);
|
|
47
|
+
if (result.exit_code !== undefined)
|
|
48
|
+
sections.push(`Process exited with code ${result.exit_code}`);
|
|
49
|
+
if (result.session_id !== undefined)
|
|
50
|
+
sections.push(`Process running with session ID ${result.session_id}`);
|
|
51
|
+
if (result.original_token_count !== undefined)
|
|
52
|
+
sections.push(`Original token count: ${result.original_token_count}`);
|
|
53
|
+
sections.push('Output:', result.output);
|
|
54
|
+
return sections.join('\n');
|
|
55
|
+
}
|
|
56
|
+
function sessionCwd(exec, workdir) {
|
|
57
|
+
const base = exec.agent?.session.header.cwd ?? process.cwd();
|
|
58
|
+
if (workdir === undefined)
|
|
59
|
+
return exec.agent?.session.header.cwd;
|
|
60
|
+
return resolvePath(base, workdir);
|
|
61
|
+
}
|
|
62
|
+
function readShellOutput(read, maxBytes) {
|
|
63
|
+
return limitOutput(read.delta, maxBytes);
|
|
64
|
+
}
|
|
65
|
+
function terminalResult(result, maxBytes, startedAt) {
|
|
66
|
+
const output = limitOutput(result.viewport, maxBytes);
|
|
67
|
+
return withChunkId({
|
|
68
|
+
wall_time_seconds: (performance.now() - startedAt) / 1000,
|
|
69
|
+
output,
|
|
70
|
+
...result.sessionStatus.kind === 'exited' ? {
|
|
71
|
+
...result.sessionStatus.exitCode === null ? {} : { exit_code: result.sessionStatus.exitCode },
|
|
72
|
+
} : {},
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function sleep(ms, signal) {
|
|
76
|
+
return new Promise(resolve => {
|
|
77
|
+
let timer;
|
|
78
|
+
const finish = (result) => {
|
|
79
|
+
if (timer !== undefined)
|
|
80
|
+
clearTimeout(timer);
|
|
81
|
+
signal.removeEventListener('abort', onAbort);
|
|
82
|
+
resolve(result);
|
|
83
|
+
};
|
|
84
|
+
const onAbort = () => finish('aborted');
|
|
85
|
+
if (signal.aborted) {
|
|
86
|
+
finish('aborted');
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
90
|
+
timer = setTimeout(() => finish('elapsed'), ms);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
async function waitForShell(process, ms, signal) {
|
|
94
|
+
const timer = sleep(ms, signal);
|
|
95
|
+
const completed = await Promise.race([
|
|
96
|
+
process.done.then(() => true),
|
|
97
|
+
timer.then(result => result === 'aborted' ? false : undefined),
|
|
98
|
+
]);
|
|
99
|
+
if (signal.aborted)
|
|
100
|
+
signal.throwIfAborted();
|
|
101
|
+
return completed === true || process.status !== 'running';
|
|
102
|
+
}
|
|
103
|
+
function allocateSession(agent, session) {
|
|
104
|
+
const state = stateFor(agent);
|
|
105
|
+
const id = ++state.nextId;
|
|
106
|
+
state.sessions.set(id, session);
|
|
107
|
+
return id;
|
|
108
|
+
}
|
|
109
|
+
function storedSession(agent, id) {
|
|
110
|
+
const session = stateFor(agent).sessions.get(id);
|
|
111
|
+
if (session === undefined)
|
|
112
|
+
throw new Error(`unknown unified exec session ${id}`);
|
|
113
|
+
return session;
|
|
114
|
+
}
|
|
115
|
+
function forgetSession(agent, id) {
|
|
116
|
+
stateFor(agent).sessions.delete(id);
|
|
117
|
+
}
|
|
118
|
+
function commandFor(args) {
|
|
119
|
+
// The selected dsh shell provider owns the actual executable and login
|
|
120
|
+
// defaults. These fields remain accepted so Codex's argument contract is
|
|
121
|
+
// stable; dsh's shell capability is the deployment extension point.
|
|
122
|
+
return args.cmd;
|
|
123
|
+
}
|
|
124
|
+
/** Execute one Codex command through the configured pipe or PTY capability. */
|
|
125
|
+
export async function runExecCommand(ctx, args, exec, config) {
|
|
126
|
+
if (args.cmd.trim().length === 0)
|
|
127
|
+
throw new Error('cmd must be a non-empty string');
|
|
128
|
+
positiveFinite('yield_time_ms', args.yield_time_ms);
|
|
129
|
+
const maxBytes = outputLimit(config.maxOutputBytes, args.max_output_tokens);
|
|
130
|
+
const workdir = sessionCwd(exec, args.workdir);
|
|
131
|
+
const startedAt = performance.now();
|
|
132
|
+
if (args.tty === true) {
|
|
133
|
+
const agent = exec.agent;
|
|
134
|
+
const terminals = ctx.get('terminals');
|
|
135
|
+
if (agent === undefined || terminals === undefined) {
|
|
136
|
+
throw new Error('exec_command with tty=true requires the dsh terminal capability and an owning agent session');
|
|
137
|
+
}
|
|
138
|
+
const spawnRequest = {
|
|
139
|
+
type: 'shell',
|
|
140
|
+
...args.shell === undefined ? {} : { shell: args.shell },
|
|
141
|
+
login: args.login ?? true,
|
|
142
|
+
...workdir === undefined ? {} : { cwd: workdir },
|
|
143
|
+
};
|
|
144
|
+
const spawned = await terminals.spawn(agent, spawnRequest, exec.signal);
|
|
145
|
+
const sendRequest = {
|
|
146
|
+
text: commandFor(args),
|
|
147
|
+
submit: true,
|
|
148
|
+
waitMs: waitMs(args.yield_time_ms, config.defaultYieldTimeMs),
|
|
149
|
+
signal: exec.signal,
|
|
150
|
+
};
|
|
151
|
+
const operation = terminals.startSend(agent, spawned.sessionId, sendRequest);
|
|
152
|
+
const result = await operation.done;
|
|
153
|
+
const output = terminalResult(result, maxBytes, startedAt);
|
|
154
|
+
if (result.sessionStatus.kind === 'running') {
|
|
155
|
+
output.session_id = allocateSession(agent, { kind: 'terminal', owner: agent, id: spawned.sessionId });
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
await terminals.kill(agent, spawned.sessionId, 'Codex command exited');
|
|
159
|
+
}
|
|
160
|
+
return output;
|
|
161
|
+
}
|
|
162
|
+
const policy = ctx.get('sandboxPolicy')?.resolve(exec.agent === undefined ? {} : { session: exec.agent.session });
|
|
163
|
+
const dshEnv = ctx.get('shellEnv')?.collect(exec);
|
|
164
|
+
const shellRequest = {
|
|
165
|
+
command: commandFor(args),
|
|
166
|
+
...args.shell === undefined ? {} : { shell: args.shell },
|
|
167
|
+
login: args.login ?? true,
|
|
168
|
+
...workdir === undefined ? {} : { workdir },
|
|
169
|
+
stdoutMaxBytes: maxBytes,
|
|
170
|
+
...dshEnv === undefined ? {} : { dshEnv },
|
|
171
|
+
...policy === undefined ? {} : { sandboxPolicy: policy },
|
|
172
|
+
};
|
|
173
|
+
const process = ctx.shell.start(ctx.shell.resolve(shellRequest));
|
|
174
|
+
const completed = await waitForShell(process, waitMs(args.yield_time_ms, config.defaultYieldTimeMs), exec.signal);
|
|
175
|
+
const output = readShellOutput(process.readOutput(), maxBytes);
|
|
176
|
+
if (!completed || process.status === 'running') {
|
|
177
|
+
if (exec.agent === undefined) {
|
|
178
|
+
process.kill();
|
|
179
|
+
await process.done;
|
|
180
|
+
return withChunkId({
|
|
181
|
+
wall_time_seconds: (performance.now() - startedAt) / 1000,
|
|
182
|
+
output: readShellOutput(process.readOutput(), maxBytes),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
return withChunkId({
|
|
186
|
+
wall_time_seconds: (performance.now() - startedAt) / 1000,
|
|
187
|
+
output,
|
|
188
|
+
session_id: allocateSession(exec.agent, { kind: 'shell', process }),
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
return withChunkId({
|
|
192
|
+
wall_time_seconds: (performance.now() - startedAt) / 1000,
|
|
193
|
+
output,
|
|
194
|
+
...process.exitCode === null ? {} : { exit_code: process.exitCode },
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/** Poll or write to one session returned by {@link runExecCommand}. */
|
|
198
|
+
export async function runWriteStdin(ctx, args, exec, config) {
|
|
199
|
+
positiveFinite('yield_time_ms', args.yield_time_ms);
|
|
200
|
+
if (!Number.isSafeInteger(args.session_id) || args.session_id <= 0) {
|
|
201
|
+
throw new Error('session_id must be a positive integer');
|
|
202
|
+
}
|
|
203
|
+
const agent = exec.agent;
|
|
204
|
+
if (agent === undefined)
|
|
205
|
+
throw new Error('write_stdin requires an owning agent session');
|
|
206
|
+
const session = storedSession(agent, args.session_id);
|
|
207
|
+
const maxBytes = outputLimit(config.maxOutputBytes, args.max_output_tokens);
|
|
208
|
+
const startedAt = performance.now();
|
|
209
|
+
const chars = args.chars ?? '';
|
|
210
|
+
if (session.kind === 'shell') {
|
|
211
|
+
if (chars.length > 0) {
|
|
212
|
+
throw new Error('this unified exec session uses pipes and does not accept stdin; rerun exec_command with tty=true');
|
|
213
|
+
}
|
|
214
|
+
const completed = await waitForShell(session.process, waitMs(args.yield_time_ms, config.pollYieldTimeMs), exec.signal);
|
|
215
|
+
const output = readShellOutput(session.process.readOutput(), maxBytes);
|
|
216
|
+
if (completed && session.process.status !== 'running') {
|
|
217
|
+
forgetSession(agent, args.session_id);
|
|
218
|
+
return withChunkId({
|
|
219
|
+
wall_time_seconds: (performance.now() - startedAt) / 1000,
|
|
220
|
+
output,
|
|
221
|
+
...session.process.exitCode === null ? {} : { exit_code: session.process.exitCode },
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
return withChunkId({
|
|
225
|
+
wall_time_seconds: (performance.now() - startedAt) / 1000,
|
|
226
|
+
output,
|
|
227
|
+
session_id: args.session_id,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
const terminals = ctx.get('terminals');
|
|
231
|
+
if (terminals === undefined)
|
|
232
|
+
throw new Error('the dsh terminal capability is no longer available');
|
|
233
|
+
const sendRequest = {
|
|
234
|
+
text: chars,
|
|
235
|
+
submit: false,
|
|
236
|
+
waitMs: waitMs(args.yield_time_ms, chars.length > 0 ? config.writeYieldTimeMs : config.pollYieldTimeMs),
|
|
237
|
+
signal: exec.signal,
|
|
238
|
+
};
|
|
239
|
+
const operation = terminals.startSend(agent, session.id, sendRequest);
|
|
240
|
+
const result = await operation.done;
|
|
241
|
+
const output = terminalResult(result, maxBytes, startedAt);
|
|
242
|
+
if (result.sessionStatus.kind === 'running') {
|
|
243
|
+
output.session_id = args.session_id;
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
forgetSession(agent, args.session_id);
|
|
247
|
+
await terminals.kill(agent, session.id, 'Codex command exited');
|
|
248
|
+
}
|
|
249
|
+
return output;
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=exec.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Codex-compatible prompt overlay and core tools for a dsh agent preset. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import z from '@deepseek-ai/schemastery';
|
|
4
|
+
export declare const name = "codex";
|
|
5
|
+
export declare const inject: string[];
|
|
6
|
+
/** Configuration for the Codex shell result bridge. */
|
|
7
|
+
export interface Config {
|
|
8
|
+
/** Default wait before a pipe-backed command yields a session id. */
|
|
9
|
+
defaultYieldTimeMs?: number;
|
|
10
|
+
/** Default wait for an empty `write_stdin` poll. */
|
|
11
|
+
pollYieldTimeMs?: number;
|
|
12
|
+
/** Default wait for a non-empty `write_stdin` send. */
|
|
13
|
+
writeYieldTimeMs?: number;
|
|
14
|
+
/** Maximum output retained in one canonical result, in UTF-8 bytes. */
|
|
15
|
+
maxOutputBytes?: number;
|
|
16
|
+
}
|
|
17
|
+
/** Runtime configuration schema for the Codex tool bridge. */
|
|
18
|
+
export declare const Config: z<Config>;
|
|
19
|
+
/** Mount the Codex prompt/tool layer inside one fixed agent preset. */
|
|
20
|
+
export declare function apply(ctx: Context, config?: Config): void;
|
|
21
|
+
declare const _default: {
|
|
22
|
+
name: string;
|
|
23
|
+
inject: string[];
|
|
24
|
+
Config: z<Config>;
|
|
25
|
+
apply: typeof apply;
|
|
26
|
+
};
|
|
27
|
+
export default _default;
|
|
28
|
+
//# sourceMappingURL=index.d.ts.map
|