mcpField
H
huawei-cloud-publish-work-to-gallery

huawei-cloud-publish-work-to-gallery

github.com/huaweicloudその他59195 回インストール2 日前に更新
リポジトリ

huawei-cloud-publish-work-to-gallery について

プロジェクトをHuawei Cloudの大学向けギャラリープラットフォームに公開するためのスキルです。スクリプトによるプロジェクト選定、メタデータや画像の準備、公開を、各段階のチェックを通じて進めます。

主な機能

  1. 01候補プロジェクトのスキャン
  2. 02アカウントドメインの解決と STS 認証情報の取得
  3. 03Git リポジトリ情報と作品名の取得
  4. 04カバー画像と詳細アーカイブの準備
  5. 05公開前の前提条件チェック

活用シーン

  1. 01大学向けギャラリーへの作品公開
  2. 02作品のカバー画像と詳細パッケージの準備
  3. 03投稿先トレーニングキャンプの選択

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/huaweicloud/huaweicloud-skills --skill huawei-cloud-publish-work-to-gallery

インストール後、Claude Code で/huawei-cloud-publish-work-to-galleryを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
api-spec.md
codearts-sandbox.md
devbridge-tunnel.md
error-codes.md
iam-policies.md
mock-server-template.md
self-verify-publish.md
troubleshooting.md
windows-setup.md
work-preparation-linux.md
work-preparation-windows.md
work-preparation.md
scripts/
api.mjs
browser_launch.py
build-cover.mjs
build-detail-zip.mjs
check-gates.mjs
check-version.mjs
count-cjk.mjs
detect-env.mjs
download-noto-color-emoji.sh
ensure-git-root.mjs
ensure-gitcode-credential.mjs
ensure-user-bindir.mjs
ensure-user-tool.mjs
ensure-utf8.mjs
extract-fonts.mjs
extract-workname.mjs
gen_sts.py
generate_cover.py

詳細

ギャラリーに作品を公開する

作品を華為クラウドの大学向け運営プラットフォームに公開します。組み込みスクリプトを優先して呼び出してください(単一のエントリーポイント、fail-fast、--help を内蔵)。エラーが発生した場合にのみ、references/troubleshooting.md を確認してください。

パイプライン

Step 1 (workDir, domainID, STS)
Step 2 (port→变量, envUrl→变量)              ← 依赖 Step 1
  ├── Step 3 (gitUrl, gitBranch, workName)   ← 只依赖 workDir
  ├── Step 5 (introduction, camps)           ← 只依赖 workDir + STS
  ├── Step 4 (coverImage)                    ← 依赖 port + workName
  └── Step 6 (detailZip)                     ← 依赖 workName + 代码分析
Step 7 (trainingCampId)                      ← 依赖 Step 5 camps
Step 8 (publish)                             ← 依赖以上全部

並列実行(Step 2 完了後):Step 3/4/5/6 は相互に依存せず、4つすべてを並列実行します(最長経路の Step 4 が約90秒で、直列実行の約160秒ではありません)。Step 4 内の preflight と ensure-utf8 も並列実行します。Step 6 の隠れた依存関係に注意:generate_diagram.py は Playwright を使用し、Step 4 の preflight でインストールされます(初回は CJK フォントと Chromium を含み、5~10分)。スクリプトにはゲートが組み込まれており、font-gate-ok マーカーがない場合は exit 1 で待機を促すメッセージを表示し、ModuleNotFoundError は発生しません。Step 6 の並列実行時にこのメッセージが表示された場合は、preflight の完了後(ログ/マーカーをポーリングして確認)にこの手順を再実行してください。実際の失敗ではありません。

変数の引き継ぎ:port/workName/envUrl は最初の該当ステップで決定し、その後は全工程で変数として渡してください。ハードコードは禁止です(トンネル URL には port が含まれるため、ポートを変更すると envUrl も変わります)。

