@f-o-h/cli 0.1.40 → 0.1.42
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/foh.js +52 -11
- package/package.json +1 -1
package/dist/foh.js
CHANGED
|
@@ -32801,7 +32801,7 @@ var StdioServerTransport = class {
|
|
|
32801
32801
|
};
|
|
32802
32802
|
|
|
32803
32803
|
// src/lib/cli-version.ts
|
|
32804
|
-
var CLI_VERSION = "0.1.
|
|
32804
|
+
var CLI_VERSION = "0.1.42";
|
|
32805
32805
|
|
|
32806
32806
|
// src/commands/mcp-serve.ts
|
|
32807
32807
|
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
@@ -39054,7 +39054,13 @@ function resolveCodexExecutionCommand() {
|
|
|
39054
39054
|
}
|
|
39055
39055
|
function validateCodexRunner(options) {
|
|
39056
39056
|
if (options.skipRunnerProbe) {
|
|
39057
|
-
return {
|
|
39057
|
+
return {
|
|
39058
|
+
binaryChecked: false,
|
|
39059
|
+
requiredFlagsChecked: false,
|
|
39060
|
+
automationMode: "ask-for-approval-never",
|
|
39061
|
+
globalArgs: ["--ask-for-approval", "never"],
|
|
39062
|
+
execArgs: []
|
|
39063
|
+
};
|
|
39058
39064
|
}
|
|
39059
39065
|
const probe = options.runnerProbe ?? defaultRunnerProbe;
|
|
39060
39066
|
const probeCommand = resolveCodexProbeCommand();
|
|
@@ -39066,26 +39072,48 @@ function validateCodexRunner(options) {
|
|
|
39066
39072
|
if (help.error || help.status !== 0) {
|
|
39067
39073
|
throw new ExternalAgentExecutorError("external_agent_runner_help_unavailable", "Codex runner probe failed: `codex exec --help` did not exit 0.");
|
|
39068
39074
|
}
|
|
39069
|
-
const
|
|
39075
|
+
const execHelpText = `${help.stdout}
|
|
39070
39076
|
${help.stderr}`;
|
|
39071
|
-
const
|
|
39077
|
+
const rootHelp = probe(probeCommand, ["--help"]);
|
|
39078
|
+
const rootHelpText = `${rootHelp.stdout}
|
|
39079
|
+
${rootHelp.stderr}`;
|
|
39080
|
+
const commonExecFlags = [
|
|
39072
39081
|
"--cd",
|
|
39073
39082
|
"--skip-git-repo-check",
|
|
39074
39083
|
"--ephemeral",
|
|
39075
39084
|
"--ignore-rules",
|
|
39076
39085
|
"--sandbox",
|
|
39077
|
-
"--full-auto",
|
|
39078
39086
|
"--json",
|
|
39079
39087
|
"--output-last-message"
|
|
39080
39088
|
];
|
|
39081
|
-
const missing =
|
|
39089
|
+
const missing = commonExecFlags.filter((flag) => !execHelpText.includes(flag));
|
|
39090
|
+
const supportsLegacyFullAuto = execHelpText.includes("--full-auto");
|
|
39091
|
+
const supportsModernApprovalMode = rootHelp.status === 0 && rootHelpText.includes("--ask-for-approval");
|
|
39092
|
+
if (!supportsLegacyFullAuto && !supportsModernApprovalMode) {
|
|
39093
|
+
missing.push("--full-auto or --ask-for-approval");
|
|
39094
|
+
}
|
|
39082
39095
|
if (missing.length > 0) {
|
|
39083
39096
|
throw new ExternalAgentExecutorError(
|
|
39084
39097
|
"external_agent_runner_required_flags_missing",
|
|
39085
39098
|
`Codex runner is missing required exec flag(s): ${missing.join(", ")}`
|
|
39086
39099
|
);
|
|
39087
39100
|
}
|
|
39088
|
-
|
|
39101
|
+
if (supportsModernApprovalMode) {
|
|
39102
|
+
return {
|
|
39103
|
+
binaryChecked: true,
|
|
39104
|
+
requiredFlagsChecked: true,
|
|
39105
|
+
automationMode: "ask-for-approval-never",
|
|
39106
|
+
globalArgs: ["--ask-for-approval", "never"],
|
|
39107
|
+
execArgs: []
|
|
39108
|
+
};
|
|
39109
|
+
}
|
|
39110
|
+
return {
|
|
39111
|
+
binaryChecked: true,
|
|
39112
|
+
requiredFlagsChecked: true,
|
|
39113
|
+
automationMode: "full-auto",
|
|
39114
|
+
globalArgs: [],
|
|
39115
|
+
execArgs: ["--full-auto"]
|
|
39116
|
+
};
|
|
39089
39117
|
}
|
|
39090
39118
|
function normalizeCodexSandboxBackend(value) {
|
|
39091
39119
|
const normalized = (value || "default").trim().toLowerCase();
|
|
@@ -39095,6 +39123,14 @@ function normalizeCodexSandboxBackend(value) {
|
|
|
39095
39123
|
`Unsupported Codex sandbox backend: ${value}. Use default or legacy-landlock.`
|
|
39096
39124
|
);
|
|
39097
39125
|
}
|
|
39126
|
+
function normalizeCodexSandboxMode(value) {
|
|
39127
|
+
const normalized = (value || "workspace-write").trim().toLowerCase();
|
|
39128
|
+
if (normalized === "workspace-write" || normalized === "danger-full-access") return normalized;
|
|
39129
|
+
throw new ExternalAgentExecutorError(
|
|
39130
|
+
"invalid_codex_sandbox_mode",
|
|
39131
|
+
`Unsupported Codex sandbox mode: ${value}. Use workspace-write or danger-full-access.`
|
|
39132
|
+
);
|
|
39133
|
+
}
|
|
39098
39134
|
function codexConfigArgs(input) {
|
|
39099
39135
|
const args = [];
|
|
39100
39136
|
if (input.backend === "legacy-landlock") {
|
|
@@ -39133,6 +39169,7 @@ function createExternalAgentExecutorPlan(options) {
|
|
|
39133
39169
|
const batch = readBatch(batchPath);
|
|
39134
39170
|
const runnerProbe = validateCodexRunner(options);
|
|
39135
39171
|
const codexSandboxBackend = normalizeCodexSandboxBackend(options.codexSandboxBackend);
|
|
39172
|
+
const codexSandboxMode = normalizeCodexSandboxMode(options.codexSandboxMode);
|
|
39136
39173
|
const codexNetworkAccess = options.codexNetworkAccess === true;
|
|
39137
39174
|
const privateRepoRoot = (0, import_path12.resolve)(options.privateRepoRoot || options.cwd || process.cwd());
|
|
39138
39175
|
const workspaceRoot = resolveWorkspaceRoot({ batchPath, workspaceRoot: options.workspaceRoot, privateRepoRoot });
|
|
@@ -39175,6 +39212,7 @@ function createExternalAgentExecutorPlan(options) {
|
|
|
39175
39212
|
const runPath = (0, import_path12.join)(runDir, "run.json");
|
|
39176
39213
|
const artifactSafetyPath = (0, import_path12.join)(runDir, "artifact-safety.json");
|
|
39177
39214
|
const args = [
|
|
39215
|
+
...runnerProbe.globalArgs,
|
|
39178
39216
|
"exec",
|
|
39179
39217
|
...codexConfigArgs({ backend: codexSandboxBackend, networkAccess: codexNetworkAccess }),
|
|
39180
39218
|
"--cd",
|
|
@@ -39183,8 +39221,8 @@ function createExternalAgentExecutorPlan(options) {
|
|
|
39183
39221
|
"--ephemeral",
|
|
39184
39222
|
"--ignore-rules",
|
|
39185
39223
|
"--sandbox",
|
|
39186
|
-
|
|
39187
|
-
|
|
39224
|
+
codexSandboxMode,
|
|
39225
|
+
...runnerProbe.execArgs,
|
|
39188
39226
|
"--json",
|
|
39189
39227
|
"--output-last-message",
|
|
39190
39228
|
lastMessagePath,
|
|
@@ -39230,6 +39268,8 @@ function createExternalAgentExecutorPlan(options) {
|
|
|
39230
39268
|
binary_checked: runnerProbe.binaryChecked,
|
|
39231
39269
|
required_flags_checked: runnerProbe.requiredFlagsChecked
|
|
39232
39270
|
},
|
|
39271
|
+
codex_automation_mode: runnerProbe.automationMode,
|
|
39272
|
+
codex_sandbox_mode: codexSandboxMode,
|
|
39233
39273
|
codex_sandbox_backend: codexSandboxBackend,
|
|
39234
39274
|
codex_network_access: codexNetworkAccess
|
|
39235
39275
|
},
|
|
@@ -39337,7 +39377,7 @@ ${stderr}`;
|
|
|
39337
39377
|
if (/(?:blocked|rejected|declined) by policy|EXEC_POLICY_BLOCKED|command execution was rejected|shell commands were rejected/i.test(combined)) {
|
|
39338
39378
|
return { status: "hold", reasonCode: "codex_exec_policy_blocked" };
|
|
39339
39379
|
}
|
|
39340
|
-
if (/bwrap:.*(?:RTM_NEWADDR|Operation not permitted)|bubblewrap.*(?:RTM_NEWADDR|Operation not permitted)|Failed RTM_NEWADDR|ENV_SANDBOX_EXEC_BLOCKED/i.test(combined)) {
|
|
39380
|
+
if (/bwrap:.*(?:RTM_NEWADDR|Operation not permitted|setting up uid map: Permission denied)|bubblewrap.*(?:RTM_NEWADDR|Operation not permitted|setting up uid map: Permission denied)|Failed RTM_NEWADDR|ENV_SANDBOX_EXEC_BLOCKED|permission profiles requiring direct runtime enforcement are incompatible with --use-legacy-landlock|legacy[_ -]?landlock.*incompatible/i.test(combined)) {
|
|
39341
39381
|
return { status: "hold", reasonCode: "codex_sandbox_exec_blocked" };
|
|
39342
39382
|
}
|
|
39343
39383
|
if (/ENV_NETWORK_DNS_BLOCK|Could not resolve host|npm ping.*timeout|NO_EXECUTABLE_INSTALL/i.test(combined)) {
|
|
@@ -39860,7 +39900,7 @@ Exit the shell to finalize run.json.
|
|
|
39860
39900
|
}), { json: Boolean(opts.json) });
|
|
39861
39901
|
if (!report.ok) process.exitCode = 1;
|
|
39862
39902
|
});
|
|
39863
|
-
external.command("execute").description("Create a guarded dry-run executor plan for programmable external-agent runners").requiredOption("--batch <path>", "Path to external_agent_batch_plan.v1 batch.json").option("--runner <runner>", "Runner implementation", "codex").option("--workspace-root <path>", "Clean executor workspace root; must be outside the private repo").option("--private-repo-root <path>", "Private repository root to guard against").option("--timeout-minutes <minutes>", "Per-run timeout planned for future execution", "30").option("--codex-sandbox-backend <backend>", "Codex sandbox backend override: default|legacy-landlock", "default").option("--codex-network-access", "Allow Codex workspace-write sandbox network access for public docs/npm probes").option("--skip-runner-probe", "Skip local runner binary/help probing").option("--dry-run", "Write the executor plan without launching the runner", true).option("--live", "Launch one controlled external-agent run after writing the guarded plan").option("--json", "Output as JSON").action(async (opts) => {
|
|
39903
|
+
external.command("execute").description("Create a guarded dry-run executor plan for programmable external-agent runners").requiredOption("--batch <path>", "Path to external_agent_batch_plan.v1 batch.json").option("--runner <runner>", "Runner implementation", "codex").option("--workspace-root <path>", "Clean executor workspace root; must be outside the private repo").option("--private-repo-root <path>", "Private repository root to guard against").option("--timeout-minutes <minutes>", "Per-run timeout planned for future execution", "30").option("--codex-sandbox-backend <backend>", "Codex sandbox backend override: default|legacy-landlock", "default").option("--codex-sandbox-mode <mode>", "Codex sandbox mode: workspace-write|danger-full-access", "workspace-write").option("--codex-network-access", "Allow Codex workspace-write sandbox network access for public docs/npm probes").option("--skip-runner-probe", "Skip local runner binary/help probing").option("--dry-run", "Write the executor plan without launching the runner", true).option("--live", "Launch one controlled external-agent run after writing the guarded plan").option("--json", "Output as JSON").action(async (opts) => {
|
|
39864
39904
|
try {
|
|
39865
39905
|
const plan = createExternalAgentExecutorPlan({
|
|
39866
39906
|
batchPath: String(opts.batch),
|
|
@@ -39869,6 +39909,7 @@ Exit the shell to finalize run.json.
|
|
|
39869
39909
|
privateRepoRoot: opts.privateRepoRoot ? String(opts.privateRepoRoot) : void 0,
|
|
39870
39910
|
timeoutMinutes: Number(opts.timeoutMinutes || 30),
|
|
39871
39911
|
codexSandboxBackend: String(opts.codexSandboxBackend || "default"),
|
|
39912
|
+
codexSandboxMode: String(opts.codexSandboxMode || "workspace-write"),
|
|
39872
39913
|
codexNetworkAccess: Boolean(opts.codexNetworkAccess),
|
|
39873
39914
|
skipRunnerProbe: Boolean(opts.skipRunnerProbe),
|
|
39874
39915
|
cwd: process.cwd()
|