From b3593d5f690d062d972cf10234273e685db6f69e Mon Sep 17 00:00:00 2001 From: createitv Date: Tue, 13 Oct 2026 12:00:08 +0800 Subject: [PATCH 1/2] Add task-oriented Agent Skills --- CHANGELOG.md | 1 + README.en.md | 2 +- README.md | 2 +- cmd/agc/command/root.go | 57 ++++++++++++++++++++++++ cmd/agc/command/root_test.go | 40 +++++++++++++++++ docs/AGENT_SKILLS.md | 41 +++++++++++++---- skills/agc-auth/SKILL.md | 51 +++++++++++++++++++++ skills/agc-auth/agents/openai.yaml | 4 ++ skills/agc-cicd/SKILL.md | 42 +++++++++++++++++ skills/agc-cicd/agents/openai.yaml | 4 ++ skills/agc-publishing/SKILL.md | 54 ++++++++++++++++++++++ skills/agc-publishing/agents/openai.yaml | 4 ++ skills/agc-reports/SKILL.md | 39 ++++++++++++++++ skills/agc-reports/agents/openai.yaml | 4 ++ skills/agc-testing/SKILL.md | 42 +++++++++++++++++ skills/agc-testing/agents/openai.yaml | 4 ++ 16 files changed, 380 insertions(+), 11 deletions(-) create mode 100644 skills/agc-auth/SKILL.md create mode 100644 skills/agc-auth/agents/openai.yaml create mode 100644 skills/agc-cicd/SKILL.md create mode 100644 skills/agc-cicd/agents/openai.yaml create mode 100644 skills/agc-publishing/SKILL.md create mode 100644 skills/agc-publishing/agents/openai.yaml create mode 100644 skills/agc-reports/SKILL.md create mode 100644 skills/agc-reports/agents/openai.yaml create mode 100644 skills/agc-testing/SKILL.md create mode 100644 skills/agc-testing/agents/openai.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index e8f698f..b2e816d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ User-visible changes are listed here. Published binaries and versions are availa ### Added +- 按 ASC Skills 的任务分层模式增加鉴权、发布、邀请测试、报表和 CI/CD Skills,并增加 `agc skills list/install` 便捷安装命令。/ Added task-oriented authentication, publishing, testing, reports, and CI/CD Skills following the ASC Skills pattern, plus `agc skills list/install` convenience commands. - 增加 `agc auth whoami`,安全显示当前凭据身份;完成华为 OAuth Client 用户授权后,可通过 `AGC_OAUTH2_TOKEN` 与 `--teams` 查询官方团队账号列表。/ Added `agc auth whoami` for secret-free local identity output and optional official team-account lookup through `AGC_OAUTH2_TOKEN` and `--teams` after Huawei OAuth Client user authorization. ## v0.3.0 — 2026-10-13 diff --git a/README.en.md b/README.en.md index 583a0b5..d3314b5 100644 --- a/README.en.md +++ b/README.en.md @@ -51,7 +51,7 @@ Endpoint definitions include `affordances` command templates and `_links` REST r JSON is the default; add `--output table` or `--output markdown` for people. `agc web-server` exposes a local REST API. Templates require parameters and currently do not check remote business state to determine submission readiness. More in the [agent and REST guide](docs/CLI_USAGE.en.md#json-and-agents). -The repository also ships an installable [`agc-cli-usage` skill](docs/AGENT_SKILLS.md) for Codex, Claude Code, and other agents. It covers command discovery, credential and project selection, dry-run review, authorized execution, and remote-state verification. +The repository also ships installable [task-oriented Agent Skills](docs/AGENT_SKILLS.md) for Codex, Claude Code, and other agents, covering general usage, authentication, publishing, testing, reports, and CI/CD. ## What It Covers diff --git a/README.md b/README.md index a0d6645..509ef7b 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ agc publishing app-info-query --invoke --query appId=YOUR_APP_ID --query lang=zh 默认 JSON;人工浏览可加 `--output table` 或 `--output markdown`。`agc web-server` 提供本地 REST API。命令模板需要补齐参数,当前不会根据远程业务状态判断能否提交。详见 [Agent 与 REST 使用说明](docs/CLI_USAGE.md#json-与-agent-支持)。 -仓库还提供可供 Codex、Claude Code 等 Agent 安装的 [`agc-cli-usage` Skill](docs/AGENT_SKILLS.md),涵盖命令发现、凭据与项目选择、dry-run 预览、授权执行和远程结果验证。 +仓库还提供可供 Codex、Claude Code 等 Agent 安装的[任务型 Agent Skills](docs/AGENT_SKILLS.md),涵盖通用使用、鉴权、发布、邀请测试、报表和 CI/CD。 ## 功能覆盖 diff --git a/cmd/agc/command/root.go b/cmd/agc/command/root.go index eba0f13..38b3b36 100644 --- a/cmd/agc/command/root.go +++ b/cmd/agc/command/root.go @@ -4,9 +4,11 @@ import ( "context" "encoding/json" "fmt" + "io" "net" "net/http" "os" + "os/exec" "strings" "time" @@ -68,12 +70,67 @@ func NewRootCommand() *cobra.Command { cmd.AddCommand(initCommand(opts)) cmd.AddCommand(webServerCommand()) cmd.AddCommand(docsCommand(opts)) + cmd.AddCommand(skillsCommand()) for _, capability := range domain.DecoratedCapabilities() { cmd.AddCommand(moduleCommand(opts, capability)) } return cmd } +var runSkillsCLI = func(ctx context.Context, stdout, stderr io.Writer, args ...string) error { + command := exec.CommandContext(ctx, "npx", args...) + command.Stdout = stdout + command.Stderr = stderr + command.Stdin = os.Stdin + if err := command.Run(); err != nil { + if execError, ok := err.(*exec.Error); ok && execError.Err == exec.ErrNotFound { + return fmt.Errorf("npx is required to manage Agent Skills; install Node.js and try again") + } + return fmt.Errorf("run Agent Skills installer: %w", err) + } + return nil +} + +func skillsCommand() *cobra.Command { + const repository = "Createitv/agc-cli" + cmd := &cobra.Command{ + Use: "skills", + Short: "Browse and install agc-cli Agent Skills", + } + list := &cobra.Command{ + Use: "list", + Short: "List Agent Skills published by agc-cli", + RunE: func(cmd *cobra.Command, args []string) error { + return runSkillsCLI(cmd.Context(), cmd.OutOrStdout(), cmd.ErrOrStderr(), "--yes", "skills", "add", repository, "--list") + }, + } + var name string + var agent string + var global bool + install := &cobra.Command{ + Use: "install", + Short: "Install one or all agc-cli Agent Skills", + RunE: func(cmd *cobra.Command, args []string) error { + installerArgs := []string{"--yes", "skills", "add", repository} + if name != "" { + installerArgs = append(installerArgs, "--skill", name) + } + if agent != "" { + installerArgs = append(installerArgs, "--agent", agent) + } + if global { + installerArgs = append(installerArgs, "--global") + } + return runSkillsCLI(cmd.Context(), cmd.OutOrStdout(), cmd.ErrOrStderr(), installerArgs...) + }, + } + install.Flags().StringVar(&name, "name", "", "Install only the named skill; omit to install all skills") + install.Flags().StringVar(&agent, "agent", "", "Target agent supported by the skills installer, for example codex or claude-code") + install.Flags().BoolVar(&global, "global", false, "Install into the selected agent's global skill directory") + cmd.AddCommand(list, install) + return cmd +} + func versionCommand(opts *options) *cobra.Command { return &cobra.Command{ Use: "version", diff --git a/cmd/agc/command/root_test.go b/cmd/agc/command/root_test.go index 566eba2..c342ac0 100644 --- a/cmd/agc/command/root_test.go +++ b/cmd/agc/command/root_test.go @@ -8,6 +8,7 @@ import ( "crypto/x509" "encoding/json" "encoding/pem" + "io" "net/http" "net/http/httptest" "os" @@ -117,6 +118,45 @@ func TestVersionCommand(t *testing.T) { } } +func TestSkillsListDelegatesToSkillsInstaller(t *testing.T) { + original := runSkillsCLI + t.Cleanup(func() { runSkillsCLI = original }) + var got []string + runSkillsCLI = func(_ context.Context, stdout, _ io.Writer, args ...string) error { + got = append([]string(nil), args...) + _, _ = io.WriteString(stdout, "agc-cli-usage\n") + return nil + } + out, err := execute("skills", "list") + if err != nil { + t.Fatal(err) + } + if strings.Join(got, " ") != "--yes skills add Createitv/agc-cli --list" { + t.Fatalf("installer args = %q", got) + } + if out != "agc-cli-usage\n" { + t.Fatalf("output = %q", out) + } +} + +func TestSkillsInstallSelectsSkillAgentAndScope(t *testing.T) { + original := runSkillsCLI + t.Cleanup(func() { runSkillsCLI = original }) + var got []string + runSkillsCLI = func(_ context.Context, _, _ io.Writer, args ...string) error { + got = append([]string(nil), args...) + return nil + } + _, err := execute("skills", "install", "--name", "agc-auth", "--agent", "codex", "--global") + if err != nil { + t.Fatal(err) + } + want := "--yes skills add Createitv/agc-cli --skill agc-auth --agent codex --global" + if strings.Join(got, " ") != want { + t.Fatalf("installer args = %q, want %q", got, want) + } +} + func TestEveryRegisteredCommandHasHelp(t *testing.T) { root := NewRootCommand() for _, cmd := range root.Commands() { diff --git a/docs/AGENT_SKILLS.md b/docs/AGENT_SKILLS.md index ad87cd5..2276a8e 100644 --- a/docs/AGENT_SKILLS.md +++ b/docs/AGENT_SKILLS.md @@ -1,8 +1,17 @@ -# Agent Skill / Agent 技能 +# Agent Skills / Agent 技能 -仓库提供可移植的 [`agc-cli-usage`](../skills/agc-cli-usage/SKILL.md) Agent Skill,帮助 Codex、Claude Code 及其他支持 `SKILL.md` 的 Agent 安全地发现命令、选择凭据与项目、预览请求、执行已授权的 AppGallery Connect 操作并验证远程结果。 +仓库按照 ASC Skills 的任务分层模式提供一组可移植 Agent Skills,帮助 Codex、Claude Code 及其他支持 `SKILL.md` 的 Agent 使用 agc-cli。 -This repository ships the portable [`agc-cli-usage`](../skills/agc-cli-usage/SKILL.md) skill for Codex, Claude Code, and other agents that support `SKILL.md`. It teaches command discovery, credential and project selection, dry-run review, authorized AppGallery Connect invocation, and remote-state verification. +This repository follows the task-oriented ASC Skills pattern and ships a portable collection for Codex, Claude Code, and other agents that support `SKILL.md`. + +| Skill | 用途 / Purpose | +| --- | --- | +| [`agc-cli-usage`](../skills/agc-cli-usage/SKILL.md) | 通用命令发现、dry-run、授权执行和验证 / General discovery, dry-run, authorized execution, and verification | +| [`agc-auth`](../skills/agc-auth/SKILL.md) | 凭据、profile、`whoami` 和授权诊断 / Credentials, profiles, `whoami`, and authorization diagnosis | +| [`agc-publishing`](../skills/agc-publishing/SKILL.md) | 应用资料、软件包、审核提交和发布状态 / Metadata, packages, review submission, and release state | +| [`agc-testing`](../skills/agc-testing/SKILL.md) | 测试版本、群组、用户、邀请码和反馈 / Test releases, groups, users, invitation codes, and feedback | +| [`agc-reports`](../skills/agc-reports/SKILL.md) | 分发、付费、留存和元服务报表 / Distribution, revenue, retention, and HarmonyOS service reports | +| [`agc-cicd`](../skills/agc-cicd/SKILL.md) | 跨平台无人值守安装与发布流水线 / Cross-platform unattended installation and release pipelines | ## 安装 / Install @@ -13,22 +22,36 @@ npm install --global @createitv/agc-cli agc version ``` -通过 Agent Skills 安装器全局安装仓库中的技能: +通过 agc-cli 浏览并安装全部技能: + +```bash +agc skills list +agc skills install --agent codex --global +``` + +也可以只安装一个技能: + +```bash +agc skills install --name agc-publishing --agent codex --global +``` + +CLI delegates installation to the open Agent Skills installer, so Node.js and `npx` must be available. The equivalent direct commands are: ```bash npx --yes skills add Createitv/agc-cli --global --agent codex +npx --yes skills add Createitv/agc-cli --skill agc-publishing --global --agent codex ``` -不使用安装器时,可以将 `skills/agc-cli-usage` 目录复制到 Agent 的技能目录,例如 Codex 的 `~/.codex/skills/` 或 Claude Code 的 `~/.claude/skills/`。保留整个目录,以便 `agents/openai.yaml` 等客户端元数据随技能一起安装。 +不使用安装器时,可以把所需的完整 Skill 目录复制到 Agent 的技能目录,例如 Codex 的 `~/.codex/skills/` 或 Claude Code 的 `~/.claude/skills/`。保留整个目录,以便 `agents/openai.yaml` 等客户端元数据随技能一起安装。 -Without the installer, copy the complete `skills/agc-cli-usage` directory into the agent's skill directory, such as `~/.codex/skills/` for Codex or `~/.claude/skills/` for Claude Code. +Without the installer, copy each complete skill directory into the agent's skill directory. ## 使用 / Use Codex 中可显式调用: ```text -Use $agc-cli-usage to inspect the publishing operation, preview the request, and execute only the authorized change. +Use $agc-publishing to inspect the app release, preview the request, and execute only the authorized change. ``` 支持自动发现的 Agent 也可以根据 `SKILL.md` 的 description 自动选择该技能。技能不会扩大用户授权:查看、预览、提交、删除、发布和审核状态仍是不同操作。 @@ -37,6 +60,6 @@ Agents that support automatic discovery can select the skill from its descriptio ## 设计原则 / Design -本技能对标 ASC Skills 的分层方式:入口技能只保存会改变 Agent 决策的稳定规则,具体命令优先从当前二进制的 `--help`、endpoint definition、`sourceUrl` 和 OpenAPI 动态发现。随着高频工作流成熟,可以再增加独立技能,例如发布编排、元数据同步或审核诊断,而不是让一个技能变成完整手册。 +这些技能对标 `tddworks/asc-cli-skills` 的分层方式:通用入口保持精简,高频工作流按任务拆分;具体命令优先从当前二进制的 `--help`、endpoint definition、`sourceUrl` 和 OpenAPI 动态发现。技能内容不会扩大用户对远程写入、提交、删除或发布的授权。 -The skill follows the layered ASC Skills pattern: the entry skill keeps stable decision rules, while exact commands are discovered from the installed binary's `--help`, endpoint definitions, `sourceUrl`, and OpenAPI contract. Mature workflows can later become separate release, metadata, or review-diagnosis skills instead of turning one skill into a copied manual. +The collection follows the layered `tddworks/asc-cli-skills` pattern: a small general entry skill plus task-specific workflow skills. Exact commands come from the installed binary's `--help`, endpoint definitions, `sourceUrl`, and OpenAPI contract. A skill never expands authorization for remote writes, submission, deletion, or publication. diff --git a/skills/agc-auth/SKILL.md b/skills/agc-auth/SKILL.md new file mode 100644 index 0000000..371b277 --- /dev/null +++ b/skills/agc-auth/SKILL.md @@ -0,0 +1,51 @@ +--- +name: agc-auth +description: Authenticate agc-cli, manage credential profiles, identify the active Huawei AppGallery Connect account, and diagnose authorization failures. Use for login, profile switching, auth checks, whoami, OAuth team lookup, or CI credential setup. +--- + +# agc auth + +Use `agc auth` for local credential profiles and identity inspection. Never ask for or expose client keys, service-account private keys, access tokens, credential files, or raw authentication responses. + +## Inspect before changing credentials + +```bash +agc auth list --output table +agc auth check +agc auth whoami --pretty +agc --profile production auth check +``` + +`auth check` validates local configuration unless `--remote` is explicitly supplied. `auth whoami` reports the selected profile, non-secret client or service-account identity, and project context. It does not invent a personal developer name from credentials that do not contain one. + +With a user-authorized Huawei OAuth token, query official team accounts without saving the token: + +```bash +AGC_OAUTH2_TOKEN="$AGC_OAUTH2_TOKEN" agc auth whoami --teams --pretty +``` + +Treat the token as a secret. Do not echo it, put it in command examples with a literal value, persist it in project files, or include it in logs. + +## Login and profile selection + +Inspect the installed command first: + +```bash +agc auth login --help +``` + +Then use a credential file or protected environment values already available on the machine: + +```bash +agc auth login --service-account-file /protected/agc-service-account.json --name production +agc auth login --api-client-file /protected/agc-api-client.json --name staging +agc auth login --client-id "$AGC_CLIENT_ID" --client-key "$AGC_CLIENT_KEY" --name ci +``` + +Use `--profile NAME` on unattended commands. Project context may provide a default profile, but an explicit profile is easier to audit in multi-environment CI. + +## Remote checks + +`agc auth check --remote` contacts Huawei and may perform an app or project read. Run it only when the user has authorized the remote check and the intended profile/project is explicit. Token creation is not proof that the profile can access a particular app. + +For 401/403 failures, report the selected profile and redacted command, then check credential mode, project/app ownership, required Huawei roles, and endpoint-specific headers. Never include secrets in the report. diff --git a/skills/agc-auth/agents/openai.yaml b/skills/agc-auth/agents/openai.yaml new file mode 100644 index 0000000..56b70c9 --- /dev/null +++ b/skills/agc-auth/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "AGC Authentication" + short_description: "Authenticate and inspect agc-cli profiles safely" + default_prompt: "Use $agc-auth to inspect the selected agc-cli identity and configure or diagnose authentication without exposing secrets." diff --git a/skills/agc-cicd/SKILL.md b/skills/agc-cicd/SKILL.md new file mode 100644 index 0000000..deed5d3 --- /dev/null +++ b/skills/agc-cicd/SKILL.md @@ -0,0 +1,42 @@ +--- +name: agc-cicd +description: Build unattended multi-platform CI/CD workflows around agc-cli. Use for Windows, macOS, or Linux installation, protected credential setup, dry-run gates, HarmonyOS Hvigor builds, release automation, and post-action verification. +--- + +# agc-cli CI/CD + +Install the pinned version needed by the pipeline and verify it before work: + +```bash +npm install --global @createitv/agc-cli@VERSION +agc version +``` + +Use an explicit profile and project directory in unattended jobs. Supply credentials through the CI provider's protected secret/file mechanism; never write secrets into the repository, workflow output, cache keys, or artifacts. + +## Pipeline shape + +1. Install and verify the pinned CLI version. +2. Materialize protected credentials with the narrowest permissions and delete ephemeral files in the runner cleanup phase. +3. Run `agc auth check` locally; use `--remote` only when an authorized live check is intended. +4. Resolve app/project/profile explicitly. +5. Discover the operation contract from the installed CLI. +6. Produce and retain a redacted dry-run artifact for review or policy gates. +7. Execute only approved live operations with `--dry-run=false`. +8. Query the remote state until the required terminal state, and preserve redacted evidence. + +For HarmonyOS local builds, inspect the current local CI/CD operation first: + +```bash +agc cicd endpoints --output table +agc cicd build-hvigor --pretty +``` + +## Reliability rules + +- Pin stable versions; do not let production jobs float on an unverified latest release. +- Keep Windows, macOS, and Linux path/quoting differences inside shell-specific steps. +- Use JSON output for automation and parse it structurally. +- Do not treat a queued job, successful build, accepted upload, review submission, approval, and public availability as the same state. +- Do not blindly retry mutations after timeouts. Query remote state and make retries idempotent where Huawei provides a stable identifier. +- Make test resources and production resources distinct. A smoke test must not publish an app or alter an existing production resource. diff --git a/skills/agc-cicd/agents/openai.yaml b/skills/agc-cicd/agents/openai.yaml new file mode 100644 index 0000000..c765e83 --- /dev/null +++ b/skills/agc-cicd/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "AGC CI/CD" + short_description: "Automate agc-cli across CI runners" + default_prompt: "Use $agc-cicd to design or operate a pinned, secret-safe agc-cli pipeline with dry-run gates and verified remote outcomes." diff --git a/skills/agc-publishing/SKILL.md b/skills/agc-publishing/SKILL.md new file mode 100644 index 0000000..dea17f8 --- /dev/null +++ b/skills/agc-publishing/SKILL.md @@ -0,0 +1,54 @@ +--- +name: agc-publishing +description: Manage AppGallery Connect application metadata, packages, staged rollout, and review submission with agc-cli. Use when preparing, previewing, submitting, or checking a Huawei or HarmonyOS app release. +--- + +# AppGallery Connect publishing + +Use the installed endpoint registry as the source of truth: + +```bash +agc publishing endpoints --output table +agc publishing --pretty +agc publishing --help +``` + +An operation without `--invoke` shows its contract. `--invoke` still defaults to dry-run. Inspect the returned method, URL, parameters, `sourceUrl`, and affordances before sending anything. + +## Release workflow + +1. Resolve the exact profile, app, project, package name, language, and release type. +2. Query current app/version state with the matching read endpoint. +3. Prepare metadata and package inputs outside the command when required. +4. Preview every request with `--invoke`; keep the default dry-run. +5. Add `--dry-run=false` only for the operation the user authorized. +6. Read back the app/version state and continue polling when processing or review is asynchronous. + +Example preview: + +```bash +agc --profile production publishing app-info-query \ + --invoke --query appId="APP_ID" --query lang="zh-CN" --pretty +``` + +For structured payloads, prefer a reviewed JSON file: + +```bash +agc --profile production publishing app-info-update \ + --invoke --body app-info.json --pretty +``` + +Only after authorization and a matching preview: + +```bash +agc --profile production publishing app-info-update \ + --invoke --body app-info.json --dry-run=false --pretty +``` + +## Important boundaries + +- Package upload may require Huawei's external upload protocol or a reachable download URL; `--body` is not a binary uploader. +- Updating metadata, associating a package, submitting review, approval, staged rollout, and public availability are separate states. +- A successful HTTP response does not prove approval or publication. +- Do not automatically retry a submission or other mutation after a timeout or ambiguous response. Query the remote state first. +- Deletion, submission, rollout changes, and publication each require their own user authorization. diff --git a/skills/agc-publishing/agents/openai.yaml b/skills/agc-publishing/agents/openai.yaml new file mode 100644 index 0000000..c9edae3 --- /dev/null +++ b/skills/agc-publishing/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "AGC Publishing" + short_description: "Prepare and verify AppGallery Connect releases" + default_prompt: "Use $agc-publishing to inspect the app release state, preview the required agc commands, and execute only the authorized publishing operation." diff --git a/skills/agc-reports/SKILL.md b/skills/agc-reports/SKILL.md new file mode 100644 index 0000000..4144c45 --- /dev/null +++ b/skills/agc-reports/SKILL.md @@ -0,0 +1,39 @@ +--- +name: agc-reports +description: Discover and download AppGallery Connect distribution, revenue, install, retention, and HarmonyOS service reports with agc-cli. Use when a user asks for AGC analytics exports, report URLs, or repeatable report collection in CI. +--- + +# AppGallery Connect reports + +Report endpoints differ in app ID placement, date range, file type, and returned data. Always inspect the current operation: + +```bash +agc reports endpoints --output table +agc reports --pretty +agc reports --help +``` + +Available exports may cover downloads, install failures, new and retained users, paid downloads, IAP, reservations, coupon or award activity, and HarmonyOS service distribution, users, or widgets. + +## Download workflow + +1. Select an explicit profile and app/project. +2. Inspect the endpoint contract and official Huawei `sourceUrl` for supported date and format values. +3. Preview the request with `--invoke`. +4. Send the authorized read request with `--dry-run=false`. +5. Distinguish an API response, a returned download URL, and a downloaded report file. +6. Save raw bytes with `--out FILE` only when the file is an intended local artifact. + +Example shape: + +```bash +agc --profile reporting reports appdownloadexport \ + --invoke --param appId="APP_ID" --query startTime="START" \ + --query endTime="END" --pretty +``` + +Read the installed operation definition before relying on example parameter names. + +## Data handling + +Reports may contain business-sensitive metrics or user-related information. Do not paste raw reports into issues, commits, or public logs. Report the requested aggregation and source period, and state whether the result is an API response, a generated link, or an actually downloaded and parsed file. diff --git a/skills/agc-reports/agents/openai.yaml b/skills/agc-reports/agents/openai.yaml new file mode 100644 index 0000000..12d05bd --- /dev/null +++ b/skills/agc-reports/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "AGC Reports" + short_description: "Collect AppGallery Connect reports safely" + default_prompt: "Use $agc-reports to discover the correct report endpoint, preview its request, and retrieve only the authorized report data." diff --git a/skills/agc-testing/SKILL.md b/skills/agc-testing/SKILL.md new file mode 100644 index 0000000..df63cf2 --- /dev/null +++ b/skills/agc-testing/SKILL.md @@ -0,0 +1,42 @@ +--- +name: agc-testing +description: Manage AppGallery Connect open, internal, and invitation testing with agc-cli. Use for HarmonyOS test versions, test groups, testers, invitation codes, public links, feedback, self-test reports, and promoting or stopping a test release. +--- + +# AppGallery Connect testing + +Discover the exact installed testing operations before constructing a workflow: + +```bash +agc testing endpoints --output table +agc testing --pretty +agc testing --help +``` + +Common operation families include test-version creation and submission, test groups and users, invitation codes, public links, tester feedback, detection reports, notifications, stopping a test, and promoting an effective test version. + +## Safe workflow + +1. Query the existing test versions or groups and identify the exact IDs. +2. Display the selected operation contract and Huawei `sourceUrl`. +3. Preview with `--invoke` and required `--param`, `--query`, `--header`, or `--body` inputs. +4. Verify group type, target users, validity window, download limits, and package/version IDs. +5. Send with `--dry-run=false` only after the specific mutation is authorized. +6. Query the resulting version, group, users, link, feedback, or report state. + +Example shape: + +```bash +agc --profile staging testing test-api-get-test-grouplist \ + --invoke --query appId="APP_ID" --pretty +``` + +Use the operation definition rather than copying this example when the installed contract differs. + +## Boundaries + +- Creating a test version is not the same as uploading its package or submitting it for review. +- Sending tester notifications communicates with third parties; require explicit authorization and verify recipients first. +- Invitation codes and public links can grant access. Do not expose them in public logs or issues. +- Stopping, deleting, or promoting a test version changes live distribution and must not be inferred from a request to inspect it. +- A submitted test version is not necessarily approved, effective, or installable. Poll and report each state separately. diff --git a/skills/agc-testing/agents/openai.yaml b/skills/agc-testing/agents/openai.yaml new file mode 100644 index 0000000..677c631 --- /dev/null +++ b/skills/agc-testing/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "AGC Testing" + short_description: "Operate HarmonyOS testing and tester workflows" + default_prompt: "Use $agc-testing to inspect the current AppGallery Connect test state, preview the command, and perform only the authorized tester or test-release operation." From 68ab0b05acc343ca9280bf06db116587980ce319 Mon Sep 17 00:00:00 2001 From: createitv Date: Tue, 13 Oct 2026 12:02:10 +0800 Subject: [PATCH 2/2] Add Agent Skills to website --- apps/web/src/App.test.tsx | 9 ++++ apps/web/src/App.tsx | 94 ++++++++++++++++++++++++++++++++++++- apps/web/src/siteContent.ts | 2 + apps/web/src/styles.css | 48 +++++++++++++++++++ 4 files changed, 151 insertions(+), 2 deletions(-) diff --git a/apps/web/src/App.test.tsx b/apps/web/src/App.test.tsx index 6295de3..1145f2c 100644 --- a/apps/web/src/App.test.tsx +++ b/apps/web/src/App.test.tsx @@ -54,6 +54,15 @@ describe('App', () => { expect(screen.getByText(/without lifecycle install scripts/i)).toBeInTheDocument(); }); + it('lists downloadable Agent Skills and copyable install commands', () => { + render(); + expect(screen.getByText('Give your coding agent a map of AppGallery Connect.')).toBeInTheDocument(); + expect(screen.getByText('agc-publishing')).toBeInTheDocument(); + expect(screen.getAllByText(/agc skills install --name/)).toHaveLength(6); + expect(screen.getAllByRole('link', { name: 'Download SKILL.md' })).toHaveLength(6); + expect(screen.getByRole('link', { name: /Contribute a Skill/ })).toHaveAttribute('href', 'https://github.com/Createitv/agc-cli/blob/main/CONTRIBUTING.md'); + }); + it('shows the complete selected family without a local API server', async () => { vi.stubGlobal('fetch', vi.fn().mockRejectedValue(new Error('offline'))); render(); diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 0fa443d..0acac41 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -1,5 +1,6 @@ import { ArrowRight, + Bot, Check, ChevronDown, ChevronRight, @@ -13,6 +14,7 @@ import { KeyRound, Layers3, PackageCheck, + Download, Rocket, ShieldCheck, Terminal, @@ -45,6 +47,12 @@ const installCommands: Record = { windows: 'if (!(Get-Command scoop -ErrorAction SilentlyContinue)) { Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force; irm get.scoop.sh | iex }; scoop bucket add createitv https://github.com/Createitv/scoop-bucket; scoop install agc-cli; agc version', }; +const agentSkills = ['agc-cli-usage', 'agc-auth', 'agc-publishing', 'agc-testing', 'agc-reports', 'agc-cicd'] as const; +const installAllSkillsCommand = 'agc skills install --agent codex --global'; +const installSkillCommand = (skill: string) => `agc skills install --name ${skill} --agent codex --global`; +const skillSourceURL = (skill: string) => `https://github.com/Createitv/agc-cli/tree/main/skills/${skill}`; +const skillDownloadURL = (skill: string) => `https://raw.githubusercontent.com/Createitv/agc-cli/main/skills/${skill}/SKILL.md`; + const fallbackCapabilities: Capability[] = [ { id: 'publishing', name: 'Publishing API', description: 'Release metadata, package state, submissions, review withdrawal, and release timing.', command: 'agc publishing', restPath: '/api/v1/publishing', status: 'registered', endpointCount: 14 }, { id: 'upload', name: 'Upload Management', description: 'APP packages, icons, screenshots, videos, PDFs, and multipart binary uploads.', command: 'agc upload', restPath: '/api/v1/upload', status: 'registered', endpointCount: 6 }, @@ -83,7 +91,7 @@ const capabilityTranslations: Record
{text.nav.installGuide} + {text.nav.skills} {text.nav.workflow} {text.nav.profiles} {text.nav.registry} @@ -566,6 +613,49 @@ export function App({ renderLanguage, renderFamily }: { renderLanguage?: Languag
+
+
+
+

{text.skills.eyebrow}

+

{text.skills.title}

+
+
+

{text.skills.body}

+ + {text.skills.contribute} + +
+
+
+ {text.skills.installAll} + $ {installAllSkillsCommand} + +
+
+ {agentSkills.map((skill) => { + const command = installSkillCommand(skill); + return ( +
+
{skill}
+

{text.skills.descriptions[skill]}

+
+ {command} + +
+ +
+ ); + })} +
+
+

{text.workflow.eyebrow}

diff --git a/apps/web/src/siteContent.ts b/apps/web/src/siteContent.ts index 27cd8b6..a670348 100644 --- a/apps/web/src/siteContent.ts +++ b/apps/web/src/siteContent.ts @@ -16,6 +16,7 @@ export const content = { { q: '156 个接口是否都完成了生产验证?', a: '156 表示注册表中的接口条目数量,分属 13 个 API 家族,不代表每个接口都已完成生产验证。注册表展示已登记参数和调用入口;完整请求、响应、权限与业务前置条件以每个接口链接的参考文档为准。' }, { q: '默认 dry-run 会修改我的应用吗?', a: '不会。带 --invoke 的接口命令默认构建并预览请求,不发送远程请求。真实调用需显式设置 --dry-run=false;调用前应检查目标应用、所选凭据和参数。' }, { q: '可以把 agc-cli 用在脚本或 AI Agent 中吗?', a: '可以。默认 JSON 输出适合脚本处理,agc capabilities 和 agc endpoints 提供能力发现;agc web-server 提供本地 REST 接口,agc openapi 导出接口契约。命令模板帮助导航,但不能替代业务状态检查或审核判断。' }, + { q: '如何安装 agc-cli 的 Codex 或 Claude Agent Skills?', a: '先安装 agc-cli,再运行 agc skills list 查看 6 个任务型 Skills。使用 agc skills install --agent codex --global 安装全部 Skills,或增加 --name agc-publishing 只安装发布 Skill。也可以从官网直接下载对应的 SKILL.md。' }, { q: '项目 Profile 会自动填入所有接口参数吗?', a: '项目配置可以绑定默认凭据 Profile,临时切换时使用 --profile。应用 ID、语言、请求头和请求体等接口参数仍需按接口要求显式提供。不要将 Service Account 私钥或凭据文件提交到 Git。' }, ], }, @@ -33,6 +34,7 @@ export const content = { { q: 'Are all 156 endpoints production-verified?', a: 'No. The registry contains 156 entries across 13 API families; this is registry coverage, not production verification of every endpoint. Registered parameters and command surfaces are shown here. Consult each endpoint reference for full request and response schemas, permissions, and business prerequisites.' }, { q: 'Does the default dry run change my app?', a: 'No. Endpoint commands with --invoke preview the request without sending it by default. Real invocation requires --dry-run=false. Check the target app, credential profile, and parameters before executing.' }, { q: 'Can I use agc-cli with scripts or AI agents?', a: 'Yes. JSON output supports script processing. agc capabilities and agc endpoints expose discovery; agc web-server provides local REST routes, and agc openapi exports the contract. Command templates support navigation but do not replace business-state checks or review decisions.' }, + { q: 'How do I install the agc-cli Skills for Codex or Claude?', a: 'Install agc-cli, then run agc skills list to browse the six task-oriented Skills. Run agc skills install --agent codex --global for all Skills, or add --name agc-publishing for only the publishing Skill. Individual SKILL.md files are also downloadable from the website.' }, { q: 'Does a project profile fill all endpoint parameters automatically?', a: 'A project configuration can select its default credential profile, with --profile for explicit overrides. App IDs, languages, headers, and request bodies still need to be supplied according to each endpoint. Keep Service Account private keys and credential files out of Git.' }, ], }, diff --git a/apps/web/src/styles.css b/apps/web/src/styles.css index 8ab39ab..65a6658 100644 --- a/apps/web/src/styles.css +++ b/apps/web/src/styles.css @@ -349,6 +349,49 @@ main { min-height: 100vh; overflow: hidden; } background: rgba(126, 226, 168, 0.055); } +.skillsSection { padding-top: 92px; padding-bottom: 132px; border-top: 1px solid var(--line); } +.skillsIntro { max-width: none; display: grid; grid-template-columns: 1.05fr 0.75fr; gap: 72px; align-items: end; } +.skillsIntro h2 { max-width: 760px; } +.skillsIntroCopy > p { margin: 0; color: var(--muted); font-size: 15px; line-height: 1.75; } +.skillsIntroCopy > a { margin-top: 18px; display: inline-flex; align-items: center; gap: 7px; color: var(--red); font-family: var(--mono); font-size: 10px; font-weight: 600; } +.skillsInstallAll { + min-height: 78px; + margin-top: 48px; + padding: 16px 18px; + display: grid; + grid-template-columns: auto minmax(0, 1fr) 38px; + align-items: center; + gap: 18px; + border: 1px solid rgba(240, 68, 68, 0.34); + border-radius: 10px; + background: linear-gradient(100deg, rgba(240, 68, 68, 0.12), #111114 48%, #0d0d0f); +} +.skillsInstallAll > span { display: inline-flex; align-items: center; gap: 9px; color: var(--paper); font-size: 12px; font-weight: 700; } +.skillsInstallAll > span svg { color: var(--red); } +.skillsInstallAll > code { color: #d5d0cd; font-size: 11px; overflow-wrap: anywhere; } +.skillsInstallAll > code span { color: var(--red); margin-right: 7px; } +.skillsInstallAll > button, .skillCommand button { + width: 36px; + height: 36px; + display: grid; + place-items: center; + color: var(--muted); + border: 1px solid var(--line-strong); + border-radius: 7px; + background: #0a0a0c; + cursor: pointer; +} +.skillsGrid { margin-top: 18px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; } +.skillCard { min-width: 0; padding: 22px; display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 10px; background: linear-gradient(155deg, #111114, #0d0d0f); } +.skillCardHeader { display: flex; align-items: center; gap: 9px; color: var(--red); } +.skillCardHeader code { color: var(--paper); font-size: 12px; font-weight: 600; } +.skillCard > p { min-height: 66px; margin: 18px 0; color: var(--muted); font-size: 12px; line-height: 1.7; } +.skillCommand { min-height: 64px; padding: 12px; display: grid; grid-template-columns: minmax(0, 1fr) 36px; align-items: center; gap: 10px; border: 1px solid var(--line); border-radius: 8px; background: #09090b; } +.skillCommand code { color: #c9c5c2; font-size: 9px; line-height: 1.55; overflow-wrap: anywhere; } +.skillLinks { margin-top: 17px; padding-top: 15px; display: flex; align-items: center; justify-content: space-between; gap: 12px; border-top: 1px solid var(--line); } +.skillLinks a { display: inline-flex; align-items: center; gap: 6px; color: var(--quiet); font-family: var(--mono); font-size: 9px; } +.skillLinks a:hover { color: var(--paper); } + .workflowSection { padding-bottom: 152px; } .workflowGrid { margin-top: 64px; display: grid; grid-template-columns: repeat(4, 1fr); border: 1px solid var(--line); } .workflowCard { min-height: 280px; padding: 27px; position: relative; border-right: 1px solid var(--line); background: linear-gradient(155deg, #111114, #0d0d0f); overflow: hidden; } @@ -627,6 +670,7 @@ footer { max-width: var(--max); min-height: 160px; margin: 0 auto; padding: 38px .profileSection, .consoleSection { grid-template-columns: 1fr; } .profileConfig { max-width: 720px; } .installGuideGrid { grid-template-columns: 1fr; } + .skillsGrid { grid-template-columns: repeat(2, 1fr); } .quickStep { grid-template-columns: 50px 1fr; } .quickStep .commandBox { grid-column: 2; } } @@ -701,3 +745,7 @@ footer { max-width: var(--max); min-height: 160px; margin: 0 auto; padding: 38px } :focus-visible { outline: 2px solid var(--red); outline-offset: 3px; } + .skillsIntro { grid-template-columns: 1fr; gap: 24px; } + .skillsInstallAll { grid-template-columns: 1fr 38px; } + .skillsInstallAll > span { grid-column: 1 / -1; } + .skillsGrid { grid-template-columns: 1fr; }