実行モデル:① スクリプトの契約を優先——stdout の成功シグナルに基づいて判定し、成功時はソースコードを一切読みません。失敗した場合にのみ、スクリプトのメッセージ → troubleshooting の該当セクション → スクリプトのソースコードを grep の順に確認します。② ゲートを手動で回避することは禁止です。③ ネットワークタイムアウトは一律 3s です。④ detect-env.mjs でプラットフォームを特定した後は、該当プラットフォームの reference のみを参照してください(ディレクトリをたどって確認し、すべてを読み込まないでください)。⑤ 依存関係のない bash 呼び出しはまとめる:; で連結して1つのコマンドにし、ツールの往復を減らしてください(1回につき約1~2秒)。⑥ ユーザーとの対話が必要なコマンドでは、リンク/QRコードをそのままユーザーに表示してください。エージェント内蔵のブラウザー/ツール(browser_use_open など)で代わりに開くことは禁止です——スクリプトはローカルでコールバックサーバーをすでに起動しており、ユーザーが任意のブラウザーで認証すると、スクリプトが自動的にトークンを取得します。エージェントは全工程を通じてブラウザーを必要としません。

コアコマンド(スクリプトの契約クイックリファレンス)

$SKILL_DIR の定義:この skill のインストールディレクトリの絶対パス(SKILL.md を含むディレクトリ)です。実行前に export SKILL_DIR=/path/to/huawei-cloud-publish-work-to-gallery を設定してください(例:$HOME/.local/share/huawei-cloud-publish-work-to-gallery)。すべてのスクリプトは実行可能ファイル(shebang 付き)なので、$SKILL_DIR/scripts/… を先頭に付けて直接呼び出してください。node/python/bash のインタープリター接頭辞は不要です(この説明が当てはまるのは Linux のみです。Windows では .mjs/.py に node/python の接頭辞が必要で、preflight.ps1 には powershell の接頭辞が必要です)。インストーラーによって実行権限が復元されていない場合(Linux で直接呼び出すと Permission denied が発生)、スクリプトを変更せずに chmod +x "$SKILL_DIR/scripts/"* を一度実行して修復してください。引数には必ず解析可能なサンプル値を使用してください(<…> のプレースホルダーは、コマンド抽出器によって削除されると引数不足/空値になるため使用しないでください)。W/R の表記:W = プラットフォームへの書き込み操作(作品の公開。必ずユーザーの確認後にのみ実行)。R = 読み取り専用の照会/ローカル補助コマンド。 | 手順 | スクリプト/コマンド | W/R | 成功のシグナル(exit 0 かつ) | 失敗(exit 1;2=引数エラー) | |------|-----------|-----|----------------------|-----------------------------------| | 前提 | $SKILL_DIR/scripts/api.mjs GET /v1/gallery/announcements/current --prefix open-api-guest | R | stdout の先頭行が #status=200 | タイムアウト/接続拒否 → ネットワークの確認を案内 | | 前提 | $SKILL_DIR/scripts/check-version.mjs(自身の name/version を読み取り、/v1/gallery/skills/status を呼び出して判定) | R | exit 0 かつ先頭行が status=ok/status=skip | exit 1(status=outdated + プラットフォームのアップグレード文言)→ そのままアップグレードを案内して停止;判定ルールは api-spec を参照 | | 5/7 | $SKILL_DIR/scripts/api.mjs GET "/v1/gallery/camps" --creds-file ./sts-creds.json --fields "id,name,school,status,startsAt,endsAt" | R | #status=200 | 401 → STS を更新 | | 1 | $SKILL_DIR/scripts/scan-projects.mjs | R | stdout が #project <n> <path> <type> | exit 1=候補なし | | 1 | $SKILL_DIR/scripts/resolve-domain.mjs --hcloud /usr/local/bin/hcloud | R | stdout が #domain=<id> name=<name> | exit 1=hcloud の失敗(stderr に確認手順を含む) | | 1 | $SKILL_DIR/scripts/gen_sts.py --account 100000000000 --hcloud /usr/local/bin/hcloud --creds-out ./sts-creds.json --sh-out ./sts-creds.sh | R | ./sts-creds.json(_refresh を含む)と ./sts-creds.sh(相対パスで、後続の --creds-file ./sts-creds.json からそのまま使用可能)を書き込む | [troubleshooting#domain-id-resolution-issues] を参照 | | 3 | $SKILL_DIR/scripts/ensure-git-root.mjs /path/to/project | R | exit 0(git -C /path/to/project rev-parse --git-dir = .git) | exit 1=workDir がリポジトリのルートではない → remote の読み取りを禁止し、Step 3 に従って対応 | | 3 | $SKILL_DIR/scripts/read-git-info.mjs /path/to/project | R | #gitUrl=<https://… .git> #gitBranch=<ブランチ>(リモートにそのブランチが実在することを確認済み) | exit 1=Git リポジトリではない/URL 検証失敗/#branchAbsent=1(リモートにブランチが存在しない——SHA に応じた対処は checkout または push のみ。stderr の内容をそのまま伝えればよい);ネットワーク/認証情報の問題で確認できない場合は stderr に警告を出すが、処理は妨げない(公開時にサーバー側でブランチの存在を検証) | | 3 | $SKILL_DIR/scripts/ensure-gitcode-credential.mjs | R | #credential=found(認証情報あり)または #credential=missing(認証情報なし、OAuth を使用) | exit 0;手動での代替手段なし | | 3 | $SKILL_DIR/scripts/gitcode-oauth.ensure.mjs --start | R | #oauth=ready(トークンあり)/#oauth=started session_id=123456 login_url=https://example.com(stdout は即時に返り、QR コードは stderr に出力) | #oauth=absent がない場合は exit 1;失敗時は #oauth=failed reason=timeout で exit 1 | | 3 | $SKILL_DIR/scripts/gitcode-oauth.ensure.mjs --wait 123456 --timeout 300 | R | #oauth=done(トークンが ~/.gitcode/auth.toml に書き込まれている) | #oauth=failed reason=timeout\|finish\|… で exit 1 | | 3 | $SKILL_DIR/scripts/extract-workname.mjs /path/to/project | R | stdout が #name=MyWork source=frontmatter | exit 1=workDir が存在しない | | 2 | $SKILL_DIR/scripts/spawn-detached.mjs --out /tmp/spawn.out --pidfile /tmp/app.pid --cwd /path/to/project -- npm run dev | R | #spawn=ok pid=12345 out=/tmp/spawn.out | exit 1=起動失敗 | | 2 | トンネル:まず $SKILL_DIR/scripts/detect-env.mjs を実行して tunnel フィールドを確認します。true(Linux)→ 組み込み skill huawei-cloud-devbridge-tunnel を読み込んでトンネルを開きます。false(Windows/macOS)→ 読み込み禁止、envUrl="" | R | envUrl を取得;skill が利用できない/失敗した場合は envUrl="" のまま通常どおり公開 | tunnel=false の場合にトンネルを開こうとする = 契約違反 | | 4 | $SKILL_DIR/scripts/preflight.sh(Win: powershell $SKILL_DIR/scripts/preflight.ps1) | R | font-gate-ok を書き込む(ok=true gate=preflight) | スクリーンショット/カバー/図表の生成禁止 | | 4 | $SKILL_DIR/scripts/ensure-utf8.mjs /path/to/project | R | utf8-gate-ok を書き込む | UTF-8 以外のエンコーディング → スクリーンショット禁止 | | 4 | $SKILL_DIR/scripts/build-cover.mjs --url http://127.0.0.1:8080 --project-dir /path/to/project --title "MyWork" --out /tmp/cover.png | R | stdout が 1 行 #cover=/tmp/cover.png layout=… multi=yes tmp=/tmp/shots(内部で screenshot_guard.py と generate_cover.py を呼び出す) | exit 1 → スクリーンショット/検証/合成のいずれかに失敗。詳細は stderr を参照 | | 4 | $SKILL_DIR/scripts/generate_cover.py --screenshot /tmp/shots/shot-index.png --title "MyWork" --out /tmp/cover.png | R | カバー PNG を生成し、その後 verify-glyphs.py で検証 | exit 1 → 合成の続行禁止 | | 4/6 | $SKILL_DIR/scripts/verify-glyphs.py /tmp/cover.png --quiet | R | exit 0(stdout はトークン節約のため 1 行のみ) | exit 1 → 豆腐文字の疑い → フォントを修正 | | 5 | $SKILL_DIR/scripts/count-cjk.mjs --file /tmp/intro.txt | R | 総文字数が 15~50 | exit 1 → 紹介文を書き直して再カウント | | 6 | $SKILL_DIR/scripts/generate_diagram.py --html /tmp/diagram.html --out /tmp/diagram.png --width 1280 | R | 図表 PNG を生成し、その後 verify-glyphs.py --quiet で検証 | カバーと同様;font-gate-ok がない場合は exit 1 で preflight の完了を待つよう案内(暗黙の依存関係。並列実行に関する説明を参照) | | 6 | $SKILL_DIR/scripts/build-detail-zip.mjs --readme README.md --resources /path/to/project/resources --out /tmp/detail.zip | R | パッケージ化と検証を一度に完了 | exit 1 → 出力に従って修正し、再パッケージ化 | | 8 | $SKILL_DIR/scripts/check-gates.mjs --cover /tmp/cover.png --detail /tmp/detail.zip --strict --max-age 3600 --quiet | R | exit 0(stdout はトークン節約のため 1 行のみ) | exit 1 → 戻ってゲートを再実行 | | 8 | $SKILL_DIR/scripts/publish-work.mjs /tmp/params.json --max-age 3600 | W | #status=201(workId/workUrl/reward のみを出力) | envUrl に到達できない → exit 1(ローカルサービスの確認を案内);409/その他 → 完全なレスポンスをそのまま出力 | ファイル位置の目印:Linux /tmp/;Windows os.tmpdir()(%TEMP%)。

