@lesscap/baton-cli 0.4.3 → 0.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/baton.mjs +39 -565
- package/package.json +1 -1
package/dist/baton.mjs
CHANGED
|
@@ -4777,30 +4777,30 @@ import { join } from "node:path";
|
|
|
4777
4777
|
var PROJECT_CONFIG_NAME = ".baton.json";
|
|
4778
4778
|
var projectConfigPath = (cwd = process.cwd()) => join(cwd, PROJECT_CONFIG_NAME);
|
|
4779
4779
|
var configPathFromArgs = (args, cwd) => args.config ?? projectConfigPath(cwd);
|
|
4780
|
-
var loadProjectConfig = (
|
|
4780
|
+
var loadProjectConfig = (path) => {
|
|
4781
4781
|
try {
|
|
4782
|
-
return JSON.parse(readFileSync(
|
|
4782
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
4783
4783
|
} catch (err) {
|
|
4784
|
-
const cause = err.code === "ENOENT" ? `not found at ${
|
|
4784
|
+
const cause = err.code === "ENOENT" ? `not found at ${path}` : String(err);
|
|
4785
4785
|
throw new Error(`${PROJECT_CONFIG_NAME} ${cause} \u2014 run \`baton init\` first`);
|
|
4786
4786
|
}
|
|
4787
4787
|
};
|
|
4788
|
-
var loadProjectConfigOrNull = (
|
|
4789
|
-
if (!existsSync(
|
|
4788
|
+
var loadProjectConfigOrNull = (path) => {
|
|
4789
|
+
if (!existsSync(path)) return null;
|
|
4790
4790
|
try {
|
|
4791
|
-
return JSON.parse(readFileSync(
|
|
4791
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
4792
4792
|
} catch {
|
|
4793
4793
|
return null;
|
|
4794
4794
|
}
|
|
4795
4795
|
};
|
|
4796
|
-
var saveProjectConfig = (
|
|
4797
|
-
writeFileSync(
|
|
4796
|
+
var saveProjectConfig = (path, config) => {
|
|
4797
|
+
writeFileSync(path, `${JSON.stringify(config, null, 2)}
|
|
4798
4798
|
`, "utf8");
|
|
4799
4799
|
};
|
|
4800
|
-
var patch = (
|
|
4801
|
-
saveProjectConfig(
|
|
4800
|
+
var patch = (path, fn) => {
|
|
4801
|
+
saveProjectConfig(path, fn(loadProjectConfig(path)));
|
|
4802
4802
|
};
|
|
4803
|
-
var setWorker = (
|
|
4803
|
+
var setWorker = (path, w) => patch(path, (cfg) => ({ ...cfg, worker: w }));
|
|
4804
4804
|
var requireBase = (cfg) => {
|
|
4805
4805
|
if (!cfg.server || !cfg.project || !cfg.worker)
|
|
4806
4806
|
throw new Error("project-config missing server/project/worker \u2014 run `baton worker register`");
|
|
@@ -5566,7 +5566,7 @@ var BY_EXT = {
|
|
|
5566
5566
|
".json": "application/json",
|
|
5567
5567
|
".csv": "text/csv"
|
|
5568
5568
|
};
|
|
5569
|
-
var contentTypeForPath = (
|
|
5569
|
+
var contentTypeForPath = (path) => BY_EXT[extname(path).toLowerCase()] ?? "application/octet-stream";
|
|
5570
5570
|
|
|
5571
5571
|
// src/commands/attach.ts
|
|
5572
5572
|
import { openAsBlob } from "node:fs";
|
|
@@ -5574,12 +5574,12 @@ import { basename } from "node:path";
|
|
|
5574
5574
|
var attachPaths = (raw) => (raw === void 0 ? [] : Array.isArray(raw) ? raw : [raw]).flatMap((p) => p.split(",")).map((p) => p.trim()).filter(Boolean);
|
|
5575
5575
|
var uploadAttachments = async (client, sessionId, paths) => {
|
|
5576
5576
|
const out = [];
|
|
5577
|
-
for (const
|
|
5578
|
-
const body = await openAsBlob(
|
|
5577
|
+
for (const path of paths) {
|
|
5578
|
+
const body = await openAsBlob(path, { type: contentTypeForPath(path) });
|
|
5579
5579
|
out.push(
|
|
5580
5580
|
await client.sessions.uploadAttachment(sessionId, {
|
|
5581
|
-
filename: basename(
|
|
5582
|
-
contentType: contentTypeForPath(
|
|
5581
|
+
filename: basename(path),
|
|
5582
|
+
contentType: contentTypeForPath(path),
|
|
5583
5583
|
body
|
|
5584
5584
|
})
|
|
5585
5585
|
);
|
|
@@ -5612,12 +5612,12 @@ var sendCommand = defineCommand({
|
|
|
5612
5612
|
if (text === void 0 && args.file) text = readFileSync2(args.file, "utf8");
|
|
5613
5613
|
if (text === void 0 && !process.stdin.isTTY) text = await readStdin();
|
|
5614
5614
|
const attachments = [];
|
|
5615
|
-
for (const
|
|
5615
|
+
for (const path of attachPaths(args.attach)) {
|
|
5616
5616
|
attachments.push(
|
|
5617
5617
|
await client.uploadAttachment(args.channel, {
|
|
5618
|
-
filename: basename2(
|
|
5619
|
-
contentType: contentTypeForPath(
|
|
5620
|
-
body: await openAsBlob2(
|
|
5618
|
+
filename: basename2(path),
|
|
5619
|
+
contentType: contentTypeForPath(path),
|
|
5620
|
+
body: await openAsBlob2(path, { type: contentTypeForPath(path) })
|
|
5621
5621
|
})
|
|
5622
5622
|
);
|
|
5623
5623
|
}
|
|
@@ -6463,10 +6463,10 @@ var parseFirstExchange = (content) => {
|
|
|
6463
6463
|
return userText || assistantText ? { userText, assistantText } : null;
|
|
6464
6464
|
};
|
|
6465
6465
|
var readFirstExchange = (agentSessionId) => {
|
|
6466
|
-
const
|
|
6467
|
-
if (!
|
|
6466
|
+
const path = findTranscriptPath(agentSessionId);
|
|
6467
|
+
if (!path) return null;
|
|
6468
6468
|
try {
|
|
6469
|
-
return parseFirstExchange(readFileSync4(
|
|
6469
|
+
return parseFirstExchange(readFileSync4(path, "utf8"));
|
|
6470
6470
|
} catch {
|
|
6471
6471
|
return null;
|
|
6472
6472
|
}
|
|
@@ -6523,534 +6523,8 @@ var augmentPrompt = (text, relPaths, labels) => {
|
|
|
6523
6523
|
${text}` : header;
|
|
6524
6524
|
};
|
|
6525
6525
|
|
|
6526
|
-
// ../../node_modules/.pnpm/@openai+codex-sdk@0.142.5/node_modules/@openai/codex-sdk/dist/index.js
|
|
6527
|
-
import { promises as fs } from "fs";
|
|
6528
|
-
import os from "os";
|
|
6529
|
-
import path from "path";
|
|
6530
|
-
import { spawn } from "child_process";
|
|
6531
|
-
import { statSync as statSync2 } from "fs";
|
|
6532
|
-
import path2 from "path";
|
|
6533
|
-
import readline2 from "readline";
|
|
6534
|
-
import { createRequire } from "module";
|
|
6535
|
-
async function createOutputSchemaFile(schema) {
|
|
6536
|
-
if (schema === void 0) {
|
|
6537
|
-
return { cleanup: async () => {
|
|
6538
|
-
} };
|
|
6539
|
-
}
|
|
6540
|
-
if (!isJsonObject(schema)) {
|
|
6541
|
-
throw new Error("outputSchema must be a plain JSON object");
|
|
6542
|
-
}
|
|
6543
|
-
const schemaDir = await fs.mkdtemp(path.join(os.tmpdir(), "codex-output-schema-"));
|
|
6544
|
-
const schemaPath = path.join(schemaDir, "schema.json");
|
|
6545
|
-
const cleanup = async () => {
|
|
6546
|
-
try {
|
|
6547
|
-
await fs.rm(schemaDir, { recursive: true, force: true });
|
|
6548
|
-
} catch {
|
|
6549
|
-
}
|
|
6550
|
-
};
|
|
6551
|
-
try {
|
|
6552
|
-
await fs.writeFile(schemaPath, JSON.stringify(schema), "utf8");
|
|
6553
|
-
return { schemaPath, cleanup };
|
|
6554
|
-
} catch (error) {
|
|
6555
|
-
await cleanup();
|
|
6556
|
-
throw error;
|
|
6557
|
-
}
|
|
6558
|
-
}
|
|
6559
|
-
function isJsonObject(value) {
|
|
6560
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6561
|
-
}
|
|
6562
|
-
var Thread = class {
|
|
6563
|
-
_exec;
|
|
6564
|
-
_options;
|
|
6565
|
-
_id;
|
|
6566
|
-
_threadOptions;
|
|
6567
|
-
/** Returns the ID of the thread. Populated after the first turn starts. */
|
|
6568
|
-
get id() {
|
|
6569
|
-
return this._id;
|
|
6570
|
-
}
|
|
6571
|
-
/* @internal */
|
|
6572
|
-
constructor(exec, options, threadOptions, id = null) {
|
|
6573
|
-
this._exec = exec;
|
|
6574
|
-
this._options = options;
|
|
6575
|
-
this._id = id;
|
|
6576
|
-
this._threadOptions = threadOptions;
|
|
6577
|
-
}
|
|
6578
|
-
/** Provides the input to the agent and streams events as they are produced during the turn. */
|
|
6579
|
-
async runStreamed(input, turnOptions = {}) {
|
|
6580
|
-
return { events: this.runStreamedInternal(input, turnOptions) };
|
|
6581
|
-
}
|
|
6582
|
-
async *runStreamedInternal(input, turnOptions = {}) {
|
|
6583
|
-
const { schemaPath, cleanup } = await createOutputSchemaFile(turnOptions.outputSchema);
|
|
6584
|
-
const options = this._threadOptions;
|
|
6585
|
-
const { prompt, images } = normalizeInput(input);
|
|
6586
|
-
const generator = this._exec.run({
|
|
6587
|
-
input: prompt,
|
|
6588
|
-
baseUrl: this._options.baseUrl,
|
|
6589
|
-
apiKey: this._options.apiKey,
|
|
6590
|
-
threadId: this._id,
|
|
6591
|
-
images,
|
|
6592
|
-
model: options?.model,
|
|
6593
|
-
sandboxMode: options?.sandboxMode,
|
|
6594
|
-
workingDirectory: options?.workingDirectory,
|
|
6595
|
-
skipGitRepoCheck: options?.skipGitRepoCheck,
|
|
6596
|
-
outputSchemaFile: schemaPath,
|
|
6597
|
-
modelReasoningEffort: options?.modelReasoningEffort,
|
|
6598
|
-
signal: turnOptions.signal,
|
|
6599
|
-
networkAccessEnabled: options?.networkAccessEnabled,
|
|
6600
|
-
webSearchMode: options?.webSearchMode,
|
|
6601
|
-
webSearchEnabled: options?.webSearchEnabled,
|
|
6602
|
-
approvalPolicy: options?.approvalPolicy,
|
|
6603
|
-
additionalDirectories: options?.additionalDirectories
|
|
6604
|
-
});
|
|
6605
|
-
try {
|
|
6606
|
-
for await (const item of generator) {
|
|
6607
|
-
let parsed;
|
|
6608
|
-
try {
|
|
6609
|
-
parsed = JSON.parse(item);
|
|
6610
|
-
} catch (error) {
|
|
6611
|
-
throw new Error(`Failed to parse item: ${item}`, { cause: error });
|
|
6612
|
-
}
|
|
6613
|
-
if (parsed.type === "thread.started") {
|
|
6614
|
-
this._id = parsed.thread_id;
|
|
6615
|
-
}
|
|
6616
|
-
yield parsed;
|
|
6617
|
-
}
|
|
6618
|
-
} finally {
|
|
6619
|
-
await cleanup();
|
|
6620
|
-
}
|
|
6621
|
-
}
|
|
6622
|
-
/** Provides the input to the agent and returns the completed turn. */
|
|
6623
|
-
async run(input, turnOptions = {}) {
|
|
6624
|
-
const generator = this.runStreamedInternal(input, turnOptions);
|
|
6625
|
-
const items = [];
|
|
6626
|
-
let finalResponse = "";
|
|
6627
|
-
let usage = null;
|
|
6628
|
-
let turnFailure = null;
|
|
6629
|
-
for await (const event of generator) {
|
|
6630
|
-
if (event.type === "item.completed") {
|
|
6631
|
-
if (event.item.type === "agent_message") {
|
|
6632
|
-
finalResponse = event.item.text;
|
|
6633
|
-
}
|
|
6634
|
-
items.push(event.item);
|
|
6635
|
-
} else if (event.type === "turn.completed") {
|
|
6636
|
-
usage = event.usage;
|
|
6637
|
-
} else if (event.type === "turn.failed") {
|
|
6638
|
-
turnFailure = event.error;
|
|
6639
|
-
break;
|
|
6640
|
-
}
|
|
6641
|
-
}
|
|
6642
|
-
if (turnFailure) {
|
|
6643
|
-
throw new Error(turnFailure.message);
|
|
6644
|
-
}
|
|
6645
|
-
return { items, finalResponse, usage };
|
|
6646
|
-
}
|
|
6647
|
-
};
|
|
6648
|
-
function normalizeInput(input) {
|
|
6649
|
-
if (typeof input === "string") {
|
|
6650
|
-
return { prompt: input, images: [] };
|
|
6651
|
-
}
|
|
6652
|
-
const promptParts = [];
|
|
6653
|
-
const images = [];
|
|
6654
|
-
for (const item of input) {
|
|
6655
|
-
if (item.type === "text") {
|
|
6656
|
-
promptParts.push(item.text);
|
|
6657
|
-
} else if (item.type === "local_image") {
|
|
6658
|
-
images.push(item.path);
|
|
6659
|
-
}
|
|
6660
|
-
}
|
|
6661
|
-
return { prompt: promptParts.join("\n\n"), images };
|
|
6662
|
-
}
|
|
6663
|
-
var INTERNAL_ORIGINATOR_ENV = "CODEX_INTERNAL_ORIGINATOR_OVERRIDE";
|
|
6664
|
-
var TYPESCRIPT_SDK_ORIGINATOR = "codex_sdk_ts";
|
|
6665
|
-
var CODEX_NPM_NAME = "@openai/codex";
|
|
6666
|
-
var PLATFORM_PACKAGE_BY_TARGET = {
|
|
6667
|
-
"x86_64-unknown-linux-musl": "@openai/codex-linux-x64",
|
|
6668
|
-
"aarch64-unknown-linux-musl": "@openai/codex-linux-arm64",
|
|
6669
|
-
"x86_64-apple-darwin": "@openai/codex-darwin-x64",
|
|
6670
|
-
"aarch64-apple-darwin": "@openai/codex-darwin-arm64",
|
|
6671
|
-
"x86_64-pc-windows-msvc": "@openai/codex-win32-x64",
|
|
6672
|
-
"aarch64-pc-windows-msvc": "@openai/codex-win32-arm64"
|
|
6673
|
-
};
|
|
6674
|
-
var moduleRequire = createRequire(import.meta.url);
|
|
6675
|
-
var CodexExec = class {
|
|
6676
|
-
executablePath;
|
|
6677
|
-
pathDirs;
|
|
6678
|
-
envOverride;
|
|
6679
|
-
configOverrides;
|
|
6680
|
-
constructor(executablePath = null, env, configOverrides) {
|
|
6681
|
-
if (executablePath) {
|
|
6682
|
-
this.executablePath = executablePath;
|
|
6683
|
-
this.pathDirs = [];
|
|
6684
|
-
} else {
|
|
6685
|
-
const resolved = findCodexPath();
|
|
6686
|
-
this.executablePath = resolved.executablePath;
|
|
6687
|
-
this.pathDirs = resolved.pathDirs;
|
|
6688
|
-
}
|
|
6689
|
-
this.envOverride = env;
|
|
6690
|
-
this.configOverrides = configOverrides;
|
|
6691
|
-
}
|
|
6692
|
-
async *run(args) {
|
|
6693
|
-
const commandArgs = ["exec", "--experimental-json"];
|
|
6694
|
-
if (this.configOverrides) {
|
|
6695
|
-
for (const override of serializeConfigOverrides(this.configOverrides)) {
|
|
6696
|
-
commandArgs.push("--config", override);
|
|
6697
|
-
}
|
|
6698
|
-
}
|
|
6699
|
-
if (args.baseUrl) {
|
|
6700
|
-
commandArgs.push(
|
|
6701
|
-
"--config",
|
|
6702
|
-
`openai_base_url=${toTomlValue(args.baseUrl, "openai_base_url")}`
|
|
6703
|
-
);
|
|
6704
|
-
}
|
|
6705
|
-
if (args.model) {
|
|
6706
|
-
commandArgs.push("--model", args.model);
|
|
6707
|
-
}
|
|
6708
|
-
if (args.sandboxMode) {
|
|
6709
|
-
commandArgs.push("--sandbox", args.sandboxMode);
|
|
6710
|
-
}
|
|
6711
|
-
if (args.workingDirectory) {
|
|
6712
|
-
commandArgs.push("--cd", args.workingDirectory);
|
|
6713
|
-
}
|
|
6714
|
-
if (args.additionalDirectories?.length) {
|
|
6715
|
-
for (const dir of args.additionalDirectories) {
|
|
6716
|
-
commandArgs.push("--add-dir", dir);
|
|
6717
|
-
}
|
|
6718
|
-
}
|
|
6719
|
-
if (args.skipGitRepoCheck) {
|
|
6720
|
-
commandArgs.push("--skip-git-repo-check");
|
|
6721
|
-
}
|
|
6722
|
-
if (args.outputSchemaFile) {
|
|
6723
|
-
commandArgs.push("--output-schema", args.outputSchemaFile);
|
|
6724
|
-
}
|
|
6725
|
-
if (args.modelReasoningEffort) {
|
|
6726
|
-
commandArgs.push("--config", `model_reasoning_effort="${args.modelReasoningEffort}"`);
|
|
6727
|
-
}
|
|
6728
|
-
if (args.networkAccessEnabled !== void 0) {
|
|
6729
|
-
commandArgs.push(
|
|
6730
|
-
"--config",
|
|
6731
|
-
`sandbox_workspace_write.network_access=${args.networkAccessEnabled}`
|
|
6732
|
-
);
|
|
6733
|
-
}
|
|
6734
|
-
if (args.webSearchMode) {
|
|
6735
|
-
commandArgs.push("--config", `web_search="${args.webSearchMode}"`);
|
|
6736
|
-
} else if (args.webSearchEnabled === true) {
|
|
6737
|
-
commandArgs.push("--config", `web_search="live"`);
|
|
6738
|
-
} else if (args.webSearchEnabled === false) {
|
|
6739
|
-
commandArgs.push("--config", `web_search="disabled"`);
|
|
6740
|
-
}
|
|
6741
|
-
if (args.approvalPolicy) {
|
|
6742
|
-
commandArgs.push("--config", `approval_policy="${args.approvalPolicy}"`);
|
|
6743
|
-
}
|
|
6744
|
-
if (args.threadId) {
|
|
6745
|
-
commandArgs.push("resume", args.threadId);
|
|
6746
|
-
}
|
|
6747
|
-
if (args.images?.length) {
|
|
6748
|
-
for (const image of args.images) {
|
|
6749
|
-
commandArgs.push("--image", image);
|
|
6750
|
-
}
|
|
6751
|
-
}
|
|
6752
|
-
const env = {};
|
|
6753
|
-
if (this.envOverride) {
|
|
6754
|
-
Object.assign(env, this.envOverride);
|
|
6755
|
-
} else {
|
|
6756
|
-
for (const [key, value] of Object.entries(process.env)) {
|
|
6757
|
-
if (value !== void 0) {
|
|
6758
|
-
env[key] = value;
|
|
6759
|
-
}
|
|
6760
|
-
}
|
|
6761
|
-
}
|
|
6762
|
-
if (!env[INTERNAL_ORIGINATOR_ENV]) {
|
|
6763
|
-
env[INTERNAL_ORIGINATOR_ENV] = TYPESCRIPT_SDK_ORIGINATOR;
|
|
6764
|
-
}
|
|
6765
|
-
if (args.apiKey) {
|
|
6766
|
-
env.CODEX_API_KEY = args.apiKey;
|
|
6767
|
-
}
|
|
6768
|
-
if (this.pathDirs.length > 0) {
|
|
6769
|
-
prependPathDirs(env, this.pathDirs);
|
|
6770
|
-
}
|
|
6771
|
-
const child = spawn(this.executablePath, commandArgs, {
|
|
6772
|
-
env,
|
|
6773
|
-
signal: args.signal
|
|
6774
|
-
});
|
|
6775
|
-
let spawnError = null;
|
|
6776
|
-
child.once("error", (err) => spawnError = err);
|
|
6777
|
-
if (!child.stdin) {
|
|
6778
|
-
child.kill();
|
|
6779
|
-
throw new Error("Child process has no stdin");
|
|
6780
|
-
}
|
|
6781
|
-
child.stdin.write(args.input);
|
|
6782
|
-
child.stdin.end();
|
|
6783
|
-
if (!child.stdout) {
|
|
6784
|
-
child.kill();
|
|
6785
|
-
throw new Error("Child process has no stdout");
|
|
6786
|
-
}
|
|
6787
|
-
const stderrChunks = [];
|
|
6788
|
-
if (child.stderr) {
|
|
6789
|
-
child.stderr.on("data", (data) => {
|
|
6790
|
-
stderrChunks.push(data);
|
|
6791
|
-
});
|
|
6792
|
-
}
|
|
6793
|
-
const exitPromise = new Promise(
|
|
6794
|
-
(resolve2) => {
|
|
6795
|
-
child.once("exit", (code, signal) => {
|
|
6796
|
-
resolve2({ code, signal });
|
|
6797
|
-
});
|
|
6798
|
-
}
|
|
6799
|
-
);
|
|
6800
|
-
const rl = readline2.createInterface({
|
|
6801
|
-
input: child.stdout,
|
|
6802
|
-
crlfDelay: Infinity
|
|
6803
|
-
});
|
|
6804
|
-
try {
|
|
6805
|
-
for await (const line of rl) {
|
|
6806
|
-
yield line;
|
|
6807
|
-
}
|
|
6808
|
-
if (spawnError) throw spawnError;
|
|
6809
|
-
const { code, signal } = await exitPromise;
|
|
6810
|
-
if (code !== 0 || signal) {
|
|
6811
|
-
const stderrBuffer = Buffer.concat(stderrChunks);
|
|
6812
|
-
const detail = signal ? `signal ${signal}` : `code ${code ?? 1}`;
|
|
6813
|
-
throw new Error(`Codex Exec exited with ${detail}: ${stderrBuffer.toString("utf8")}`);
|
|
6814
|
-
}
|
|
6815
|
-
} finally {
|
|
6816
|
-
rl.close();
|
|
6817
|
-
child.removeAllListeners();
|
|
6818
|
-
try {
|
|
6819
|
-
if (!child.killed) child.kill();
|
|
6820
|
-
} catch {
|
|
6821
|
-
}
|
|
6822
|
-
}
|
|
6823
|
-
}
|
|
6824
|
-
};
|
|
6825
|
-
function serializeConfigOverrides(configOverrides) {
|
|
6826
|
-
const overrides = [];
|
|
6827
|
-
flattenConfigOverrides(configOverrides, "", overrides);
|
|
6828
|
-
return overrides;
|
|
6829
|
-
}
|
|
6830
|
-
function flattenConfigOverrides(value, prefix, overrides) {
|
|
6831
|
-
if (!isPlainObject(value)) {
|
|
6832
|
-
if (prefix) {
|
|
6833
|
-
overrides.push(`${prefix}=${toTomlValue(value, prefix)}`);
|
|
6834
|
-
return;
|
|
6835
|
-
} else {
|
|
6836
|
-
throw new Error("Codex config overrides must be a plain object");
|
|
6837
|
-
}
|
|
6838
|
-
}
|
|
6839
|
-
const entries = Object.entries(value);
|
|
6840
|
-
if (!prefix && entries.length === 0) {
|
|
6841
|
-
return;
|
|
6842
|
-
}
|
|
6843
|
-
if (prefix && entries.length === 0) {
|
|
6844
|
-
overrides.push(`${prefix}={}`);
|
|
6845
|
-
return;
|
|
6846
|
-
}
|
|
6847
|
-
for (const [key, child] of entries) {
|
|
6848
|
-
if (!key) {
|
|
6849
|
-
throw new Error("Codex config override keys must be non-empty strings");
|
|
6850
|
-
}
|
|
6851
|
-
if (child === void 0) {
|
|
6852
|
-
continue;
|
|
6853
|
-
}
|
|
6854
|
-
const path3 = prefix ? `${prefix}.${key}` : key;
|
|
6855
|
-
if (isPlainObject(child)) {
|
|
6856
|
-
flattenConfigOverrides(child, path3, overrides);
|
|
6857
|
-
} else {
|
|
6858
|
-
overrides.push(`${path3}=${toTomlValue(child, path3)}`);
|
|
6859
|
-
}
|
|
6860
|
-
}
|
|
6861
|
-
}
|
|
6862
|
-
function toTomlValue(value, path3) {
|
|
6863
|
-
if (typeof value === "string") {
|
|
6864
|
-
return JSON.stringify(value);
|
|
6865
|
-
} else if (typeof value === "number") {
|
|
6866
|
-
if (!Number.isFinite(value)) {
|
|
6867
|
-
throw new Error(`Codex config override at ${path3} must be a finite number`);
|
|
6868
|
-
}
|
|
6869
|
-
return `${value}`;
|
|
6870
|
-
} else if (typeof value === "boolean") {
|
|
6871
|
-
return value ? "true" : "false";
|
|
6872
|
-
} else if (Array.isArray(value)) {
|
|
6873
|
-
const rendered = value.map((item, index) => toTomlValue(item, `${path3}[${index}]`));
|
|
6874
|
-
return `[${rendered.join(", ")}]`;
|
|
6875
|
-
} else if (isPlainObject(value)) {
|
|
6876
|
-
const parts = [];
|
|
6877
|
-
for (const [key, child] of Object.entries(value)) {
|
|
6878
|
-
if (!key) {
|
|
6879
|
-
throw new Error("Codex config override keys must be non-empty strings");
|
|
6880
|
-
}
|
|
6881
|
-
if (child === void 0) {
|
|
6882
|
-
continue;
|
|
6883
|
-
}
|
|
6884
|
-
parts.push(`${formatTomlKey(key)} = ${toTomlValue(child, `${path3}.${key}`)}`);
|
|
6885
|
-
}
|
|
6886
|
-
return `{${parts.join(", ")}}`;
|
|
6887
|
-
} else if (value === null) {
|
|
6888
|
-
throw new Error(`Codex config override at ${path3} cannot be null`);
|
|
6889
|
-
} else {
|
|
6890
|
-
const typeName = typeof value;
|
|
6891
|
-
throw new Error(`Unsupported Codex config override value at ${path3}: ${typeName}`);
|
|
6892
|
-
}
|
|
6893
|
-
}
|
|
6894
|
-
var TOML_BARE_KEY = /^[A-Za-z0-9_-]+$/;
|
|
6895
|
-
function formatTomlKey(key) {
|
|
6896
|
-
return TOML_BARE_KEY.test(key) ? key : JSON.stringify(key);
|
|
6897
|
-
}
|
|
6898
|
-
function isPlainObject(value) {
|
|
6899
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6900
|
-
}
|
|
6901
|
-
function findCodexPath() {
|
|
6902
|
-
const { platform, arch } = process;
|
|
6903
|
-
let targetTriple = null;
|
|
6904
|
-
switch (platform) {
|
|
6905
|
-
case "linux":
|
|
6906
|
-
case "android":
|
|
6907
|
-
switch (arch) {
|
|
6908
|
-
case "x64":
|
|
6909
|
-
targetTriple = "x86_64-unknown-linux-musl";
|
|
6910
|
-
break;
|
|
6911
|
-
case "arm64":
|
|
6912
|
-
targetTriple = "aarch64-unknown-linux-musl";
|
|
6913
|
-
break;
|
|
6914
|
-
default:
|
|
6915
|
-
break;
|
|
6916
|
-
}
|
|
6917
|
-
break;
|
|
6918
|
-
case "darwin":
|
|
6919
|
-
switch (arch) {
|
|
6920
|
-
case "x64":
|
|
6921
|
-
targetTriple = "x86_64-apple-darwin";
|
|
6922
|
-
break;
|
|
6923
|
-
case "arm64":
|
|
6924
|
-
targetTriple = "aarch64-apple-darwin";
|
|
6925
|
-
break;
|
|
6926
|
-
default:
|
|
6927
|
-
break;
|
|
6928
|
-
}
|
|
6929
|
-
break;
|
|
6930
|
-
case "win32":
|
|
6931
|
-
switch (arch) {
|
|
6932
|
-
case "x64":
|
|
6933
|
-
targetTriple = "x86_64-pc-windows-msvc";
|
|
6934
|
-
break;
|
|
6935
|
-
case "arm64":
|
|
6936
|
-
targetTriple = "aarch64-pc-windows-msvc";
|
|
6937
|
-
break;
|
|
6938
|
-
default:
|
|
6939
|
-
break;
|
|
6940
|
-
}
|
|
6941
|
-
break;
|
|
6942
|
-
default:
|
|
6943
|
-
break;
|
|
6944
|
-
}
|
|
6945
|
-
if (!targetTriple) {
|
|
6946
|
-
throw new Error(`Unsupported platform: ${platform} (${arch})`);
|
|
6947
|
-
}
|
|
6948
|
-
const platformPackage = PLATFORM_PACKAGE_BY_TARGET[targetTriple];
|
|
6949
|
-
if (!platformPackage) {
|
|
6950
|
-
throw new Error(`Unsupported target triple: ${targetTriple}`);
|
|
6951
|
-
}
|
|
6952
|
-
let vendorRoot;
|
|
6953
|
-
try {
|
|
6954
|
-
const codexPackageJsonPath = moduleRequire.resolve(`${CODEX_NPM_NAME}/package.json`);
|
|
6955
|
-
const codexRequire = createRequire(codexPackageJsonPath);
|
|
6956
|
-
const platformPackageJsonPath = codexRequire.resolve(`${platformPackage}/package.json`);
|
|
6957
|
-
vendorRoot = path2.join(path2.dirname(platformPackageJsonPath), "vendor");
|
|
6958
|
-
} catch {
|
|
6959
|
-
throw new Error(
|
|
6960
|
-
`Unable to locate Codex CLI binaries. Ensure ${CODEX_NPM_NAME} is installed with optional dependencies.`
|
|
6961
|
-
);
|
|
6962
|
-
}
|
|
6963
|
-
const codexBinaryName = process.platform === "win32" ? "codex.exe" : "codex";
|
|
6964
|
-
const nativePackage = resolveNativePackage(vendorRoot, targetTriple, codexBinaryName);
|
|
6965
|
-
if (!nativePackage) {
|
|
6966
|
-
throw new Error(
|
|
6967
|
-
`Unable to locate Codex CLI binaries for ${targetTriple}. Ensure ${CODEX_NPM_NAME} is installed with optional dependencies.`
|
|
6968
|
-
);
|
|
6969
|
-
}
|
|
6970
|
-
return nativePackage;
|
|
6971
|
-
}
|
|
6972
|
-
function resolveNativePackage(vendorRoot, targetTriple, codexBinaryName) {
|
|
6973
|
-
const packageRoot = path2.join(vendorRoot, targetTriple);
|
|
6974
|
-
const packageBinaryPath = path2.join(packageRoot, "bin", codexBinaryName);
|
|
6975
|
-
if (isFile(packageBinaryPath) && isFile(path2.join(packageRoot, "codex-package.json"))) {
|
|
6976
|
-
return {
|
|
6977
|
-
executablePath: packageBinaryPath,
|
|
6978
|
-
pathDirs: existingDirs(path2.join(packageRoot, "codex-path"))
|
|
6979
|
-
};
|
|
6980
|
-
}
|
|
6981
|
-
const legacyBinaryPath = path2.join(packageRoot, "codex", codexBinaryName);
|
|
6982
|
-
if (isFile(legacyBinaryPath)) {
|
|
6983
|
-
return {
|
|
6984
|
-
executablePath: legacyBinaryPath,
|
|
6985
|
-
pathDirs: existingDirs(path2.join(packageRoot, "path"))
|
|
6986
|
-
};
|
|
6987
|
-
}
|
|
6988
|
-
return null;
|
|
6989
|
-
}
|
|
6990
|
-
function existingDirs(...dirs) {
|
|
6991
|
-
return dirs.filter(isDirectory);
|
|
6992
|
-
}
|
|
6993
|
-
function prependPathDirs(env, pathDirs, platform = process.platform) {
|
|
6994
|
-
const pathKey = pathEnvKey(env, platform);
|
|
6995
|
-
if (platform === "win32") {
|
|
6996
|
-
for (const key of Object.keys(env)) {
|
|
6997
|
-
if (key.toLowerCase() === "path" && key !== pathKey) {
|
|
6998
|
-
delete env[key];
|
|
6999
|
-
}
|
|
7000
|
-
}
|
|
7001
|
-
}
|
|
7002
|
-
const existingEntries = (env[pathKey] ?? "").split(path2.delimiter).filter((entry) => entry.length > 0 && !pathDirs.includes(entry));
|
|
7003
|
-
env[pathKey] = [...pathDirs, ...existingEntries].join(path2.delimiter);
|
|
7004
|
-
}
|
|
7005
|
-
function pathEnvKey(env, platform) {
|
|
7006
|
-
if (platform !== "win32") {
|
|
7007
|
-
return "PATH";
|
|
7008
|
-
}
|
|
7009
|
-
const matchingKeys = Object.keys(env).filter((key) => key.toLowerCase() === "path");
|
|
7010
|
-
return matchingKeys.includes("Path") ? "Path" : matchingKeys.at(-1) ?? "PATH";
|
|
7011
|
-
}
|
|
7012
|
-
function isFile(filePath) {
|
|
7013
|
-
try {
|
|
7014
|
-
return statSync2(filePath).isFile();
|
|
7015
|
-
} catch {
|
|
7016
|
-
return false;
|
|
7017
|
-
}
|
|
7018
|
-
}
|
|
7019
|
-
function isDirectory(filePath) {
|
|
7020
|
-
try {
|
|
7021
|
-
return statSync2(filePath).isDirectory();
|
|
7022
|
-
} catch {
|
|
7023
|
-
return false;
|
|
7024
|
-
}
|
|
7025
|
-
}
|
|
7026
|
-
var Codex = class {
|
|
7027
|
-
exec;
|
|
7028
|
-
options;
|
|
7029
|
-
constructor(options = {}) {
|
|
7030
|
-
const { codexPathOverride, env, config } = options;
|
|
7031
|
-
this.exec = new CodexExec(codexPathOverride, env, config);
|
|
7032
|
-
this.options = options;
|
|
7033
|
-
}
|
|
7034
|
-
/**
|
|
7035
|
-
* Starts a new conversation with an agent.
|
|
7036
|
-
* @returns A new thread instance.
|
|
7037
|
-
*/
|
|
7038
|
-
startThread(options = {}) {
|
|
7039
|
-
return new Thread(this.exec, this.options, options);
|
|
7040
|
-
}
|
|
7041
|
-
/**
|
|
7042
|
-
* Resumes a conversation with an agent based on the thread id.
|
|
7043
|
-
* Threads are persisted in ~/.codex/sessions.
|
|
7044
|
-
*
|
|
7045
|
-
* @param id The id of the thread to resume.
|
|
7046
|
-
* @returns A new thread instance.
|
|
7047
|
-
*/
|
|
7048
|
-
resumeThread(id, options = {}) {
|
|
7049
|
-
return new Thread(this.exec, this.options, options, id);
|
|
7050
|
-
}
|
|
7051
|
-
};
|
|
7052
|
-
|
|
7053
6526
|
// src/session/runner/codex.ts
|
|
6527
|
+
import { Codex } from "@openai/codex-sdk";
|
|
7054
6528
|
var isRecord2 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
7055
6529
|
var str = (v) => typeof v === "string" ? v : void 0;
|
|
7056
6530
|
var compactEnv = (env) => {
|
|
@@ -7302,12 +6776,12 @@ var startedItemFromToolUse = (block) => {
|
|
|
7302
6776
|
};
|
|
7303
6777
|
}
|
|
7304
6778
|
if (name === "Edit" || name === "Write" || name === "MultiEdit" || name === "Delete") {
|
|
7305
|
-
const
|
|
6779
|
+
const path = pathOf(input);
|
|
7306
6780
|
return {
|
|
7307
6781
|
type: "file_change",
|
|
7308
6782
|
id,
|
|
7309
6783
|
status: "in_progress",
|
|
7310
|
-
changes:
|
|
6784
|
+
changes: path ? [{ path, kind: fileKindOf(name) }] : []
|
|
7311
6785
|
};
|
|
7312
6786
|
}
|
|
7313
6787
|
const mcp = mcpParts(name);
|
|
@@ -8115,7 +7589,7 @@ var createLiveness = (deps) => {
|
|
|
8115
7589
|
};
|
|
8116
7590
|
|
|
8117
7591
|
// src/worker/session-supervisor.ts
|
|
8118
|
-
import { spawn
|
|
7592
|
+
import { spawn } from "node:child_process";
|
|
8119
7593
|
import { randomUUID } from "node:crypto";
|
|
8120
7594
|
import { existsSync as existsSync5 } from "node:fs";
|
|
8121
7595
|
import { dirname as dirname2, join as join7 } from "node:path";
|
|
@@ -8248,12 +7722,12 @@ var ensureExcluded = (repo, pattern) => {
|
|
|
8248
7722
|
});
|
|
8249
7723
|
if (r.status !== 0) return;
|
|
8250
7724
|
const rel = r.stdout.trim();
|
|
8251
|
-
const
|
|
8252
|
-
const current = existsSync4(
|
|
7725
|
+
const path = isAbsolute2(rel) ? rel : resolve(repo, rel);
|
|
7726
|
+
const current = existsSync4(path) ? readFileSync5(path, "utf8") : "";
|
|
8253
7727
|
if (current.split("\n").includes(pattern)) return;
|
|
8254
|
-
mkdirSync3(dirname(
|
|
7728
|
+
mkdirSync3(dirname(path), { recursive: true });
|
|
8255
7729
|
const sep = current === "" || current.endsWith("\n") ? "" : "\n";
|
|
8256
|
-
appendFileSync(
|
|
7730
|
+
appendFileSync(path, `${sep}${pattern}
|
|
8257
7731
|
`, "utf8");
|
|
8258
7732
|
} catch {
|
|
8259
7733
|
}
|
|
@@ -8300,7 +7774,7 @@ var createSessionSupervisor = (deps) => {
|
|
|
8300
7774
|
const children = /* @__PURE__ */ new Map();
|
|
8301
7775
|
const spawnChild = (sessionId, worktreePath) => {
|
|
8302
7776
|
if (children.has(sessionId)) return;
|
|
8303
|
-
const child =
|
|
7777
|
+
const child = spawn(process.execPath, [binPath(), "session", "run", String(sessionId)], {
|
|
8304
7778
|
detached: true,
|
|
8305
7779
|
stdio: "inherit",
|
|
8306
7780
|
env: { ...process.env, BATON_SERVER: cfg.server, BATON_WORKER_TOKEN: cfg.apiToken }
|
|
@@ -8406,7 +7880,7 @@ var createSessionSupervisor = (deps) => {
|
|
|
8406
7880
|
|
|
8407
7881
|
// src/worker/terminal-manager.ts
|
|
8408
7882
|
import { existsSync as existsSync7 } from "node:fs";
|
|
8409
|
-
import { spawn as
|
|
7883
|
+
import { spawn as spawn2 } from "node-pty";
|
|
8410
7884
|
|
|
8411
7885
|
// ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/wrapper.mjs
|
|
8412
7886
|
var import_stream2 = __toESM(require_stream(), 1);
|
|
@@ -8445,7 +7919,7 @@ var createTerminalManager = (deps) => {
|
|
|
8445
7919
|
return;
|
|
8446
7920
|
}
|
|
8447
7921
|
const claudeBin = process.env.BATON_CLAUDE_BIN ?? "claude";
|
|
8448
|
-
const term =
|
|
7922
|
+
const term = spawn2(claudeBin, ptyArgs(agentSessionId, hasSessionJsonl(agentSessionId)), {
|
|
8449
7923
|
name: "xterm-color",
|
|
8450
7924
|
cols: 80,
|
|
8451
7925
|
rows: 24,
|
|
@@ -8598,14 +8072,14 @@ import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as rea
|
|
|
8598
8072
|
import { homedir as homedir4 } from "node:os";
|
|
8599
8073
|
import { dirname as dirname3, join as join9 } from "node:path";
|
|
8600
8074
|
var machineIdPath = (env = process.env) => join9(env.XDG_DATA_HOME ?? join9(env.HOME ?? homedir4(), ".local/share"), "baton", "machine-id");
|
|
8601
|
-
var readOrCreateMachineId = (
|
|
8602
|
-
if (existsSync8(
|
|
8603
|
-
const s = readFileSync6(
|
|
8075
|
+
var readOrCreateMachineId = (path = machineIdPath()) => {
|
|
8076
|
+
if (existsSync8(path)) {
|
|
8077
|
+
const s = readFileSync6(path, "utf8").trim();
|
|
8604
8078
|
if (s) return s;
|
|
8605
8079
|
}
|
|
8606
8080
|
const id = randomUUID2();
|
|
8607
|
-
mkdirSync4(dirname3(
|
|
8608
|
-
writeFileSync5(
|
|
8081
|
+
mkdirSync4(dirname3(path), { recursive: true });
|
|
8082
|
+
writeFileSync5(path, `${id}
|
|
8609
8083
|
`, "utf8");
|
|
8610
8084
|
return id;
|
|
8611
8085
|
};
|