cofounder-crew 0.1.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/README.md +206 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +249 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/codex.d.ts +8 -0
- package/dist/src/codex.js +335 -0
- package/dist/src/codex.js.map +1 -0
- package/dist/src/codexConfig.d.ts +10 -0
- package/dist/src/codexConfig.js +136 -0
- package/dist/src/codexConfig.js.map +1 -0
- package/dist/src/codexSessions.d.ts +5 -0
- package/dist/src/codexSessions.js +100 -0
- package/dist/src/codexSessions.js.map +1 -0
- package/dist/src/config.d.ts +14 -0
- package/dist/src/config.js +154 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/errors.d.ts +4 -0
- package/dist/src/errors.js +12 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/git.d.ts +15 -0
- package/dist/src/git.js +151 -0
- package/dist/src/git.js.map +1 -0
- package/dist/src/init.d.ts +8 -0
- package/dist/src/init.js +43 -0
- package/dist/src/init.js.map +1 -0
- package/dist/src/mcp.d.ts +4 -0
- package/dist/src/mcp.js +159 -0
- package/dist/src/mcp.js.map +1 -0
- package/dist/src/memberRuntime.d.ts +13 -0
- package/dist/src/memberRuntime.js +70 -0
- package/dist/src/memberRuntime.js.map +1 -0
- package/dist/src/paths.d.ts +7 -0
- package/dist/src/paths.js +36 -0
- package/dist/src/paths.js.map +1 -0
- package/dist/src/prompt.d.ts +2 -0
- package/dist/src/prompt.js +59 -0
- package/dist/src/prompt.js.map +1 -0
- package/dist/src/runtime.d.ts +50 -0
- package/dist/src/runtime.js +362 -0
- package/dist/src/runtime.js.map +1 -0
- package/dist/src/setup.d.ts +6 -0
- package/dist/src/setup.js +48 -0
- package/dist/src/setup.js.map +1 -0
- package/dist/src/tasks.d.ts +10 -0
- package/dist/src/tasks.js +130 -0
- package/dist/src/tasks.js.map +1 -0
- package/dist/src/templates.d.ts +15 -0
- package/dist/src/templates.js +158 -0
- package/dist/src/templates.js.map +1 -0
- package/dist/src/types.d.ts +141 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/worker.d.ts +2 -0
- package/dist/src/worker.js +17 -0
- package/dist/src/worker.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { diffChangedFiles, mergeFiles, readGitSnapshot } from "./git.js";
|
|
5
|
+
import { appendTaskEvent, appendTaskLog, markTaskStatus, readTask, updateTask } from "./tasks.js";
|
|
6
|
+
export const CODEX_CAPABILITIES = {
|
|
7
|
+
runner: "codex",
|
|
8
|
+
async_tasks: true,
|
|
9
|
+
watch: true,
|
|
10
|
+
cancel: true,
|
|
11
|
+
live_interrupt: false,
|
|
12
|
+
interrupt_mode: "cancel-resume",
|
|
13
|
+
normalized_events: true,
|
|
14
|
+
member_home: true
|
|
15
|
+
};
|
|
16
|
+
export function buildCodexCommand(task, member, settings, codexConfig) {
|
|
17
|
+
const executionCwd = getExecutionCwd(task);
|
|
18
|
+
const isResume = Boolean(task.codex_resume_session_id);
|
|
19
|
+
const args = isResume
|
|
20
|
+
? [
|
|
21
|
+
"exec",
|
|
22
|
+
"resume",
|
|
23
|
+
"--skip-git-repo-check",
|
|
24
|
+
"--output-last-message",
|
|
25
|
+
path.resolve(task.cwd, task.result_path)
|
|
26
|
+
]
|
|
27
|
+
: [
|
|
28
|
+
"exec",
|
|
29
|
+
"--cd",
|
|
30
|
+
executionCwd,
|
|
31
|
+
"--skip-git-repo-check",
|
|
32
|
+
"--output-last-message",
|
|
33
|
+
path.resolve(task.cwd, task.result_path)
|
|
34
|
+
];
|
|
35
|
+
if (settings.model) {
|
|
36
|
+
args.push("-m", settings.model);
|
|
37
|
+
}
|
|
38
|
+
if (!isResume && settings.sandbox) {
|
|
39
|
+
args.push("-s", settings.sandbox);
|
|
40
|
+
}
|
|
41
|
+
if (!isResume && settings.approval) {
|
|
42
|
+
args.push("-a", settings.approval);
|
|
43
|
+
}
|
|
44
|
+
if (settings.reasoning_effort) {
|
|
45
|
+
args.push("-c", `model_reasoning_effort="${settings.reasoning_effort}"`);
|
|
46
|
+
}
|
|
47
|
+
if (settings.runner?.codex?.json) {
|
|
48
|
+
args.push("--json");
|
|
49
|
+
}
|
|
50
|
+
if (codexConfig?.isolated) {
|
|
51
|
+
args.push("--ignore-user-config");
|
|
52
|
+
args.push(...codexConfig.override_args);
|
|
53
|
+
}
|
|
54
|
+
if (settings.runner?.codex?.extra_args?.length) {
|
|
55
|
+
args.push(...settings.runner.codex.extra_args);
|
|
56
|
+
}
|
|
57
|
+
if (task.codex_resume_session_id) {
|
|
58
|
+
args.push(task.codex_resume_session_id);
|
|
59
|
+
}
|
|
60
|
+
args.push("-");
|
|
61
|
+
const env = { ...process.env };
|
|
62
|
+
if (settings.runner?.codex?.use_member_home && member.home) {
|
|
63
|
+
env.CODEX_HOME = path.resolve(task.config_root, member.home);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
command: "codex",
|
|
67
|
+
args,
|
|
68
|
+
env,
|
|
69
|
+
cwd: executionCwd
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export async function runCodexTask(task, member, settings, options = {}) {
|
|
73
|
+
let current = await markTaskStatus(task.cwd, task, "running", "Codex runner started");
|
|
74
|
+
const prompt = await readFile(path.resolve(task.cwd, task.prompt_path), "utf8");
|
|
75
|
+
const command = buildCodexCommand(current, member, settings, options.codexConfig);
|
|
76
|
+
const executionCwd = getExecutionCwd(current);
|
|
77
|
+
const baseSnapshot = await readGitSnapshot(executionCwd);
|
|
78
|
+
current = await updateTask(task.cwd, current.id, {
|
|
79
|
+
git_available: baseSnapshot.available,
|
|
80
|
+
base_changed_files: baseSnapshot.files
|
|
81
|
+
});
|
|
82
|
+
await appendTaskEvent(task.cwd, current, {
|
|
83
|
+
time: new Date().toISOString(),
|
|
84
|
+
task_id: current.id,
|
|
85
|
+
type: "runner.command",
|
|
86
|
+
message: [command.command, ...command.args.filter((arg) => arg !== prompt)].join(" ")
|
|
87
|
+
});
|
|
88
|
+
await appendTaskEvent(task.cwd, current, {
|
|
89
|
+
time: new Date().toISOString(),
|
|
90
|
+
task_id: current.id,
|
|
91
|
+
type: "runner.environment",
|
|
92
|
+
message: `cwd=${command.cwd} CODEX_HOME=${command.env.CODEX_HOME ?? "default"}`
|
|
93
|
+
});
|
|
94
|
+
await appendTaskEvent(task.cwd, current, {
|
|
95
|
+
time: new Date().toISOString(),
|
|
96
|
+
task_id: current.id,
|
|
97
|
+
type: "git.snapshot",
|
|
98
|
+
message: baseSnapshot.available
|
|
99
|
+
? `base changed files: ${baseSnapshot.files.length}`
|
|
100
|
+
: "git unavailable"
|
|
101
|
+
});
|
|
102
|
+
return await new Promise((resolve) => {
|
|
103
|
+
const child = spawn(command.command, command.args, {
|
|
104
|
+
cwd: command.cwd,
|
|
105
|
+
env: command.env,
|
|
106
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
107
|
+
});
|
|
108
|
+
const pendingWrites = [];
|
|
109
|
+
let stdoutBuffer = "";
|
|
110
|
+
let stderrBuffer = "";
|
|
111
|
+
void updateTask(task.cwd, current.id, { runner_pid: child.pid }).then((updated) => {
|
|
112
|
+
current = updated;
|
|
113
|
+
});
|
|
114
|
+
child.stdin.end(prompt);
|
|
115
|
+
child.stdout.on("data", (chunk) => {
|
|
116
|
+
const message = chunk.toString("utf8");
|
|
117
|
+
if (options.streamToConsole) {
|
|
118
|
+
process.stdout.write(message);
|
|
119
|
+
}
|
|
120
|
+
pendingWrites.push(appendTaskLog(task.cwd, current.stdout_path, message));
|
|
121
|
+
const processed = processOutputLines(stdoutBuffer + message);
|
|
122
|
+
stdoutBuffer = processed.remainder;
|
|
123
|
+
for (const line of processed.lines) {
|
|
124
|
+
maybeRecordCodexSessionId(task.cwd, current, line, pendingWrites);
|
|
125
|
+
pendingWrites.push(appendTaskEvent(task.cwd, current, normalizeCodexOutputLine(current.id, line, "stdout")));
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
child.stderr.on("data", (chunk) => {
|
|
129
|
+
const message = chunk.toString("utf8");
|
|
130
|
+
if (options.streamToConsole) {
|
|
131
|
+
process.stderr.write(message);
|
|
132
|
+
}
|
|
133
|
+
pendingWrites.push(appendTaskLog(task.cwd, current.stderr_path, message));
|
|
134
|
+
const processed = processOutputLines(stderrBuffer + message);
|
|
135
|
+
stderrBuffer = processed.remainder;
|
|
136
|
+
for (const line of processed.lines) {
|
|
137
|
+
maybeRecordCodexSessionId(task.cwd, current, line, pendingWrites);
|
|
138
|
+
pendingWrites.push(appendTaskEvent(task.cwd, current, normalizeCodexOutputLine(current.id, line, "stderr")));
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
child.on("error", (error) => {
|
|
142
|
+
pendingWrites.push(appendTaskEvent(task.cwd, current, {
|
|
143
|
+
time: new Date().toISOString(),
|
|
144
|
+
task_id: current.id,
|
|
145
|
+
type: "task.error",
|
|
146
|
+
message: error.message
|
|
147
|
+
}));
|
|
148
|
+
void Promise.allSettled(pendingWrites).then(() => updateTask(task.cwd, current.id, { error: error.message })).then((updated) => {
|
|
149
|
+
void markTaskStatus(task.cwd, updated, "failed", error.message).then(resolve);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
child.on("close", (code) => {
|
|
153
|
+
if (stdoutBuffer.length > 0) {
|
|
154
|
+
maybeRecordCodexSessionId(task.cwd, current, stdoutBuffer, pendingWrites);
|
|
155
|
+
pendingWrites.push(appendTaskEvent(task.cwd, current, normalizeCodexOutputLine(current.id, stdoutBuffer, "stdout")));
|
|
156
|
+
}
|
|
157
|
+
if (stderrBuffer.length > 0) {
|
|
158
|
+
maybeRecordCodexSessionId(task.cwd, current, stderrBuffer, pendingWrites);
|
|
159
|
+
pendingWrites.push(appendTaskEvent(task.cwd, current, normalizeCodexOutputLine(current.id, stderrBuffer, "stderr")));
|
|
160
|
+
}
|
|
161
|
+
void Promise.allSettled(pendingWrites)
|
|
162
|
+
.then(() => readTask(task.cwd, current.id))
|
|
163
|
+
.then((latest) => {
|
|
164
|
+
if (latest.status === "cancelled") {
|
|
165
|
+
resolve(latest);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
void finalizeGitState(task.cwd, executionCwd, current).then((gitPatch) => updateTask(task.cwd, current.id, { exit_code: code, ...gitPatch })).then((updated) => {
|
|
169
|
+
const status = code === 0 ? "succeeded" : "failed";
|
|
170
|
+
return markTaskStatus(task.cwd, updated, status, `Codex exited with code ${code ?? "unknown"}`).then(resolve);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
async function finalizeGitState(projectRoot, executionCwd, task) {
|
|
177
|
+
const afterSnapshot = await readGitSnapshot(executionCwd);
|
|
178
|
+
if (!afterSnapshot.available) {
|
|
179
|
+
await appendTaskEvent(projectRoot, task, {
|
|
180
|
+
time: new Date().toISOString(),
|
|
181
|
+
task_id: task.id,
|
|
182
|
+
type: "git.unavailable",
|
|
183
|
+
message: "git status unavailable after task"
|
|
184
|
+
});
|
|
185
|
+
return {
|
|
186
|
+
git_available: false,
|
|
187
|
+
changed_files: [],
|
|
188
|
+
touched_files: [],
|
|
189
|
+
conflict_risk: false
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
const baseFiles = task.base_changed_files ?? [];
|
|
193
|
+
const newChangedFiles = diffChangedFiles(baseFiles, afterSnapshot.files);
|
|
194
|
+
const retainedDirtyFiles = afterSnapshot.files.filter((file) => baseFiles.includes(file));
|
|
195
|
+
const changedFiles = afterSnapshot.files;
|
|
196
|
+
const touchedFiles = mergeFiles(newChangedFiles, retainedDirtyFiles);
|
|
197
|
+
const conflictRisk = retainedDirtyFiles.length > 0;
|
|
198
|
+
await appendTaskEvent(projectRoot, task, {
|
|
199
|
+
time: new Date().toISOString(),
|
|
200
|
+
task_id: task.id,
|
|
201
|
+
type: "git.changed_files",
|
|
202
|
+
message: newChangedFiles.length > 0 ? newChangedFiles.join(", ") : "no new changed files",
|
|
203
|
+
raw: {
|
|
204
|
+
base_changed_files: baseFiles,
|
|
205
|
+
changed_files: changedFiles,
|
|
206
|
+
new_changed_files: newChangedFiles,
|
|
207
|
+
touched_files: touchedFiles,
|
|
208
|
+
conflict_risk: conflictRisk
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
return {
|
|
212
|
+
git_available: true,
|
|
213
|
+
changed_files: changedFiles,
|
|
214
|
+
new_changed_files: newChangedFiles,
|
|
215
|
+
touched_files: touchedFiles,
|
|
216
|
+
conflict_risk: conflictRisk
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
function maybeRecordCodexSessionId(projectRoot, task, line, pendingWrites) {
|
|
220
|
+
if (task.codex_session_id) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const sessionId = extractCodexSessionId(line);
|
|
224
|
+
if (!sessionId) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
task.codex_session_id = sessionId;
|
|
228
|
+
pendingWrites.push(updateTask(projectRoot, task.id, { codex_session_id: sessionId })
|
|
229
|
+
.then((updated) => appendTaskEvent(projectRoot, updated, {
|
|
230
|
+
time: new Date().toISOString(),
|
|
231
|
+
task_id: task.id,
|
|
232
|
+
type: "codex.session",
|
|
233
|
+
message: sessionId
|
|
234
|
+
})));
|
|
235
|
+
}
|
|
236
|
+
function extractCodexSessionId(line) {
|
|
237
|
+
try {
|
|
238
|
+
const raw = JSON.parse(line);
|
|
239
|
+
if (!isRecord(raw)) {
|
|
240
|
+
return undefined;
|
|
241
|
+
}
|
|
242
|
+
const topLevel = firstString(raw.session_id, raw.thread_id, raw.conversation_id);
|
|
243
|
+
if (topLevel) {
|
|
244
|
+
return topLevel;
|
|
245
|
+
}
|
|
246
|
+
const payload = raw.payload;
|
|
247
|
+
if (isRecord(payload)) {
|
|
248
|
+
if (raw.type === "session_meta") {
|
|
249
|
+
return firstString(payload.id, payload.session_id, payload.thread_id);
|
|
250
|
+
}
|
|
251
|
+
return firstString(payload.session_id, payload.thread_id, payload.conversation_id);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
return undefined;
|
|
256
|
+
}
|
|
257
|
+
return undefined;
|
|
258
|
+
}
|
|
259
|
+
function getExecutionCwd(task) {
|
|
260
|
+
return task.execution_cwd ?? task.cwd;
|
|
261
|
+
}
|
|
262
|
+
function processOutputLines(buffer) {
|
|
263
|
+
const parts = buffer.split(/\r?\n/);
|
|
264
|
+
const remainder = parts.pop() ?? "";
|
|
265
|
+
return {
|
|
266
|
+
lines: parts.filter((line) => line.length > 0),
|
|
267
|
+
remainder
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
function normalizeCodexOutputLine(taskId, line, fallbackType) {
|
|
271
|
+
const time = new Date().toISOString();
|
|
272
|
+
try {
|
|
273
|
+
const raw = JSON.parse(line);
|
|
274
|
+
if (isRecord(raw)) {
|
|
275
|
+
const rawType = firstString(raw.type, raw.event, raw.name) ?? fallbackType;
|
|
276
|
+
return {
|
|
277
|
+
time,
|
|
278
|
+
task_id: taskId,
|
|
279
|
+
type: mapCodexEventType(rawType),
|
|
280
|
+
message: extractMessage(raw) ?? line,
|
|
281
|
+
raw
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
// Plain text output is expected when --json is disabled or a runner writes non-JSON diagnostics.
|
|
287
|
+
}
|
|
288
|
+
return {
|
|
289
|
+
time,
|
|
290
|
+
task_id: taskId,
|
|
291
|
+
type: fallbackType,
|
|
292
|
+
message: line
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
function mapCodexEventType(rawType) {
|
|
296
|
+
const normalized = rawType.toLowerCase().replace(/[^a-z0-9]+/g, ".");
|
|
297
|
+
if (/agent.*message|assistant.*message|message.*delta|response.*output/.test(normalized)) {
|
|
298
|
+
return "agent.message";
|
|
299
|
+
}
|
|
300
|
+
if (/tool.*call|function.*call|command.*start/.test(normalized)) {
|
|
301
|
+
return "tool.call";
|
|
302
|
+
}
|
|
303
|
+
if (/tool.*result|function.*result|command.*end/.test(normalized)) {
|
|
304
|
+
return "tool.result";
|
|
305
|
+
}
|
|
306
|
+
if (/error|failed/.test(normalized)) {
|
|
307
|
+
return "task.error";
|
|
308
|
+
}
|
|
309
|
+
return `codex.${normalized}`;
|
|
310
|
+
}
|
|
311
|
+
function extractMessage(raw) {
|
|
312
|
+
for (const key of ["message", "text", "content", "delta", "summary"]) {
|
|
313
|
+
const value = raw[key];
|
|
314
|
+
if (typeof value === "string" && value.length > 0) {
|
|
315
|
+
return value;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
const nested = raw.item ?? raw.data ?? raw.payload;
|
|
319
|
+
if (isRecord(nested)) {
|
|
320
|
+
return extractMessage(nested);
|
|
321
|
+
}
|
|
322
|
+
return undefined;
|
|
323
|
+
}
|
|
324
|
+
function firstString(...values) {
|
|
325
|
+
for (const value of values) {
|
|
326
|
+
if (typeof value === "string" && value.length > 0) {
|
|
327
|
+
return value;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return undefined;
|
|
331
|
+
}
|
|
332
|
+
function isRecord(value) {
|
|
333
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { LoadedProject, MemberDefinition, MemberSettings } from "./types.js";
|
|
2
|
+
export type McpMode = "inherit" | "none" | "allowlist";
|
|
3
|
+
export interface PreparedCodexConfig {
|
|
4
|
+
mode: McpMode;
|
|
5
|
+
config_path: string | null;
|
|
6
|
+
allowed_servers: string[];
|
|
7
|
+
isolated: boolean;
|
|
8
|
+
override_args: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare function prepareCodexConfig(project: LoadedProject, member: MemberDefinition, settings: MemberSettings, memberHomeAbsolutePath: string | null): Promise<PreparedCodexConfig>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
|
|
5
|
+
import { CofounderError } from "./errors.js";
|
|
6
|
+
import { pathExists } from "./paths.js";
|
|
7
|
+
export async function prepareCodexConfig(project, member, settings, memberHomeAbsolutePath) {
|
|
8
|
+
const mode = settings.mcp?.mode ?? "inherit";
|
|
9
|
+
const allowedServers = settings.mcp?.allow ?? [];
|
|
10
|
+
validateMcpSettings(mode, allowedServers);
|
|
11
|
+
const selectedServers = mode === "allowlist"
|
|
12
|
+
? await loadSelectedMcpServers(project, settings, allowedServers)
|
|
13
|
+
: {};
|
|
14
|
+
const codexConfig = buildCodexConfig(settings, selectedServers);
|
|
15
|
+
let configPath = null;
|
|
16
|
+
if (memberHomeAbsolutePath) {
|
|
17
|
+
const configAbsolutePath = path.join(memberHomeAbsolutePath, "config.toml");
|
|
18
|
+
await writeFile(configAbsolutePath, codexConfig, "utf8");
|
|
19
|
+
configPath = path.relative(project.projectRoot, configAbsolutePath);
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
mode,
|
|
23
|
+
config_path: configPath,
|
|
24
|
+
allowed_servers: mode === "allowlist" ? allowedServers : [],
|
|
25
|
+
isolated: mode !== "inherit",
|
|
26
|
+
override_args: mode === "allowlist" ? buildMcpOverrideArgs(selectedServers) : []
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function validateMcpSettings(mode, allowedServers) {
|
|
30
|
+
if (!["inherit", "none", "allowlist"].includes(mode)) {
|
|
31
|
+
throw new CofounderError(`Unsupported MCP mode: ${mode}`);
|
|
32
|
+
}
|
|
33
|
+
if (mode !== "allowlist" && allowedServers.length > 0) {
|
|
34
|
+
throw new CofounderError("mcp.allow can only be used when mcp.mode = \"allowlist\"");
|
|
35
|
+
}
|
|
36
|
+
for (const server of allowedServers) {
|
|
37
|
+
if (!/^[A-Za-z0-9_-]+$/.test(server)) {
|
|
38
|
+
throw new CofounderError(`Unsupported MCP server id: ${server}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function loadSelectedMcpServers(project, settings, allowedServers) {
|
|
43
|
+
const configPath = resolveBaseCodexConfigPath(project, settings);
|
|
44
|
+
if (!(await pathExists(configPath))) {
|
|
45
|
+
throw new CofounderError(`Codex config not found for MCP allowlist: ${configPath}`);
|
|
46
|
+
}
|
|
47
|
+
const raw = await readFile(configPath, "utf8");
|
|
48
|
+
const parsed = parseToml(raw);
|
|
49
|
+
const mcpServers = isRecord(parsed) && isRecord(parsed.mcp_servers) ? parsed.mcp_servers : {};
|
|
50
|
+
const selected = {};
|
|
51
|
+
const missing = [];
|
|
52
|
+
for (const server of allowedServers) {
|
|
53
|
+
const definition = mcpServers[server];
|
|
54
|
+
if (!isRecord(definition)) {
|
|
55
|
+
missing.push(server);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
selected[server] = sanitizeMcpServerDefinition(definition, settings.mcp?.include_inline_env === true);
|
|
59
|
+
}
|
|
60
|
+
if (missing.length > 0) {
|
|
61
|
+
throw new CofounderError(`MCP server(s) not found in Codex config: ${missing.join(", ")}`);
|
|
62
|
+
}
|
|
63
|
+
return selected;
|
|
64
|
+
}
|
|
65
|
+
function resolveBaseCodexConfigPath(project, settings) {
|
|
66
|
+
if (settings.mcp?.config_path) {
|
|
67
|
+
return path.isAbsolute(settings.mcp.config_path)
|
|
68
|
+
? settings.mcp.config_path
|
|
69
|
+
: path.resolve(project.projectRoot, settings.mcp.config_path);
|
|
70
|
+
}
|
|
71
|
+
const codexHome = process.env.CODEX_HOME ? path.resolve(process.env.CODEX_HOME) : path.join(os.homedir(), ".codex");
|
|
72
|
+
return path.join(codexHome, "config.toml");
|
|
73
|
+
}
|
|
74
|
+
function sanitizeMcpServerDefinition(definition, includeInlineEnv) {
|
|
75
|
+
const allowedKeys = [
|
|
76
|
+
"url",
|
|
77
|
+
"command",
|
|
78
|
+
"args",
|
|
79
|
+
"cwd",
|
|
80
|
+
"bearer_token_env_var",
|
|
81
|
+
"startup_timeout_sec",
|
|
82
|
+
"tool_timeout_sec"
|
|
83
|
+
];
|
|
84
|
+
const sanitized = {};
|
|
85
|
+
for (const key of allowedKeys) {
|
|
86
|
+
if (definition[key] !== undefined) {
|
|
87
|
+
sanitized[key] = definition[key];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (includeInlineEnv && isRecord(definition.env)) {
|
|
91
|
+
sanitized.env = definition.env;
|
|
92
|
+
}
|
|
93
|
+
return sanitized;
|
|
94
|
+
}
|
|
95
|
+
function buildCodexConfig(settings, selectedServers) {
|
|
96
|
+
const config = {};
|
|
97
|
+
if (settings.model) {
|
|
98
|
+
config.model = settings.model;
|
|
99
|
+
}
|
|
100
|
+
if (settings.reasoning_effort) {
|
|
101
|
+
config.model_reasoning_effort = settings.reasoning_effort;
|
|
102
|
+
}
|
|
103
|
+
if (Object.keys(selectedServers).length > 0) {
|
|
104
|
+
config.mcp_servers = selectedServers;
|
|
105
|
+
}
|
|
106
|
+
return `# Generated by Cofounder. Do not put auth secrets here.\n${stringifyToml(config)}\n`;
|
|
107
|
+
}
|
|
108
|
+
function buildMcpOverrideArgs(selectedServers) {
|
|
109
|
+
const args = [];
|
|
110
|
+
for (const [serverName, definition] of Object.entries(selectedServers)) {
|
|
111
|
+
for (const [key, value] of Object.entries(definition)) {
|
|
112
|
+
args.push("-c", `mcp_servers.${serverName}.${key}=${tomlValue(value)}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return args;
|
|
116
|
+
}
|
|
117
|
+
function tomlValue(value) {
|
|
118
|
+
if (typeof value === "string") {
|
|
119
|
+
return JSON.stringify(value);
|
|
120
|
+
}
|
|
121
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
122
|
+
return String(value);
|
|
123
|
+
}
|
|
124
|
+
if (Array.isArray(value)) {
|
|
125
|
+
return `[${value.map(tomlValue).join(", ")}]`;
|
|
126
|
+
}
|
|
127
|
+
if (isRecord(value)) {
|
|
128
|
+
const entries = Object.entries(value).map(([key, entryValue]) => `${key} = ${tomlValue(entryValue)}`);
|
|
129
|
+
return `{ ${entries.join(", ")} }`;
|
|
130
|
+
}
|
|
131
|
+
throw new CofounderError(`Unsupported MCP config value: ${String(value)}`);
|
|
132
|
+
}
|
|
133
|
+
function isRecord(value) {
|
|
134
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=codexConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codexConfig.js","sourceRoot":"","sources":["../../src/codexConfig.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { createReadStream } from "node:fs";
|
|
2
|
+
import { readdir, stat } from "node:fs/promises";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { createInterface } from "node:readline";
|
|
6
|
+
export async function findRecentCodexSessionId(options) {
|
|
7
|
+
const sessionsRoot = path.join(options.codexHome ?? process.env.CODEX_HOME ?? path.join(os.homedir(), ".codex"), "sessions");
|
|
8
|
+
const candidates = await listCandidateSessionFiles(sessionsRoot, options.since);
|
|
9
|
+
const sinceMs = options.since ? Date.parse(options.since) - 60_000 : 0;
|
|
10
|
+
for (const filePath of candidates) {
|
|
11
|
+
const meta = await readSessionMeta(filePath);
|
|
12
|
+
if (!meta) {
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
if (path.resolve(meta.cwd) !== path.resolve(options.cwd)) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (sinceMs > 0 && meta.timestamp && Date.parse(meta.timestamp) < sinceMs) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
return meta.id;
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
async function listCandidateSessionFiles(sessionsRoot, since) {
|
|
26
|
+
const days = candidateDays(since ? new Date(since) : new Date());
|
|
27
|
+
const files = [];
|
|
28
|
+
for (const day of days) {
|
|
29
|
+
const dir = path.join(sessionsRoot, day.year, day.month, day.day);
|
|
30
|
+
let entries;
|
|
31
|
+
try {
|
|
32
|
+
entries = await readdir(dir);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
for (const entry of entries) {
|
|
38
|
+
if (!entry.endsWith(".jsonl")) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const filePath = path.join(dir, entry);
|
|
42
|
+
try {
|
|
43
|
+
const info = await stat(filePath);
|
|
44
|
+
files.push({ path: filePath, mtimeMs: info.mtimeMs });
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Ignore files that disappeared while scanning.
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return files
|
|
52
|
+
.sort((left, right) => right.mtimeMs - left.mtimeMs)
|
|
53
|
+
.map((file) => file.path);
|
|
54
|
+
}
|
|
55
|
+
async function readSessionMeta(filePath) {
|
|
56
|
+
const stream = createReadStream(filePath, { encoding: "utf8" });
|
|
57
|
+
const reader = createInterface({ input: stream, crlfDelay: Infinity });
|
|
58
|
+
try {
|
|
59
|
+
for await (const line of reader) {
|
|
60
|
+
const raw = JSON.parse(line);
|
|
61
|
+
if (!isRecord(raw) || raw.type !== "session_meta" || !isRecord(raw.payload)) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const id = raw.payload.id;
|
|
65
|
+
const cwd = raw.payload.cwd;
|
|
66
|
+
const timestamp = raw.payload.timestamp;
|
|
67
|
+
if (typeof id === "string" && typeof cwd === "string") {
|
|
68
|
+
return {
|
|
69
|
+
id,
|
|
70
|
+
cwd,
|
|
71
|
+
timestamp: typeof timestamp === "string" ? timestamp : undefined
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
reader.close();
|
|
82
|
+
stream.destroy();
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
function candidateDays(date) {
|
|
87
|
+
return [-1, 0, 1].map((offset) => {
|
|
88
|
+
const next = new Date(date);
|
|
89
|
+
next.setDate(date.getDate() + offset);
|
|
90
|
+
return {
|
|
91
|
+
year: String(next.getFullYear()),
|
|
92
|
+
month: String(next.getMonth() + 1).padStart(2, "0"),
|
|
93
|
+
day: String(next.getDate()).padStart(2, "0")
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function isRecord(value) {
|
|
98
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=codexSessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codexSessions.js","sourceRoot":"","sources":["../../src/codexSessions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { LoadedProject, MemberDefinition, MemberSettings } from "./types.js";
|
|
2
|
+
export declare function loadProject(startDir?: string): Promise<LoadedProject>;
|
|
3
|
+
export declare function loadMemberSettings(project: LoadedProject, member: MemberDefinition): Promise<MemberSettings>;
|
|
4
|
+
export declare function getMemberPaths(project: LoadedProject, member: MemberDefinition): {
|
|
5
|
+
promptPath: string;
|
|
6
|
+
settingsPath: string;
|
|
7
|
+
homePath: string | null;
|
|
8
|
+
promptAbsolutePath: string;
|
|
9
|
+
settingsAbsolutePath: string;
|
|
10
|
+
homeAbsolutePath: string | null;
|
|
11
|
+
};
|
|
12
|
+
export declare function getMember(project: LoadedProject, memberId: string): MemberDefinition;
|
|
13
|
+
export declare function assertCanCall(project: LoadedProject, callerId: string, assigneeId: string): void;
|
|
14
|
+
export declare function summarizeTeam(project: LoadedProject): string;
|