パラメーターの確認

パラメーター必須説明取得元
workDirはい作品プロジェクトのルートディレクトリ(git リポジトリのルートである必要があります)Step 1(ユーザーが選択)
domainIDはいHuawei Cloud アカウントの Domain IDStep 1(resolve-domain.mjs)
credsFileはいSTS 一時認証情報 JSON(sts-creds.json)Step 1(gen_sts.py)
port条件付きローカルサービスのポート(ユーザーがプロジェクトの実行を拒否した場合は不要)Step 2
envUrl条件付きDevBridge トンネルのパブリック URL(失敗した場合は空文字列)Step 2
gitUrl / gitBranchはい作品リポジトリの URL/ブランチStep 3
workNameはい作品名(30 文字未満)Step 3(extract-workname.mjs)
coverImagePathはいカバー PNG(verify-glyphs の検証に合格する必要があります)Step 4
introductionはい1 文の紹介文(合計文字数 15~50)Step 5(count-cjk.mjs)
detailsZipPathはい作品詳細 zip(ルートに README.md + resources/)Step 6
trainingCampIdはいトレーニングキャンプ/イベント IDStep 7(ユーザーが番号で選択)

前提条件と依存関係の固定

  • hcloud + AK/SK:Step 1 で必要です。未インストール/未設定の場合 → troubleshooting#domain-id-resolution-issues。
  • git:Step 3 で必要です。zip は build-detail-zip.mjs が使用できない場合の代替手段です(Linux yum install zip;Windows .NET ZipFile。 windows-setup.md を参照)。
  • Git Bash の前提条件:source $SKILL_DIR/scripts/setup-env.sh(MSYS のパス変換を防止)。PowerShell/CMD では不要です。
  • OAuth とローカル環境の依存関係(自動化/サンドボックスの制限):公開フローでは、ユーザーによる GitCode OAuth 認可(Step 3)とローカルプロジェクトの実行(Step 2 のトンネル/Step 8 の公開)が必要です。無人運用またはサンドボックス環境(ユーザーのブラウザーで認可できない環境)では、実際のプラットフォーム API にアクセスできません。このようなユースケースには requires manual verification と明記し、実際のユーザー環境で再検証してください。

