Compare commits

..

13 Commits

Author SHA1 Message Date
Atif Ali bb128fa077 docs(codex): clarify standalone and AI Bridge usage 2026-02-04 12:45:55 +00:00
Atif Ali 7c5f9b2adc style(codex): remove trailing whitespace in test file 2026-02-04 12:39:29 +00:00
Atif Ali 0a92c5c18f fix(codex): update tests to work with conditional agentapi module
- Only set install_agentapi when explicitly installing real AgentAPI
- Let enable_tasks (defaults to true) control agentapi module in tests
- This fixes tests that were inadvertently triggering standalone mode

All 18 tests now pass 
2026-02-04 11:58:07 +00:00
Atif Ali a443767ef3 chore(codex): apply bun fmt to README 2026-02-04 11:43:32 +00:00
Atif Ali 316269e437 fix(codex): only remove top-level profile key, preserve profiles sections
Use awk to track when we enter a TOML section and only remove 'profile ='
lines that appear at the top level (before any [section] headers). This
ensures user-provided [profiles.*] sections are preserved intact.
2026-02-04 10:32:21 +00:00
Atif Ali 9af62366b7 fix(codex): P2 - override profile when enable_aibridge=true
The previous fix would skip setting profile when one already existed,
breaking enable_aibridge=true with custom base configs. Now when
enable_aibridge=true, we explicitly remove any existing profile line
and set profile="aibridge" (since enable_aibridge=true is an explicit
user intention to use AI Bridge).
2026-02-04 10:29:54 +00:00
Atif Ali 46726a903d style(codex): terraform fmt 2026-02-04 07:24:09 +00:00
Atif Ali 8be5d5e01c fix(codex): address review comments
- P1: Make agentapi module conditional when enable_tasks=false
  - Add standalone coder_script for install when tasks disabled
  - Prevents AgentAPI requirement errors in standalone mode
- P2: Guard against duplicate profile key in config.toml
  - Check if profile already exists before prepending
  - Prevents TOML parsing errors with custom base configs
2026-02-04 07:23:56 +00:00
Atif Ali fa5fb31454 chore(codex): add TODO for removing deprecated install_agentapi in 5.0.0 2026-02-04 07:20:22 +00:00
Atif Ali 52603754cd docs(codex): simplify AI Bridge section in README 2026-02-04 07:19:19 +00:00
Atif Ali e18caa5a46 feat(codex): optimize for standalone usage with optional workdir and default AI Bridge profile
- Add 'enable_tasks' variable (defaults to true) for better discoverability
- Make 'workdir' optional when enable_tasks=false for standalone CLI usage
- Keep 'install_agentapi' as deprecated alias for backward compatibility
- Prepend 'profile = "aibridge"' to config.toml when AI Bridge is enabled
  so users can run 'codex' directly without --profile flag
