doer-agent 0.7.3 → 0.7.4
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/agent-codex-cli.js
CHANGED
|
@@ -11,6 +11,21 @@ function toTomlStringLiteral(value) {
|
|
|
11
11
|
function toTomlStringArray(values) {
|
|
12
12
|
return `[${values.map((value) => toTomlStringLiteral(value)).join(", ")}]`;
|
|
13
13
|
}
|
|
14
|
+
function buildMcpServerConfigArgs(args) {
|
|
15
|
+
const serverName = args.serverName.trim();
|
|
16
|
+
const configArgs = [
|
|
17
|
+
"--config",
|
|
18
|
+
`mcp_servers.${serverName}.command=${toTomlStringLiteral(args.command)}`,
|
|
19
|
+
"--config",
|
|
20
|
+
`mcp_servers.${serverName}.args=${toTomlStringArray(args.commandArgs)}`,
|
|
21
|
+
"--config",
|
|
22
|
+
`mcp_servers.${serverName}.enabled=${args.enabled === false ? "false" : "true"}`,
|
|
23
|
+
];
|
|
24
|
+
for (const [key, value] of Object.entries(args.env ?? {})) {
|
|
25
|
+
configArgs.push("--config", `mcp_servers.${serverName}.env.${key}=${toTomlStringLiteral(value)}`);
|
|
26
|
+
}
|
|
27
|
+
return configArgs;
|
|
28
|
+
}
|
|
14
29
|
function hasDirectCodexBinary() {
|
|
15
30
|
const result = spawnSync("bash", ["-lc", "command -v codex >/dev/null 2>&1"], {
|
|
16
31
|
stdio: "ignore",
|
|
@@ -71,6 +86,26 @@ export function buildMobileMcpConfigArgs(args) {
|
|
|
71
86
|
},
|
|
72
87
|
});
|
|
73
88
|
}
|
|
89
|
+
export function buildCustomMcpConfigArgs(servers) {
|
|
90
|
+
const configArgs = [];
|
|
91
|
+
const reservedNames = new Set(["doer_daemon", "doer_mobile"]);
|
|
92
|
+
const seenNames = new Set();
|
|
93
|
+
for (const server of servers) {
|
|
94
|
+
const serverName = server.name.trim();
|
|
95
|
+
if (!server.enabled || !serverName || !server.command.trim() || reservedNames.has(serverName) || seenNames.has(serverName)) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
seenNames.add(serverName);
|
|
99
|
+
configArgs.push(...buildMcpServerConfigArgs({
|
|
100
|
+
serverName,
|
|
101
|
+
command: server.command,
|
|
102
|
+
commandArgs: server.args,
|
|
103
|
+
env: Object.fromEntries(server.env.map((variable) => [variable.key, variable.value])),
|
|
104
|
+
enabled: true,
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
return configArgs;
|
|
108
|
+
}
|
|
74
109
|
function buildWorkspaceMcpConfigArgs(args) {
|
|
75
110
|
const serverName = args.serverName.trim();
|
|
76
111
|
const distEntry = path.join(args.agentProjectDir, args.distEntryRelativePath);
|
|
@@ -80,20 +115,16 @@ function buildWorkspaceMcpConfigArgs(args) {
|
|
|
80
115
|
const commandArgs = existsSync(distEntry)
|
|
81
116
|
? [distEntry, "--workspace-root", args.workspaceRoot]
|
|
82
117
|
: ["--import", tsxLoaderPath, srcEntry, "--workspace-root", args.workspaceRoot];
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
for (const [key, value] of Object.entries(args.env ?? {})) {
|
|
94
|
-
configArgs.push("--config", `mcp_servers.${serverName}.env.${key}=${toTomlStringLiteral(value)}`);
|
|
95
|
-
}
|
|
96
|
-
return configArgs;
|
|
118
|
+
return buildMcpServerConfigArgs({
|
|
119
|
+
serverName,
|
|
120
|
+
command,
|
|
121
|
+
commandArgs,
|
|
122
|
+
env: {
|
|
123
|
+
[args.workspaceRootEnvName]: args.workspaceRoot,
|
|
124
|
+
...(args.env ?? {}),
|
|
125
|
+
},
|
|
126
|
+
enabled: true,
|
|
127
|
+
});
|
|
97
128
|
}
|
|
98
129
|
export function buildLocalCodexCliCommand(args) {
|
|
99
130
|
const quotedArgs = args.map(shellSingleQuote).join(" ");
|
package/dist/agent-settings.js
CHANGED
|
@@ -41,6 +41,9 @@ export function createDefaultAgentSettingsConfig() {
|
|
|
41
41
|
env: {
|
|
42
42
|
variables: [],
|
|
43
43
|
},
|
|
44
|
+
mcp: {
|
|
45
|
+
servers: [],
|
|
46
|
+
},
|
|
44
47
|
};
|
|
45
48
|
}
|
|
46
49
|
function normalizeNullableString(value) {
|
|
@@ -115,6 +118,74 @@ function normalizeAgentEnvironmentSettings(value, fallback) {
|
|
|
115
118
|
}
|
|
116
119
|
return { variables };
|
|
117
120
|
}
|
|
121
|
+
function normalizeMcpServerName(value) {
|
|
122
|
+
if (typeof value !== "string") {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
const trimmed = value.trim();
|
|
126
|
+
if (!trimmed || !/^[A-Za-z0-9_-]+$/.test(trimmed)) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
if (trimmed === "doer_daemon" || trimmed === "doer_mobile") {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
return trimmed;
|
|
133
|
+
}
|
|
134
|
+
function normalizeStringArray(value) {
|
|
135
|
+
if (!Array.isArray(value)) {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
return value
|
|
139
|
+
.map((item) => (typeof item === "string" ? item.replace(/\r/g, "") : null))
|
|
140
|
+
.filter((item) => item !== null && item.trim().length > 0);
|
|
141
|
+
}
|
|
142
|
+
function normalizeAgentMcpServer(value) {
|
|
143
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
const raw = value;
|
|
147
|
+
const name = normalizeMcpServerName(raw.name);
|
|
148
|
+
const command = typeof raw.command === "string" ? raw.command.trim() : "";
|
|
149
|
+
if (!name || !command) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
const env = [];
|
|
153
|
+
const seenKeys = new Set();
|
|
154
|
+
const envRaw = Array.isArray(raw.env) ? raw.env : [];
|
|
155
|
+
for (const item of envRaw) {
|
|
156
|
+
const normalized = normalizeAgentEnvironmentVariable(item);
|
|
157
|
+
if (!normalized || seenKeys.has(normalized.key)) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
seenKeys.add(normalized.key);
|
|
161
|
+
env.push(normalized);
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
name,
|
|
165
|
+
command,
|
|
166
|
+
args: normalizeStringArray(raw.args),
|
|
167
|
+
env,
|
|
168
|
+
enabled: raw.enabled !== false,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
function normalizeAgentMcpSettings(value, fallback) {
|
|
172
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
173
|
+
return fallback;
|
|
174
|
+
}
|
|
175
|
+
const raw = value;
|
|
176
|
+
const serversRaw = Array.isArray(raw.servers) ? raw.servers : [];
|
|
177
|
+
const servers = [];
|
|
178
|
+
const seenNames = new Set();
|
|
179
|
+
for (const item of serversRaw) {
|
|
180
|
+
const normalized = normalizeAgentMcpServer(item);
|
|
181
|
+
if (!normalized || seenNames.has(normalized.name)) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
seenNames.add(normalized.name);
|
|
185
|
+
servers.push(normalized);
|
|
186
|
+
}
|
|
187
|
+
return { servers };
|
|
188
|
+
}
|
|
118
189
|
export function normalizeAgentSettingsConfig(value, fallback) {
|
|
119
190
|
const base = fallback ?? createDefaultAgentSettingsConfig();
|
|
120
191
|
const raw = value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
@@ -123,6 +194,7 @@ export function normalizeAgentSettingsConfig(value, fallback) {
|
|
|
123
194
|
const realtime = raw.realtime && typeof raw.realtime === "object" ? raw.realtime : {};
|
|
124
195
|
const git = raw.git && typeof raw.git === "object" ? raw.git : {};
|
|
125
196
|
const env = raw.env && typeof raw.env === "object" ? raw.env : null;
|
|
197
|
+
const mcp = raw.mcp && typeof raw.mcp === "object" ? raw.mcp : null;
|
|
126
198
|
return {
|
|
127
199
|
general: {
|
|
128
200
|
personality: normalizeCodexPersonality(general.personality, base.general.personality),
|
|
@@ -152,6 +224,7 @@ export function normalizeAgentSettingsConfig(value, fallback) {
|
|
|
152
224
|
oauthScope: git.oauthScope === null ? null : normalizeNullableString(git.oauthScope) ?? base.git.oauthScope,
|
|
153
225
|
},
|
|
154
226
|
env: normalizeAgentEnvironmentSettings(env, base.env),
|
|
227
|
+
mcp: normalizeAgentMcpSettings(mcp, base.mcp),
|
|
155
228
|
};
|
|
156
229
|
}
|
|
157
230
|
export async function readAgentSettingsConfig(args) {
|
|
@@ -245,6 +318,18 @@ export async function toAgentSettingsPublic(args) {
|
|
|
245
318
|
value: variable.value,
|
|
246
319
|
})),
|
|
247
320
|
},
|
|
321
|
+
mcp: {
|
|
322
|
+
servers: args.config.mcp.servers.map((server) => ({
|
|
323
|
+
name: server.name,
|
|
324
|
+
command: server.command,
|
|
325
|
+
args: [...server.args],
|
|
326
|
+
env: server.env.map((variable) => ({
|
|
327
|
+
key: variable.key,
|
|
328
|
+
value: variable.value,
|
|
329
|
+
})),
|
|
330
|
+
enabled: server.enabled,
|
|
331
|
+
})),
|
|
332
|
+
},
|
|
248
333
|
};
|
|
249
334
|
}
|
|
250
335
|
export function normalizeAgentSettingsPatch(value) {
|
|
@@ -287,6 +372,7 @@ export function normalizeAgentSettingsPatch(value) {
|
|
|
287
372
|
move("gitOauthLogin", "git", "oauthLogin");
|
|
288
373
|
move("gitOauthScope", "git", "oauthScope");
|
|
289
374
|
move("environmentVariables", "env", "variables");
|
|
375
|
+
move("mcpServers", "mcp", "servers");
|
|
290
376
|
return patch;
|
|
291
377
|
}
|
|
292
378
|
export function buildAgentSettingsEnvPatch(config) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { buildAgentSettingsEnvPatch, readAgentModelInstructions, resolveAgentModelInstructionsFilePath, } from "./agent-settings.js";
|
|
2
|
-
import { buildDaemonMcpConfigArgs, buildMobileMcpConfigArgs } from "./agent-codex-cli.js";
|
|
2
|
+
import { buildCustomMcpConfigArgs, buildDaemonMcpConfigArgs, buildMobileMcpConfigArgs } from "./agent-codex-cli.js";
|
|
3
3
|
import { CodexAppServerClient } from "./codex-app-server-client.js";
|
|
4
4
|
function toTomlStringLiteral(value) {
|
|
5
5
|
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
@@ -40,6 +40,7 @@ async function buildCodexAppServerArgs(args) {
|
|
|
40
40
|
userId: args.userId,
|
|
41
41
|
workspaceRoot: args.workspaceRoot,
|
|
42
42
|
}),
|
|
43
|
+
...buildCustomMcpConfigArgs(args.settings.mcp.servers),
|
|
43
44
|
...buildFeatureArg(true, "goals"),
|
|
44
45
|
...buildFeatureArg(args.settings.codex.computerUseEnabled, "computer_use"),
|
|
45
46
|
...buildFeatureArg(args.settings.codex.browserUseEnabled, "browser_use"),
|
|
@@ -82,7 +83,7 @@ export function createCodexAppServerManager(args) {
|
|
|
82
83
|
settings,
|
|
83
84
|
userId: args.userId,
|
|
84
85
|
});
|
|
85
|
-
args.onLog?.(`starting codex app-server model=${settings.codex.model} reasoningEffort=${settings.codex.reasoningEffort} personality=${settings.general.personality} computerUse=${settings.codex.computerUseEnabled} browserUse=${settings.codex.browserUseEnabled}`);
|
|
86
|
+
args.onLog?.(`starting codex app-server model=${settings.codex.model} reasoningEffort=${settings.codex.reasoningEffort} personality=${settings.general.personality} computerUse=${settings.codex.computerUseEnabled} browserUse=${settings.codex.browserUseEnabled} mcpServers=${settings.mcp.servers.filter((server) => server.enabled).length}`);
|
|
86
87
|
return new CodexAppServerClient({
|
|
87
88
|
cwd: args.workspaceRoot,
|
|
88
89
|
args: appServerArgs,
|