コアワークフロー

Step 1: 作品ディレクトリの選択と IAM Domain 情報の解決
  1. ユーザーに通知します(ディレクトリの選択をもって同意とします):IAM の自己委任 SELF_VERIFY を作成し、STS 一時認証情報(900s)を生成します。永続的な AK/SK はローカルに保持し、アップロードしません。
  2. プロジェクトのルートをスキャンします:$SKILL_DIR/scripts/scan-projects.mjs——**/README.md を自動的に再帰検索し、指示ファイルを確認して、skills//node_modules//dist/ などを除外し、CodeArts のサンドボックスディレクトリをスキャンします。stdout の各行は #project <n> <path> <type> です。
  3. 候補を列挙してユーザーの選択を待ち、workDir に設定します。
  4. Domain ID を解決します:$SKILL_DIR/scripts/resolve-domain.mjs --hcloud /usr/local/bin/hcloud——hcloud configure set --region + IAM KeystoneListAuthDomains を自動実行し、domain_id を抽出します。stdout は #domain=<id> name=<name> です。認証情報の優先順位:env → 設定済みの hcloud → ユーザーに設定を案内(troubleshooting#2)。Windows では install-hcloud.ps1 によるインストールとユーザー PATH への追加が完了しているため、通常 --hcloud は不要です。
  5. STS を生成します:$SKILL_DIR/scripts/gen_sts.py --account 100000000000 --hcloud /usr/local/bin/hcloud --creds-out ./sts-creds.json --sh-out ./sts-creds.sh → ./sts-creds.json(_refresh を含み、401 が発生すると自動更新します)。認証情報ファイルは相対パスで読み書きします(同じ CWD のセッション内では一貫しており、プラットフォームごとに /tmp/%TEMP% を使い分ける必要はありません);⚠️ この認証情報ファイルを git add したり、コミットしたりしないでください。Step 8 の終了後にまとめて削除します。hcloud の検出順序は resolve-domain と同じです。
  6. 出力:IAM Domain ID: <id> を取得しました。作品をお客様の Huawei Cloud アカウントに関連付けるために使用します。

