Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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。

## 功能覆盖

Expand Down
9 changes: 9 additions & 0 deletions apps/web/src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(<App />);
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(<App />);
Expand Down
94 changes: 92 additions & 2 deletions apps/web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
ArrowRight,
Bot,
Check,
ChevronDown,
ChevronRight,
Expand All @@ -13,6 +14,7 @@ import {
KeyRound,
Layers3,
PackageCheck,
Download,
Rocket,
ShieldCheck,
Terminal,
Expand Down Expand Up @@ -45,6 +47,12 @@ const installCommands: Record<InstallPlatform, string> = {
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 },
Expand Down Expand Up @@ -83,7 +91,7 @@ const capabilityTranslations: Record<Language, Record<string, { name: string; de
const translations = {
en: {
documentTitle: 'agc CLI — AppGallery Connect from one command surface',
nav: { installGuide: 'Install', workflow: 'Workflow', profiles: 'Profiles', registry: 'API registry', quickstart: 'Quick start', language: 'Language', install: 'Install' },
nav: { installGuide: 'Install', skills: 'Agent Skills', workflow: 'Workflow', profiles: 'Profiles', registry: 'API registry', quickstart: 'Quick start', language: 'Language', install: 'Install' },
hero: {
kicker: 'AppGallery Connect, mapped for the terminal',
titleLead: 'Move every release through',
Expand Down Expand Up @@ -159,6 +167,25 @@ const translations = {
copyWindows: 'Copy Windows install command',
requirements: ['NPM: Node.js 18+', 'No postinstall download', 'Five checksum-verified platform binaries'],
},
skills: {
eyebrow: 'Agent Skills',
title: 'Give your coding agent a map of AppGallery Connect.',
body: 'Six portable Skills follow the task-oriented asc-cli pattern. Install all of them, choose one workflow, inspect the source, or contribute improvements through GitHub.',
installAll: 'Install all six for Codex',
copyAll: 'Copy install-all command',
installOne: 'Install this Skill',
download: 'Download SKILL.md',
source: 'View source',
contribute: 'Contribute a Skill',
descriptions: {
'agc-cli-usage': 'General command discovery, dry-run review, authorized execution, and remote verification.',
'agc-auth': 'Credential profiles, whoami, OAuth team lookup, and authorization diagnosis.',
'agc-publishing': 'Metadata, packages, review submission, staged rollout, and release-state verification.',
'agc-testing': 'Test versions, groups, testers, invitation links, feedback, and promotion.',
'agc-reports': 'Distribution, install, revenue, retention, and HarmonyOS service report exports.',
'agc-cicd': 'Pinned cross-platform installation, protected credentials, dry-run gates, and CI verification.',
},
},
console: {
eyebrow: 'Local command center',
title: 'The browser is a window into the same registry.',
Expand Down Expand Up @@ -186,7 +213,7 @@ const translations = {
},
zh: {
documentTitle: 'agc CLI — 用一套命令管理 AppGallery Connect',
nav: { installGuide: '安装', workflow: '发布流程', profiles: '凭据 Profile', registry: '接口注册表', quickstart: '快速开始', language: '语言', install: '安装' },
nav: { installGuide: '安装', skills: 'Agent Skills', workflow: '发布流程', profiles: '凭据 Profile', registry: '接口注册表', quickstart: '快速开始', language: '语言', install: '安装' },
hero: {
kicker: '为终端而生的 AppGallery Connect 控制面',
titleLead: '让每一次发布沿着',
Expand Down Expand Up @@ -262,6 +289,25 @@ const translations = {
copyWindows: '复制 Windows 安装命令',
requirements: ['NPM:Node.js 18+', '安装时不运行 postinstall 下载', '内置五个平台校验后二进制'],
},
skills: {
eyebrow: 'Agent Skills',
title: '让 Coding Agent 真正理解 AppGallery Connect 工作流。',
body: '6 个可移植 Skills 参考 asc-cli 的任务分层方式设计。可以全部安装,也可以只选择一个工作流;每个 Skill 都支持查看源码、直接下载和通过 GitHub 参与完善。',
installAll: '为 Codex 安装全部 6 个 Skills',
copyAll: '复制全部安装命令',
installOne: '安装这个 Skill',
download: '下载 SKILL.md',
source: '查看源码',
contribute: '提交一个 Skill',
descriptions: {
'agc-cli-usage': '通用命令发现、dry-run 预演、授权执行和远程结果验证。',
'agc-auth': '凭据 Profile、whoami、OAuth 团队查询和权限诊断。',
'agc-publishing': '应用资料、软件包、提交审核、分阶段发布和发布状态验证。',
'agc-testing': '测试版本、群组、测试用户、邀请链接、反馈和版本转正。',
'agc-reports': '分发、安装、付费、留存和鸿蒙元服务报表导出。',
'agc-cicd': '跨平台固定版本安装、受保护凭据、dry-run 门禁和 CI 验证。',
},
},
console: {
eyebrow: '本地命令中心',
title: '浏览器看到的,就是 CLI 使用的同一份注册表。',
Expand Down Expand Up @@ -436,6 +482,7 @@ export function App({ renderLanguage, renderFamily }: { renderLanguage?: Languag
</a>
<div className="navlinks">
<a href="#install">{text.nav.installGuide}</a>
<a href="#skills">{text.nav.skills}</a>
<a href="#workflow">{text.nav.workflow}</a>
<a href="#profiles">{text.nav.profiles}</a>
<a href="#registry">{text.nav.registry}</a>
Expand Down Expand Up @@ -566,6 +613,49 @@ export function App({ renderLanguage, renderFamily }: { renderLanguage?: Languag
</div>
</section>

<section className="section skillsSection" id="skills">
<div className="sectionIntro skillsIntro">
<div>
<p className="eyebrow">{text.skills.eyebrow}</p>
<h2>{text.skills.title}</h2>
</div>
<div className="skillsIntroCopy">
<p>{text.skills.body}</p>
<a href="https://github.com/Createitv/agc-cli/blob/main/CONTRIBUTING.md" target="_blank" rel="noreferrer">
{text.skills.contribute} <ArrowRight size={15} />
</a>
</div>
</div>
<div className="skillsInstallAll">
<span><Bot size={20} /> {text.skills.installAll}</span>
<code><span>$</span> {installAllSkillsCommand}</code>
<button type="button" onClick={() => copyCommand('skills-all', installAllSkillsCommand)} aria-label={text.skills.copyAll}>
{copied === 'skills-all' ? <Check size={16} /> : <Clipboard size={16} />}
</button>
</div>
<div className="skillsGrid">
{agentSkills.map((skill) => {
const command = installSkillCommand(skill);
return (
<article className="skillCard" key={skill}>
<div className="skillCardHeader"><Bot size={18} /><code>{skill}</code></div>
<p>{text.skills.descriptions[skill]}</p>
<div className="skillCommand">
<code>{command}</code>
<button type="button" onClick={() => copyCommand(`skill-${skill}`, command)} aria-label={`${text.skills.installOne}: ${skill}`}>
{copied === `skill-${skill}` ? <Check size={15} /> : <Clipboard size={15} />}
</button>
</div>
<div className="skillLinks">
<a href={skillDownloadURL(skill)} target="_blank" rel="noreferrer"><Download size={14} /> {text.skills.download}</a>
<a href={skillSourceURL(skill)} target="_blank" rel="noreferrer">{text.skills.source} <ArrowRight size={14} /></a>
</div>
</article>
);
})}
</div>
</section>

<section className="section workflowSection" id="workflow">
<div className="sectionIntro">
<p className="eyebrow">{text.workflow.eyebrow}</p>
Expand Down
2 changes: 2 additions & 0 deletions apps/web/src/siteContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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。' },
],
},
Expand All @@ -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.' },
],
},
Expand Down
48 changes: 48 additions & 0 deletions apps/web/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down Expand Up @@ -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; }
}
Expand Down Expand Up @@ -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; }
Loading
Loading