feat: default to workspace-write when the working directory is a Git repo
This commit is contained in:
@@ -38,6 +38,7 @@ Provide either `prompt` or `prompt_file`; the other may be left empty. The actio
|
||||
| `prompt_file` | Conditionally | Path (relative to the repository root) of a file that contains the prompt. Provide this or `prompt`. | `""` |
|
||||
| `output_file` | No | File where the final Codex message is written. Leave empty to skip writing a file. | `""` |
|
||||
| `working_directory` | No | Directory passed to `codex exec --cd`. Defaults to the repository root. | `""` |
|
||||
| `sandbox` | No | Sandbox mode for Codex. One of `workspace-write` (default), `read-only` or `danger-full-access`. | `""` |
|
||||
| `codex_version` | No | Version of `@openai/codex` to install. | `0.42.0-alpha.3` |
|
||||
| `codex_args` | No | Extra arguments forwarded to `codex exec`. Accepts JSON arrays (`["--flag", "value"]`) or shell-style strings. | `""` |
|
||||
| `output_schema` | No | Inline schema contents written to a temp file and passed to `codex exec --output-schema`. Mutually exclusive with `output_schema_file`. | `""` |
|
||||
|
||||
@@ -21,6 +21,11 @@ inputs:
|
||||
description: "Optional working directory to `cd` into before running `codex exec`."
|
||||
required: false
|
||||
default: ""
|
||||
sandbox:
|
||||
description: |
|
||||
Sandbox mode for Codex. One of `workspace-write` (default), `read-only` or `danger-full-access`.
|
||||
required: false
|
||||
default: "workspace-write"
|
||||
codex_version:
|
||||
description: "Version of `@openai/codex` to install."
|
||||
required: false
|
||||
@@ -185,6 +190,7 @@ runs:
|
||||
CODEX_OUTPUT_FILE: ${{ inputs.output_file }}
|
||||
CODEX_HOME: ${{ inputs.codex_home }}
|
||||
CODEX_WORKING_DIRECTORY: ${{ inputs.working_directory || github.workspace }}
|
||||
CODEX_SANDBOX: ${{ inputs.sandbox }}
|
||||
CODEX_ARGS: ${{ inputs.codex_args }}
|
||||
CODEX_OUTPUT_SCHEMA: ${{ inputs.output_schema }}
|
||||
CODEX_OUTPUT_SCHEMA_FILE: ${{ inputs.output_schema_file }}
|
||||
@@ -204,6 +210,7 @@ runs:
|
||||
--extra-args "$CODEX_ARGS" \
|
||||
--output-schema "$CODEX_OUTPUT_SCHEMA" \
|
||||
--output-schema-file "$CODEX_OUTPUT_SCHEMA_FILE" \
|
||||
--sandbox "$CODEX_SANDBOX" \
|
||||
--model "$CODEX_MODEL" \
|
||||
--safety-strategy "$CODEX_SAFETY_STRATEGY" \
|
||||
--codex-user "$CODEX_USER"
|
||||
|
||||
Vendored
+35
-5
File diff suppressed because one or more lines are too long
+21
@@ -3,6 +3,7 @@ import pkg from "../package.json" assert { type: "json" };
|
||||
|
||||
import { readServerInfo } from "./readServerInfo";
|
||||
import {
|
||||
SandboxMode,
|
||||
OutputSchemaSource,
|
||||
PromptSource,
|
||||
runCodexExec,
|
||||
@@ -83,6 +84,10 @@ export async function main() {
|
||||
"--output-schema <SCHEMA>",
|
||||
"Inline schema contents to pass to `codex exec --output-schema`."
|
||||
)
|
||||
.requiredOption(
|
||||
"--sandbox <SANDBOX>",
|
||||
"Sandbox mode override to pass to `codex exec`."
|
||||
)
|
||||
.requiredOption("--model <model>", "Model the agent should use")
|
||||
.requiredOption(
|
||||
"--safety-strategy <strategy>",
|
||||
@@ -103,6 +108,7 @@ export async function main() {
|
||||
outputFile: string;
|
||||
outputSchemaFile: string;
|
||||
outputSchema: string;
|
||||
sandbox: string;
|
||||
model: string;
|
||||
safetyStrategy: string;
|
||||
codexUser: string;
|
||||
@@ -117,6 +123,7 @@ export async function main() {
|
||||
extraArgs,
|
||||
outputSchema,
|
||||
outputSchemaFile,
|
||||
sandbox,
|
||||
model,
|
||||
safetyStrategy,
|
||||
codexUser,
|
||||
@@ -170,6 +177,7 @@ export async function main() {
|
||||
extraArgs,
|
||||
explicitOutputFile: emptyAsNull(outputFile),
|
||||
outputSchema: outputSchemaSource,
|
||||
sandbox: toSandboxMode(sandbox),
|
||||
model: emptyAsNull(model),
|
||||
safetyStrategy: toSafetyStrategy(safetyStrategy),
|
||||
codexUser: emptyAsNull(codexUser),
|
||||
@@ -242,6 +250,19 @@ function toSafetyStrategy(value: string): SafetyStrategy {
|
||||
}
|
||||
}
|
||||
|
||||
function toSandboxMode(value: string): SandboxMode {
|
||||
switch (value) {
|
||||
case "read-only":
|
||||
case "workspace-write":
|
||||
case "danger-full-access":
|
||||
return value;
|
||||
default:
|
||||
throw new Error(
|
||||
`Invalid sandbox: ${value}. Must be one of 'read-only', 'workspace-write', or 'danger-full-access'.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function emptyAsNull(value: string): string | null {
|
||||
return value.trim().length == 0 ? null : value;
|
||||
}
|
||||
|
||||
+26
-5
@@ -19,6 +19,11 @@ export type SafetyStrategy =
|
||||
| "unprivileged_user"
|
||||
| "unsafe";
|
||||
|
||||
export type SandboxMode =
|
||||
| "read-only"
|
||||
| "workspace-write"
|
||||
| "danger-full-access";
|
||||
|
||||
export type OutputSchemaSource =
|
||||
| {
|
||||
type: "file";
|
||||
@@ -40,6 +45,7 @@ export async function runCodexExec({
|
||||
model,
|
||||
safetyStrategy,
|
||||
codexUser,
|
||||
sandbox,
|
||||
}: {
|
||||
prompt: PromptSource;
|
||||
codexHome: string | null;
|
||||
@@ -51,6 +57,7 @@ export async function runCodexExec({
|
||||
model: string | null;
|
||||
safetyStrategy: SafetyStrategy;
|
||||
codexUser: string | null;
|
||||
sandbox: SandboxMode;
|
||||
}): Promise<void> {
|
||||
let input: string;
|
||||
switch (prompt.type) {
|
||||
@@ -70,6 +77,10 @@ export async function runCodexExec({
|
||||
}
|
||||
|
||||
const resolvedOutputSchema = await resolveOutputSchema(outputSchema);
|
||||
const sandboxMode = await determineSandboxMode({
|
||||
safetyStrategy,
|
||||
requestedSandbox: sandbox,
|
||||
});
|
||||
|
||||
const command: Array<string> = [];
|
||||
|
||||
@@ -111,11 +122,7 @@ export async function runCodexExec({
|
||||
|
||||
command.push(...extraArgs);
|
||||
|
||||
// Note that if profiles expand to support their own sandbox policies, a
|
||||
// custom profile could override this setting.
|
||||
if (safetyStrategy === "read_only") {
|
||||
command.push("--config", 'sandbox_mode="read-only"');
|
||||
}
|
||||
command.push("--sandbox", sandboxMode);
|
||||
|
||||
const env = { ...process.env };
|
||||
let extraEnv = "";
|
||||
@@ -244,3 +251,17 @@ async function cleanupOutputSchema(
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
async function determineSandboxMode({
|
||||
safetyStrategy,
|
||||
requestedSandbox,
|
||||
}: {
|
||||
safetyStrategy: SafetyStrategy;
|
||||
requestedSandbox: SandboxMode;
|
||||
}): Promise<SandboxMode> {
|
||||
if (safetyStrategy === "read_only") {
|
||||
return "read-only";
|
||||
} else {
|
||||
return requestedSandbox;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user