出力: workDir、domainID、credsFile。

Step 2: プロジェクトの実行とトンネルの開設

まず $SKILL_DIR/scripts/detect-env.mjs を実行して tunnel フィールドを取得します。true(Linux)の場合はトンネルを開くかどうかを尋ねます。false(Windows/macOS)の場合はトンネルを完全にスキップし、envUrl="" に設定して、DevBridge skill の読み込みを試みないでください。プロジェクトを実行するかユーザーに尋ねます。拒否された場合は envUrl="" として Step 3 に進みます。

  • ポートの解放:netstat -ano | findstr :<port>(Win)を実行し、残っているプロセスを kill します。
  • プロジェクトを起動します:$SKILL_DIR/scripts/spawn-detached.mjs --out /tmp/spawn.out --pidfile /tmp/app.pid --cwd /path/to/project -- npm run dev → #spawn=ok pid=12345。必ず --cwd <workDir> を指定してください(スクリプトのデフォルトは process.cwd() です。実行ディレクトリが workDir でない場合、http-server . が誤ったディレクトリを配信し、スクリーンショットが空白になります——2026-09-20 の教訓)。エントリースクリプトを優先します(npm run dev/python main.py)。フロントエンドのみの場合は http-server . -p <port> を使用します。30 秒以内にヘルスチェックを行います:curl -sf --max-time 3 http://localhost:<port>。
  • トンネル(DevBridge):Linux では、対象環境に組み込まれている skill huawei-cloud-devbridge-tunnel を読み込み、その手順に従ってトンネルを開設し、envUrl を取得してください——DevBridge コマンドを推測したり、独自に組み立てたりしないでください。この skill が使用できない場合、またはトンネルの開設に失敗した場合は、envUrl="" として通常どおり公開します。Windows では DevBridge を使用しません(トンネル機能が組み込まれていません)→ envUrl=""。公開終了後にトンネルを自動でクリーンアップしないでください——公開の終了はトンネルのライフサイクルの終了を意味しません(後続の公開や 409 による名前変更の再試行でトンネルが再利用されることがあります)。ユーザーが明示的にクリーンアップを求めた場合に限り、組み込み skill の手順に従ってストリームを停止/トンネルを削除してください。詳しくは devbridge-tunnel.md を参照してください。

