[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71MBR87MVJH94HC5EGFJEGK":3,"skill-same:01M71MBR87MVJH94HC5EGFJEGK":100},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":59,"commitSha":60,"skillDirectory":61,"forksCount":14,"repositoryHtmlUrl":62,"repositoryHomepageUrl":63,"ownerHtmlUrl":64,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":65,"install":66,"resources":79},"01M71MBR87MVJH94HC5EGFJEGK","amc-setup-calibration-stack",null,"Launch AutoMagicCalib microservice and web UI from NGC release images via Docker Compose. Use when user says 'deploy auto calibration', 'launch auto calibration', 'launch AMC', 'start MS+UI', or 'set up auto-magic-calib'. Requires NGC API key.","pattanation\u002FNorvik","pattanation","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F235419268?v=4","01M71M5THHYYB15ME8R2E4FCZG","Patta","01M71M5TJM1NDM992M8PDKYR2K",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Famc-setup-calibration-stack\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"calibration","amc setup calibration stack","setup","stack","docker","NVIDIA","compose","microservice","ui","start","release","2026","api","when","auto","up","docker compose","ms","SET","images","2026-11-10 10:56:23",false,"---\nname: \"amc-setup-calibration-stack\"\ndescription: \"Launch AutoMagicCalib microservice and web UI from NGC release images via Docker Compose. Use when user says 'deploy auto calibration', 'launch auto calibration', 'launch AMC', 'start MS+UI', or 'set up auto-magic-calib'. Requires NGC API key.\"\nmetadata:\n  tags: [amc, deepstream, docker, calibration, setup, ngc]\nowner: \"NVIDIA CORPORATION\"\nservice: \"auto-magic-calib\"\nversion: \"1.0.0\"\nreviewed: \"2026-04-28\"\nlicense: \"Apache-2.0\"\ndata_classification: public\n---\n\n# Skill: Launch AutoMagicCalib Release Containers\n\n## When to Use This Skill\n\nActivate this skill when the user wants to bring up the AutoMagicCalib stack. Typical prompts:\n\n- \"deploy auto calibration\"\n- \"launch auto calibration\" \u002F \"launch AMC\"\n- \"start MS+UI\" \u002F \"bring up the microservice and UI\"\n- \"set up auto-magic-calib\"\n\nPrerequisite: NGC API key (the skill prompts for it). For first-time setup on a fresh machine, this also resolves or clones the `auto-magic-calib` repo after explicit user confirmation.\n\n## Overview\nLaunch the AutoMagicCalib microservice (MS) and UI from pre-built release images via Docker Compose. Use this for production deployments or when you want to run the full stack (backend + web UI) without building images locally.\n\n## Prerequisites\n- Docker and Docker Compose installed\n- NVIDIA Docker Runtime configured (for GPU support)\n- `auto-magic-calib` repo on disk — Step 0b auto-resolves an existing checkout via `git rev-parse --show-toplevel`, or offers to clone `https:\u002F\u002Fgithub.com\u002FNVIDIA-AI-IOT\u002Fauto-magic-calib` into `~\u002Fauto-magic-calib` if none is found\n- NGC account with access to NVIDIA container registry\n- **Docker must be runnable without `sudo`** — verify with `docker ps`. If it fails, ask the user to follow the post-install steps: https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Finstall\u002Flinux-postinstall\u002F\n\n> **If `docker ps` fails with \"permission denied\"**, ask the user to run:\n> ```bash\n> sudo usermod -aG docker $USER\n> newgrp docker   # applies group change in current shell without logout\n> ```\n> Then verify with `docker ps` before continuing.\n\n## Instructions\n\n### Step 0: Verify Docker Runs Without sudo\n\n```bash\ndocker ps\n```\n\n- If it succeeds → continue.\n- If it fails with \"permission denied\" → the user is not in the `docker` group. Ask the user to run:\n  ```bash\n  sudo usermod -aG docker $USER && newgrp docker\n  ```\n  Then ask the user to confirm `docker ps` works before continuing.\n\n> **Agent note**: If `docker ps` cannot be run from within the agent sandbox, ask the user to confirm it works (e.g. \"Can you confirm `docker ps` runs without sudo?\") before proceeding.\n\n### Step 0b: Resolve Repo Checkout\n\nThe skill needs `compose\u002F`, `assets\u002Fsdg_08_2_sample_data_010926.zip`, and a `models\u002F` mount point — all of which live in the `auto-magic-calib` repo. If you're already inside a checkout, the skill uses it. Otherwise it asks for explicit user confirmation using the host's question mechanism; if none is available, ask in chat and wait before cloning into `~\u002Fauto-magic-calib`.\n\n```bash\nREPO_URL=\"https:\u002F\u002Fgithub.com\u002FNVIDIA-AI-IOT\u002Fauto-magic-calib.git\"\nDEFAULT_CLONE_DIR=\"$HOME\u002Fauto-magic-calib\"\n\n# 1. Already inside a usable checkout?\nREPO_ROOT=\"$(git rev-parse --show-toplevel 2>\u002Fdev\u002Fnull)\"\nif [ -n \"$REPO_ROOT\" ] && [ -f \"$REPO_ROOT\u002Fcompose\u002Fcompose.yml\" ] && [ -d \"$REPO_ROOT\u002Fassets\" ]; then\n  echo \"✓ Using existing checkout: $REPO_ROOT\"\n\n# 2. Default clone dir already populated from a prior run?\nelif [ -d \"$DEFAULT_CLONE_DIR\u002F.git\" ] && [ -f \"$DEFAULT_CLONE_DIR\u002Fcompose\u002Fcompose.yml\" ]; then\n  REPO_ROOT=\"$DEFAULT_CLONE_DIR\"\n  echo \"✓ Found existing clone at $REPO_ROOT\"\n\n# 3. Nothing on disk — STOP and ask the user for confirmation using the\n#    host's question mechanism; if none is available, ask in chat and wait.\n#    Do NOT clone silently from this block.\nelse\n  echo \"No auto-magic-calib checkout found. Ask the user for confirmation:\"\n  echo \"  Clone $REPO_URL into $DEFAULT_CLONE_DIR? [y\u002FN]\"\n  echo \"On 'y' — run: git clone \\\"$REPO_URL\\\" \\\"$DEFAULT_CLONE_DIR\\\"\"\n  exit 1\nfi\n\ncd \"$REPO_ROOT\"\nexport REPO_ROOT\necho \"REPO_ROOT=$REPO_ROOT\"\n```\n\n> **Agent note**: do **not** clone silently. Ask the user first using the host's question mechanism; if none is available, ask in chat and wait. Example: \"auto-magic-calib repo not found. Clone `https:\u002F\u002Fgithub.com\u002FNVIDIA-AI-IOT\u002Fauto-magic-calib` into `~\u002Fauto-magic-calib`? (or provide your own path)\". Honour an alternate path if the user offers one. The clone is a few hundred MB (compose files + sample dataset + assets).\n\n### Step 0c: Install Python venv (New Systems Only)\n\nOn a fresh system, `pip` and `python3-venv` may not be available. Install them first:\n\n```bash\n# Create a venv for HuggingFace CLI (project-local preferred)\nREPO_DIR=\"$(git rev-parse --show-toplevel 2>\u002Fdev\u002Fnull || pwd)\"\nHF_VENV=\"${REPO_DIR}\u002Fvenv\"\npython3 -m venv \"$HF_VENV\" 2>\u002Fdev\u002Fnull || {\n  echo \"ERROR: python3-venv not available.\" >&2\n  echo \"Install it manually: sudo apt install -y python3-venv python3-pip\" >&2\n  exit 1\n}\n\n# Install HuggingFace hub (needed for VGGT download)\n\"$HF_VENV\u002Fbin\u002Fpip\" install --upgrade pip huggingface_hub\n```\n\n> **Note**: Skip this step if a venv with `hf` already exists (check `venv\u002Fbin\u002Fhf` in the repo root or `~\u002Fvenv\u002Famc\u002Fbin\u002Fhf`).\n\n### Step 1: Login to NGC\n\nAsk the user for their NGC API key using the host's question mechanism; if none is available, ask in chat and wait. Then run:\n\n```bash\necho \"\u003CNGC_API_KEY>\" | docker login nvcr.io --username '$oauthtoken' --password-stdin\necho \"✓ NGC authentication complete\"\n```\n\n### Step 2: Download VGGT Model (If Not Already Present)\n\n```bash\nexport REPO_ROOT=$(git rev-parse --show-toplevel)\ncd \"$REPO_ROOT\"\n\nif [ -f \"models\u002Fvggt\u002Fvggt_1B_commercial.pt\" ]; then\n  echo \"✓ VGGT model already present\"\nelse\n  echo \"✗ VGGT model not found\"\n  echo \"Options:\"\n  echo \"  1. Continue without VGGT (AMC only - sufficient for most use cases)\"\n  echo \"  2. Download VGGT model (~4.7GB, requires HuggingFace account)\"\nfi\n```\n\n**To download VGGT** (ask the user for a HuggingFace token using the host's question mechanism; if none is available, ask in chat and wait):\n\n**Step 2a: Accept Model License** (required, one-time):\n1. Visit: https:\u002F\u002Fhuggingface.co\u002Ffacebook\u002FVGGT-1B-Commercial\n2. Log in to your HuggingFace account\n3. Click \"Agree and access repository\" to accept license terms\n\n**Step 2b: Get HuggingFace Token**:\n1. Visit: https:\u002F\u002Fhuggingface.co\u002Fsettings\u002Ftokens\n2. Create new token with \"Read\" access (starts with `hf_...`)\n3. Ask the user for the token using the host's question mechanism; if none is available, ask in chat and wait. Do NOT ask them to run a command\n\n**Step 2c: Download** (pass token via `HF_TOKEN` env var — keeps the secret out of `hf`'s argv \u002F `ps aux`; no interactive login needed):\n```bash\nREPO_DIR=\"$(git rev-parse --show-toplevel 2>\u002Fdev\u002Fnull || pwd)\"\ncd \"$REPO_DIR\"\n\n# Find the HuggingFace CLI binary (named 'hf', not 'huggingface-cli')\nHF_BIN=\"$(find \"$REPO_DIR\u002Fvenv\" ~\u002Fvenv\u002Famc -name hf -type f 2>\u002Fdev\u002Fnull | head -1)\"\n{ [ -z \"$HF_BIN\" ] || [ ! -x \"$HF_BIN\" ]; } && { echo \"ERROR: hf binary not found or not executable; install the hf CLI (Step 0c) or set HF_BIN\" >&2; exit 1; }\n\n# Do NOT use --token on the command line (leaks via ps\u002Fargv). The HF CLI\n# reads HF_TOKEN from the environment automatically.\nHF_TOKEN=\"\u003CHF_TOKEN>\" \"$HF_BIN\" download facebook\u002FVGGT-1B-Commercial \\\n  --local-dir models\u002Fvggt\u002F\n\n# Verify\nls -lh models\u002Fvggt\u002Fvggt_1B_commercial.pt\n# Should show ~4.7GB file\n```\n\n> **Important**: Download BEFORE setting `chown 1000:1000` on the models directory — the current user needs write access during download. Set permissions in Step 4 after download completes.\n\n### Step 3: Configure .env Variables\n\nThe `.env` file at `compose\u002F.env` controls ports and paths. Update it before launching:\n\n```bash\ncd $REPO_ROOT\u002Fcompose\n\n# Find available backend port (8000-8009)\nfor port in {8000..8009}; do\n  if ! lsof -Pi :$port -sTCP:LISTEN -t >\u002Fdev\u002Fnull 2>&1; then\n    MS_PORT=$port\n    echo \"Using backend port: $MS_PORT\"\n    break\n  fi\ndone\n[ -z \"$MS_PORT\" ] && { echo \"ERROR: no free backend port in 8000-8009; free one or widen the range.\" >&2; exit 1; }\n\n# Find available UI port (5000-5009)\nfor port in {5000..5009}; do\n  if ! lsof -Pi :$port -sTCP:LISTEN -t >\u002Fdev\u002Fnull 2>&1; then\n    UI_PORT=$port\n    echo \"Using UI port: $UI_PORT\"\n    break\n  fi\ndone\n[ -z \"$UI_PORT\" ] && { echo \"ERROR: no free UI port in 5000-5009; free one or widen the range.\" >&2; exit 1; }\n\n# Get host IP\nHOST_IP=$(hostname -I | awk '{print $1}')\necho \"Host IP: $HOST_IP\"\n\n# Update .env — preserve any keys the user has already set; back up first.\n# .env may contain credentials, so restrict permissions on both the backup and\n# the live file (chmod 600). Add `compose\u002F.env.bak.*` to .gitignore.\nENV_FILE=\".env\"\nif [ -f \"$ENV_FILE\" ]; then\n  BACKUP=\"${ENV_FILE}.bak.$(date +%s)\"\n  cp \"$ENV_FILE\" \"$BACKUP\"\n  chmod 600 \"$BACKUP\"\nfi\ntouch \"$ENV_FILE\"\nchmod 600 \"$ENV_FILE\"\nset_env_key() {\n  local k=\"$1\" v=\"$2\"\n  if grep -qE \"^${k}=\" \"$ENV_FILE\"; then\n    sed -i \"s|^${k}=.*|${k}=${v}|\" \"$ENV_FILE\"\n  else\n    echo \"${k}=${v}\" >> \"$ENV_FILE\"\n  fi\n}\nset_env_key AUTO_MAGIC_CALIB_MS_PORT \"${MS_PORT}\"\nset_env_key AUTO_MAGIC_CALIB_UI_PORT \"${UI_PORT}\"\nset_env_key PROJECT_DIR \"..\u002F..\u002Fprojects\"\nset_env_key MODEL_DIR \"..\u002F..\u002Fmodels\"\nset_env_key HOST_IP \"${HOST_IP}\"\n\n# Keep timestamped .env backups out of git.\nGITIGNORE=\"$REPO_ROOT\u002F.gitignore\"\ntouch \"$GITIGNORE\"\ngrep -qxF \"compose\u002F.env.bak.*\" \"$GITIGNORE\" || echo \"compose\u002F.env.bak.*\" >> \"$GITIGNORE\"\n\necho \"✓ .env updated\"\ncat .env\n```\n\n**Important**: `HOST_IP` must be the machine's network IP (not `localhost`) so the UI container can reach the backend from a browser.\n\nOptional: set `VGGT_MODEL_PATH` only if the VGGT model is mounted at a non-default container path; default is `\u002Ftmp\u002Fvggt_model\u002Fvggt_1B_commercial.pt` inside the MS container.\n\n### Step 4: Set Directory Permissions\n\nThe containers run as UID\u002FGID 1000. The `projects` and `models` directories must be owned by this UID for containers to read\u002Fwrite properly:\n\n```bash\ncd \"$REPO_ROOT\"\n\n# Create projects directory if it doesn't exist\nmkdir -p projects\n\n# Set ownership (required for containers to write calibration outputs).\n# Do this AFTER VGGT download is complete (current user needs write access during download).\n# Get explicit user confirmation before running sudo chown — it recursively changes\n# ownership of $REPO_ROOT\u002Fprojects and $REPO_ROOT\u002Fmodels to UID\u002FGID 1000.\n[ -d projects ] && [ -d models ] || {\n  echo \"ERROR: expected projects\u002F and models\u002F under $REPO_ROOT\" >&2; exit 1;\n}\necho \"About to chown -R 1000:1000 on:\"\necho \"  $REPO_ROOT\u002Fprojects\"\necho \"  $REPO_ROOT\u002Fmodels\"\necho \"(required because containers run as UID 1000). Confirm before proceeding.\"\nsudo chown 1000:1000 -R projects\nsudo chown 1000:1000 -R models\n\necho \"✓ Permissions set\"\n```\n\n### Step 5: Launch Services\n\nBefore pulling, fail fast if the NGC key authenticated in Step 1 but cannot actually access a release image — otherwise `docker compose up` aborts partway with a 401\u002F403 after some work is already done.\n\n```bash\ncd $REPO_ROOT\u002Fcompose\n\n# Fail-fast image-access check: confirm the NGC key can reach every release\n# image BEFORE pulling. `docker manifest inspect` checks registry access without\n# downloading layers, and the image list is read from the resolved compose so it\n# tracks the release tag automatically.\nIMAGES=$(docker compose config --images | sort -u)\n[ -z \"$IMAGES\" ] && { echo \"ERROR: no images resolved from compose — check compose\u002F.env and the chosen profile.\" >&2; exit 1; }\nfor img in $IMAGES; do\n  echo \"Checking access: $img\"\n  if ! docker manifest inspect \"$img\" >\u002Fdev\u002Fnull 2>&1; then\n    echo \"NGC login succeeded, but this key cannot access the required image:\" >&2\n    echo \"  $img\" >&2\n    echo \"Provide an NGC key with access to this image's namespace, then re-run Step 1 (login) and retry.\" >&2\n    exit 1\n  fi\ndone\n\n# Start all services (images pulled automatically on first run)\ndocker compose up -d\n\n# Check containers are running\ndocker compose ps\n```\n\n**Expected output**:\n```\nNAME                    IMAGE                                                              STATUS\nauto-magic-calib-ms-1   nvcr.io\u002Fnvidia\u002Fauto-magic-calib:2.0.0           Up (healthy)\nauto-magic-calib-ui-1   nvcr.io\u002Fnvidia\u002Fauto-magic-calib-ui:2.0.0        Up\n```\n\n### Step 6: Verify Services Are Running\n\n```bash\n# Read ports from .env\nMS_PORT=$(grep AUTO_MAGIC_CALIB_MS_PORT $REPO_ROOT\u002Fcompose\u002F.env | cut -d= -f2)\nUI_PORT=$(grep AUTO_MAGIC_CALIB_UI_PORT $REPO_ROOT\u002Fcompose\u002F.env | cut -d= -f2)\nHOST_IP=$(grep HOST_IP $REPO_ROOT\u002Fcompose\u002F.env | cut -d= -f2)\n\n# Wait for microservice readiness. Cold image pulls or first startup can need\n# extra time after `docker compose up -d` returns.\nREADY_URL=\"http:\u002F\u002Flocalhost:${MS_PORT}\u002Fv1\u002Fready\"\necho \"Waiting for microservice readiness at ${READY_URL} ...\"\nready_response=\"\"\nfor attempt in $(seq 1 24); do\n  if ready_response=$(curl -fsS --max-time 5 \"${READY_URL}\" 2>\u002Fdev\u002Fnull) && \\\n     echo \"${ready_response}\" | grep -q '\"code\"[[:space:]]*:[[:space:]]*0'; then\n    echo \"Microservice ready: ${ready_response}\"\n    break\n  fi\n  if [ \"${attempt}\" -lt 24 ]; then\n    printf \"  [%02d\u002F24] Microservice not ready yet; retrying in 5s...\\n\" \"${attempt}\"\n    sleep 5\n  fi\ndone\n\nif ! echo \"${ready_response}\" | grep -q '\"code\"[[:space:]]*:[[:space:]]*0'; then\n  echo \"ERROR: microservice did not report ready within 120 seconds: ${READY_URL}\" >&2\n  echo \"Check status and logs:\" >&2\n  echo \"  cd ${REPO_ROOT}\u002Fcompose && docker compose ps\" >&2\n  echo \"  cd ${REPO_ROOT}\u002Fcompose && docker compose logs auto-magic-calib-ms\" >&2\n  exit 1\nfi\n\n# Check UI is serving\nUI_STATUS=$(curl -s -o \u002Fdev\u002Fnull -w \"%{http_code}\" --max-time 5 \"http:\u002F\u002Flocalhost:${UI_PORT}\")\nif [ \"${UI_STATUS}\" != \"200\" ]; then\n  echo \"ERROR: Web UI returned HTTP ${UI_STATUS}; check docker compose ps and UI logs.\" >&2\n  exit 1\nfi\necho \"Web UI ready: HTTP ${UI_STATUS}\"\n\necho \"Microservice: http:\u002F\u002F${HOST_IP}:${MS_PORT}\"\necho \"Web UI:       http:\u002F\u002F${HOST_IP}:${UI_PORT}\"\n```\n\n## Success Criteria\n\n**Both containers running** — see `docker compose ps` output from Step 5. Both services should show \"Up\" status; microservice should show \"(healthy)\" in the STATUS column.\n\n**Microservice healthy** — Step 6 readiness polling returns `code:0` from `\u002Fv1\u002Fready` and prints the service URL.\n\n**Web UI accessible**:\n- Open browser: `http:\u002F\u002F\u003CHOST_IP>:\u003CAUTO_MAGIC_CALIB_UI_PORT>`\n- Should display the AutoMagicCalib web interface\n- Should be able to create projects and run calibration\n\n## Key Output\n\n**Microservice**: `http:\u002F\u002F\u003CHOST_IP>:\u003CAUTO_MAGIC_CALIB_MS_PORT>` (default port 8000)\n- API docs: `http:\u002F\u002F\u003CHOST_IP>:\u003CAUTO_MAGIC_CALIB_MS_PORT>\u002Fdocs`\n\n**Web UI**: `http:\u002F\u002F\u003CHOST_IP>:\u003CAUTO_MAGIC_CALIB_UI_PORT>` (default port 5000)\n- Interactive project management\n- File upload interface\n- Calibration configuration\n- Real-time status monitoring\n- Results visualization and download\n\n**Data Persistence**:\n- Projects stored: `$REPO_ROOT\u002Fprojects\u002F`\n- State persisted: `$REPO_ROOT\u002Fprojects\u002Fstate.json`\n\n## Troubleshooting\n\n| Issue | Symptoms | Solution |\n|-------|----------|----------|\n| `pip` not found | `pip: command not found` | Run `sudo apt install -y python3.12-venv python3-pip` then create venv (Step 0) |\n| `huggingface-cli` not found | `huggingface-cli: command not found` | The binary is named `hf` in the venv. Find it with: `find venv ~\u002Fvenv\u002Famc -name hf -type f 2>\u002Fdev\u002Fnull \\| head -1` |\n| `python3 -m venv` fails | \"ensurepip not available\" | Run `sudo apt install -y python3.12-venv` first |\n| Docker permission denied | \"permission denied while trying to connect to docker socket\" | User not in docker group — ask user to run: `sudo usermod -aG docker $USER && newgrp docker`. See: https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Finstall\u002Flinux-postinstall\u002F |\n| `docker login` itself rejected | Step 1 login returns an authentication error | The key is invalid or expired. Ask the user for a current NGC key and log in again before continuing. |\n| Key logs in but can't access an image | The Step 5 access check stops with \"cannot access the required image\" \u002F a 401\u002F403 on `docker manifest inspect`, before any pull | The key authenticates but lacks access to that image's namespace. Re-running login with the same key won't help — ask the user for an NGC key with access to the required namespace, re-run Step 1, then retry Step 5. |\n| VGGT download permission error | \"PermissionError: [Errno 13] Permission denied: 'models\u002Fvggt\u002F.cache'\" | Download VGGT BEFORE setting `chown 1000:1000` on models. Fix: `sudo chown -R $(id -u):$(id -g) models` then re-download |\n| Port already in use | \"address already in use\" | Find available port in 8000-8009 (MS) or 5000-5009 (UI); update `.env` |\n| Microservice readiness timeout | Step 6 reports that `\u002Fv1\u002Fready` did not return `code:0` within 120 seconds | Run `cd $REPO_ROOT\u002Fcompose && docker compose ps`, then inspect logs with `docker compose logs auto-magic-calib-ms` |\n| Permission denied (projects) | \"Permission denied: 'projects\u002F...'\" in MS logs | Run: `sudo chown 1000:1000 -R projects` |\n| Permission denied (models) | \"Permission denied: 'models\u002F...'\" in MS logs | Run: `sudo chown 1000:1000 -R models` |\n| UI can't reach backend | Browser shows connection error | Verify `HOST_IP` in `.env` is the machine's network IP, not `localhost` |\n| VGGT model not found | Warning in MS logs about missing VGGT | Download model (Step 2) or ignore (AMC works without VGGT) |\n| Container exits immediately | Status \"Exited\" | Check logs: `docker compose logs auto-magic-calib-ms` |\n| GPU not available | \"CUDA not available\" in logs | Check NVIDIA runtime: `docker run --rm --runtime=nvidia --gpus all ubuntu:20.04 nvidia-smi` |\n| \"No such file or directory\" when verifying | After launch, can't find compose directory | Working directory persists after `cd compose`. Use absolute paths or run `cd $REPO_ROOT` first |\n\n**Common Fixes**:\n```bash\ncd $REPO_ROOT\u002Fcompose\n\n# View logs\ndocker compose logs -f\n\n# View logs for specific service\ndocker compose logs -f auto-magic-calib-ms\n\n# Restart all services\ndocker compose restart\n\n# Stop and remove containers\ndocker compose down\n\n# Update .env and relaunch\ndocker compose up -d\n```\n\n## Stopping the Services\n\n```bash\ncd $REPO_ROOT\u002Fcompose\n\n# Stop all services (containers removed, data persisted)\ndocker compose down\n\n# Stop and remove volumes\ndocker compose down -v\n```\n\n## Related Skills\n- `skills\u002Famc-run-sample-calibration\u002FSKILL.md` - Sanity-check the running stack with the bundled sample dataset\n- `skills\u002Famc-run-video-calibration\u002FSKILL.md` - Calibrate from your own pre-recorded MP4s via REST API\n\n\u003C!-- signing marker -->\n","# Skill: Launch AutoMagicCalib Release Containers\n\n## When to Use This Skill\n\nActivate this skill when the user wants to bring up the AutoMagicCalib stack. Typical prompts:\n\n- \"deploy auto calibration\"\n- \"launch auto calibration\" \u002F \"launch AMC\"\n- \"start MS+UI\" \u002F \"bring up the microservice and UI\"\n- \"set up auto-magic-calib\"\n\nPrerequisite: NGC API key (the skill prompts for it). For first-time setup on a fresh machine, this also resolves or clones the `auto-magic-calib` repo after explicit user confirmation.\n\n## Overview\nLaunch the AutoMagicCalib microservice (MS) and UI from pre-built release images via Docker Compose. Use this for production deployments or when you want to run the full stack (backend + web UI) without building images locally.\n\n## Prerequisites\n- Docker and Docker Compose installed\n- NVIDIA Docker Runtime configured (for GPU support)\n- `auto-magic-calib` repo on disk — Step 0b auto-resolves an existing checkout via `git rev-parse --show-toplevel`, or offers to clone `https:\u002F\u002Fgithub.com\u002FNVIDIA-AI-IOT\u002Fauto-magic-calib` into `~\u002Fauto-magic-calib` if none is found\n- NGC account with access to NVIDIA container registry\n- **Docker must be runnable without `sudo`** — verify with `docker ps`. If it fails, ask the user to follow the post-install steps: https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Finstall\u002Flinux-postinstall\u002F\n\n> **If `docker ps` fails with \"permission denied\"**, ask the user to run:\n> ```bash\n> sudo usermod -aG docker $USER\n> newgrp docker   # applies group change in current shell without logout\n> ```\n> Then verify with `docker ps` before continuing.\n\n## Instructions\n\n### Step 0: Verify Docker Runs Without sudo\n\n```bash\ndocker ps\n```\n\n- If it succeeds → continue.\n- If it fails with \"permission denied\" → the user is not in the `docker` group. Ask the user to run:\n  ```bash\n  sudo usermod -aG docker $USER && newgrp docker\n  ```\n  Then ask the user to confirm `docker ps` works before continuing.\n\n> **Agent note**: If `docker ps` cannot be run from within the agent sandbox, ask the user to confirm it works (e.g. \"Can you confirm `docker ps` runs without sudo?\") before proceeding.\n\n### Step 0b: Resolve Repo Checkout\n\nThe skill needs `compose\u002F`, `assets\u002Fsdg_08_2_sample_data_010926.zip`, and a `models\u002F` mount point — all of which live in the `auto-magic-calib` repo. If you're already inside a checkout, the skill uses it. Otherwise it asks for explicit user confirmation using the host's question mechanism; if none is available, ask in chat and wait before cloning into `~\u002Fauto-magic-calib`.\n\n```bash\nREPO_URL=\"https:\u002F\u002Fgithub.com\u002FNVIDIA-AI-IOT\u002Fauto-magic-calib.git\"\nDEFAULT_CLONE_DIR=\"$HOME\u002Fauto-magic-calib\"\n\n# 1. Already inside a usable checkout?\nREPO_ROOT=\"$(git rev-parse --show-toplevel 2>\u002Fdev\u002Fnull)\"\nif [ -n \"$REPO_ROOT\" ] && [ -f \"$REPO_ROOT\u002Fcompose\u002Fcompose.yml\" ] && [ -d \"$REPO_ROOT\u002Fassets\" ]; then\n  echo \"✓ Using existing checkout: $REPO_ROOT\"\n\n# 2. Default clone dir already populated from a prior run?\nelif [ -d \"$DEFAULT_CLONE_DIR\u002F.git\" ] && [ -f \"$DEFAULT_CLONE_DIR\u002Fcompose\u002Fcompose.yml\" ]; then\n  REPO_ROOT=\"$DEFAULT_CLONE_DIR\"\n  echo \"✓ Found existing clone at $REPO_ROOT\"\n\n# 3. Nothing on disk — STOP and ask the user for confirmation using the\n#    host's question mechanism; if none is available, ask in chat and wait.\n#    Do NOT clone silently from this block.\nelse\n  echo \"No auto-magic-calib checkout found. Ask the user for confirmation:\"\n  echo \"  Clone $REPO_URL into $DEFAULT_CLONE_DIR? [y\u002FN]\"\n  echo \"On 'y' — run: git clone \\\"$REPO_URL\\\" \\\"$DEFAULT_CLONE_DIR\\\"\"\n  exit 1\nfi\n\ncd \"$REPO_ROOT\"\nexport REPO_ROOT\necho \"REPO_ROOT=$REPO_ROOT\"\n```\n\n> **Agent note**: do **not** clone silently. Ask the user first using the host's question mechanism; if none is available, ask in chat and wait. Example: \"auto-magic-calib repo not found. Clone `https:\u002F\u002Fgithub.com\u002FNVIDIA-AI-IOT\u002Fauto-magic-calib` into `~\u002Fauto-magic-calib`? (or provide your own path)\". Honour an alternate path if the user offers one. The clone is a few hundred MB (compose files + sample dataset + assets).\n\n### Step 0c: Install Python venv (New Systems Only)\n\nOn a fresh system, `pip` and `python3-venv` may not be available. Install them first:\n\n```bash\n# Create a venv for HuggingFace CLI (project-local preferred)\nREPO_DIR=\"$(git rev-parse --show-toplevel 2>\u002Fdev\u002Fnull || pwd)\"\nHF_VENV=\"${REPO_DIR}\u002Fvenv\"\npython3 -m venv \"$HF_VENV\" 2>\u002Fdev\u002Fnull || {\n  echo \"ERROR: python3-venv not available.\" >&2\n  echo \"Install it manually: sudo apt install -y python3-venv python3-pip\" >&2\n  exit 1\n}\n\n# Install HuggingFace hub (needed for VGGT download)\n\"$HF_VENV\u002Fbin\u002Fpip\" install --upgrade pip huggingface_hub\n```\n\n> **Note**: Skip this step if a venv with `hf` already exists (check `venv\u002Fbin\u002Fhf` in the repo root or `~\u002Fvenv\u002Famc\u002Fbin\u002Fhf`).\n\n### Step 1: Login to NGC\n\nAsk the user for their NGC API key using the host's question mechanism; if none is available, ask in chat and wait. Then run:\n\n```bash\necho \"\u003CNGC_API_KEY>\" | docker login nvcr.io --username '$oauthtoken' --password-stdin\necho \"✓ NGC authentication complete\"\n```\n\n### Step 2: Download VGGT Model (If Not Already Present)\n\n```bash\nexport REPO_ROOT=$(git rev-parse --show-toplevel)\ncd \"$REPO_ROOT\"\n\nif [ -f \"models\u002Fvggt\u002Fvggt_1B_commercial.pt\" ]; then\n  echo \"✓ VGGT model already present\"\nelse\n  echo \"✗ VGGT model not found\"\n  echo \"Options:\"\n  echo \"  1. Continue without VGGT (AMC only - sufficient for most use cases)\"\n  echo \"  2. Download VGGT model (~4.7GB, requires HuggingFace account)\"\nfi\n```\n\n**To download VGGT** (ask the user for a HuggingFace token using the host's question mechanism; if none is available, ask in chat and wait):\n\n**Step 2a: Accept Model License** (required, one-time):\n1. Visit: https:\u002F\u002Fhuggingface.co\u002Ffacebook\u002FVGGT-1B-Commercial\n2. Log in to your HuggingFace account\n3. Click \"Agree and access repository\" to accept license terms\n\n**Step 2b: Get HuggingFace Token**:\n1. Visit: https:\u002F\u002Fhuggingface.co\u002Fsettings\u002Ftokens\n2. Create new token with \"Read\" access (starts with `hf_...`)\n3. Ask the user for the token using the host's question mechanism; if none is available, ask in chat and wait. Do NOT ask them to run a command\n\n**Step 2c: Download** (pass token via `HF_TOKEN` env var — keeps the secret out of `hf`'s argv \u002F `ps aux`; no interactive login needed):\n```bash\nREPO_DIR=\"$(git rev-parse --show-toplevel 2>\u002Fdev\u002Fnull || pwd)\"\ncd \"$REPO_DIR\"\n\n# Find the HuggingFace CLI binary (named 'hf', not 'huggingface-cli')\nHF_BIN=\"$(find \"$REPO_DIR\u002Fvenv\" ~\u002Fvenv\u002Famc -name hf -type f 2>\u002Fdev\u002Fnull | head -1)\"\n{ [ -z \"$HF_BIN\" ] || [ ! -x \"$HF_BIN\" ]; } && { echo \"ERROR: hf binary not found or not executable; install the hf CLI (Step 0c) or set HF_BIN\" >&2; exit 1; }\n\n# Do NOT use --token on the command line (leaks via ps\u002Fargv). The HF CLI\n# reads HF_TOKEN from the environment automatically.\nHF_TOKEN=\"\u003CHF_TOKEN>\" \"$HF_BIN\" download facebook\u002FVGGT-1B-Commercial \\\n  --local-dir models\u002Fvggt\u002F\n\n# Verify\nls -lh models\u002Fvggt\u002Fvggt_1B_commercial.pt\n# Should show ~4.7GB file\n```\n\n> **Important**: Download BEFORE setting `chown 1000:1000` on the models directory — the current user needs write access during download. Set permissions in Step 4 after download completes.\n\n### Step 3: Configure .env Variables\n\nThe `.env` file at `compose\u002F.env` controls ports and paths. Update it before launching:\n\n```bash\ncd $REPO_ROOT\u002Fcompose\n\n# Find available backend port (8000-8009)\nfor port in {8000..8009}; do\n  if ! lsof -Pi :$port -sTCP:LISTEN -t >\u002Fdev\u002Fnull 2>&1; then\n    MS_PORT=$port\n    echo \"Using backend port: $MS_PORT\"\n    break\n  fi\ndone\n[ -z \"$MS_PORT\" ] && { echo \"ERROR: no free backend port in 8000-8009; free one or widen the range.\" >&2; exit 1; }\n\n# Find available UI port (5000-5009)\nfor port in {5000..5009}; do\n  if ! lsof -Pi :$port -sTCP:LISTEN -t >\u002Fdev\u002Fnull 2>&1; then\n    UI_PORT=$port\n    echo \"Using UI port: $UI_PORT\"\n    break\n  fi\ndone\n[ -z \"$UI_PORT\" ] && { echo \"ERROR: no free UI port in 5000-5009; free one or widen the range.\" >&2; exit 1; }\n\n# Get host IP\nHOST_IP=$(hostname -I | awk '{print $1}')\necho \"Host IP: $HOST_IP\"\n\n# Update .env — preserve any keys the user has already set; back up first.\n# .env may contain credentials, so restrict permissions on both the backup and\n# the live file (chmod 600). Add `compose\u002F.env.bak.*` to .gitignore.\nENV_FILE=\".env\"\nif [ -f \"$ENV_FILE\" ]; then\n  BACKUP=\"${ENV_FILE}.bak.$(date +%s)\"\n  cp \"$ENV_FILE\" \"$BACKUP\"\n  chmod 600 \"$BACKUP\"\nfi\ntouch \"$ENV_FILE\"\nchmod 600 \"$ENV_FILE\"\nset_env_key() {\n  local k=\"$1\" v=\"$2\"\n  if grep -qE \"^${k}=\" \"$ENV_FILE\"; then\n    sed -i \"s|^${k}=.*|${k}=${v}|\" \"$ENV_FILE\"\n  else\n    echo \"${k}=${v}\" >> \"$ENV_FILE\"\n  fi\n}\nset_env_key AUTO_MAGIC_CALIB_MS_PORT \"${MS_PORT}\"\nset_env_key AUTO_MAGIC_CALIB_UI_PORT \"${UI_PORT}\"\nset_env_key PROJECT_DIR \"..\u002F..\u002Fprojects\"\nset_env_key MODEL_DIR \"..\u002F..\u002Fmodels\"\nset_env_key HOST_IP \"${HOST_IP}\"\n\n# Keep timestamped .env backups out of git.\nGITIGNORE=\"$REPO_ROOT\u002F.gitignore\"\ntouch \"$GITIGNORE\"\ngrep -qxF \"compose\u002F.env.bak.*\" \"$GITIGNORE\" || echo \"compose\u002F.env.bak.*\" >> \"$GITIGNORE\"\n\necho \"✓ .env updated\"\ncat .env\n```\n\n**Important**: `HOST_IP` must be the machine's network IP (not `localhost`) so the UI container can reach the backend from a browser.\n\nOptional: set `VGGT_MODEL_PATH` only if the VGGT model is mounted at a non-default container path; default is `\u002Ftmp\u002Fvggt_model\u002Fvggt_1B_commercial.pt` inside the MS container.\n\n### Step 4: Set Directory Permissions\n\nThe containers run as UID\u002FGID 1000. The `projects` and `models` directories must be owned by this UID for containers to read\u002Fwrite properly:\n\n```bash\ncd \"$REPO_ROOT\"\n\n# Create projects directory if it doesn't exist\nmkdir -p projects\n\n# Set ownership (required for containers to write calibration outputs).\n# Do this AFTER VGGT download is complete (current user needs write access during download).\n# Get explicit user confirmation before running sudo chown — it recursively changes\n# ownership of $REPO_ROOT\u002Fprojects and $REPO_ROOT\u002Fmodels to UID\u002FGID 1000.\n[ -d projects ] && [ -d models ] || {\n  echo \"ERROR: expected projects\u002F and models\u002F under $REPO_ROOT\" >&2; exit 1;\n}\necho \"About to chown -R 1000:1000 on:\"\necho \"  $REPO_ROOT\u002Fprojects\"\necho \"  $REPO_ROOT\u002Fmodels\"\necho \"(required because containers run as UID 1000). Confirm before proceeding.\"\nsudo chown 1000:1000 -R projects\nsudo chown 1000:1000 -R models\n\necho \"✓ Permissions set\"\n```\n\n### Step 5: Launch Services\n\nBefore pulling, fail fast if the NGC key authenticated in Step 1 but cannot actually access a release image — otherwise `docker compose up` aborts partway with a 401\u002F403 after some work is already done.\n\n```bash\ncd $REPO_ROOT\u002Fcompose\n\n# Fail-fast image-access check: confirm the NGC key can reach every release\n# image BEFORE pulling. `docker manifest inspect` checks registry access without\n# downloading layers, and the image list is read from the resolved compose so it\n# tracks the release tag automatically.\nIMAGES=$(docker compose config --images | sort -u)\n[ -z \"$IMAGES\" ] && { echo \"ERROR: no images resolved from compose — check compose\u002F.env and the chosen profile.\" >&2; exit 1; }\nfor img in $IMAGES; do\n  echo \"Checking access: $img\"\n  if ! docker manifest inspect \"$img\" >\u002Fdev\u002Fnull 2>&1; then\n    echo \"NGC login succeeded, but this key cannot access the required image:\" >&2\n    echo \"  $img\" >&2\n    echo \"Provide an NGC key with access to this image's namespace, then re-run Step 1 (login) and retry.\" >&2\n    exit 1\n  fi\ndone\n\n# Start all services (images pulled automatically on first run)\ndocker compose up -d\n\n# Check containers are running\ndocker compose ps\n```\n\n**Expected output**:\n```\nNAME                    IMAGE                                                              STATUS\nauto-magic-calib-ms-1   nvcr.io\u002Fnvidia\u002Fauto-magic-calib:2.0.0           Up (healthy)\nauto-magic-calib-ui-1   nvcr.io\u002Fnvidia\u002Fauto-magic-calib-ui:2.0.0        Up\n```\n\n### Step 6: Verify Services Are Running\n\n```bash\n# Read ports from .env\nMS_PORT=$(grep AUTO_MAGIC_CALIB_MS_PORT $REPO_ROOT\u002Fcompose\u002F.env | cut -d= -f2)\nUI_PORT=$(grep AUTO_MAGIC_CALIB_UI_PORT $REPO_ROOT\u002Fcompose\u002F.env | cut -d= -f2)\nHOST_IP=$(grep HOST_IP $REPO_ROOT\u002Fcompose\u002F.env | cut -d= -f2)\n\n# Wait for microservice readiness. Cold image pulls or first startup can need\n# extra time after `docker compose up -d` returns.\nREADY_URL=\"http:\u002F\u002Flocalhost:${MS_PORT}\u002Fv1\u002Fready\"\necho \"Waiting for microservice readiness at ${READY_URL} ...\"\nready_response=\"\"\nfor attempt in $(seq 1 24); do\n  if ready_response=$(curl -fsS --max-time 5 \"${READY_URL}\" 2>\u002Fdev\u002Fnull) && \\\n     echo \"${ready_response}\" | grep -q '\"code\"[[:space:]]*:[[:space:]]*0'; then\n    echo \"Microservice ready: ${ready_response}\"\n    break\n  fi\n  if [ \"${attempt}\" -lt 24 ]; then\n    printf \"  [%02d\u002F24] Microservice not ready yet; retrying in 5s...\\n\" \"${attempt}\"\n    sleep 5\n  fi\ndone\n\nif ! echo \"${ready_response}\" | grep -q '\"code\"[[:space:]]*:[[:space:]]*0'; then\n  echo \"ERROR: microservice did not report ready within 120 seconds: ${READY_URL}\" >&2\n  echo \"Check status and logs:\" >&2\n  echo \"  cd ${REPO_ROOT}\u002Fcompose && docker compose ps\" >&2\n  echo \"  cd ${REPO_ROOT}\u002Fcompose && docker compose logs auto-magic-calib-ms\" >&2\n  exit 1\nfi\n\n# Check UI is serving\nUI_STATUS=$(curl -s -o \u002Fdev\u002Fnull -w \"%{http_code}\" --max-time 5 \"http:\u002F\u002Flocalhost:${UI_PORT}\")\nif [ \"${UI_STATUS}\" != \"200\" ]; then\n  echo \"ERROR: Web UI returned HTTP ${UI_STATUS}; check docker compose ps and UI logs.\" >&2\n  exit 1\nfi\necho \"Web UI ready: HTTP ${UI_STATUS}\"\n\necho \"Microservice: http:\u002F\u002F${HOST_IP}:${MS_PORT}\"\necho \"Web UI:       http:\u002F\u002F${HOST_IP}:${UI_PORT}\"\n```\n\n## Success Criteria\n\n**Both containers running** — see `docker compose ps` output from Step 5. Both services should show \"Up\" status; microservice should show \"(healthy)\" in the STATUS column.\n\n**Microservice healthy** — Step 6 readiness polling returns `code:0` from `\u002Fv1\u002Fready` and prints the service URL.\n\n**Web UI accessible**:\n- Open browser: `http:\u002F\u002F\u003CHOST_IP>:\u003CAUTO_MAGIC_CALIB_UI_PORT>`\n- Should display the AutoMagicCalib web interface\n- Should be able to create projects and run calibration\n\n## Key Output\n\n**Microservice**: `http:\u002F\u002F\u003CHOST_IP>:\u003CAUTO_MAGIC_CALIB_MS_PORT>` (default port 8000)\n- API docs: `http:\u002F\u002F\u003CHOST_IP>:\u003CAUTO_MAGIC_CALIB_MS_PORT>\u002Fdocs`\n\n**Web UI**: `http:\u002F\u002F\u003CHOST_IP>:\u003CAUTO_MAGIC_CALIB_UI_PORT>` (default port 5000)\n- Interactive project management\n- File upload interface\n- Calibration configuration\n- Real-time status monitoring\n- Results visualization and download\n\n**Data Persistence**:\n- Projects stored: `$REPO_ROOT\u002Fprojects\u002F`\n- State persisted: `$REPO_ROOT\u002Fprojects\u002Fstate.json`\n\n## Troubleshooting\n\n| Issue | Symptoms | Solution |\n|-------|----------|----------|\n| `pip` not found | `pip: command not found` | Run `sudo apt install -y python3.12-venv python3-pip` then create venv (Step 0) |\n| `huggingface-cli` not found | `huggingface-cli: command not found` | The binary is named `hf` in the venv. Find it with: `find venv ~\u002Fvenv\u002Famc -name hf -type f 2>\u002Fdev\u002Fnull \\| head -1` |\n| `python3 -m venv` fails | \"ensurepip not available\" | Run `sudo apt install -y python3.12-venv` first |\n| Docker permission denied | \"permission denied while trying to connect to docker socket\" | User not in docker group — ask user to run: `sudo usermod -aG docker $USER && newgrp docker`. See: https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Finstall\u002Flinux-postinstall\u002F |\n| `docker login` itself rejected | Step 1 login returns an authentication error | The key is invalid or expired. Ask the user for a current NGC key and log in again before continuing. |\n| Key logs in but can't access an image | The Step 5 access check stops with \"cannot access the required image\" \u002F a 401\u002F403 on `docker manifest inspect`, before any pull | The key authenticates but lacks access to that image's namespace. Re-running login with the same key won't help — ask the user for an NGC key with access to the required namespace, re-run Step 1, then retry Step 5. |\n| VGGT download permission error | \"PermissionError: [Errno 13] Permission denied: 'models\u002Fvggt\u002F.cache'\" | Download VGGT BEFORE setting `chown 1000:1000` on models. Fix: `sudo chown -R $(id -u):$(id -g) models` then re-download |\n| Port already in use | \"address already in use\" | Find available port in 8000-8009 (MS) or 5000-5009 (UI); update `.env` |\n| Microservice readiness timeout | Step 6 reports that `\u002Fv1\u002Fready` did not return `code:0` within 120 seconds | Run `cd $REPO_ROOT\u002Fcompose && docker compose ps`, then inspect logs with `docker compose logs auto-magic-calib-ms` |\n| Permission denied (projects) | \"Permission denied: 'projects\u002F...'\" in MS logs | Run: `sudo chown 1000:1000 -R projects` |\n| Permission denied (models) | \"Permission denied: 'models\u002F...'\" in MS logs | Run: `sudo chown 1000:1000 -R models` |\n| UI can't reach backend | Browser shows connection error | Verify `HOST_IP` in `.env` is the machine's network IP, not `localhost` |\n| VGGT model not found | Warning in MS logs about missing VGGT | Download model (Step 2) or ignore (AMC works without VGGT) |\n| Container exits immediately | Status \"Exited\" | Check logs: `docker compose logs auto-magic-calib-ms` |\n| GPU not available | \"CUDA not available\" in logs | Check NVIDIA runtime: `docker run --rm --runtime=nvidia --gpus all ubuntu:20.04 nvidia-smi` |\n| \"No such file or directory\" when verifying | After launch, can't find compose directory | Working directory persists after `cd compose`. Use absolute paths or run `cd $REPO_ROOT` first |\n\n**Common Fixes**:\n```bash\ncd $REPO_ROOT\u002Fcompose\n\n# View logs\ndocker compose logs -f\n\n# View logs for specific service\ndocker compose logs -f auto-magic-calib-ms\n\n# Restart all services\ndocker compose restart\n\n# Stop and remove containers\ndocker compose down\n\n# Update .env and relaunch\ndocker compose up -d\n```\n\n## Stopping the Services\n\n```bash\ncd $REPO_ROOT\u002Fcompose\n\n# Stop all services (containers removed, data persisted)\ndocker compose down\n\n# Stop and remove volumes\ndocker compose down -v\n```\n\n## Related Skills\n- `skills\u002Famc-run-sample-calibration\u002FSKILL.md` - Sanity-check the running stack with the bundled sample dataset\n- `skills\u002Famc-run-video-calibration\u002FSKILL.md` - Calibrate from your own pre-recorded MP4s via REST API\n\n\u003C!-- signing marker -->\n",{"name":5,"owner":49,"license":15,"service":50,"version":51,"metadata":52,"reviewed":57,"description":7,"data_classification":58},"NVIDIA CORPORATION","auto-magic-calib","1.0.0",{"tags":53},[54,55,28,24,26,56],"amc","deepstream","ngc","2026-04-28","public","claude\u002Finstall-gsd-build-foQdV","d86cd127f527124b5fd0fd0bc679a4d79b7d01d7",".agents\u002Fskills\u002Famc-setup-calibration-stack","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik","https:\u002F\u002Fnorvik-orpin.vercel.app","https:\u002F\u002Fgithub.com\u002Fpattanation","2026-07-17 11:17:04",{"source":8,"skillName":5,"commands":67,"prompt":77,"zipAvailable":78},[68,71,74],{"tool":69,"command":70},"npx","npx skills add pattanation\u002FNorvik --skill amc-setup-calibration-stack",{"tool":72,"command":73},"bunx","bunx skills add pattanation\u002FNorvik --skill amc-setup-calibration-stack",{"tool":75,"command":76},"pnpm","pnpm dlx skills add pattanation\u002FNorvik --skill amc-setup-calibration-stack","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Famc-setup-calibration-stack\u002FSKILL.md",true,[80,86,90,94],{"path":81,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":84,"sourceHtmlUrl":85},"BENCHMARK.md","REFERENCE","参考文档",4489,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Famc-setup-calibration-stack\u002FBENCHMARK.md",{"path":87,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":88,"sourceHtmlUrl":89},"evals\u002Fevals.json",7113,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Famc-setup-calibration-stack\u002Fevals\u002Fevals.json",{"path":91,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":92,"sourceHtmlUrl":93},"skill-card.md",3737,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Famc-setup-calibration-stack\u002Fskill-card.md",{"path":95,"resourceType":96,"resourceTypeDesc":97,"sizeBytes":98,"sourceHtmlUrl":99},"skill.oms.sig","OTHER","其他",4681,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Famc-setup-calibration-stack\u002Fskill.oms.sig",[101,132,158,182,204,219],{"skillNo":102,"name":103,"nameZh":6,"description":104,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":105,"sourceHtmlUrl":106,"categories":107,"keywords":114,"publishedAt":131},"01M71QDV4DM8T19HEHWATEF1K4","webapp-testing","Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fwebapp-testing\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fwebapp-testing\u002FSKILL.md",[108,111],{"categoryNo":109,"categoryName":110,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":112,"categoryName":113,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发",[115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,32,130],"webapp","testing","webapp testing","for","applications","local","frontend","debugging","toolkit","logs","browser","with","playwright","web","behavior","screenshots","2026-11-10 13:02:02",{"skillNo":133,"name":134,"nameZh":6,"description":135,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":136,"sourceHtmlUrl":137,"categories":138,"keywords":140,"publishedAt":131},"01M71QDH2GGMXGA9105C9W1N7B","web-artifacts-builder","Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn\u002Fui). Use for complex artifacts requiring state management, routing, or shadcn\u002Fui components - not for simple single-file HTML\u002FJSX artifacts.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fweb-artifacts-builder\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fweb-artifacts-builder\u002FSKILL.md",[139],{"categoryNo":112,"categoryName":113,"taxonomyType":21,"taxonomyTypeDesc":22},[141,142,143,128,144,145,146,118,147,148,121,149,150,151,152,153,154,155,156,157],"builder","artifacts builder","artifacts","web artifacts builder","single-file","css","Tailwind","ui components","single","use","file","components","react","multi","state","routing","state management",{"skillNo":159,"name":160,"nameZh":6,"description":161,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":162,"licenseFileUrl":163,"sourceHtmlUrl":164,"categories":165,"keywords":167,"publishedAt":131},"01M71QD9T2XC3EWMQNN9ACNWQ1","vueuse-functions","Apply VueUse composables where appropriate to build concise, maintainable Vue.js \u002F Nuxt features.","MIT","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvueuse-functions\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvueuse-functions\u002FSKILL.md",[166],{"categoryNo":112,"categoryName":113,"taxonomyType":21,"taxonomyTypeDesc":22},[168,169,170,171,172,173,174,175,176,177,178,179,180,181],"functions","vueuse","vueuse functions","project","nuxt","apply","github","concise","build","https","features","vue","js","composables",{"skillNo":183,"name":184,"nameZh":6,"description":185,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":162,"licenseFileUrl":186,"sourceHtmlUrl":187,"categories":188,"keywords":191,"publishedAt":131},"01M71QD51HWSGYMCMB7RW7PGK8","vue-testing-best-practices","Use for Vue.js testing. Covers Vitest, Vue Test Utils, component testing, mocking, testing patterns, and Playwright for E2E testing.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-testing-best-practices\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-testing-best-practices\u002FSKILL.md",[189,190],{"categoryNo":109,"categoryName":110,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":112,"categoryName":113,"taxonomyType":21,"taxonomyTypeDesc":22},[192,116,193,179,194,127,195,196,197,174,198,118,199,200,201,150,202,180,203],"vue testing best practices","testing best practices","best practices","test","testing patterns","component","vitest","mocking","e2e","utils","patterns","e2e testing",{"skillNo":205,"name":206,"nameZh":6,"description":207,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":162,"licenseFileUrl":208,"sourceHtmlUrl":209,"categories":210,"keywords":212,"publishedAt":131},"01M71QD358H2DJ9THJRBP77T3T","vue-router-best-practices","Vue Router 4 patterns, navigation guards, route params, and route-component lifecycle interactions.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-router-best-practices\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-router-best-practices\u002FSKILL.md",[211],{"categoryNo":112,"categoryName":113,"taxonomyType":21,"taxonomyTypeDesc":22},[213,179,214,194,215,197,216,174,202,217,218],"router","vue router best practices","route","guards","navigation","lifecycle",{"skillNo":220,"name":221,"nameZh":6,"description":222,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":162,"licenseFileUrl":223,"sourceHtmlUrl":224,"categories":225,"keywords":227,"publishedAt":131},"01M71QCYPNWDE2MQZ1TF3ED5S4","vue-best-practices","MUST be used for Vue.js tasks. Strongly recommends Composition API with `\u003Cscript setup>` and TypeScript as the standard approach. Covers Vue 3, SSR, Volar, vue-tsc. Load for any Vue, .vue files, Vue Router, Pinia, or Vite with Vue work. ALWAYS use Composition API unless the project explicitly requires Options API.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-best-practices\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-best-practices\u002FSKILL.md",[226],{"categoryNo":112,"categoryName":113,"taxonomyType":21,"taxonomyTypeDesc":22},[228,179,194,229,171,230,231,36,213,232,233,234,235,236,237,118,238,150,239,240],"vue best practices","Composition","files","tasks","pinia","work","options","ssr","typescript","as","vite","load","standard"]