- Update README with standalone usage examples and version 4.2.0
- Add tests for aibridge profile at config top and standalone mode
2026-02-04 07:12:00 +00:00
Harsh Singh Panwar 49a7985bc6 fix(coder/modules/jupyterlab): fix a typo (#689)
Closes https://github.com/coder/registry/issues/685

---------

Co-authored-by: Atif Ali <atif@coder.com>
Co-authored-by: Muhammad Atif Ali <me@matifali.dev>
2026-02-04 09:10:27 +05:00
Andreas Skorczyk 08e68a2da4 Don't create CLAUDE_API_KEY coder_env if not set (#686)
## Description

At the moment, the `CLAUDE_API_KEY` coder_env will always be created,
even if the variable itself is not. This can lead to the environment
variable being unset if it has been set outside of Terraform.

With this PR, we make the `claude_api_key` coder_env conditional, so it
will only be created if an API key has been set.

## Type of Change

- [ ] New module
- [ ] New template
- [x] Bug fix
- [ ] Feature/enhancement
- [ ] Documentation
- [ ] Other

## Module Information

<!-- Delete this section if not applicable -->

**Path:** `registry/coder/modules/claude-code/main.tf`  
**New version:** `v4.7.4`  
**Breaking change:** [ ] Yes [x] No

## Testing & Validation

- [x] Tests pass (`bun test`)
- [x] Code formatted (`bun fmt`)
- [x] Changes tested locally

## Related Issues

None

---------

Co-authored-by: 35C4n0r <70096901+35C4n0r@users.noreply.github.com>
2026-02-04 08:10:16 +05:30
10 changed files with 188 additions and 61 deletions
+31 -28
View File
@@ -1,19 +1,19 @@
---
display_name: Codex CLI
icon: ../../../../.icons/openai.svg
description: Run Codex CLI in your workspace with AgentAPI integration
description: Run Codex CLI in your workspace with optional Tasks integration
verified: true
tags: [agent, codex, ai, openai, tasks, aibridge]
---
# Codex CLI
Run Codex CLI in your workspace to access OpenAI's models through the Codex interface, with custom pre/post install scripts. This module integrates with [AgentAPI](https://github.com/coder/agentapi) for Coder Tasks compatibility.
Install Codex CLI in your workspace with optional Coder Tasks integration via [AgentAPI](https://github.com/coder/agentapi). The module supports AI Bridge, custom install scripts, and MCP server configuration.
```tf
module "codex" {
source = "registry.coder.com/coder-labs/codex/coder"
version = "4.1.0"
version = "4.2.0"
agent_id = coder_agent.example.id
openai_api_key = var.openai_api_key
workdir = "/home/coder/project"
@@ -22,47 +22,51 @@ module "codex" {
## Prerequisites
- OpenAI API key for Codex access
- OpenAI API key for Codex access (not required when `enable_aibridge = true`)
## Examples
### Run standalone
### Standalone (no Tasks UI)
Use `enable_tasks = false` to install Codex without AgentAPI/Tasks. `workdir` is optional in this mode.
```tf
module "codex" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder-labs/codex/coder"
version = "4.1.0"
version = "4.2.0"
agent_id = coder_agent.example.id
openai_api_key = "..."
workdir = "/home/coder/project"
report_tasks = false
enable_tasks = false
# workdir not required in standalone mode
}
```
### Usage with AI Bridge
[AI Bridge](https://coder.com/docs/ai-coder/ai-bridge) is a Premium Coder feature that provides centralized LLM proxy management. To use AI Bridge, set `enable_aibridge = true`. Requires Coder version 2.30+
For tasks integration with AI Bridge, add `enable_aibridge = true` to the [Usage with Tasks](#usage-with-tasks) example below.
#### Standalone usage with AI Bridge
[AI Bridge](https://coder.com/docs/ai-coder/ai-bridge) is a Premium Coder feature that provides centralized LLM proxy management. Set `enable_aibridge = true` to use it (requires Coder 2.30+). When AI Bridge is enabled, authentication uses the workspace owner session token, so `openai_api_key` should be omitted.
```tf
module "codex" {
source = "registry.coder.com/coder-labs/codex/coder"
version = "4.1.0"
version = "4.2.0"
agent_id = coder_agent.example.id
workdir = "/home/coder/project"
enable_aibridge = true
enable_tasks = false # Standalone mode - just CLI, no Tasks UI
# workdir not required in standalone mode
}
```
For Tasks integration, add `enable_aibridge = true` to the [Usage with Tasks](#usage-with-tasks) example below.
When `enable_aibridge = true`, the module:
- Configures Codex to use the AI Bridge profile with `base_url` pointing to `${data.coder_workspace.me.access_url}/api/v2/aibridge/openai/v1` and `env_key` pointing to the workspace owner's session token
- Sets `profile = "aibridge"` at the top of `config.toml` so Codex uses AI Bridge by default
```toml
profile = "aibridge"
[model_providers.aibridge]
name = "AI Bridge"
base_url = "https://example.coder.com/api/v2/aibridge/openai/v1"
@@ -75,9 +79,7 @@ model = "<model>" # as configured in the module input
model_reasoning_effort = "<model_reasoning_effort>" # as configured in the module input
```
Codex then runs with `--profile aibridge`
This allows Codex to route API requests through Coder's AI Bridge instead of directly to OpenAI's API.
Codex uses the AI Bridge profile by default, so running `codex` manually does not require `--profile aibridge`.
Template build will fail if `openai_api_key` is provided alongside `enable_aibridge = true`.
### Usage with Tasks
@@ -94,7 +96,7 @@ data "coder_task" "me" {}
module "codex" {
source = "registry.coder.com/coder-labs/codex/coder"
version = "4.1.0"
version = "4.2.0"
agent_id = coder_agent.example.id
openai_api_key = "..."
ai_prompt = data.coder_task.me.prompt
@@ -112,7 +114,7 @@ This example shows additional configuration options for custom models, MCP serve
```tf
module "codex" {
source = "registry.coder.com/coder-labs/codex/coder"
version = "4.1.0"
version = "4.2.0"
agent_id = coder_agent.example.id
openai_api_key = "..."
workdir = "/home/coder/project"
@@ -142,11 +144,11 @@ module "codex" {
## How it Works
- **Install**: The module installs Codex CLI and sets up the environment
- **System Prompt**: If `codex_system_prompt` is set, writes the prompt to `AGENTS.md` in the `~/.codex/` directory
- **Start**: Launches Codex CLI in the specified directory, wrapped by AgentAPI
- **Configuration**: Sets `OPENAI_API_KEY` environment variable and passes `--model` flag to Codex CLI (if variables provided)
- **Session Continuity**: When `continue = true` (default), the module automatically tracks task sessions in `~/.codex-module/.codex-task-session`. On workspace restart, it resumes the existing session with full conversation history. Set `continue = false` to always start fresh sessions.
- **Install**: Installs Codex CLI and prepares configuration.
- **System Prompt**: If `codex_system_prompt` is set, writes it to `~/.codex/AGENTS.md`.
- **Start**: When `enable_tasks = true`, launches Codex via AgentAPI in the selected `workdir`. When `enable_tasks = false`, only the install script runs.
- **Configuration**: Writes `OPENAI_API_KEY` when provided, and sets the AI Bridge profile when `enable_aibridge = true`.
- **Session Continuity**: When `continue = true` (default), task sessions are tracked in `~/.codex-module/.codex-task-session` for resume on restart. Set `continue = false` to always start fresh sessions.
## Configuration
@@ -168,13 +170,14 @@ network_access = true
## Troubleshooting
- Check installation and startup logs in `~/.codex-module/`
- Ensure your OpenAI API key has access to the specified model
- Tasks mode: check installation/startup logs in `~/.codex-module/`.
- Standalone mode: review the workspace script output for the "Install Codex" script.
- Ensure your OpenAI API key has access to the specified model (unless using AI Bridge).
> [!IMPORTANT]
> To use tasks with Codex CLI, ensure you have the `openai_api_key` variable set. [Tasks Template Example](https://registry.coder.com/templates/coder-labs/tasks-docker).
> The module automatically configures Codex with your API key and model preferences.
> workdir is a required variable for the module to function correctly.
> `workdir` is required when `enable_tasks = true` (default). For standalone CLI usage, set `enable_tasks = false` and `workdir` becomes optional.
## References
+40 -7
View File
@@ -41,15 +41,25 @@ interface SetupProps {
const setup = async (props?: SetupProps): Promise<{ id: string }> => {
const projectDir = "/home/coder/project";
const moduleVars: Record<string, string> = {
install_codex: props?.skipCodexMock ? "true" : "false",
codex_model: "gpt-4-turbo",
workdir: "/home/coder",
...props?.moduleVariables,
};
// For backward compatibility: install_agentapi takes precedence over enable_tasks
// Only set install_agentapi when explicitly installing real AgentAPI
if (props?.skipAgentAPIMock) {
moduleVars.install_agentapi = "true";
}
// Otherwise, let enable_tasks control whether agentapi module runs
// (defaults to true unless explicitly disabled in moduleVariables)
const { id } = await setupUtil({
moduleDir: import.meta.dir,
moduleVariables: {
install_codex: props?.skipCodexMock ? "true" : "false",
install_agentapi: props?.skipAgentAPIMock ? "true" : "false",
codex_model: "gpt-4-turbo",
workdir: "/home/coder",
...props?.moduleVariables,
},
moduleVariables: moduleVars,
registerCleanup,
projectDir,
skipAgentAPIMock: props?.skipAgentAPIMock,
@@ -481,5 +491,28 @@ describe("codex", async () => {
expect(configToml).toContain(
"[profiles.aibridge]\n" + 'model_provider = "aibridge"',
);
// Verify profile = "aibridge" is set at the top of the config
expect(configToml.startsWith('profile = "aibridge"')).toBe(true);
});
test("codex-standalone-mode", async () => {
// Test standalone mode without tasks (enable_tasks = false)
// workdir should default to /home/coder when not explicitly provided
const { id } = await setup({
moduleVariables: {
enable_tasks: "false",
enable_aibridge: "true",
},
});
await execModuleScript(id);
const configToml = await readFileContainer(
id,
"/home/coder/.codex/config.toml",
);
// In standalone mode, config should still have aibridge profile set as default
expect(configToml.startsWith('profile = "aibridge"')).toBe(true);
expect(configToml).toContain("[profiles.aibridge]");
});
});
+54 -7
View File
@@ -38,7 +38,19 @@ variable "icon" {
variable "workdir" {
type = string
description = "The folder to run Codex in."
description = "The folder to run Codex in. Required when enable_tasks is true."
default = null
validation {
condition = var.workdir != null || !local.tasks_enabled
error_message = "workdir is required when enable_tasks is true. Set workdir or set enable_tasks = false for standalone CLI usage."
}
}
variable "enable_tasks" {
type = bool
description = "Enable Tasks UI for Codex (requires workdir). When false, only installs Codex CLI with config for standalone usage."
default = true
}
variable "report_tasks" {
@@ -122,10 +134,11 @@ variable "openai_api_key" {
default = ""
}
# TODO: Remove install_agentapi in next major version (5.0.0)
variable "install_agentapi" {
type = bool
description = "Whether to install AgentAPI."
default = true
description = "DEPRECATED: Use enable_tasks instead. Whether to install AgentAPI."
default = null
}
variable "agentapi_version" {
@@ -184,7 +197,9 @@ resource "coder_env" "coder_aibridge_session_token" {
}
locals {
workdir = trimsuffix(var.workdir, "/")
# Use enable_tasks, but fall back to install_agentapi if explicitly set (for backward compat)
tasks_enabled = var.install_agentapi != null ? var.install_agentapi : var.enable_tasks
workdir = var.workdir != null ? trimsuffix(var.workdir, "/") : "/home/coder"
app_slug = "codex"
install_script = file("${path.module}/scripts/install.sh")
start_script = file("${path.module}/scripts/start.sh")
@@ -204,6 +219,7 @@ locals {
}
module "agentapi" {
count = local.tasks_enabled ? 1 : 0
source = "registry.coder.com/coder/agentapi/coder"
version = "2.0.0"
@@ -218,7 +234,7 @@ module "agentapi" {
cli_app_slug = var.cli_app ? "${local.app_slug}-cli" : null
cli_app_display_name = var.cli_app ? var.cli_app_display_name : null
module_dir_name = local.module_dir_name
install_agentapi = var.install_agentapi
install_agentapi = true
agentapi_subdomain = var.subdomain
agentapi_version = var.agentapi_version
pre_install_script = var.pre_install_script
@@ -262,6 +278,37 @@ module "agentapi" {
EOT
}
output "task_app_id" {
value = module.agentapi.task_app_id
# Standalone installation (when tasks are disabled)
resource "coder_script" "standalone_install" {
count = local.tasks_enabled ? 0 : 1
agent_id = var.agent_id
display_name = "Install Codex"
icon = var.icon
run_on_start = true
start_blocks_login = false
script = <<-EOT
#!/bin/bash
set -o errexit
set -o pipefail
echo -n '${base64encode(local.install_script)}' | base64 -d > /tmp/install.sh
chmod +x /tmp/install.sh
ARG_OPENAI_API_KEY='${var.openai_api_key}' \
ARG_REPORT_TASKS='false' \
ARG_INSTALL='${var.install_codex}' \
ARG_CODEX_VERSION='${var.codex_version}' \
ARG_BASE_CONFIG_TOML='${base64encode(var.base_config_toml)}' \
ARG_ENABLE_AIBRIDGE='${var.enable_aibridge}' \
ARG_AIBRIDGE_CONFIG='${base64encode(var.enable_aibridge ? local.aibridge_config : "")}' \
ARG_ADDITIONAL_MCP_SERVERS='${base64encode(var.additional_mcp_servers)}' \
ARG_CODER_MCP_APP_STATUS_SLUG='' \
ARG_CODEX_START_DIRECTORY='${local.workdir}' \
ARG_CODEX_INSTRUCTION_PROMPT='${base64encode(var.codex_system_prompt)}' \
/tmp/install.sh
EOT
}
output "task_app_id" {
value = local.tasks_enabled ? module.agentapi[0].task_app_id : null
}
@@ -151,6 +151,25 @@ function populate_config_toml() {
write_minimal_default_config "$CONFIG_PATH"
fi
# Set aibridge as default profile when AI Bridge is enabled
# This allows users to run `codex` without --profile flag
if [ "$ARG_ENABLE_AIBRIDGE" = "true" ]; then
printf "Setting aibridge as default profile\n"
# Remove any existing top-level profile line (before first section header)
# This only removes profile = ... at top level, not inside [profiles.*] sections
awk '
BEGIN { in_top_level = 1 }
/^\[/ { in_top_level = 0 }
in_top_level && /^profile[ \t]*=/ { next }
{ print }
' "$CONFIG_PATH" > "${CONFIG_PATH}.tmp"
mv "${CONFIG_PATH}.tmp" "$CONFIG_PATH"
# Prepend profile = "aibridge" to the config
local temp_config
temp_config=$(cat "$CONFIG_PATH")
echo -e "profile = \"aibridge\"\n\n$temp_config" > "$CONFIG_PATH"
fi
append_mcp_servers_section "$CONFIG_PATH"
if [ "$ARG_ENABLE_AIBRIDGE" = "true" ]; then
+9 -9
View File
@@ -13,7 +13,7 @@ Run the [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude
```tf
module "claude-code" {
source = "registry.coder.com/coder/claude-code/coder"
version = "4.7.3"
version = "4.7.4"
agent_id = coder_agent.main.id
workdir = "/home/coder/project"
claude_api_key = "xxxx-xxxxx-xxxx"
@@ -47,7 +47,7 @@ By default, when `enable_boundary = true`, the module uses `coder boundary` subc
```tf
module "claude-code" {
source = "registry.coder.com/coder/claude-code/coder"
version = "4.7.3"
version = "4.7.4"
agent_id = coder_agent.main.id
workdir = "/home/coder/project"
enable_boundary = true
@@ -68,7 +68,7 @@ For tasks integration with AI Bridge, add `enable_aibridge = true` to the [Usage
```tf
module "claude-code" {
source = "registry.coder.com/coder/claude-code/coder"
version = "4.7.3"
version = "4.7.4"
agent_id = coder_agent.main.id
workdir = "/home/coder/project"
enable_aibridge = true
@@ -97,7 +97,7 @@ data "coder_task" "me" {}
module "claude-code" {
source = "registry.coder.com/coder/claude-code/coder"
version = "4.7.3"
version = "4.7.4"
agent_id = coder_agent.main.id
workdir = "/home/coder/project"
ai_prompt = data.coder_task.me.prompt
@@ -120,7 +120,7 @@ This example shows additional configuration options for version pinning, custom
```tf
module "claude-code" {
source = "registry.coder.com/coder/claude-code/coder"
version = "4.7.3"
version = "4.7.4"
agent_id = coder_agent.main.id
workdir = "/home/coder/project"
@@ -176,7 +176,7 @@ Run and configure Claude Code as a standalone CLI in your workspace.
```tf
module "claude-code" {
source = "registry.coder.com/coder/claude-code/coder"
version = "4.7.3"
version = "4.7.4"
agent_id = coder_agent.main.id
workdir = "/home/coder/project"
install_claude_code = true
@@ -198,7 +198,7 @@ variable "claude_code_oauth_token" {
module "claude-code" {
source = "registry.coder.com/coder/claude-code/coder"
version = "4.7.3"
version = "4.7.4"
agent_id = coder_agent.main.id
workdir = "/home/coder/project"
claude_code_oauth_token = var.claude_code_oauth_token
@@ -271,7 +271,7 @@ resource "coder_env" "bedrock_api_key" {
module "claude-code" {
source = "registry.coder.com/coder/claude-code/coder"
version = "4.7.3"
version = "4.7.4"
agent_id = coder_agent.main.id
workdir = "/home/coder/project"
model = "global.anthropic.claude-sonnet-4-5-20250929-v1:0"
@@ -328,7 +328,7 @@ resource "coder_env" "google_application_credentials" {
module "claude-code" {
source = "registry.coder.com/coder/claude-code/coder"
version = "4.7.3"
version = "4.7.4"
agent_id = coder_agent.main.id
workdir = "/home/coder/project"
model = "claude-sonnet-4@20250514"
+5 -2
View File
@@ -276,9 +276,11 @@ resource "coder_env" "claude_code_oauth_token" {
}
resource "coder_env" "claude_api_key" {
count = local.claude_api_key != "" ? 1 : 0
agent_id = var.agent_id
name = "CLAUDE_API_KEY"
value = var.enable_aibridge ? data.coder_workspace_owner.me.session_token : var.claude_api_key
value = local.claude_api_key
}
resource "coder_env" "disable_autoupdater" {
@@ -324,7 +326,8 @@ locals {
start_script = file("${path.module}/scripts/start.sh")
module_dir_name = ".claude-module"
# Extract hostname from access_url for boundary --allow flag
coder_host = replace(replace(data.coder_workspace.me.access_url, "https://", ""), "http://", "")
coder_host = replace(replace(data.coder_workspace.me.access_url, "https://", ""), "http://", "")
claude_api_key = var.enable_aibridge ? data.coder_workspace_owner.me.session_token : var.claude_api_key
# Required prompts for the module to properly report task status to Coder
report_tasks_system_prompt = <<-EOT
@@ -42,7 +42,7 @@ run "test_claude_code_with_api_key" {
}
assert {
condition = coder_env.claude_api_key.value == "test-api-key-123"
condition = coder_env.claude_api_key[0].value == "test-api-key-123"
error_message = "Claude API key value should match the input"
}
}
@@ -298,6 +298,13 @@ run "test_aibridge_enabled" {
enable_aibridge = true
}
override_data {
target = data.coder_workspace_owner.me
values = {
session_token = "mock-session-token"
}
}
assert {
condition = var.enable_aibridge == true
error_message = "AI Bridge should be enabled"
@@ -314,12 +321,12 @@ run "test_aibridge_enabled" {
}
assert {
condition = coder_env.claude_api_key.name == "CLAUDE_API_KEY"
condition = coder_env.claude_api_key[0].name == "CLAUDE_API_KEY"
error_message = "CLAUDE_API_KEY environment variable should be set"
}
assert {
condition = coder_env.claude_api_key.value == data.coder_workspace_owner.me.session_token
condition = coder_env.claude_api_key[0].value == data.coder_workspace_owner.me.session_token
error_message = "CLAUDE_API_KEY should use workspace owner's session token when aibridge is enabled"
}
}
@@ -370,7 +377,7 @@ run "test_aibridge_disabled_with_api_key" {
}
assert {
condition = coder_env.claude_api_key.value == "test-api-key-xyz"
condition = coder_env.claude_api_key[0].value == "test-api-key-xyz"
error_message = "CLAUDE_API_KEY should use the provided API key when aibridge is disabled"
}
@@ -379,3 +386,18 @@ run "test_aibridge_disabled_with_api_key" {
error_message = "ANTHROPIC_BASE_URL should not be set when aibridge is disabled"
}
}
run "test_no_api_key_no_env" {
command = plan
variables {
agent_id = "test-agent-no-key"
workdir = "/home/coder/test"
enable_aibridge = false
}
assert {
condition = length(coder_env.claude_api_key) == 0
error_message = "CLAUDE_API_KEY should not be created when no API key is provided and aibridge is disabled"
}
}
+2 -2
View File
@@ -16,7 +16,7 @@ A module that adds JupyterLab in your Coder template.
module "jupyterlab" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/jupyterlab/coder"
version = "1.2.1"
version = "1.2.2"
agent_id = coder_agent.main.id
}
```
@@ -29,7 +29,7 @@ JupyterLab is automatically configured to work with Coder's iframe embedding. Fo
module "jupyterlab" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/jupyterlab/coder"
version = "1.2.1"
version = "1.2.2"
agent_id = coder_agent.main.id
config = {
ServerApp = {
@@ -77,7 +77,7 @@ describe("jupyterlab", async () => {
expect(output.exitCode).toBe(1);
expect(output.stdout).toEqual([
"Checking for a supported installer",
"No valid installer is not installed",
"No supported installer found.",
"Please install pipx or uv in your Dockerfile/VM image before running this script",
]);
});
+1 -1
View File
@@ -14,7 +14,7 @@ check_available_installer() {
INSTALLER="uv"
return
fi
echo "No valid installer is not installed"
echo "No supported installer found."
echo "Please install pipx or uv in your Dockerfile/VM image before running this script"
exit 1
}