出力: port、envUrl(または "")。

Step 3: Git Repository Info & Work Name

gitUrl 必填,gitBranch 必须显式读取。workName 从 README 解析/合成(<30 字符)。

  1. 仓库根检测(fail-stop):$SKILL_DIR/scripts/ensure-git-root.mjs /path/to/project——硬检测 workDir 自身是否为 git 仓库根(git -C /path/to/project rev-parse --git-dir 必须返回 .git)。若不是(如 workDir 无 .git 但父目录有,git 会向上递归返回父仓库 remote),脚本 exit 1 并提示。此时 禁止 直接 git -C /path/to/project remote get-url origin(会拿到父仓库 URL)。处理方式:① 问用户手动提供 gitUrl + gitBranch;② 或在 workDir git init + 推到远端后再读。检测通过才继续。
  2. $SKILL_DIR/scripts/read-git-info.mjs /path/to/project 一步取 gitUrl/gitBranch(含仓库自检 + 凭证剥离 + 远端分支核对,契约见上表)。#branchAbsent=1 → 转述 stderr 的唯一处置(脚本已按 SHA 判定:远端某分支与本地当前提交一致 → git checkout <该分支> 后重跑,无损且优于 push;否则 → git push -u origin <branch> 后重跑,切到远端旧分支会提交旧代码)。
  3. 凭证排查:$SKILL_DIR/scripts/ensure-gitcode-credential.mjs——有凭证即 #credential=found。无凭证时走 gitcode-oauth 两阶段授权(契约见上方 gitcode-oauth.ensure.mjs --start/--wait):① --start 拿登录链接/二维码原样展示给用户,请用户在任意浏览器打开授权(禁止用 agent 内置浏览器代开),脚本本地已起回调服务器;② --wait <session_id> 阻塞轮询到 token 落盘。
  4. 命名:$SKILL_DIR/scripts/extract-workname.mjs /path/to/project——按优先级 frontmatter → H1 → manifest → index.html <title> → 目录名提取。stdout #name=<name> source=<来源>。source=dirname 时 agent 可合成/修改(<30 字符)。

Output: gitUrl、gitBranch、workName。

Step 4: Cover Image

门禁(并行):

门禁命令标记
渲染$SKILL_DIR/scripts/preflight.sh(Win: $SKILL_DIR/scripts/preflight.ps1)font-gate-ok
编码$SKILL_DIR/scripts/ensure-utf8.mjs /path/to/projectutf8-gate-ok

门禁失败禁止截图/合成。preflight 以标记文件 ok=true 为准,Linux 一律后台化启动(首次下载 Chromium 慢网 5~10 分钟)。轮询上限与心跳/卡死换源判定见 work-preparation-linux.md#preflight-后台化与轮询linux。

封面一键生成(内置:页数判定 + 单/多图概率抽样 + 截图 + 合成 + 校验):

$SKILL_DIR/scripts/build-cover.mjs \
  --url "http://127.0.0.1:8080" --project-dir /path/to/project \
  --title "MyWork" --tagline "一句话简介" --description "主体介绍,1~3 句" \
  --out /tmp/cover.png
  • 布局决策在脚本内部闭环(单/多页自动判定 + 布局概率抽样 + 失败页自动跳过,agent 无感知),规则详见 work-preparation.md。
  • stdout 仅输出一行结果:#cover=… layout=… multi=yes|no pages=<n> scheme=… tmp=<截图临时目录>;日志走 stderr。失败 exit 1。
  • 截图临时目录 tmp=<abs> 保留到整体流程结束(供 Step 8 409 改名复用原截图,见下),由 Step 8 发布成功/放弃后统一清理(Remove-Item -Recurse -Force <abs> 或 rm -rf <abs>),build-cover 不删。

⚠️ workName↔封面强依赖: 封面标题即 --title "${workName}"。一旦之后因 409 改名,必须用新 workName 重新合成封面(见 Step 8 改名重推流程),禁止旧封面配新名发布。

输出 coverTmp:从 build-cover stdout 的 tmp= 提取并作为变量贯穿到 Step 8(409 改名时 --screenshot ${coverTmp}/shot-index.png)。

