diff --git a/docs/import-worker.md b/docs/import-worker.md index b9c047de4..16be7415a 100644 --- a/docs/import-worker.md +++ b/docs/import-worker.md @@ -299,8 +299,7 @@ Create a Worker directly with a model and optional built-in skills, no ZIP neede ```bash bash hiclaw-import.sh worker --name bob --model claude-sonnet-4-6 \ - --skills github-operations,git-delegation \ - --mcp-servers github + --skills github-operations,git-delegation ``` Or via YAML (preferred for repeatable deployments): @@ -380,7 +379,6 @@ bash hiclaw-import.sh -f # forwards to hiclaw-apply.sh (same f | `--package ` | Remote package URI (`nacos://`, `http://`, `oss://`) | — | | `--model ` | LLM model ID | `qwen3.5-plus` | | `--skills ` | Comma-separated built-in skills | — | -| `--mcp-servers ` | Comma-separated MCP servers | — | | `--runtime ` | Agent runtime (`openclaw`\|`copaw`\|`hermes`) | `openclaw` | | `--yes` | Skip interactive confirmations (swallowed by wrapper when unsupported) | off | @@ -389,23 +387,26 @@ bash hiclaw-import.sh -f # forwards to hiclaw-apply.sh (same f ### hiclaw-import.ps1 (PowerShell — Windows) ```powershell -.\hiclaw-import.ps1 worker -Name [-Zip ] [-Package ] [-Model MODEL] [-Skills s1,s2] [-McpServers m1,m2] [-Runtime rt] [-Yes] +.\hiclaw-import.ps1 worker -Name [-Zip ] [-Package ] [-Model MODEL] [-Skills s1,s2] [-Runtime rt] [-Yes] .\hiclaw-import.ps1 -File ``` -Parameters mirror the Bash version (no `-Prune`/`-DryRun` on YAML path). +Parameters mirror the Bash version (no `-Prune`/`-DryRun` on YAML path). Configure +`mcpServers` through a YAML manifest because each entry requires structured +`name`, `url`, and `transport` fields. ### hiclaw-apply.sh (Bash — macOS/Linux) ```bash -bash hiclaw-apply.sh -f [-- additional args passed to hiclaw apply] +bash hiclaw-apply.sh -f ``` | Option | Description | Default | |--------|-------------|---------| | `-f ` | YAML resource file (required) | — | -The install script header may mention **`--prune` / `--dry-run` / `--watch`** — those are **not** implemented in `hiclaw apply` today; use explicit deletes instead. +The wrapper advertises only `-f`/`--file`. **`--prune`**, **`--dry-run`**, and +**`--watch`** are not implemented in `hiclaw apply`; use explicit deletes instead. ## Troubleshooting diff --git a/docs/zh-cn/declarative-resource-management.md b/docs/zh-cn/declarative-resource-management.md index 749fce8bb..74bfea0ac 100644 --- a/docs/zh-cn/declarative-resource-management.md +++ b/docs/zh-cn/declarative-resource-management.md @@ -653,7 +653,7 @@ bash install/hiclaw-import.sh worker --name alice --package nacos://host:8848/ns # 不带包,直接创建 bash install/hiclaw-import.sh worker --name bob --model claude-sonnet-4-6 \ - --skills github-operations,git-delegation --mcp-servers github + --skills github-operations,git-delegation ``` ### hiclaw CLI — 容器内管理 diff --git a/docs/zh-cn/import-worker.md b/docs/zh-cn/import-worker.md index 70365823f..c96ebcced 100644 --- a/docs/zh-cn/import-worker.md +++ b/docs/zh-cn/import-worker.md @@ -296,8 +296,7 @@ bash hiclaw-import.sh worker --name devops-alice --package nacos://host:8848/nam ```bash bash hiclaw-import.sh worker --name bob --model claude-sonnet-4-6 \ - --skills github-operations,git-delegation \ - --mcp-servers github + --skills github-operations,git-delegation ``` 或通过 YAML(推荐用于可重复部署): @@ -377,7 +376,6 @@ bash hiclaw-import.sh -f # 转发到 hiclaw-apply.sh(与 app | `--package ` | 远程包 URI(`nacos://`、`http://`、`oss://`) | — | | `--model <模型>` | LLM 模型 ID | `qwen3.5-plus` | | `--skills ` | 逗号分隔的内置技能 | — | -| `--mcp-servers ` | 逗号分隔的 MCP Server | — | | `--runtime <运行时>` | Agent 运行时(`openclaw`\|`copaw`\|`hermes`) | `openclaw` | | `--yes` | 跳过交互确认(包装脚本可能在底层吞掉) | 关闭 | @@ -386,23 +384,25 @@ bash hiclaw-import.sh -f # 转发到 hiclaw-apply.sh(与 app ### hiclaw-import.ps1(PowerShell — Windows) ```powershell -.\hiclaw-import.ps1 worker -Name <名称> [-Zip <路径或URL>] [-Package ] [-Model 模型] [-Skills s1,s2] [-McpServers m1,m2] [-Runtime rt] [-Yes] +.\hiclaw-import.ps1 worker -Name <名称> [-Zip <路径或URL>] [-Package ] [-Model 模型] [-Skills s1,s2] [-Runtime rt] [-Yes] .\hiclaw-import.ps1 -File ``` -参数与 Bash 版本一致(YAML 路径无 `-Prune`/`-DryRun`)。 +参数与 Bash 版本一致(YAML 路径无 `-Prune`/`-DryRun`)。`mcpServers` 的每个 +条目都需要结构化的 `name`、`url` 和 `transport` 字段,因此请通过 YAML 清单配置。 ### hiclaw-apply.sh(Bash — macOS/Linux) ```bash -bash hiclaw-apply.sh -f [-- 其余参数原样传给 hiclaw apply] +bash hiclaw-apply.sh -f ``` | 选项 | 说明 | 默认值 | |------|------|--------| | `-f <路径>` | YAML 资源文件(必需) | — | -安装脚本头部若仍提到 **`--prune` / `--dry-run` / `--watch`**,请以当前 **`hiclaw apply` 实现为准**(未实现上述开关),改用显式 `hiclaw delete`。 +包装脚本只公开 `-f`/`--file`。当前 **`hiclaw apply`** 未实现 +**`--prune`**、**`--dry-run`** 或 **`--watch`**,请改用显式 `hiclaw delete`。 ## 故障排查 diff --git a/install/hiclaw-apply.sh b/install/hiclaw-apply.sh index 50456182f..5c9b3df30 100644 --- a/install/hiclaw-apply.sh +++ b/install/hiclaw-apply.sh @@ -6,9 +6,9 @@ # # Usage: # ./hiclaw-apply.sh -f resource.yaml # incremental apply -# ./hiclaw-apply.sh -f resource.yaml --prune # full sync (delete extras) -# ./hiclaw-apply.sh -f resource.yaml --dry-run # show diff only -# ./hiclaw-apply.sh -f resource.yaml --watch # watch file changes +# +# The current `hiclaw apply` command supports -f/--file only. Delete stale +# resources explicitly with `hiclaw delete`. # # Environment: # AGENTTEAMS_CONTAINER_CMD Override container runtime (docker/podman) diff --git a/install/hiclaw-import.ps1 b/install/hiclaw-import.ps1 index f99713761..66262b62e 100644 --- a/install/hiclaw-import.ps1 +++ b/install/hiclaw-import.ps1 @@ -7,8 +7,8 @@ # .\hiclaw-import.ps1 worker -Name -Zip # .\hiclaw-import.ps1 worker -Name -Package [-Model MODEL] # .\hiclaw-import.ps1 worker -Name # auto-imports package -# .\hiclaw-import.ps1 worker -Name -Model MODEL [-Skills s1,s2] [-McpServers m1,m2] -# .\hiclaw-import.ps1 -File [-Prune] [-DryRun] +# .\hiclaw-import.ps1 worker -Name -Model MODEL [-Skills s1,s2] [-Runtime RUNTIME] +# .\hiclaw-import.ps1 -File param( [Parameter(Position = 0)] @@ -19,11 +19,8 @@ param( [string]$Zip = "", [string]$Package = "", [string]$Skills = "", - [string]$McpServers = "", [string]$Runtime = "", [string]$File = "", - [switch]$Prune, - [switch]$DryRun, [switch]$Yes ) @@ -81,8 +78,6 @@ if ($File) { Write-Host "[AgentTeams Import] Copied $FileName -> container:/tmp/import/" -ForegroundColor Cyan $hiclawArgs = @("apply", "-f", "/tmp/import/$FileName") - if ($Prune) { $hiclawArgs += "--prune" } - if ($DryRun) { $hiclawArgs += "--dry-run" } # Accept -Yes for wrapper compatibility, but do not forward it because the # container-internal hiclaw CLI does not support --yes. @@ -141,9 +136,7 @@ switch ($ResourceType) { if ($Model) { $hiclawArgs += @("--model", $Model) } if ($Package) { $hiclawArgs += @("--package", $Package) } if ($Skills) { $hiclawArgs += @("--skills", $Skills) } - if ($McpServers) { $hiclawArgs += @("--mcp-servers", $McpServers) } if ($Runtime) { $hiclawArgs += @("--runtime", $Runtime) } - if ($DryRun) { $hiclawArgs += "--dry-run" } & $ContainerCmd exec agentteams-manager hiclaw @hiclawArgs exit $LASTEXITCODE @@ -154,8 +147,8 @@ switch ($ResourceType) { Write-Host " .\hiclaw-import.ps1 worker -Name -Zip " Write-Host " .\hiclaw-import.ps1 worker -Name -Package [-Model MODEL]" Write-Host " .\hiclaw-import.ps1 worker -Name # auto-import package " - Write-Host " .\hiclaw-import.ps1 worker -Name -Model MODEL [-Skills s1,s2] [-McpServers m1,m2]" - Write-Host " .\hiclaw-import.ps1 -File [-Prune] [-DryRun]" + Write-Host " .\hiclaw-import.ps1 worker -Name -Model MODEL [-Skills s1,s2] [-Runtime RUNTIME]" + Write-Host " .\hiclaw-import.ps1 -File " exit 0 } diff --git a/install/hiclaw-import.sh b/install/hiclaw-import.sh index 837880d31..55810024e 100755 --- a/install/hiclaw-import.sh +++ b/install/hiclaw-import.sh @@ -8,8 +8,8 @@ # ./hiclaw-import.sh worker --name --zip [--yes] # ./hiclaw-import.sh worker --name --package [--model MODEL] # ./hiclaw-import.sh worker --name # auto-imports package -# ./hiclaw-import.sh worker --name --model MODEL [--skills s1,s2] [--mcp-servers m1,m2] -# ./hiclaw-import.sh -f [--prune] [--dry-run] +# ./hiclaw-import.sh worker --name --model MODEL [--skills s1,s2] [--runtime RUNTIME] +# ./hiclaw-import.sh -f # # Environment variables (for automation): # AGENTTEAMS_NON_INTERACTIVE Skip all prompts (same as --yes) @@ -84,10 +84,8 @@ case "${RESOURCE_TYPE}" in PACKAGE_URI="$2" AGENTTEAMS_ARGS+=("$1" "$2") shift 2 ;; - --model|--skills|--mcp-servers|--runtime) + --model|--skills|--runtime) AGENTTEAMS_ARGS+=("$1" "$2"); shift 2 ;; - --dry-run) - AGENTTEAMS_ARGS+=("$1"); shift ;; --yes) shift ;; *) echo "Unknown option: $1"; exit 1 ;; @@ -125,8 +123,8 @@ case "${RESOURCE_TYPE}" in echo " $0 worker --name --zip " echo " $0 worker --name --package [--model MODEL]" echo " $0 worker --name # auto-import package " - echo " $0 worker --name --model MODEL [--skills s1,s2] [--mcp-servers m1,m2]" - echo " $0 -f [--prune] [--dry-run]" + echo " $0 worker --name --model MODEL [--skills s1,s2] [--runtime RUNTIME]" + echo " $0 -f " exit 0 ;; diff --git a/install/tests/test-import-wrapper-contract.sh b/install/tests/test-import-wrapper-contract.sh new file mode 100755 index 000000000..e8e39c12b --- /dev/null +++ b/install/tests/test-import-wrapper-contract.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash + +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +BASH_IMPORT="${ROOT_DIR}/install/hiclaw-import.sh" +POWERSHELL_IMPORT="${ROOT_DIR}/install/hiclaw-import.ps1" +TEST_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/agentteams-import-contract.XXXXXX")" +trap 'rm -rf "${TEST_ROOT}"' EXIT + +FAKE_BIN="${TEST_ROOT}/bin" +FAKE_DOCKER_CAPTURE="${TEST_ROOT}/docker-args.txt" +TEST_HOME="${TEST_ROOT}/home" +mkdir -p "${FAKE_BIN}" "${TEST_HOME}/cache" "${TEST_HOME}/config" "${TEST_HOME}/data" +export FAKE_DOCKER_CAPTURE + +cat > "${FAKE_BIN}/docker" <<'EOF' +#!/usr/bin/env bash +set -e + +case "${1:-}" in + info) + exit 0 + ;; + ps) + printf '%s\n' agentteams-manager + exit 0 + ;; + cp) + exit 0 + ;; + exec) + if [ "${3:-}" = "mkdir" ]; then + exit 0 + fi + printf '%s\n' "$@" > "${FAKE_DOCKER_CAPTURE}" + exit 0 + ;; +esac + +printf 'unexpected docker invocation: %s\n' "$*" >&2 +exit 1 +EOF +chmod +x "${FAKE_BIN}/docker" + +PASS=0 +FAIL=0 +RUN_OUTPUT="" +RUN_RC=0 + +pass() { + printf 'PASS: %s\n' "$1" + PASS=$((PASS + 1)) +} + +fail() { + printf 'FAIL: %s\n' "$1" >&2 + FAIL=$((FAIL + 1)) +} + +run_bash_import() { + set +e + RUN_OUTPUT="$(PATH="${FAKE_BIN}:${PATH}" bash "${BASH_IMPORT}" "$@" 2>&1)" + RUN_RC=$? + set -e +} + +run_powershell_import() { + local pwsh_bin="$1" + shift + set +e + RUN_OUTPUT="$( + HOME="${TEST_HOME}" \ + XDG_CACHE_HOME="${TEST_HOME}/cache" \ + XDG_CONFIG_HOME="${TEST_HOME}/config" \ + XDG_DATA_HOME="${TEST_HOME}/data" \ + POWERSHELL_TELEMETRY_OPTOUT=1 \ + PATH="${FAKE_BIN}:${PATH}" \ + "${pwsh_bin}" -NoProfile -File "${POWERSHELL_IMPORT}" "$@" 2>&1 + )" + RUN_RC=$? + set -e +} + +assert_rejected() { + local label="$1" + local expected="$2" + if [ "${RUN_RC}" -ne 0 ] && [[ "${RUN_OUTPUT}" == *"${expected}"* ]]; then + pass "${label}" + else + fail "${label}: rc=${RUN_RC}, output=${RUN_OUTPUT}" + fi +} + +assert_not_advertised() { + local label="$1" + local flag="$2" + if [[ "${RUN_OUTPUT}" != *"${flag}"* ]]; then + pass "${label}" + else + fail "${label}: help still contains ${flag}" + fi +} + +run_bash_import worker --name alice --skills github-operations +if [ "${RUN_RC}" -eq 0 ] && grep -Fxq -- '--skills' "${FAKE_DOCKER_CAPTURE}"; then + pass "Bash forwards supported worker flags" +else + fail "Bash did not forward supported worker flags" +fi + +run_bash_import worker --name alice --mcp-servers github +assert_rejected "Bash rejects removed --mcp-servers" "Unknown option: --mcp-servers" + +run_bash_import worker --name alice --dry-run +assert_rejected "Bash rejects unimplemented --dry-run" "Unknown option: --dry-run" + +run_bash_import --help +assert_not_advertised "Bash help omits removed MCP flag" "--mcp-servers" +assert_not_advertised "Bash help omits unimplemented dry-run flag" "--dry-run" +assert_not_advertised "Bash help omits unimplemented prune flag" "--prune" + +if grep -Eq -- '--prune|--dry-run|--watch' "${ROOT_DIR}/install/hiclaw-apply.sh"; then + fail "Bash apply wrapper still advertises unimplemented flags" +else + pass "Bash apply wrapper omits unimplemented flags" +fi + +PWSH_BIN="${PWSH_BIN:-$(command -v pwsh || true)}" +if [ -n "${PWSH_BIN}" ]; then + run_powershell_import "${PWSH_BIN}" worker -Name alice -Skills github-operations + if [ "${RUN_RC}" -eq 0 ] && grep -Fxq -- '--skills' "${FAKE_DOCKER_CAPTURE}"; then + pass "PowerShell forwards supported worker parameters" + else + fail "PowerShell did not forward supported worker parameters" + fi + + run_powershell_import "${PWSH_BIN}" worker -Name alice -McpServers github + assert_rejected "PowerShell rejects removed -McpServers" "parameter name 'McpServers'" + + run_powershell_import "${PWSH_BIN}" worker -Name alice -DryRun + assert_rejected "PowerShell rejects unimplemented -DryRun" "parameter name 'DryRun'" + + run_powershell_import "${PWSH_BIN}" worker -Name alice -Prune + assert_rejected "PowerShell rejects unimplemented -Prune" "parameter name 'Prune'" + + run_powershell_import "${PWSH_BIN}" + assert_not_advertised "PowerShell help omits removed MCP parameter" "McpServers" + assert_not_advertised "PowerShell help omits unimplemented dry-run parameter" "DryRun" + assert_not_advertised "PowerShell help omits unimplemented prune parameter" "Prune" +else + printf 'SKIP: pwsh is unavailable; PowerShell runtime assertions skipped\n' +fi + +printf '\nResults: %d passed, %d failed\n' "${PASS}" "${FAIL}" +if [ "${FAIL}" -ne 0 ]; then + exit 1 +fi