diff --git a/skills/minimax-docx/SKILL.md b/skills/minimax-docx/SKILL.md index 0d99f52..d692fe3 100644 --- a/skills/minimax-docx/SKILL.md +++ b/skills/minimax-docx/SKILL.md @@ -42,6 +42,28 @@ Create, edit, and format DOCX documents via CLI tools or direct C# scripts built **First operation in session:** `scripts/env_check.sh` — do not proceed if `NOT READY`. (Skip on subsequent operations within the same session.) +The setup helpers restore and build `scripts/dotnet/MiniMaxAIDocx.Cli/MiniMaxAIDocx.Cli.csproj` directly for .NET 8+ compatibility. Do not rely on `dotnet restore scripts/dotnet/` because the repo's `.slnx` file is not supported by older SDKs. + +### Restricted network / offline NuGet setup + +If `nuget.org` is blocked, set `MINIMAX_DOCX_NUGET_SOURCES` before running setup or `env_check.sh`. Use a semicolon-separated list of reachable NuGet feeds or local package directories: + +```bash +export MINIMAX_DOCX_NUGET_SOURCES="https://mirror.example/v3/index.json;/absolute/path/to/local/feed" +bash scripts/setup.sh --minimal +``` + +```powershell +$env:MINIMAX_DOCX_NUGET_SOURCES = "https://mirror.example/v3/index.json;C:\path\to\local\feed" +powershell -ExecutionPolicy Bypass -File scripts/setup.ps1 -Minimal +``` + +If you stage offline `.nupkg` files locally, the setup scripts also auto-detect these directories: +- `scripts/dotnet/packages` +- `assets/nuget` + +The restore step uses `--ignore-failed-sources`, so a blocked remote feed will not break installation when the required packages are already available from cache or a local mirror. + ## Quick Start: Direct C# Path When the task requires structural document manipulation (custom styles, complex tables, multi-section layouts, headers/footers, TOC, images), write C# directly instead of wrestling with CLI limitations. Use this scaffold: diff --git a/skills/minimax-docx/scripts/env_check.sh b/skills/minimax-docx/scripts/env_check.sh index 871317c..a858733 100755 --- a/skills/minimax-docx/scripts/env_check.sh +++ b/skills/minimax-docx/scripts/env_check.sh @@ -7,6 +7,8 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" DOTNET_DIR="$SCRIPT_DIR/dotnet" +CLI_PROJECT="$DOTNET_DIR/MiniMaxAIDocx.Cli/MiniMaxAIDocx.Cli.csproj" +DEFAULT_NUGET_SOURCE="https://api.nuget.org/v3/index.json" # Force English output for dotnet CLI export DOTNET_CLI_UI_LANGUAGE=en @@ -17,6 +19,59 @@ echo "" STATUS="READY" WARNINGS=0 +trim() { + local value="$1" + value="${value#"${value%%[![:space:]]*}"}" + value="${value%"${value##*[![:space:]]}"}" + printf '%s' "$value" +} + +append_default_restore_sources() { + RESTORE_SOURCE_ARGS+=("--source" "$DEFAULT_NUGET_SOURCE") + RESTORE_SOURCE_LABELS+=("$DEFAULT_NUGET_SOURCE") + + local local_feed + for local_feed in "$DOTNET_DIR/packages" "$PROJECT_DIR/assets/nuget"; do + if [ -d "$local_feed" ]; then + RESTORE_SOURCE_ARGS+=("--source" "$local_feed") + RESTORE_SOURCE_LABELS+=("$local_feed") + fi + done +} + +collect_restore_sources() { + RESTORE_SOURCE_ARGS=() + RESTORE_SOURCE_LABELS=() + + local raw_sources="${MINIMAX_DOCX_NUGET_SOURCES:-}" + local source + + if [ -n "$raw_sources" ]; then + local OLDIFS="$IFS" + IFS=';' + read -r -a configured_sources <<< "$raw_sources" + IFS="$OLDIFS" + + for source in "${configured_sources[@]}"; do + source="$(trim "$source")" + [ -n "$source" ] || continue + RESTORE_SOURCE_ARGS+=("--source" "$source") + RESTORE_SOURCE_LABELS+=("$source") + done + + if [ "${#RESTORE_SOURCE_ARGS[@]}" -gt 0 ]; then + return + fi + fi + + append_default_restore_sources +} + +quote_for_display() { + local value="$1" + printf '"%s"' "$value" +} + # --- Detect platform --- OS="unknown" case "$(uname -s)" in @@ -61,26 +116,30 @@ fi # --- Critical: NuGet packages --- if [ -d "$DOTNET_DIR" ]; then + collect_restore_sources if [ -f "$DOTNET_DIR/MiniMaxAIDocx.Cli/bin/Debug/net10.0/MiniMaxAIDocx.Cli.dll" ] || \ [ -f "$DOTNET_DIR/MiniMaxAIDocx.Cli/bin/Debug/net8.0/MiniMaxAIDocx.Cli.dll" ]; then printf "[OK] %-14s built\n" "project" else # Try restore + build - if dotnet restore "$DOTNET_DIR" --verbosity quiet &>/dev/null; then + if dotnet restore "$CLI_PROJECT" --verbosity quiet --ignore-failed-sources "${RESTORE_SOURCE_ARGS[@]}" &>/dev/null; then printf "[OK] %-14s packages restored\n" "nuget" - if dotnet build "$DOTNET_DIR" --verbosity quiet --no-restore &>/dev/null; then + if dotnet build "$CLI_PROJECT" --verbosity quiet --no-restore &>/dev/null; then printf "[OK] %-14s build succeeded\n" "project" else - printf "[FAIL] %-14s build failed (run: dotnet build %s)\n" "project" "$DOTNET_DIR" + printf "[FAIL] %-14s build failed (run: dotnet build %s)\n" "project" "$(quote_for_display "$CLI_PROJECT")" STATUS="NOT READY" fi else printf "[FAIL] %-14s restore failed\n" "nuget" echo "" echo " Common causes:" - echo " - No internet access (NuGet needs to download packages)" - echo " - Corporate proxy blocking nuget.org" + echo " - No internet access to the configured NuGet source(s)" + echo " - Corporate proxy or sandbox DNS blocking nuget.org" + echo " - Custom/local feed missing required packages" echo " - SSL certificate issues (try: dotnet nuget list source)" + echo " Source(s): ${RESTORE_SOURCE_LABELS[*]}" + echo " Override sources: export MINIMAX_DOCX_NUGET_SOURCES='https://mirror.example/v3/index.json;/path/to/local/feed'" echo "" STATUS="NOT READY" fi diff --git a/skills/minimax-docx/scripts/setup.ps1 b/skills/minimax-docx/scripts/setup.ps1 index 86ac12a..6669dfa 100644 --- a/skills/minimax-docx/scripts/setup.ps1 +++ b/skills/minimax-docx/scripts/setup.ps1 @@ -13,7 +13,9 @@ $ErrorActionPreference = "Stop" $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $ProjectDir = Split-Path -Parent $ScriptDir $DotnetDir = Join-Path $ScriptDir "dotnet" +$CliProject = Join-Path (Join-Path $DotnetDir "MiniMaxAIDocx.Cli") "MiniMaxAIDocx.Cli.csproj" $LogFile = Join-Path $ProjectDir ".setup.log" +$DefaultNugetSource = "https://api.nuget.org/v3/index.json" # --- Output Helpers --- function Log { Write-Host "[OK] $args" -ForegroundColor Green } @@ -22,6 +24,66 @@ function Fail { Write-Host "[FAIL] $args" -ForegroundColor Red } function Info { Write-Host "[INFO] $args" -ForegroundColor Cyan } function Step { Write-Host "`n=== $args ===" -ForegroundColor Blue } +function Add-DefaultRestoreSources { + param( + [string[]]$Sources = @() + ) + + $result = @($Sources) + $result += $DefaultNugetSource + + $localFeeds = @( + (Join-Path $DotnetDir "packages"), + (Join-Path $ProjectDir "assets/nuget") + ) + foreach ($feed in $localFeeds) { + if (Test-Path $feed) { + $result += $feed + } + } + + return $result +} + +function Get-RestoreSources { + $sources = @() + + if ($env:MINIMAX_DOCX_NUGET_SOURCES) { + foreach ($source in ($env:MINIMAX_DOCX_NUGET_SOURCES -split ';')) { + $trimmed = $source.Trim() + if ($trimmed) { + $sources += $trimmed + } + } + + if ($sources.Count -gt 0) { + return [pscustomobject]@{ + Mode = "custom" + Sources = $sources + } + } + + Warn "MINIMAX_DOCX_NUGET_SOURCES contained no valid entries; falling back to default NuGet sources." + } + + return [pscustomobject]@{ + Mode = "default" + Sources = (Add-DefaultRestoreSources) + } +} + +function Get-RestoreArgs { + param( + [string[]]$Sources + ) + + $args = @($CliProject, "--verbosity", "quiet", "--ignore-failed-sources") + foreach ($source in $Sources) { + $args += @("--source", $source) + } + return $args +} + if ($Help) { Write-Host @" Usage: setup.ps1 [options] @@ -152,11 +214,28 @@ if (-not $Minimal) { Step "Checking NuGet configuration" $nugetSources = & dotnet nuget list source 2>$null -if ($nugetSources -match "nuget.org") { - Log "nuget.org source is configured" +$restoreSourceConfig = Get-RestoreSources +$restoreSources = $restoreSourceConfig.Sources +if ($restoreSourceConfig.Mode -eq "custom") { + Info "Using custom restore source(s) from MINIMAX_DOCX_NUGET_SOURCES" + foreach ($source in $restoreSources) { + Log "restore source: $source" + } } else { - Warn "nuget.org not in sources. Adding..." - & dotnet nuget add source "https://api.nuget.org/v3/index.json" --name "nuget.org" 2>>$LogFile + if ($nugetSources -match "nuget.org") { + Log "nuget.org source is configured" + } else { + Warn "nuget.org not in sources. Adding..." + & dotnet nuget add source $DefaultNugetSource --name "nuget.org" 2>>$LogFile + } + + foreach ($feed in @((Join-Path $DotnetDir "packages"), (Join-Path $ProjectDir "assets/nuget"))) { + if (Test-Path $feed) { + Log "Detected local NuGet feed: $feed" + } + } + + Info "Set MINIMAX_DOCX_NUGET_SOURCES to override restore source(s) in restricted networks" } # --- Encoding Check --- @@ -200,26 +279,34 @@ if (-not (Test-Path $DotnetDir)) { Fail "Dotnet project directory not found: $DotnetDir" exit 1 } +if (-not (Test-Path $CliProject)) { + Fail "CLI project not found: $CliProject" + exit 1 +} Push-Location $DotnetDir Info "Restoring NuGet packages..." -$restoreResult = & dotnet restore --verbosity quiet 2>&1 +$restoreArgs = Get-RestoreArgs -Sources $restoreSources +$restoreResult = & dotnet restore @restoreArgs 2>&1 if ($LASTEXITCODE -ne 0) { Fail "NuGet restore failed:" $restoreResult | ForEach-Object { Fail " $_" } Fail "Common causes:" - Fail " - No internet (NuGet needs to download packages)" + Fail " - No internet access to the configured NuGet source(s)" Fail " - Corporate proxy/firewall blocking nuget.org" + Fail " - Custom/local feed missing required packages" Fail " - Insufficient disk space" - Fail "Try: dotnet restore --verbosity detailed" + Fail "Configured source(s): $($restoreSources -join ', ')" + Fail "Try: dotnet restore `"$CliProject`" --verbosity detailed --ignore-failed-sources" + Fail "Restricted network? Set MINIMAX_DOCX_NUGET_SOURCES='https://mirror.example/v3/index.json;C:\path\to\local\feed'" Pop-Location exit 1 } Log "NuGet packages restored" Info "Building project..." -$buildResult = & dotnet build --verbosity quiet --no-restore 2>&1 +$buildResult = & dotnet build $CliProject --verbosity quiet --no-restore 2>&1 if ($LASTEXITCODE -ne 0) { Fail "Build failed:" $buildResult | ForEach-Object { Fail " $_" } @@ -238,7 +325,7 @@ if (-not $SkipVerify) { Info "Creating a test document..." Push-Location $DotnetDir - $testResult = & dotnet run --project MiniMaxAIDocx.Cli -- create --type report --output $testOutput --title "Setup Test" 2>&1 + $testResult = & dotnet run --project $CliProject -- create --type report --output $testOutput --title "Setup Test" 2>&1 $testExitCode = $LASTEXITCODE Pop-Location @@ -269,6 +356,6 @@ Write-Host " pandoc: $pandocInfo" Write-Host " Project: $DotnetDir" Write-Host "" Write-Host " Usage:" -Write-Host " dotnet run --project $DotnetDir\MiniMaxAIDocx.Cli -- create --type report --output my_report.docx" +Write-Host " dotnet run --project `"$CliProject`" -- create --type report --output my_report.docx" Write-Host "" Write-Host " Log file: $LogFile" diff --git a/skills/minimax-docx/scripts/setup.sh b/skills/minimax-docx/scripts/setup.sh index 2e4bcca..eb50d9b 100755 --- a/skills/minimax-docx/scripts/setup.sh +++ b/skills/minimax-docx/scripts/setup.sh @@ -10,7 +10,9 @@ export DOTNET_CLI_UI_LANGUAGE=en SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" DOTNET_DIR="$SCRIPT_DIR/dotnet" +CLI_PROJECT="$DOTNET_DIR/MiniMaxAIDocx.Cli/MiniMaxAIDocx.Cli.csproj" LOG_FILE="$PROJECT_DIR/.setup.log" +DEFAULT_NUGET_SOURCE="https://api.nuget.org/v3/index.json" # --- Colors --- RED='\033[0;31m' @@ -25,6 +27,58 @@ fail() { echo -e "${RED}[FAIL]${NC} $*"; } info() { echo -e "${BLUE}[INFO]${NC} $*"; } step() { echo -e "\n${BLUE}=== $* ===${NC}"; } +trim() { + local value="$1" + value="${value#"${value%%[![:space:]]*}"}" + value="${value%"${value##*[![:space:]]}"}" + printf '%s' "$value" +} + +append_default_restore_sources() { + RESTORE_SOURCE_ARGS+=("--source" "$DEFAULT_NUGET_SOURCE") + RESTORE_SOURCE_LABELS+=("$DEFAULT_NUGET_SOURCE") + + local local_feed + for local_feed in "$DOTNET_DIR/packages" "$PROJECT_DIR/assets/nuget"; do + if [ -d "$local_feed" ]; then + RESTORE_SOURCE_ARGS+=("--source" "$local_feed") + RESTORE_SOURCE_LABELS+=("$local_feed") + fi + done +} + +collect_restore_sources() { + RESTORE_SOURCE_ARGS=() + RESTORE_SOURCE_LABELS=() + RESTORE_SOURCE_MODE="default" + + local raw_sources="${MINIMAX_DOCX_NUGET_SOURCES:-}" + local source + + if [ -n "$raw_sources" ]; then + local OLDIFS="$IFS" + IFS=';' + read -r -a configured_sources <<< "$raw_sources" + IFS="$OLDIFS" + + for source in "${configured_sources[@]}"; do + source="$(trim "$source")" + [ -n "$source" ] || continue + RESTORE_SOURCE_ARGS+=("--source" "$source") + RESTORE_SOURCE_LABELS+=("$source") + done + + if [ "${#RESTORE_SOURCE_ARGS[@]}" -gt 0 ]; then + RESTORE_SOURCE_MODE="custom" + return + fi + + warn "MINIMAX_DOCX_NUGET_SOURCES is set but contains no valid sources; falling back to default NuGet sources." + fi + + append_default_restore_sources +} + # --- Detect OS & Package Manager --- detect_platform() { OS="unknown" @@ -265,26 +319,35 @@ build_project() { fail "Dotnet project directory not found: $DOTNET_DIR" return 1 fi + if [ ! -f "$CLI_PROJECT" ]; then + fail "CLI project not found: $CLI_PROJECT" + return 1 + fi + + collect_restore_sources cd "$DOTNET_DIR" info "Restoring NuGet packages..." - if ! dotnet restore --verbosity quiet 2>>"$LOG_FILE"; then + if ! dotnet restore "$CLI_PROJECT" --verbosity quiet --ignore-failed-sources "${RESTORE_SOURCE_ARGS[@]}" 2>>"$LOG_FILE"; then fail "NuGet restore failed. Check network and $LOG_FILE for details." fail "Common causes:" - fail " - No internet access (NuGet needs to download packages)" - fail " - Corporate proxy blocking nuget.org" + fail " - No internet access to the configured NuGet source(s)" + fail " - Corporate proxy or sandbox DNS blocking nuget.org" + fail " - Custom/local feed missing required packages" fail " - Disk space insufficient" echo "" - fail "Try manually: cd $DOTNET_DIR && dotnet restore --verbosity detailed" + fail "Configured source(s): ${RESTORE_SOURCE_LABELS[*]}" + fail "Try manually: dotnet restore \"$CLI_PROJECT\" --verbosity detailed --ignore-failed-sources" + fail "Restricted network? Set MINIMAX_DOCX_NUGET_SOURCES='https://mirror.example/v3/index.json;/path/to/local/feed'" return 1 fi log "NuGet packages restored" info "Building project..." - if ! dotnet build --verbosity quiet --no-restore 2>>"$LOG_FILE"; then + if ! dotnet build "$CLI_PROJECT" --verbosity quiet --no-restore 2>>"$LOG_FILE"; then fail "Build failed. Check $LOG_FILE for details." - fail "Try manually: cd $DOTNET_DIR && dotnet build --verbosity normal" + fail "Try manually: dotnet build \"$CLI_PROJECT\" --verbosity normal" return 1 fi log "Project built successfully" @@ -322,12 +385,30 @@ check_nuget_config() { info "No custom NuGet config found (using defaults)" fi - # Test NuGet connectivity - if dotnet nuget list source 2>/dev/null | grep -q "nuget.org"; then - log "nuget.org source is configured" + collect_restore_sources + + if [ "$RESTORE_SOURCE_MODE" = "custom" ]; then + info "Using custom restore source(s) from MINIMAX_DOCX_NUGET_SOURCES" + local source + for source in "${RESTORE_SOURCE_LABELS[@]}"; do + log "restore source: $source" + done else - warn "nuget.org not in sources. Adding..." - dotnet nuget add source "https://api.nuget.org/v3/index.json" --name "nuget.org" 2>/dev/null || true + if dotnet nuget list source 2>/dev/null | grep -q "nuget.org"; then + log "nuget.org source is configured" + else + warn "nuget.org not in sources. Adding..." + dotnet nuget add source "$DEFAULT_NUGET_SOURCE" --name "nuget.org" 2>/dev/null || true + fi + + local local_feed + for local_feed in "$DOTNET_DIR/packages" "$PROJECT_DIR/assets/nuget"; do + if [ -d "$local_feed" ]; then + log "Detected local NuGet feed: $local_feed" + fi + done + + info "Set MINIMAX_DOCX_NUGET_SOURCES to override restore source(s) in restricted networks" fi } @@ -410,7 +491,7 @@ verify_installation() { local test_output="/tmp/minimax-docx-setup-test-$$.docx" info "Creating a test document..." - if cd "$DOTNET_DIR" && dotnet run --project MiniMaxAIDocx.Cli -- create \ + if dotnet run --project "$CLI_PROJECT" -- create \ --type report --output "$test_output" --title "Setup Test" 2>>"$LOG_FILE"; then log "Test document created: $test_output" @@ -446,8 +527,8 @@ print_summary() { echo " Project: $DOTNET_DIR" echo "" echo " Usage:" - echo " dotnet run --project $DOTNET_DIR/MiniMaxAIDocx.Cli -- create --type report --output my_report.docx" - echo " bash $SCRIPT_DIR/env_check.sh # Quick environment check" + echo " dotnet run --project \"$CLI_PROJECT\" -- create --type report --output my_report.docx" + echo " bash \"$SCRIPT_DIR/env_check.sh\" # Quick environment check" echo "" echo " Log file: $LOG_FILE" }