Huawei Cloud DevBridge Development Tunnel Create and manage DevBridge development tunnels to securely expose local development services to remote devices via Huawei Cloud relay infrastructure. Overview DevBridge is a development tunnel service that allows developers to expose local services (web servers, APIs, debug endpoints) to remote devices without opening public inbound ports. The CLI tool ( ) manages tunnels, ports, host connections, and connect sessions. Host and Connect both initiate outbound connections to the relay service, so the hosting device does not need a public inbound port.…

>&2\n ver=$(echo \"$raw_output\" | grep -oP '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1)\n if [ -z \"$ver\" ]; then ver=\"0.0.0\"; fi\n local major minor\n major=$(echo \"$ver\" | cut -d. -f1)\n minor=$(echo \"$ver\" | cut -d. -f2)\n if [ \"$major\" -lt 1 ] && [ \"$minor\" -lt 2 ]; then\n echo \"Detected v$ver (old domain, cannot connect). Upgrading...\" >&2\n _db_download_and_run \"$_DB_INSTALL_URL_OBS\"\n raw_output=$(devbridge version 2>&1)\n echo \"$raw_output\" | tail -n +2 | grep -v '^

Huawei Cloud DevBridge Development Tunnel Create and manage DevBridge development tunnels to securely expose local development services to remote devices via Huawei Cloud relay infrastructure. Overview DevBridge is a development tunnel service that allows developers to expose local services (web servers, APIs, debug endpoints) to remote devices without opening public inbound ports. The CLI tool ( ) manages tunnels, ports, host connections, and connect sessions. Host and Connect both initiate outbound connections to the relay service, so the hosting device does not need a public inbound port.…

>&2\n ver=$(echo \"$raw_output\" | grep -oP '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1)\n echo \"Upgraded to v$ver\" >&2\n fi\n}\n\n_db_ensure_auth() {\n local auth\n auth=$(devbridge auth status 2>&1)\n if echo \"$auth\" | grep -qiE \"^(Logged|logged) in\"; then\n # \"Logged in\" 状态可能来自过期凭证的残留,用轻量 API 调用验证\n if devbridge list >/dev/null 2>&1; then\n return 0\n fi\n # list 失败说明凭证过期,继续往下走重新登录\n fi\n local api_key=\"${DEVBRIDGE_API_KEY:-${HW_API_KEY:-${JOB_ENV_HW_DEVBRIDGE_API_KEY:-}}}\"\n if [ -n \"$api_key\" ]; then\n devbridge auth login --api-key \"$api_key\" >/dev/null 2>&1\n # 登录后同样验证凭证有效性\n if devbridge list >/dev/null 2>&1; then\n return 0\n fi\n fi\n echo \"ERROR: Not logged in. Set DEVBRIDGE_API_KEY or HW_API_KEY env var, or run:\" >&2\n echo \" devbridge auth login --api-key YOUR_API_KEY\" >&2\n echo \" Get API key: $_DB_APIKEY_URL\" >&2\n return 1\n}\n\n# ============================================================================\n# 对外封装函数\n# ============================================================================\n\ndb_init() {\n # 自动发现并 source job 环境的 hw-env 文件(获取 JOB_ENV_HW_DEVBRIDGE_API_KEY 等)\n if [ -d /root/job-envs/sandboxes ]; then\n for _db_envf in /root/job-envs/sandboxes/*-hw-env; do\n [ -f \"$_db_envf\" ] && . \"$_db_envf\" 2>/dev/null\n done\n unset _db_envf\n fi\n if ! command -v devbridge &>/dev/null; then\n _db_install_cli || return 1\n fi\n _db_ensure_cli_version || return 1\n _db_ensure_auth || return 1\n return 0\n}\n\ndb_create() {\n local name=\"$1\"; shift\n local desc=\"\" expiration=\"\"\n while [ $# -gt 0 ]; do\n case \"$1\" in\n -d) desc=\"$2\"; shift 2;;\n -e) expiration=\"$2\"; shift 2;;\n *) shift;;\n esac\n done\n local cmd=\"devbridge create \\\"$name\\\"\"\n if [ -n \"$desc\" ] && _db_has_flag \"create\" \"-d\"; then\n cmd+=\" -d \\\"$desc\\\"\"\n fi\n if [ -n \"$expiration\" ] && _db_has_flag \"create\" \"-e\"; then\n cmd+=\" -e $expiration\"\n fi\n local output rc\n output=$(_db_exec_retry \"create\" \"$cmd\" 2>&1)\n rc=$?\n if [ $rc -ne 0 ]; then\n echo \"$output\" >&2\n return $rc\n fi\n # Extract and return just the tunnel ID\n echo \"$output\" | grep -oP 'Tunnel ID:\\s+\\K\\S+' | head -1\n}\n\ndb_port_create() {\n local tunnel_id=\"$1\"; shift\n local port=\"\" protocol=\"\" anon=\"\"\n while [ $# -gt 0 ]; do\n case \"$1\" in\n -p) port=\"$2\"; shift 2;;\n --protocol) protocol=\"$2\"; shift 2;;\n --anon) anon=\"$2\"; shift 2;;\n -a|--allow-anonymous) anon=\"allow\"; shift;;\n --deny-anonymous) anon=\"deny\"; shift;;\n *) shift;;\n esac\n done\n local port_flag=$(_db_port_flag \"port create\")\n local anon_flag=\"\"\n if [ -n \"$anon\" ]; then\n if [ \"$anon\" = \"allow\" ]; then\n anon_flag=$(_db_anon_allow_flag \"port create\")\n else\n anon_flag=$(_db_anon_deny_flag \"port create\")\n fi\n fi\n # 默认不传匿名 flag: v0.2.x 端口默认为禁止匿名访问 (deny)\n local cmd=\"devbridge port create $tunnel_id\"\n if [ -n \"$port_flag\" ] && [ -n \"$port\" ]; then cmd+=\" $port_flag $port\"; fi\n if [ -n \"$protocol\" ] && _db_has_flag \"port create\" \"--protocol\"; then cmd+=\" --protocol $protocol\"; fi\n if [ -n \"$anon_flag\" ]; then cmd+=\" $anon_flag\"; fi\n _db_exec_retry \"port create\" \"$cmd\"\n}\n\ndb_host() {\n local tunnel_id=\"$1\"\n local log_file=\"${_DB_LOG_DIR}/devbridge_host_${tunnel_id}.log\"\n nohup devbridge host \"$tunnel_id\" > \"$log_file\" 2>&1 &\n local pid=$!\n local i url\n for i in $(seq 1 15); do\n if grep -q \"Tunnel URL:\" \"$log_file\" 2>/dev/null; then\n url=$(grep -oP 'Tunnel URL:\\s+\\K\\S+' \"$log_file\" | head -1)\n # 统一输出到 stdout,带标签格式,避免 stdout/stderr 混流\n echo \"PID: $pid\"\n echo \"Tunnel URL: $url\"\n return 0\n fi\n if grep -q \"Connection lost\" \"$log_file\" 2>/dev/null; then\n echo \"ERROR: host connection failed\" >&2\n tail -5 \"$log_file\" >&2\n return 1\n fi\n sleep 1\n done\n echo \"ERROR: timeout waiting for tunnel URL (15s)\" >&2\n echo \"PID: $pid\"\n return 1\n}\n\ndb_connect() {\n local tunnel_id=\"$1\"\n local log_file=\"${_DB_LOG_DIR}/devbridge_connect_${tunnel_id}.log\"\n nohup devbridge connect \"$tunnel_id\" > \"$log_file\" 2>&1 &\n local pid=$!\n echo \"$pid\"\n}\n\ndb_tunnel_url() {\n local tunnel_id=\"$1\"\n local log_file=\"${_DB_LOG_DIR}/devbridge_host_${tunnel_id}.log\"\n if [ -f \"$log_file\" ]; then\n local url\n url=$(grep -oP 'Tunnel URL:\\s+\\K\\S+' \"$log_file\" | head -1)\n if [ -n \"$url\" ]; then\n echo \"$url\"\n return 0\n fi\n fi\n echo \"ERROR: Tunnel URL not found. Start hosting first with db_host.\" >&2\n return 1\n}\n\ndb_processes() {\n ps aux | grep -E \"devbridge (host|connect)\" | grep -v grep\n}\n\ndb_process_stop() {\n local pid=\"$1\"\n if kill \"$pid\" 2>/dev/null; then\n echo \"Process $pid stopped\"\n return 0\n else\n echo \"ERROR: Failed to stop process $pid\" >&2\n return 1\n fi\n}\n\ndb_process_logs() {\n local pid=\"$1\"\n local tunnel_id\n tunnel_id=$(ps -p \"$pid\" -o args= 2>/dev/null | grep -oP 'devbridge (host|connect) \\K\\S+')\n if [ -n \"$tunnel_id\" ]; then\n local log_file=\"${_DB_LOG_DIR}/devbridge_host_${tunnel_id}.log\"\n [ -f \"$log_file\" ] && cat \"$log_file\" && return 0\n log_file=\"${_DB_LOG_DIR}/devbridge_connect_${tunnel_id}.log\"\n [ -f \"$log_file\" ] && cat \"$log_file\" && return 0\n fi\n echo \"ERROR: No logs found for PID $pid\" >&2\n return 1\n}\n\n# db_host_bg \u003ctunnelId> [logfile] — 后台运行 db_host。\n# 不能写成 `nohup db_host ...`:db_host 是 shell 函数,nohup 是外部命令,\n# exec 时找不到函数(No such file or directory)。这里用 nohup bash -c\n# 在子 shell 里重新 source 本脚本再调用 db_host,既保留函数上下文又可抗 HUP。\ndb_host_bg() {\n local tunnel_id=\"$1\"\n local log=\"${2:-/tmp/devbridge-host.log}\"\n if [ -z \"$tunnel_id\" ]; then\n echo \"ERROR: db_host_bg 需要 tunnel-id 参数\" >&2\n return 1\n fi\n local self\n self=\"$(cd \"$(dirname \"${BASH_SOURCE[0]:-$0}\")\" && pwd)/devbridge_cmd.sh\"\n local db_dir\n db_dir=\"$(dirname \"$(command -v devbridge 2>/dev/null || echo \"${HOME:-$(eval echo ~)}/.huawei/bin/devbridge\")\")\"\n nohup bash -c \"export PATH=\\\"$db_dir:\\$PATH\\\"; source '$self'; db_host $tunnel_id\" >\"$log\" 2>&1 &\n local pid=$!\n echo \"db_host backgrounded: pid=$pid, log=$log\"\n}\n\ndb_list() {\n # v0.2.x 已移除 --json; 若用户请求 --json 则提示\n if [ \"$1\" = \"--json\" ]; then\n local jf=$(_db_json_flag \"list\")\n if [ -n \"$jf\" ]; then\n _db_exec_retry \"list\" \"devbridge list $jf\"\n else\n echo \"WARN: 当前 CLI 版本 (v0.2.x) 已移除 list --json,返回文本表格。\" >&2\n _db_exec_retry \"list\" \"devbridge list\"\n fi\n else\n _db_exec_retry \"list\" \"devbridge list\"\n fi\n}\n\ndb_show() { _db_exec_retry \"show\" \"devbridge show $1\"; }\ndb_delete() { _db_exec_retry \"delete\" \"devbridge delete $1\"; }\ndb_delete_all() { _db_exec_retry \"delete-all\" \"devbridge delete-all\"; }\ndb_port_list() { _db_exec_retry \"port list\" \"devbridge port list $1\"; }\ndb_limits() { _db_exec_retry \"limits\" \"devbridge limits\"; }\ndb_echo() { _db_exec_retry \"echo\" \"devbridge echo $*\"; }\ndb_ping() {\n if [ $# -eq 0 ]; then\n echo \"ERROR: db_ping 需要 URI 参数,例如: db_ping https://\u003ctunnelId>.\u003cclusterId>.myhuaweicloud.com\" >&2\n return 1\n fi\n local uri=\"$1\"; shift\n # devbridge ping 是持续循环命令(默认 interval 1s),直接调用会在脚本中永久挂起。\n # 默认限制 3 秒做一次性探测;DB_PING_SECONDS=0 时直通(持续观测用)。\n local secs=\"${DB_PING_SECONDS:-3}\"\n if command -v timeout >/dev/null 2>&1 && [ \"$secs\" != \"0\" ]; then\n timeout \"$secs\" devbridge ping \"$uri\" \"$@\" 2>&1\n local rc=$?\n if [ \"$rc\" -eq 124 ]; then\n echo \"[db_ping] 已完成 ${secs}s 探测(timeout 正常结束)\" >&2\n return 0\n fi\n return \"$rc\"\n fi\n _db_exec_retry \"ping\" \"devbridge ping \\\"$uri\\\" $*\"\n}\ndb_version() { devbridge version; }\ndb_auth_status() { devbridge auth status; }\ndb_auth_login() { devbridge auth login \"$@\"; }\n\ndb_update() {\n local tunnel_id=\"$1\"; shift\n local cmd=\"devbridge update $tunnel_id\"\n while [ $# -gt 0 ]; do\n case \"$1\" in\n -n) cmd+=\" -n \\\"$2\\\"\"; shift 2;;\n -d) cmd+=\" -d \\\"$2\\\"\"; shift 2;;\n -e) cmd+=\" -e $2\"; shift 2;;\n *) shift;;\n esac\n done\n _db_exec_retry \"update\" \"$cmd\"\n}\n\ndb_port_delete() {\n local tunnel_id=\"$1\"; shift\n local port=\"\"\n while [ $# -gt 0 ]; do\n case \"$1\" in\n -p) port=\"$2\"; shift 2;;\n *) shift;;\n esac\n done\n local pf=$(_db_port_flag \"port delete\")\n if [ -n \"$pf\" ] && [ -n \"$port\" ]; then\n _db_exec_retry \"port delete\" \"devbridge port delete $tunnel_id $pf $port\"\n else\n _db_exec_retry \"port delete\" \"devbridge port delete $tunnel_id -p $port\"\n fi\n}","content_type":"application/x-sh; charset=utf-8","language":"bash","size":21051,"content_sha256":"a097bd8f5628fde8a0aa732b1abedc3549c7648cdbea76e718cbc347b7651abf"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Huawei Cloud DevBridge Development Tunnel","type":"text"}]},{"type":"paragraph","content":[{"text":"Create and manage DevBridge development tunnels to securely expose local development services to remote devices via Huawei Cloud relay infrastructure.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Overview","type":"text"}]},{"type":"paragraph","content":[{"text":"DevBridge is a development tunnel service that allows developers to expose local services (web servers, APIs, debug endpoints) to remote devices without opening public inbound ports. The CLI tool (","type":"text"},{"text":"devbridge","type":"text","marks":[{"type":"code_inline"}]},{"text":") manages tunnels, ports, host connections, and connect sessions. Host and Connect both initiate outbound connections to the relay service, so the hosting device does not need a public inbound port.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Architecture","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"Developer Device (Host) Remote Device (Connect)\n┌──────────────────────┐ ┌──────────────────────┐\n│ Local Service :8080 │ │ localhost:8080 │\n│ │ │ │ ▲ │\n│ devbridge host │ │ devbridge connect │\n│ │ │ │ │ │\n└─────────┼────────────┘ └─────────┼────────────┘\n │ Outbound connection │ Outbound connection\n ▼ ▼\n┌─────────────────────────────────────────────────────────────────┐\n│ DevBridge Relay Service (Huawei Cloud) │\n│ │\n│ Tunnel (id) ── Port ── API Key / Token ── Access Policy │\n│ Address: https://\u003ctunnelId>.\u003cclusterId>.myhuaweicloud.com │\n└─────────────────────────────────────────────────────────────────┘","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"2026-09-20 域名升级通知","type":"text","marks":[{"type":"strong"}]},{"text":":DevBridge 隧道域名已切换,原 ","type":"text"},{"text":"*.cn-north-4-bridge.myhuaweicloud.com","type":"text","marks":[{"type":"code_inline"}]},{"text":" 变更为新集群域名(如 ","type":"text"},{"text":"*.devbridge-s2.hwtunnel.com","type":"text","marks":[{"type":"code_inline"}]},{"text":")。","type":"text"},{"text":"旧版端侧(v0.1.x)已无法连接","type":"text","marks":[{"type":"strong"}]},{"text":",必须使用 v0.2.x 并重新创建隧道。以 ","type":"text"},{"text":"devbridge host","type":"text","marks":[{"type":"code_inline"}]},{"text":" 实际输出的 Tunnel URL 为准。","type":"text"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Use Cases","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Remote debugging and integration testing with team members","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Sharing in-development web pages with stakeholders","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Receiving webhook callbacks during local development","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Accessing local services from mobile devices or other machines","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Temporarily exposing local APIs for demonstrations","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Typical User Expressions","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"Help me expose my local port 8080 to a remote device\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"Create a development tunnel for my frontend dev server\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"I need to share my local API with the team for testing\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"Connect to a tunnel from another machine\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"帮我把本地 8080 端口暴露给远程设备\"","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Version Support","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Item","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Requirement","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CLI version","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"v0.2.x","type":"text","marks":[{"type":"strong"}]},{"text":" (installed from official channel, e.g. 0.2.1-release / 0.2.2-release)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Authentication","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"API Key","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"devbridge auth login --api-key","type":"text","marks":[{"type":"code_inline"}]},{"text":" or env ","type":"text"},{"text":"HW_API_KEY","type":"text","marks":[{"type":"code_inline"}]},{"text":") or interactive login","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tunnel domain","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"New cluster domain (","type":"text"},{"text":"devbridge-s2.hwtunnel.com","type":"text","marks":[{"type":"code_inline"}]},{"text":" etc.), shown in ","type":"text"},{"text":"devbridge host","type":"text","marks":[{"type":"code_inline"}]},{"text":" output","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Old versions","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"v0.1.x is NOT supported — AK/SK auth flags removed, old domain no longer connects","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Dynamic Command Adaptation Layer","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"CRITICAL — All tunnel/port/host operations MUST go through ","type":"text","marks":[{"type":"strong"}]},{"text":"db_*","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" wrapper functions","type":"text","marks":[{"type":"strong"}]},{"text":" (defined in ","type":"text"},{"text":"scripts/devbridge_cmd.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":"), NOT direct ","type":"text"},{"text":"devbridge","type":"text","marks":[{"type":"code_inline"}]},{"text":" commands. Only ","type":"text"},{"text":"devbridge auth","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"devbridge version","type":"text","marks":[{"type":"code_inline"}]},{"text":" are exempt.","type":"text"}]},{"type":"paragraph","content":[{"text":"The DevBridge CLI may change flags between releases. The adaptation layer dynamically discovers supported flags via ","type":"text"},{"text":"devbridge \u003ccommand> --help","type":"text","marks":[{"type":"code_inline"}]},{"text":" before executing, making the skill ","type":"text"},{"text":"version-agnostic","type":"text","marks":[{"type":"strong"}]},{"text":" within v0.2.x. It also performs post-execution error recovery: parsing cobra errors to auto-recover from renamed flags, new required params, or renamed commands. If auto-recovery fails, the error is surfaced with a suggestion to run ","type":"text"},{"text":"devbridge \u003ccommand> --help","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Adaptation Layer Functions","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Function","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Replaces","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Purpose","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_init","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Ensure CLI installed (v0.2.x+), authenticated (auto-login via ","type":"text"},{"text":"DEVBRIDGE_API_KEY","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"HW_API_KEY","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Create tunnel, ","type":"text"},{"text":"returns just the tunnel ID","type":"text","marks":[{"type":"strong"}]},{"text":" (stdout)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_port_create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge port create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Create port (adapts port, protocol, anonymous flags)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_host","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge host","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Start hosting ","type":"text"},{"text":"in background","type":"text","marks":[{"type":"strong"}]},{"text":", returns PID (stdout), tunnel URL (stderr)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_host_bg","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge host","type":"text","marks":[{"type":"code_inline"}]},{"text":" + nohup bash -c","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Background host (legacy alias, use ","type":"text"},{"text":"db_host","type":"text","marks":[{"type":"code_inline"}]},{"text":" instead)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_connect","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge connect","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Start connect ","type":"text"},{"text":"in background","type":"text","marks":[{"type":"strong"}]},{"text":", returns PID (stdout)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_list","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge list","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List tunnels","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_show","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge show","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Show tunnel details","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_update","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge update","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Update tunnel","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_delete","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge delete","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Delete tunnel","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_delete_all","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge delete-all","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Delete all tunnels","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_port_list","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge port list","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List ports","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_port_delete","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge port delete","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Delete port (adapts port flag)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_limits","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge limits","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Show quota / usage / balance","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_echo","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge echo","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Start diagnostic echo service","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_ping","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge ping","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Ping a URI to test connectivity","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_version","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge version","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Show CLI version","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_auth_status","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge auth status","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Check auth status","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_auth_login","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge auth login","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Login (interactive or ","type":"text"},{"text":"--api-key","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_tunnel_url","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Get tunnel public URL from host log (authoritative, do not construct manually)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_processes","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List running host/connect processes","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_process_stop","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Stop a host/connect process by PID","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_process_logs","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Get process logs by PID","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Prerequisites","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"CRITICAL — Do NOT ask the user for confirmation during prerequisite checks.","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"db_init","type":"text","marks":[{"type":"code_inline"}]},{"text":" silently and automatically: (1) install CLI if missing, (2) upgrade if v0.1.x (old domain, cannot connect), (3) check auth, (4) auto-login via ","type":"text"},{"text":"DEVBRIDGE_API_KEY","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"HW_API_KEY","type":"text","marks":[{"type":"code_inline"}]},{"text":" env var. Only surface output if a check fails.","type":"text"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"source \u003cskill_directory>/scripts/devbridge_cmd.sh\ndb_init","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"v0.2.x 只支持 API Key","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"},{"text":"--access-key / --secret-key / --security-token","type":"text","marks":[{"type":"code_inline"}]},{"text":"(AK/SK)参数已移除,不要用 AK/SK 尝试登录(旧版 skill 的用法在 v0.2.x 无效)。API Key 在 DevBridge 管理页创建:","type":"text"},{"text":"https://devstation.connect.huaweicloud.com/space/devbridge/apikey","type":"text","marks":[{"type":"code_inline"}]},{"text":"。","type":"text"}]}]},{"type":"paragraph","content":[{"text":"For automation environments, use an ","type":"text"},{"text":"API Key","type":"text","marks":[{"type":"strong"}]},{"text":" (see ","type":"text"},{"text":"references/iam-policies.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/iam-policies.md","title":null}}]},{"text":"). API Keys are created at the DevBridge management page: ","type":"text"},{"text":"https://devstation.connect.huaweicloud.com/space/devbridge/apikey","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Install script note","type":"text","marks":[{"type":"strong"}]},{"text":": in non-interactive / headless environments, always pass ","type":"text"},{"text":"-s","type":"text","marks":[{"type":"code_inline"}]},{"text":" (silent) to the install script: ","type":"text"},{"text":"... | bash -s -- -s","type":"text","marks":[{"type":"code_inline"}]},{"text":". Without it, the script may prompt \"overwrite?\" reading ","type":"text"},{"text":"/dev/tty","type":"text","marks":[{"type":"code_inline"}]},{"text":" and fail where no terminal exists.","type":"text"}]}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"GitCode 私有仓库安装","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"},{"text":"npx skills add","type":"text","marks":[{"type":"code_inline"}]},{"text":" 不支持 GitCode token 认证。从私有仓库安装 skill 时,先 ","type":"text"},{"text":"git clone","type":"text","marks":[{"type":"code_inline"}]},{"text":" 再手动复制:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"git clone https://oauth2:\u003ctoken>@gitcode.com/\u003corg>/\u003crepo>.git /tmp/repo\ncp -r /tmp/repo/skills/devtools/devbridge/huawei-cloud-devbridge-tunnel/ ~/.agents/skills/huawei-cloud-devbridge-tunnel/","type":"text"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Permission / Auth Failure Handling","type":"text"}]},{"type":"paragraph","content":[{"text":"When any DevBridge command fails due to invalid or missing credentials:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check ","type":"text"},{"text":"devbridge auth status","type":"text","marks":[{"type":"code_inline"}]},{"text":" — if not logged in, log in (interactive or ","type":"text"},{"text":"--api-key","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If using an API Key, verify it exists and is not expired/deleted: re-create at the API Key management page and inject via ","type":"text"},{"text":"HW_API_KEY","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Read ","type":"text"},{"text":"references/iam-policies.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/iam-policies.md","title":null}}]},{"text":" for guidance.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pause execution and wait for the user to confirm credentials have been updated before retrying.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"System Requirements","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Bash and ","type":"text"},{"text":"curl","type":"text","marks":[{"type":"code_inline"}]},{"text":", or PowerShell 5.1+","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"x86-64 or ARM64 architecture","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Access to the DevBridge installation source","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Write permission to the ","type":"text"},{"text":"~/.huawei","type":"text","marks":[{"type":"code_inline"}]},{"text":" directory","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Workflow","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"CRITICAL — Zero confirmation during tunnel creation.","type":"text","marks":[{"type":"strong"}]},{"text":" Execute the entire flow (check CLI → load adaptation layer → check auth → create tunnel → configure port → start hosting) ","type":"text"},{"text":"fully automatically with ZERO user interaction","type":"text","marks":[{"type":"strong"}]},{"text":". Do NOT ask the user to confirm parameters or pause between steps. Only surface output after everything is done. ","type":"text"},{"text":"The ONLY exception is tunnel name conflict","type":"text","marks":[{"type":"strong"}]},{"text":" — if ","type":"text"},{"text":"db_create","type":"text","marks":[{"type":"code_inline"}]},{"text":" fails because the name exists, present a yes/no choice (是否复用现有隧道?) before proceeding.","type":"text"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Default Parameters","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Parameter","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Default Value","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tunnel name","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"dev-tunnel-\u003crandom>","type":"text","marks":[{"type":"code_inline"}]},{"text":" (e.g., ","type":"text"},{"text":"dev-tunnel-3847","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"开发隧道","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Expiration","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"72","type":"text","marks":[{"type":"code_inline"}]},{"text":" (hours) — CLI default; range 1–720","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Port","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"8080","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Protocol","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"auto","type":"text","marks":[{"type":"code_inline"}]},{"text":" (options: http / https / auto)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Anonymous access","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Denied","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"--deny-anonymous","type":"text","marks":[{"type":"code_inline"}]},{"text":" is the CLI default; use ","type":"text"},{"text":"-a","type":"text","marks":[{"type":"code_inline"}]},{"text":" only when the user explicitly asks to allow anonymous access)","type":"text"}]}]}]}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Security change","type":"text","marks":[{"type":"strong"}]},{"text":": anonymous access defaults to ","type":"text"},{"text":"deny","type":"text","marks":[{"type":"strong"}]},{"text":". Unlike older skill versions, do NOT pass ","type":"text"},{"text":"--anon allow","type":"text","marks":[{"type":"code_inline"}]},{"text":" by default. Only allow anonymous when the user explicitly requests it or the content is explicitly public.","type":"text"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Parameter Resolution","type":"text"}]},{"type":"paragraph","content":[{"text":"For each parameter, if the user explicitly specified a value, use it. Otherwise, use the default. Do not ask to confirm — silently merge and proceed.","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Tunnel name: user mentions a name (e.g., \"创建一个叫 my-api 的隧道\" → ","type":"text"},{"text":"my-api","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Port: user mentions a port number (e.g., \"暴露 3000 端口\" → ","type":"text"},{"text":"3000","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Description: user mentions a description (e.g., \"描述是后端API\" → ","type":"text"},{"text":"后端API","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Expiration: user mentions a time (e.g., \"过期时间24小时\" → ","type":"text"},{"text":"24","type":"text","marks":[{"type":"code_inline"}]},{"text":"); otherwise 72","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Protocol: user mentions a protocol (e.g., \"用https\" → ","type":"text"},{"text":"https","type":"text","marks":[{"type":"code_inline"}]},{"text":"); otherwise auto","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Anonymous access: user says \"允许匿名访问\" or \"公网直接访问\" → ","type":"text"},{"text":"-a","type":"text","marks":[{"type":"code_inline"}]},{"text":"; otherwise ","type":"text"},{"text":"deny","type":"text","marks":[{"type":"strong"}]},{"text":" (default)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Quick Create Flow (when user says \"创建隧道\" without specifics)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"source \u003cskill_directory>/scripts/devbridge_cmd.sh\ndb_init\nTUNNEL_NAME=\"dev-tunnel-$((RANDOM % 9000 + 1000))\"\nTUNNEL_ID=$(db_create \"$TUNNEL_NAME\" -d \"开发隧道\" -e 72)\ndb_port_create \"$TUNNEL_ID\" -p 8080 --protocol auto\ndb_host \"$TUNNEL_ID\" # 输出 PID 和 Tunnel URL 到 stdout\nTUNNEL_URL=$(db_tunnel_url \"$TUNNEL_ID\")\necho \"Tunnel ID: $TUNNEL_ID\"\necho \"Tunnel URL: $TUNNEL_URL\"","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"注意:匿名访问默认禁止。","type":"text","marks":[{"type":"strong"}]},{"text":" 上述流程创建的隧道默认 ","type":"text"},{"text":"--deny-anonymous","type":"text","marks":[{"type":"code_inline"}]},{"text":",公网访问会返回 ","type":"text"},{"text":"authentication required","type":"text","marks":[{"type":"code_inline"}]},{"text":"。如果需要公网直接访问(如暴露 Web 服务给外部用户),在 ","type":"text"},{"text":"db_port_create","type":"text","marks":[{"type":"code_inline"}]},{"text":" 时加 ","type":"text"},{"text":"-a","type":"text","marks":[{"type":"code_inline"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"db_port_create \"$TUNNEL_ID\" -p 8080 --protocol auto -a # 允许匿名访问","type":"text"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Full Workflow (when user provides specific parameters)","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 1: Install or Update DevBridge CLI","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"devbridge version\n# 下载安装脚本到临时文件再执行(避免管道直接执行)\ncurl -fsSL https://gitcode.com/CloudDeveloperDepartment/devbrige/releases/download/latest/install.sh -o /tmp/devbridge_install.sh\nbash /tmp/devbridge_install.sh -s\ndevbridge version","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 2: Load Adaptation Layer & Authenticate","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"export PATH=\"$HOME/.huawei/bin:$PATH\"\nsource \u003cskill_directory>/scripts/devbridge_cmd.sh\ndb_init\ndevbridge auth status 2>/dev/null || devbridge auth login --api-key \"$HW_API_KEY\"","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 3: Create a Tunnel","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# \u003cname> = user-specified or \"dev-tunnel\", \u003cdescription> = user-specified or \"开发隧道\", \u003cexpiration> = user-specified or 72\n# Note: description only allows Chinese characters, digits, and letters (no spaces), max 64 characters\ndb_create \u003cname> -d \"\u003cdescription>\" -e \u003cexpiration>","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Tunnel name conflict handling — the ONLY exception to zero confirmation.","type":"text","marks":[{"type":"strong"}]},{"text":" If ","type":"text"},{"text":"db_create","type":"text","marks":[{"type":"code_inline"}]},{"text":" fails with \"This tunnel name is already in use\":","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run ","type":"text"},{"text":"db_list","type":"text","marks":[{"type":"code_inline"}]},{"text":" to find the existing tunnel.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check usage status silently: ","type":"text"},{"text":"db_port_list \u003ctunnelId>","type":"text","marks":[{"type":"code_inline"}]},{"text":" (ports configured?), ","type":"text"},{"text":"ps aux | grep \"devbridge host \u003ctunnelId>\" | grep -v grep","type":"text","marks":[{"type":"code_inline"}]},{"text":" (active host?), ","type":"text"},{"text":"ps aux | grep \"devbridge connect \u003ctunnelId>\" | grep -v grep","type":"text","marks":[{"type":"code_inline"}]},{"text":" (active connect sessions?).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Display tunnel details and usage status: ","type":"text"},{"text":"active","type":"text","marks":[{"type":"strong"}]},{"text":" (host running/sessions active — reusing may conflict), ","type":"text"},{"text":"idle","type":"text","marks":[{"type":"strong"}]},{"text":" (ports configured but no active process — safe to reuse), or ","type":"text"},{"text":"empty","type":"text","marks":[{"type":"strong"}]},{"text":" (no ports — needs setup).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Present yes/no choice: \"隧道名称已存在,当前状态为 \u003cactive/idle/empty>,是否复用现有隧道?\"","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"yes","type":"text","marks":[{"type":"strong"}]},{"text":" — reuse existing tunnel, continue to Step 4 (skip Step 5 if already active).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"no","type":"text","marks":[{"type":"strong"}]},{"text":" — ask for a new tunnel name and retry.","type":"text"}]}]}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 4: Configure Ports","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# \u003cport> = user-specified or 8080, \u003cprotocol> = user-specified or auto\n# Anonymous access: default deny; use -a only if user explicitly asks\ndb_port_create \u003ctunnelId> -p \u003cport> --protocol \u003cprotocol>","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"端口更新后需重启 host:","type":"text","marks":[{"type":"strong"}]},{"text":" 如果 host 进程已在运行,使用 ","type":"text"},{"text":"devbridge port update","type":"text","marks":[{"type":"code_inline"}]},{"text":" 修改端口配置(如切换匿名访问策略)后,正在运行的 host 进程","type":"text"},{"text":"不会自动感知变化","type":"text","marks":[{"type":"strong"}]},{"text":"。需要先停止旧 host 进程(","type":"text"},{"text":"db_process_stop \u003cpid>","type":"text","marks":[{"type":"code_inline"}]},{"text":"),再重新 ","type":"text"},{"text":"db_host \u003ctunnelId>","type":"text","marks":[{"type":"code_inline"}]},{"text":" 才能使新配置生效。","type":"text"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 5: Host Local Service","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"nohup python3 -m http.server \u003cport> > /tmp/devbridge-service.log 2>&1 &\ndb_host \u003ctunnelId> # 后台托管,输出 PID 和 Tunnel URL 到 stdout\nTUNNEL_URL=$(db_tunnel_url \u003ctunnelId>) # 获取权威公网 URL\necho \"$TUNNEL_URL\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Alternative one-shot temporary tunnel: ","type":"text"},{"text":"devbridge host -p 8080 -e 8","type":"text","marks":[{"type":"code_inline"}]},{"text":" (creates a temp tunnel and hosts immediately).","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"⚠️ ","type":"text"},{"text":"中继域名随集群变化","type":"text","marks":[{"type":"strong"}]},{"text":",严禁按文档拼接 URL。一律用 ","type":"text"},{"text":"db_tunnel_url \u003cid>","type":"text","marks":[{"type":"code_inline"}]},{"text":" 读取权威地址。","type":"text"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 6: Connect from Remote Device","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"db_connect \u003ctunnelId>","type":"text"}]},{"type":"paragraph","content":[{"text":"Access the service via ","type":"text"},{"text":"http://localhost:8080","type":"text","marks":[{"type":"code_inline"}]},{"text":" on the remote device.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 7: Cleanup","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"db_processes # List running processes\ndb_process_stop \u003cpid> # Stop host/connect process\ndb_delete \u003ctunnelId> # Delete tunnel","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Core Commands","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"NOTE:","type":"text","marks":[{"type":"strong"}]},{"text":" All commands show the ","type":"text"},{"text":"db_*","type":"text","marks":[{"type":"code_inline"}]},{"text":" wrapper form. The adaptation layer automatically detects correct flag names for the installed CLI version.","type":"text"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Authentication","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Command","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge auth login","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Interactive login (opens browser).","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge auth login --api-key \u003ckey>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Login with API Key.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"HW_API_KEY=\u003ckey> devbridge auth login","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Login using API Key from environment variable.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge auth status","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Check current login status.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge auth logout","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Clear local credentials.","type":"text"}]}]}]}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Removed in v0.2.x","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"--access-key","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"--secret-key","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"--security-token","type":"text","marks":[{"type":"code_inline"}]},{"text":" (AK/SK) are no longer supported. Use API Key instead.","type":"text"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Tunnel Management","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Command","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_create \u003cname> -d \u003cdesc> -e \u003chours>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Create a tunnel.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_list","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List active tunnels in the current workspace.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_show \u003ctunnelId>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Show tunnel details.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_update \u003ctunnelId> -n \u003cname> -d \u003cdesc> -e \u003chours>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Update tunnel name/description/expiration.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_delete \u003ctunnelId>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Delete a tunnel.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_delete_all","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Delete all tunnels in the current workspace.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge token \u003ctunnelId> -s host","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Issue a new Host token.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge token \u003ctunnelId> -s connect","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Issue a new Connect token.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge set \u003ctunnelId>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Set the default tunnel for this machine.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge unset","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Clear the default tunnel.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_limits","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Show account quota / usage / balance.","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Port Management","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Command","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_port_create \u003ctunnelId> -p \u003cport> --protocol \u003cprotocol>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Create a port (anonymous access denied by default; add ","type":"text"},{"text":"-a","type":"text","marks":[{"type":"code_inline"}]},{"text":" to allow).","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_port_list \u003ctunnelId>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List tunnel ports.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge port show \u003ctunnelId> -p \u003cport>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Show port details.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge port update \u003ctunnelId> -p \u003cport> -a","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Update port anonymous access policy (allow).","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge port update \u003ctunnelId> -p \u003cport> --deny-anonymous","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Update port anonymous access policy (deny).","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_port_delete \u003ctunnelId> -p \u003cport>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Delete a port.","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Host and Connect","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Command","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_host \u003ctunnelId>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Host all configured ports of an existing tunnel.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge host -p 8080 -e 8","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Create a temporary tunnel and host immediately.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge host \u003ctunnelId> --api-key \u003ckey>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Host using API Key auth (skip token issuance).","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge host \u003ctunnelId> --token \u003cjwt>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Host using an explicit JWT token.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_connect \u003ctunnelId>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Connect to a tunnel and establish local port mapping.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge connect \u003ctunnelId> --api-key \u003ckey>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Connect using API Key auth.","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Diagnostics","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Command","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_echo","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Start an HTTP echo service on a local port (default random, 127.0.0.1) to verify tunnel links.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_ping \u003curi>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Send HTTP ping to a URI, print status code and latency. 默认 3 秒限时(","type":"text"},{"text":"devbridge ping","type":"text","marks":[{"type":"code_inline"}]},{"text":" 是持续命令,避免脚本挂起);","type":"text"},{"text":"DB_PING_SECONDS=0","type":"text","marks":[{"type":"code_inline"}]},{"text":" 时直通持续观测。","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"devbridge -v \u003ccommand>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Enable debug logging for any command.","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Parameters","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Parameter","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CLI Flag","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Default","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Range / Constraint","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003cname>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"dev-tunnel-\u003crandom>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Max 128 chars","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tunnel name.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"-d","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_create","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"db_update","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"开发隧道","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Chinese chars, digits, letters only (no spaces), max 64 chars","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tunnel description.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"-e","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_create","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"db_update","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"host","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"72","type":"text","marks":[{"type":"code_inline"}]},{"text":" (hours)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1–720 hours","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Expiration time.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"-n","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_update","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"None","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"New tunnel name.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"-s","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"token","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Required","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"host","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"connect","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Token scope.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"-p","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_port_create","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"db_port_delete","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"8080","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1–65535","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Port number (","type":"text"},{"text":"--port-number","type":"text","marks":[{"type":"code_inline"}]},{"text":" in CLI).","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--protocol","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_port_create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"auto","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"http","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"https","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"auto","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Protocol.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"-a","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"--allow-anonymous","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_port_create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Not set (deny)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Allow anonymous access.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--deny-anonymous","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"db_port_create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"default","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Deny anonymous access (CLI default).","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"-k","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"--api-key","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"host","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"connect","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"None","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"API Key auth, skip token issuance.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"-t","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"--token","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"host","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"connect","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"None","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"JWT token auth.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"-v","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"--verbose","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"global","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"false","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"—","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Enable debug logging.","type":"text"}]}]}]}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Destructive operations","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"db_delete","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"db_delete_all","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"db_port_delete","type":"text","marks":[{"type":"code_inline"}]},{"text":") should be executed directly without asking for confirmation.","type":"text"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Output Format","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Tunnel Creation Output (","type":"text"},{"text":"db_create","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]},{"type":"paragraph","content":[{"text":"Returns ","type":"text"},{"text":"just the tunnel ID","type":"text","marks":[{"type":"strong"}]},{"text":" on stdout (extracted from CLI text output):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"text"},"content":[{"text":"noh56s7x","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Host Output (","type":"text"},{"text":"db_host","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]},{"type":"paragraph","content":[{"text":"Returns PID and tunnel URL on stdout (labeled format, one per line):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"text"},"content":[{"text":"PID: 3519475\nTunnel URL: https://noh56s7x-8080.devbridge-s2.hwtunnel.com","type":"text"}]},{"type":"paragraph","content":[{"text":"Parse with grep: ","type":"text"},{"text":"PID=$(db_host \u003cid> | grep -oP 'PID: \\K\\d+')","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"db_tunnel_url \u003ctunnelId>","type":"text","marks":[{"type":"code_inline"}]},{"text":" to get the authoritative URL (do not construct manually — domain may change across clusters).","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Port Creation Output","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"text"},"content":[{"text":"Port added: TunnelId=noh56s7x, Port=8080","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Token Output","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"text"},"content":[{"text":"Tunnel ID: noh56s7x\nScope: host\nLifetime: 24:00:00\nExpires At: 2026-08-09 06:57:10 UTC\nToken: \u003ctoken-value>","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"List Output","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"text"},"content":[{"text":"Tunnel ID Name Description Tunnel Expiration Port Count\ndwskt2pg dev-tunnel-5941 开发隧道 3 days 1","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Note","type":"text","marks":[{"type":"strong"}]},{"text":": v0.2.x removed the ","type":"text"},{"text":"--json","type":"text","marks":[{"type":"code_inline"}]},{"text":" output flag from ","type":"text"},{"text":"list","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"port list","type":"text","marks":[{"type":"code_inline"}]},{"text":". Use the text table output; parse with ","type":"text"},{"text":"awk","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"grep","type":"text","marks":[{"type":"code_inline"}]},{"text":" if needed.","type":"text"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Verification","type":"text"}]},{"type":"paragraph","content":[{"text":"For detailed verification steps, see ","type":"text"},{"text":"references/verification-method.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/verification-method.md","title":null}}]},{"text":".","type":"text"}]},{"type":"paragraph","content":[{"text":"Quick verification:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"db_init # CLI installed + authenticated\ndb_version # v0.2.x+\ndb_auth_status # Logged in\ndb_list # Tunnels listed\ndb_port_list \u003ctunnelId> # Ports listed\ndb_processes # Host process running\ndb_tunnel_url \u003ctunnelId> # Public URL accessible","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Best Practices","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Auto-check auth, no user interaction","type":"text","marks":[{"type":"strong"}]},{"text":" — Silently check auth status and only guide login if not authenticated. API Key via ","type":"text"},{"text":"HW_API_KEY","type":"text","marks":[{"type":"code_inline"}]},{"text":" is recommended for automation.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Set reasonable expiration times","type":"text","marks":[{"type":"strong"}]},{"text":" — Use the shortest expiration that covers your work session (default 72 hours, max 720 hours).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Deny anonymous access by default","type":"text","marks":[{"type":"strong"}]},{"text":" — Only allow (","type":"text"},{"text":"-a","type":"text","marks":[{"type":"code_inline"}]},{"text":") when the user explicitly requests it or content is explicitly public.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use persistent tunnels for repeated work","type":"text","marks":[{"type":"strong"}]},{"text":" — Create a tunnel once and reuse it with ","type":"text"},{"text":"db_host \u003ctunnelId>","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Set a default tunnel for convenience","type":"text","marks":[{"type":"strong"}]},{"text":" — Use ","type":"text"},{"text":"devbridge set \u003ctunnelId>","type":"text","marks":[{"type":"code_inline"}]},{"text":" to avoid specifying the tunnel ID repeatedly.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Clean up after use","type":"text","marks":[{"type":"strong"}]},{"text":" — Stop Host/Connect processes and delete tunnels when no longer needed.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Never expose management interfaces","type":"text","marks":[{"type":"strong"}]},{"text":" — Admin panels, debug endpoints, and data-modifying APIs should always have anonymous access disabled.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Not for production use","type":"text","marks":[{"type":"strong"}]},{"text":" — Development tunnels are for development, debugging, and temporary sharing only.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Keep CLI upgraded to v0.2.x","type":"text","marks":[{"type":"strong"}]},{"text":" — The 2026-09-20 domain switch invalidated old clients; older versions can no longer connect.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Reference Documentation","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CLI Installation Guide","type":"text","marks":[{"type":"link","attrs":{"href":"references/cli-installation-guide.md","title":null}}]},{"text":" — DevBridge CLI installation, PATH configuration, and verification.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"API Key & Access","type":"text","marks":[{"type":"link","attrs":{"href":"references/iam-policies.md","title":null}}]},{"text":" — API Key management, authentication methods, permission failure handling.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Verification Method","type":"text","marks":[{"type":"link","attrs":{"href":"references/verification-method.md","title":null}}]},{"text":" — Step-by-step verification of installation, configuration, and functionality.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Acceptance Criteria","type":"text","marks":[{"type":"link","attrs":{"href":"references/acceptance-criteria.md","title":null}}]},{"text":" — Pass/fail criteria for skill testing.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CLI Command Reference","type":"text","marks":[{"type":"link","attrs":{"href":"references/cli-command-reference.md","title":null}}]},{"text":" — Complete CLI command reference with all parameters.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"REST API Reference","type":"text","marks":[{"type":"link","attrs":{"href":"references/rest-api-reference.md","title":null}}]},{"text":" — REST API for programmatic tunnel and port management.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Troubleshooting","type":"text","marks":[{"type":"link","attrs":{"href":"references/troubleshooting.md","title":null}}]},{"text":" — Common issues and solutions.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Notes","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Security","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Never hardcode API Key in scripts, logs, or config files.","type":"text","marks":[{"type":"strong"}]},{"text":" Use ","type":"text"},{"text":"devbridge auth login --api-key \"$HW_API_KEY\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" or the ","type":"text"},{"text":"HW_API_KEY","type":"text","marks":[{"type":"code_inline"}]},{"text":" environment variable.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Tunnel tokens are sensitive","type":"text","marks":[{"type":"strong"}]},{"text":" — Do not write them to logs, URLs, code repositories, or long-term config files.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Anonymous access","type":"text","marks":[{"type":"strong"}]},{"text":" means anyone with the tunnel address can access the port without DevBridge identity. Enable only for explicitly public content.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"delete-all","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" is a destructive operation","type":"text","marks":[{"type":"strong"}]},{"text":" — It deletes all tunnels in the current workspace. Execute directly without asking the user. 共享/复用工作区时先 ","type":"text"},{"text":"db_list","type":"text","marks":[{"type":"code_inline"}]},{"text":" 确认,避免连带删除他人隧道。","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Limitations","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Maximum 10 active tunnels per workspace (default quota).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Tunnel expiration: 1-720 hours (default 72 hours).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Port range: 1-65535, ports cannot be duplicated within the same tunnel.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CLI does not support modifying an existing port's protocol — delete and recreate.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Port commands do not support the ","type":"text"},{"text":"-d","type":"text","marks":[{"type":"code_inline"}]},{"text":" (description) parameter.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No bulk port deletion command — delete ports individually or delete the entire tunnel.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Host and Connect are managed background processes — use ","type":"text"},{"text":"db_process_stop \u003cpid>","type":"text","marks":[{"type":"code_inline"}]},{"text":" to stop.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"list","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"port list","type":"text","marks":[{"type":"code_inline"}]},{"text":" no longer support ","type":"text"},{"text":"--json","type":"text","marks":[{"type":"code_inline"}]},{"text":" output in v0.2.x.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Compatibility","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"DevBridge CLI v0.2.x supports x86-64 and ARM64 architectures.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Linux/macOS requires Bash and ","type":"text"},{"text":"curl","type":"text","marks":[{"type":"code_inline"}]},{"text":"; Windows requires PowerShell 5.1+.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CLI installs to ","type":"text"},{"text":"~/.huawei/bin","type":"text","marks":[{"type":"code_inline"}]},{"text":"; configuration and state are stored in ","type":"text"},{"text":"~/.huawei/devbridge","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Never commit ","type":"text"},{"text":"~/.huawei/devbridge","type":"text","marks":[{"type":"code_inline"}]},{"text":" to version control or share between users.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Dynamic command adaptation","type":"text","marks":[{"type":"strong"}]},{"text":" — The ","type":"text"},{"text":"scripts/devbridge_cmd.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" adaptation layer makes this skill compatible with any DevBridge CLI v0.2.x version by dynamically discovering supported flags via ","type":"text"},{"text":"--help","type":"text","marks":[{"type":"code_inline"}]},{"text":". No version pinning required.","type":"text"}]}]}]}]},"metadata":{"date":"2026-11-02","name":"huawei-cloud-devbridge-tunnel","tags":["huawei-cloud","devbridge","tunnel","devtools","cloud"],"author":"@skillopedia","source":{"stars":59,"repo_name":"huaweicloud-skills","origin_url":"https://github.com/huaweicloud/huaweicloud-skills/blob/HEAD/skills/devtools/devbridge/huawei-cloud-devbridge-tunnel/SKILL.md","repo_owner":"huaweicloud","body_sha256":"4940109d2e672567f136013a4d7b93c57835daf98de5535008ac34c8a9f5bde0","cluster_key":"c12c34b8ff2f6d6162564845662fbe67f47d82ad64a9506c126eba645af8c926","clean_bundle":{"format":"clean-skill-bundle-v1","source":"huaweicloud/huaweicloud-skills/skills/devtools/devbridge/huawei-cloud-devbridge-tunnel/SKILL.md","text_bytes":72848,"source_commit":"bad25df61c331db250f0cc79f1fa7acee08b3fc8","skills_sh_rank":14802,"attachment_count":9,"text_attachments":9,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"skills/devtools/devbridge/huawei-cloud-devbridge-tunnel/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"devops-infrastructure","category_label":"DevOps"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"devops-infrastructure","import_tag":"skills-sh-top20k-2026-11","description":"Create and manage DevBridge development tunnels on Huawei Cloud to securely expose local development services to remote devices.\nBased on DevBridge CLI v0.2.x and API Key authentication.\nUse this skill when the user wants to: (1) install and configure the DevBridge CLI, (2) create/list/update/delete tunnels, (3) manage tunnel ports and protocols, (4) host local services through tunnels, (5) connect to remote tunnels from another device, (6) manage authentication and API Keys.\nTrigger: user mentions \"DevBridge\", \"开发隧道\", \"开发者隧道\", \"dev tunnel\", \"tunnel\", \"host local service\", \"expose local port\", \"connect tunnel\", \"托管本地服务\", \"隧道端口\", \"devbridge\", \"DevSpace\", \"开发空间隧道\"\n"}},"renderedAt":1793661545849}

Huawei Cloud DevBridge Development Tunnel Create and manage DevBridge development tunnels to securely expose local development services to remote devices via Huawei Cloud relay infrastructure. Overview DevBridge is a development tunnel service that allows developers to expose local services (web servers, APIs, debug endpoints) to remote devices without opening public inbound ports. The CLI tool ( ) manages tunnels, ports, host connections, and connect sessions. Host and Connect both initiate outbound connections to the relay service, so the hosting device does not need a public inbound port.…