排布规则、视觉基线见 work-preparation.md#screenshot-layout-rules。

Output: coverImage(封面 PNG 绝对路径)。

Step 5: Introduction

读写 README 生成一句话简介。总字符数 15~50,脚本计数通过才继续:

$SKILL_DIR/scripts/count-cjk.mjs --file "$env:TEMP\intro.txt"   # Win 必须 --file(GBK 转码问题)

规则见 work-preparation.md#introduction-generation。

⏩ 并行:预取活动列表供 Step 7——表行 5/7 命令 + --query "pageNo=1&pageSize=100&periodYear=${currentYear}"。

Output: introduction。

Step 6: Work Details

生成详解文章(500–1500 字)配图并打包 zip。

  1. 图表:必选系统架构图;可选 0–2 张(路由/依赖/统计图)。用 DevLens/GitNexus 理解项目后出图。禁用 emoji。
    $SKILL_DIR/scripts/generate_diagram.py --html /path/to/project/diagram.html --out /path/to/project/resources/architecture.png --width 1280
    $SKILL_DIR/scripts/verify-glyphs.py /path/to/project/resources/architecture.png --quiet   # 每张含中文图必跑
    
  2. 打包 zip + 校验一步到位(build-detail-zip.mjs 内置正确目录结构 README.md@根 + resources/,打包后自动跑服务端同源校验,跨平台无需 zip/ZipFile):
    $SKILL_DIR/scripts/build-detail-zip.mjs --readme /path/to/project/README.md --resources /path/to/project/resources --out /tmp/detail.zip
    

Output: detailZip(详情 zip 绝对路径)。

Step 7: Select Activity
  1. 获取活动列表(Step 5 预取则直接用,$SKILL_DIR/scripts/api.mjs GET /v1/gallery/camps 输出 items 数组)。
  2. 依据 startsAt/endsAt/status 判定投稿状态(api-spec.md#submission-status-determination)。
  3. 分「可投稿」/「不可投稿」两表展示,每行按当前列表顺序编号(<n>. <activity name> — <school>(状态)),必须包含 school(学校)列;school 为空时显示 —。用户回序号选择活动(编号对应 items 数组下标序),选不可投稿项提示「未开放投稿」。

Output: trainingCampId。

Step 8: 公開
  1. 作品 ${workName} の公開を開始します と宣言します。
  2. ゲートを再確認:$SKILL_DIR/scripts/check-gates.mjs --cover /tmp/cover.png --detail /tmp/detail.zip --strict --max-age 3600 --quiet(exit 0 の場合のみ続行します。publish-work.mjs に組み込まれた verifyGates() でもブロックされます)。publish-work.mjs はリクエスト送信前に envUrl に到達できるかも検証します(curl -sf --max-time 10)。トンネルに接続できない場合は exit 1 で終了し、ローカルサービスを確認するよう通知します。
  3. パラメーターを UTF-8 JSON に書き込みます。Idempotency-Key=gallery-publish-${domainID}-${timestamp}。パラメーターの key は publish-work.mjs --help を参照してください(値は出力変数に対応します:coverImage←Step 4、detailZip←Step 6、trainingCampId←Step 7、gitUrl/gitBranch←Step 3、envUrl←Step 2)。domainId はパラメーターに含めません(Idempotency-Key の組み立てにのみ使用)。credsFile は JSON に含めません(STS の 3 フィールド accessKeyId/secretAccessKey/securityToken をインラインで指定します):
    $SKILL_DIR/scripts/publish-work.mjs /tmp/params.json --max-age 3600
    # 成功仅输出 workId/workName/workUrl/reward;失败原样输出完整响应
    
  4. 201 → 成功です。workId/workUrl/reward を取得し、一時ファイル(Step 4 の coverTmp スクリーンショットディレクトリを含む)を削除します。ポイントに関する案内(成功・失敗にかかわらず、「1 日 1 回のみ」と必ず案内します):
    • is_success===true:✅ ポイント獲得リクエストを送信しました。⚠️ 1 日 1 回のみです。残高を確認:https://developer.huaweicloud.com/grow
    • is_success===false:ポイントを獲得できませんでした:<error_msg> + 1 日 1 回のみの案内 + 成長センターの URL + フィードバック窓口 https://gallery.developer.huaweicloud.com/gallery/profile?tab=feedback。
  5. 409 DUPLICATE → 現在の公開を停止します。次の選択肢を提示します:① 中止する ② 名前を変更して再送する。名前を変更して再送する場合、以下を必ず連動させます:
    1. 新しい名前 workName'(30 文字未満):ユーザーが指定するか、バージョン表記のない通常の名前に連番を追加します(例:掃雷→掃雷-2)。無関係な文字を任意に付け加えることは禁止です。
    2. カバーを再生成(カバーのタイトルは新しい名前と一致させます):**Step 4 で保持した元のスクリーンショット(${coverTmp}/shot-index.png)**と元の tagline/description を再利用し、--title "<workName'>" のみ変更して build-cover.mjs を再実行します(スクリーンショットの上書き・合成・検証を一括で実行し、終了後に tmp を再処理しません):
      $SKILL_DIR/scripts/build-cover.mjs --url http://127.0.0.1:8080 --project-dir /path/to/project \
        --screenshot ${coverTmp}/shot-index.png --title "NewName" \
        --tagline "原tagline" --description "原description" --out /tmp/cover-new.png
      $SKILL_DIR/scripts/verify-glyphs.py /tmp/cover-new.png --quiet   # exit 0 の場合のみ続行できます
      
      coverTmp がすでに削除されている、または存在しない場合は、--screenshot を付けずに build-cover.mjs を再実行します(スクリーンショットを撮り直します。ローカルサービスが引き続き稼働している必要があります)。
    3. ゲートを再確認(カバーを更新したため、再実行が必要です):$SKILL_DIR/scripts/check-gates.mjs --cover /tmp/cover-new.png --detail /tmp/detail.zip --strict --max-age 3600 --quiet。
    4. 新しい workName' と新しいカバー、新しい Idempotency-Key を使って再公開します(手順 3 に戻ります)。最終的に成功または中止した後、いずれの場合も各 coverTmp を削除します。 注意:詳細 zip は通常、作り直す必要はありません。zip 内の README のタイトルまたは本文に古い作品名(新しい名前と一致しないもの)が記載されている場合に限り、古い名前を新しい名前に変更して、詳細 zip を再パッケージ化する必要があります。
  6. その他のエラー → <msg>(<code>) を通知し、一時ファイルを保持して、修正して再送するかを確認します。エラーコードについては error-codes.md を参照してください。

参考資料

ドキュメント用途読むタイミング
troubleshooting.mdネットワーク/各手順の失敗時のトラブルシューティングスクリプトでエラーが発生した場合→まずここを確認
error-codes.mdプラットフォーム API の全エラーコード一覧API が 2xx 以外を返した場合に確認
api-spec.mdAPI 契約、投稿ステータスの判定Step 7/8 でレスポンスを解析
work-preparation.md名前/カバー/紹介文/詳細/図表の共通ルールStep 3–6 で詳細が必要な場合は目次から該当箇所へ
work-preparation-windows.mdWindows 専用:PowerShell の事前確認/フォント/zipWindows のみ
work-preparation-linux.mdLinux 専用:bash の事前確認/yum/fontconfigLinux のみ
windows-setup.mdWindows の初回準備:エンコーディング/Playwright/zipWindows 環境での初回
self-verify-publish.md自己委任 SELF_VERIFY と STS の仕組みStep 1 で問題が発生した場合
iam-policies.md最小権限 IAM ポリシー(Domain の照会 + SELF_VERIFY の自己委任)Step 1 で AK/SK の権限を設定する場合
devbridge-tunnel.mdDevBridge トンネル:Linux では組み込みの huawei-cloud-devbridge-tunnel skill を使用/Windows では非推奨Step 2 のトンネル(Linux/Windows)
codearts-sandbox.mdCodeArts サンドボックスディレクトリStep 1 でサンドボックスが検出された場合

コメント