add stable media support and sync skillhub UI
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
import type { Locale } from "@/lib/site-content";
|
||||
|
||||
type LiveCopy = {
|
||||
nav: {
|
||||
skills: string;
|
||||
};
|
||||
header: {
|
||||
zh: string;
|
||||
en: string;
|
||||
logout: string;
|
||||
loggingOut: string;
|
||||
loginHint: string;
|
||||
};
|
||||
login: {
|
||||
fieldLabel: string;
|
||||
fieldHint: string;
|
||||
submit: string;
|
||||
submitting: string;
|
||||
helperTitle: string;
|
||||
helperBody: string;
|
||||
commandLabel: string;
|
||||
alreadySignedIn: string;
|
||||
continueCta: string;
|
||||
invalidKey: string;
|
||||
};
|
||||
console: {
|
||||
unauthenticatedTitle: string;
|
||||
unauthenticatedBody: string;
|
||||
loginCta: string;
|
||||
docsCta: string;
|
||||
signedInAs: string;
|
||||
liveTitle: string;
|
||||
liveSubtitle: string;
|
||||
quickstartTitle: string;
|
||||
quickstartBody: string;
|
||||
catalogCount: string;
|
||||
noSkills: string;
|
||||
noUsage: string;
|
||||
loadErrorPrefix: string;
|
||||
};
|
||||
skills: {
|
||||
tag: string;
|
||||
title: string;
|
||||
subtitle: string;
|
||||
searchLabel: string;
|
||||
searchPlaceholder: string;
|
||||
searchAction: string;
|
||||
resultsPrefix: string;
|
||||
unauthenticatedTitle: string;
|
||||
unauthenticatedBody: string;
|
||||
loginCta: string;
|
||||
docsCta: string;
|
||||
noResults: string;
|
||||
routeKey: string;
|
||||
modelType: string;
|
||||
latency: string;
|
||||
tags: string;
|
||||
loadErrorPrefix: string;
|
||||
};
|
||||
};
|
||||
|
||||
const copy: Record<Locale, LiveCopy> = {
|
||||
zh: {
|
||||
nav: {
|
||||
skills: "技能页",
|
||||
},
|
||||
header: {
|
||||
zh: "中文",
|
||||
en: "EN",
|
||||
logout: "登出",
|
||||
loggingOut: "退出中...",
|
||||
loginHint: "未登录",
|
||||
},
|
||||
login: {
|
||||
fieldLabel: "PopiNewAPI Key",
|
||||
fieldHint: "使用和 `popiart auth login --key ...` 相同的上游 key 登录,页面会换取产品层 session。",
|
||||
submit: "登录控制台",
|
||||
submitting: "登录中...",
|
||||
helperTitle: "与 CLI 使用同一条认证链路",
|
||||
helperBody: "页面登录后,控制台会通过 popiartServer 会话去读取 skills、budget 和 usage,而不是直接在浏览器里保存 provider key。",
|
||||
commandLabel: "CLI 等价命令",
|
||||
alreadySignedIn: "当前已登录,可直接进入控制台或继续查看技能目录。",
|
||||
continueCta: "进入控制台",
|
||||
invalidKey: "请输入可用的 PopiNewAPI Key。",
|
||||
},
|
||||
console: {
|
||||
unauthenticatedTitle: "登录后查看真实控制台数据",
|
||||
unauthenticatedBody: "这页现在直接读取 popiartServer 的 auth、skills、budget 和 usage 接口。未登录时不会伪造密钥和余额。",
|
||||
loginCta: "去登录",
|
||||
docsCta: "看接入文档",
|
||||
signedInAs: "当前账号",
|
||||
liveTitle: "已接入 popiartServer 实时数据",
|
||||
liveSubtitle: "页面逻辑沿用 `popiart auth login`、`skills list` 和 `budget` 的产品层协议。",
|
||||
quickstartTitle: "快速安装指令",
|
||||
quickstartBody: "CLI 和 Web 共用同一个产品层 endpoint,下面这段命令可直接对应到当前控制台。",
|
||||
catalogCount: "技能目录",
|
||||
noSkills: "当前账号下没有可见技能。",
|
||||
noUsage: "当前周期还没有技能用量。",
|
||||
loadErrorPrefix: "控制台数据加载失败",
|
||||
},
|
||||
skills: {
|
||||
tag: "SKILL CATALOG",
|
||||
title: "官方技能目录",
|
||||
subtitle: "当前列表直接读取 `/v1/skills`,与 `popiart skills list` 使用同一份产品层数据。",
|
||||
searchLabel: "搜索技能",
|
||||
searchPlaceholder: "搜索技能名、描述或标签",
|
||||
searchAction: "查询",
|
||||
resultsPrefix: "共找到",
|
||||
unauthenticatedTitle: "登录后查看真实技能目录",
|
||||
unauthenticatedBody: "技能页会直接走产品层会话鉴权,因此未登录时不展示假数据。",
|
||||
loginCta: "登录查看",
|
||||
docsCta: "阅读文档",
|
||||
noResults: "没有匹配的技能。",
|
||||
routeKey: "路由键",
|
||||
modelType: "模型类型",
|
||||
latency: "预计耗时",
|
||||
tags: "标签",
|
||||
loadErrorPrefix: "技能目录加载失败",
|
||||
},
|
||||
},
|
||||
en: {
|
||||
nav: {
|
||||
skills: "Skills",
|
||||
},
|
||||
header: {
|
||||
zh: "中文",
|
||||
en: "EN",
|
||||
logout: "Logout",
|
||||
loggingOut: "Logging out...",
|
||||
loginHint: "Signed out",
|
||||
},
|
||||
login: {
|
||||
fieldLabel: "PopiNewAPI Key",
|
||||
fieldHint:
|
||||
"Use the same upstream key as `popiart auth login --key ...`. The web app exchanges it for a product-layer session.",
|
||||
submit: "Sign in to console",
|
||||
submitting: "Signing in...",
|
||||
helperTitle: "The same auth path as the CLI",
|
||||
helperBody:
|
||||
"After sign-in, the console reads skills, budget, and usage through popiartServer instead of storing provider credentials in the browser.",
|
||||
commandLabel: "Equivalent CLI command",
|
||||
alreadySignedIn: "You are already signed in. Jump back to the console or continue browsing the catalog.",
|
||||
continueCta: "Open console",
|
||||
invalidKey: "Enter a valid PopiNewAPI key.",
|
||||
},
|
||||
console: {
|
||||
unauthenticatedTitle: "Sign in to view live console data",
|
||||
unauthenticatedBody:
|
||||
"This page now reads popiartServer auth, skills, budget, and usage endpoints directly. It no longer fakes keys or credits for signed-out users.",
|
||||
loginCta: "Sign in",
|
||||
docsCta: "Read docs",
|
||||
signedInAs: "Signed in as",
|
||||
liveTitle: "Connected to live popiartServer data",
|
||||
liveSubtitle:
|
||||
"The page follows the same product-layer protocol used by `popiart auth login`, `skills list`, and `budget`.",
|
||||
quickstartTitle: "Quick install commands",
|
||||
quickstartBody: "The CLI and the web console share the same product endpoint and auth flow.",
|
||||
catalogCount: "Catalog",
|
||||
noSkills: "No skills are visible for this account yet.",
|
||||
noUsage: "No skill usage has been recorded for the current period.",
|
||||
loadErrorPrefix: "Failed to load console data",
|
||||
},
|
||||
skills: {
|
||||
tag: "SKILL CATALOG",
|
||||
title: "Official skill catalog",
|
||||
subtitle: "This list is fetched from `/v1/skills`, the same surface used by `popiart skills list`.",
|
||||
searchLabel: "Search skills",
|
||||
searchPlaceholder: "Search by skill name, description, or tag",
|
||||
searchAction: "Search",
|
||||
resultsPrefix: "Results",
|
||||
unauthenticatedTitle: "Sign in to view the live catalog",
|
||||
unauthenticatedBody:
|
||||
"The catalog page uses product-layer session auth, so it does not render fake skill data for signed-out users.",
|
||||
loginCta: "Sign in",
|
||||
docsCta: "Read docs",
|
||||
noResults: "No skills matched this query.",
|
||||
routeKey: "Route key",
|
||||
modelType: "Model type",
|
||||
latency: "Estimated duration",
|
||||
tags: "Tags",
|
||||
loadErrorPrefix: "Failed to load the skill catalog",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export function getLiveCopy(locale: Locale) {
|
||||
return copy[locale] ?? copy.zh;
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
import { cookies } from "next/headers";
|
||||
|
||||
export const SESSION_COOKIE_NAME = "popiart_session";
|
||||
|
||||
type ApiEnvelope<T> = {
|
||||
ok: boolean;
|
||||
data?: T;
|
||||
error?: {
|
||||
code?: string;
|
||||
message?: string;
|
||||
details?: unknown;
|
||||
};
|
||||
};
|
||||
|
||||
export type PopiartUser = {
|
||||
id: string;
|
||||
email: string;
|
||||
name: string;
|
||||
scopes?: string[];
|
||||
};
|
||||
|
||||
export type LoginResponse = {
|
||||
key: string;
|
||||
token: string;
|
||||
user: PopiartUser;
|
||||
};
|
||||
|
||||
export type AuthSessionView = {
|
||||
user: PopiartUser;
|
||||
session_key?: string;
|
||||
upstream_key_masked?: string;
|
||||
};
|
||||
|
||||
export type Skill = {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
tags: string[];
|
||||
version: string;
|
||||
model_type: string;
|
||||
route_key?: string;
|
||||
estimated_duration_s: number;
|
||||
};
|
||||
|
||||
export type SkillListResponse = {
|
||||
items: Skill[];
|
||||
total: number;
|
||||
limit: number;
|
||||
offset: number;
|
||||
};
|
||||
|
||||
export type BudgetSummary = {
|
||||
period: {
|
||||
start: string;
|
||||
end: string;
|
||||
};
|
||||
used: {
|
||||
tokens: number;
|
||||
cost_usd: number;
|
||||
};
|
||||
limit: {
|
||||
monthly_tokens: number;
|
||||
monthly_cost_usd: number;
|
||||
};
|
||||
remaining: {
|
||||
tokens: number;
|
||||
cost_usd: number;
|
||||
};
|
||||
};
|
||||
|
||||
export type BudgetUsageRow = {
|
||||
dimension: string;
|
||||
tokens_used: number;
|
||||
cost_usd: number;
|
||||
job_count: number;
|
||||
};
|
||||
|
||||
export type BudgetUsage = {
|
||||
rows: BudgetUsageRow[];
|
||||
total: {
|
||||
tokens_used: number;
|
||||
cost_usd: number;
|
||||
job_count: number;
|
||||
};
|
||||
};
|
||||
|
||||
export class PopiartApiError extends Error {
|
||||
status: number;
|
||||
code?: string;
|
||||
details?: unknown;
|
||||
|
||||
constructor(status: number, message: string, code?: string, details?: unknown) {
|
||||
super(message);
|
||||
this.name = "PopiartApiError";
|
||||
this.status = status;
|
||||
this.code = code;
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
|
||||
function stripTrailingSlash(value: string) {
|
||||
return value.replace(/\/+$/, "");
|
||||
}
|
||||
|
||||
export function getPopiartEndpoint() {
|
||||
const configured =
|
||||
process.env.POPIART_ENDPOINT ??
|
||||
process.env.POPIART_SERVER_URL ??
|
||||
"http://127.0.0.1:8080/v1";
|
||||
return stripTrailingSlash(configured);
|
||||
}
|
||||
|
||||
export function buildPopiartUrl(pathname: string) {
|
||||
const path = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
||||
return `${getPopiartEndpoint()}${path}`;
|
||||
}
|
||||
|
||||
async function readEnvelope<T>(response: Response) {
|
||||
try {
|
||||
return (await response.json()) as ApiEnvelope<T>;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function popiartFetchEnvelope<T>(pathname: string, init: RequestInit = {}) {
|
||||
const response = await fetch(buildPopiartUrl(pathname), {
|
||||
...init,
|
||||
cache: "no-store",
|
||||
});
|
||||
const payload = await readEnvelope<T>(response);
|
||||
return { response, payload };
|
||||
}
|
||||
|
||||
export async function popiartRequest<T>(
|
||||
pathname: string,
|
||||
options: {
|
||||
method?: string;
|
||||
body?: BodyInit | object;
|
||||
headers?: HeadersInit;
|
||||
token?: string;
|
||||
} = {},
|
||||
) {
|
||||
const headers = new Headers(options.headers);
|
||||
let body: BodyInit | undefined;
|
||||
|
||||
if (options.token) {
|
||||
headers.set("Authorization", `Bearer ${options.token}`);
|
||||
}
|
||||
|
||||
if (options.body instanceof FormData || typeof options.body === "string") {
|
||||
body = options.body;
|
||||
} else if (options.body !== undefined) {
|
||||
headers.set("Content-Type", "application/json");
|
||||
body = JSON.stringify(options.body);
|
||||
}
|
||||
|
||||
const { response, payload } = await popiartFetchEnvelope<T>(pathname, {
|
||||
method: options.method ?? (body ? "POST" : "GET"),
|
||||
headers,
|
||||
body,
|
||||
});
|
||||
|
||||
if (!response.ok || !payload?.ok) {
|
||||
throw new PopiartApiError(
|
||||
response.status,
|
||||
payload?.error?.message ?? `Request failed with status ${response.status}`,
|
||||
payload?.error?.code,
|
||||
payload?.error?.details,
|
||||
);
|
||||
}
|
||||
|
||||
return payload.data as T;
|
||||
}
|
||||
|
||||
export async function getSessionToken() {
|
||||
const cookieStore = await cookies();
|
||||
return cookieStore.get(SESSION_COOKIE_NAME)?.value ?? null;
|
||||
}
|
||||
|
||||
export async function getViewerSession() {
|
||||
const token = await getSessionToken();
|
||||
if (!token) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return await popiartRequest<AuthSessionView>("/auth/me", { token });
|
||||
} catch (error) {
|
||||
if (error instanceof PopiartApiError && error.status === 401) {
|
||||
return null;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSkillsCatalog(search?: string) {
|
||||
const token = await getSessionToken();
|
||||
if (!token) {
|
||||
return null;
|
||||
}
|
||||
const query = new URLSearchParams();
|
||||
query.set("limit", "100");
|
||||
if (search) {
|
||||
query.set("search", search);
|
||||
}
|
||||
return popiartRequest<SkillListResponse>(`/skills?${query.toString()}`, { token });
|
||||
}
|
||||
|
||||
export async function getBudgetSummary() {
|
||||
const token = await getSessionToken();
|
||||
if (!token) {
|
||||
return null;
|
||||
}
|
||||
return popiartRequest<BudgetSummary>("/budget", { token });
|
||||
}
|
||||
|
||||
export async function getBudgetUsage() {
|
||||
const token = await getSessionToken();
|
||||
if (!token) {
|
||||
return null;
|
||||
}
|
||||
return popiartRequest<BudgetUsage>("/budget/usage", { token });
|
||||
}
|
||||
+159
-78
@@ -18,6 +18,14 @@ type Step = {
|
||||
description: string;
|
||||
};
|
||||
|
||||
type InstallMethod = {
|
||||
badge: string;
|
||||
name: string;
|
||||
description: string;
|
||||
command: string;
|
||||
note: string;
|
||||
};
|
||||
|
||||
type Plan = {
|
||||
badge: string;
|
||||
name: string;
|
||||
@@ -116,6 +124,13 @@ export type AppDictionary = {
|
||||
flowTitle: string;
|
||||
flowSubtitle: string;
|
||||
flowSteps: Step[];
|
||||
installTag: string;
|
||||
installTitle: string;
|
||||
installSubtitle: string;
|
||||
installMethods: InstallMethod[];
|
||||
bootstrapTitle: string;
|
||||
bootstrapDescription: string;
|
||||
bootstrapCommand: string;
|
||||
trustTag: string;
|
||||
trustTitle: string;
|
||||
trustStats: Stat[];
|
||||
@@ -194,23 +209,23 @@ const zh: AppDictionary = {
|
||||
},
|
||||
home: {
|
||||
tag: "OFFICIAL SKILLS",
|
||||
title: "把官方 PopiArt Skills 接进你的创作与自动化流程",
|
||||
title: "安装 popiartcli,把官方 PopiArt Skills 接进你的 Coding Agent",
|
||||
subtitle:
|
||||
"覆盖图片生成、编辑、视频与批量工作流,让团队用统一账号、统一计费、统一控制台管理所有 AI 能力。",
|
||||
primaryCta: "开始使用",
|
||||
"通过统一 CLI 发现、查看、调用官方 skills;当任务需要图像、视频与多模态模型时,再由产品层统一处理授权、路由和计费。",
|
||||
primaryCta: "安装 CLI",
|
||||
secondaryCta: "查看文档",
|
||||
freeTrial: "无需信用卡,注册即送 50 Credits",
|
||||
socialProof: "已为团队工作流准备好账号、订阅与用量追踪",
|
||||
stageLabel: "本月概览",
|
||||
stageValue: "12,480 Credits",
|
||||
stageDescription: "管理官方技能、订阅计划、API key 与项目级用量。",
|
||||
freeTrial: "支持 Homebrew、curl | sh、Windows PowerShell 与源码构建",
|
||||
socialProof: "安装后可直接 bootstrap 到 Codex、OpenCode 与 OpenClaw",
|
||||
stageLabel: "CLI 命令面",
|
||||
stageValue: "auth / skills / run",
|
||||
stageDescription: "继续用 jobs、artifacts、budget、project、models、bootstrap 完成完整工作流。",
|
||||
heroPhrases: [
|
||||
"图片生成",
|
||||
"图像编辑",
|
||||
"图生视频",
|
||||
"动作迁移",
|
||||
"批量处理",
|
||||
"官方计费",
|
||||
"auth login",
|
||||
"skills list",
|
||||
"run --wait",
|
||||
"jobs wait",
|
||||
"artifacts pull",
|
||||
"budget status",
|
||||
],
|
||||
scenesTag: "SCENARIOS",
|
||||
scenesTitle: "覆盖高频 AI 创作场景",
|
||||
@@ -247,30 +262,62 @@ const zh: AppDictionary = {
|
||||
description: "把技能能力、额度、项目和账单统一到一个控制台管理。",
|
||||
},
|
||||
],
|
||||
flowTag: "INTEGRATION",
|
||||
flowTitle: "三步接入官方控制台",
|
||||
flowSubtitle: "先搭出官网结构,再逐步接回 popiartServer 的登录、用量和计费接口。",
|
||||
flowTag: "QUICK START",
|
||||
flowTitle: "三步开始使用 popiartcli",
|
||||
flowSubtitle: "直接沿用仓库 README 的真实安装与首次使用路径,而不是另造一套平台流程。",
|
||||
flowSteps: [
|
||||
{
|
||||
title: "注册并登录 PopiArt 账号",
|
||||
description: "先拿到产品层账号与 API key,而不是把供应商密钥直接暴露给客户端。",
|
||||
title: "安装 popiartcli",
|
||||
description: "优先使用 Homebrew、官方 install.sh 或 PowerShell 脚本,把 CLI 先装到本地环境。",
|
||||
},
|
||||
{
|
||||
title: "在文档页完成 CLI 或 API 接入",
|
||||
description: "根据官方 quick start 配置 endpoint、token 和默认输出目录。",
|
||||
title: "执行 bootstrap 接入 agent 生态",
|
||||
description: "生成 completion、默认 discovery profile,并可直接暴露给 Codex / OpenCode 使用。",
|
||||
},
|
||||
{
|
||||
title: "在控制台查看技能、用量和账单",
|
||||
description: "按项目查看技能调用量、订阅状态和充值记录。",
|
||||
title: "登录并调用官方 skill",
|
||||
description: "执行 auth login、skills list、run、jobs wait、artifacts pull,进入完整工作流。",
|
||||
},
|
||||
],
|
||||
trustTag: "CONTROL",
|
||||
trustTitle: "围绕产品层能力组织,而不是裸模型调用",
|
||||
installTag: "INSTALL",
|
||||
installTitle: "首页直接开始安装 popiartcli",
|
||||
installSubtitle: "推荐先安装 CLI,再按需执行 bootstrap,让 PopiArt 在你的 agent 环境里直接可发现。",
|
||||
installMethods: [
|
||||
{
|
||||
badge: "RECOMMENDED",
|
||||
name: "Homebrew",
|
||||
description: "适合 macOS / Linux,也是后续升级最稳定的方式。",
|
||||
command: "brew tap wtgoku-create/popi\nbrew install wtgoku-create/popi/popiart",
|
||||
note: "升级:brew upgrade wtgoku-create/popi/popiart",
|
||||
},
|
||||
{
|
||||
badge: "CLI ONLY",
|
||||
name: "curl | sh",
|
||||
description: "从 GitHub Releases 安装 Go CLI 二进制,默认只安装 CLI 本体。",
|
||||
command:
|
||||
"curl -fsSL https://raw.githubusercontent.com/wtgoku-create/popiartcli/main/install.sh | sh -s -- --cli-only",
|
||||
note: "升级:popiart update",
|
||||
},
|
||||
{
|
||||
badge: "WINDOWS",
|
||||
name: "PowerShell",
|
||||
description: "Windows 环境使用官方 install.ps1,支持指定版本安装。",
|
||||
command:
|
||||
"irm https://raw.githubusercontent.com/wtgoku-create/popiartcli/main/install.ps1 | iex",
|
||||
note: "也可以通过 VERSION 环境变量安装指定版本。",
|
||||
},
|
||||
],
|
||||
bootstrapTitle: "安装后建议立即执行 bootstrap",
|
||||
bootstrapDescription: "生成 shell completion、默认 skill discovery profile,并把 PopiArt 直接暴露给 agent。",
|
||||
bootstrapCommand:
|
||||
"popiart bootstrap --agent codex --completion zsh\npopiart bootstrap --agent codex --discoverable\npopiart skills list",
|
||||
trustTag: "CLI DESIGN",
|
||||
trustTitle: "围绕 agent 工作流设计,而不是零散脚本拼装",
|
||||
trustStats: [
|
||||
{ label: "官方技能目录", value: "24+" },
|
||||
{ label: "项目级路由覆盖", value: "Per Project" },
|
||||
{ label: "统一登录与会话", value: "1 Account" },
|
||||
{ label: "订阅与充值", value: "Built In" },
|
||||
{ label: "默认 JSON 输出", value: "ok / data" },
|
||||
{ label: "长任务轮询", value: "jobs wait" },
|
||||
{ label: "工件恢复下载", value: "artifacts pull" },
|
||||
{ label: "生态引导", value: "bootstrap" },
|
||||
],
|
||||
},
|
||||
pricing: {
|
||||
@@ -329,23 +376,24 @@ const zh: AppDictionary = {
|
||||
tag: "DOCUMENTATION",
|
||||
title: "PopiArt 开发者文档",
|
||||
intro:
|
||||
"先把官网、登录和控制台骨架搭起来,后续直接把文档页接到 popiartcli 与 popiartServer 的真实协议。",
|
||||
"首页与文档都直接围绕 popiartcli README 的真实安装链路、bootstrap 和命令面来组织。",
|
||||
quickStartTitle: "快速开始",
|
||||
quickSteps: [
|
||||
{
|
||||
title: "1. 设置服务地址",
|
||||
description: "将 Web 控制台和 CLI 指向统一的产品层后端。",
|
||||
code: "export POPIART_ENDPOINT=http://127.0.0.1:8080/v1",
|
||||
title: "1. 安装 popiartcli",
|
||||
description: "优先使用 Homebrew,或者用官方 install.sh / install.ps1 安装 CLI。",
|
||||
code: "brew tap wtgoku-create/popi\nbrew install wtgoku-create/popi/popiart",
|
||||
},
|
||||
{
|
||||
title: "2. 登录并写入 token",
|
||||
description: "先拿到产品层 session,后端再桥接到上游模型网关。",
|
||||
code: "popiart auth login --key <your-product-token>",
|
||||
title: "2. 执行 bootstrap",
|
||||
description: "把 PopiArt 直接接进 Codex / OpenCode,并生成 completion 与默认发现配置。",
|
||||
code: "popiart bootstrap --agent codex --discoverable",
|
||||
},
|
||||
{
|
||||
title: "3. 调用官方 skill",
|
||||
description: "直接通过技能名或 route key 发起任务。",
|
||||
code: "popiart skills list\npopiart run --skill popiskill-image-text2image-basic-v1",
|
||||
title: "3. 登录并调用官方 skill",
|
||||
description: "完成 auth login 后,先列技能,再执行 run / jobs wait / artifacts pull。",
|
||||
code:
|
||||
"popiart auth login --key <your-product-token>\npopiart skills list\npopiart run popiskill-image-text2image-basic-v1 --input @params.json --wait",
|
||||
},
|
||||
],
|
||||
envTitle: "环境变量",
|
||||
@@ -486,23 +534,23 @@ const en: AppDictionary = {
|
||||
},
|
||||
home: {
|
||||
tag: "OFFICIAL SKILLS",
|
||||
title: "Bring official PopiArt skills into your creative and automation workflows",
|
||||
title: "Install popiartcli and bring official PopiArt skills into your coding agent",
|
||||
subtitle:
|
||||
"One account, one console, and one billing layer for image generation, editing, video, and team-ready AI operations.",
|
||||
primaryCta: "Get started",
|
||||
"Use one CLI to discover, inspect, and run official skills, while product-layer auth, routing, and billing stay behind the PopiArt backend.",
|
||||
primaryCta: "Install CLI",
|
||||
secondaryCta: "Read docs",
|
||||
freeTrial: "No credit card required. 50 free credits on signup.",
|
||||
socialProof: "Built for account management, subscriptions, and usage visibility.",
|
||||
stageLabel: "This month",
|
||||
stageValue: "12,480 Credits",
|
||||
stageDescription: "Manage official skills, subscriptions, API keys, and per-project usage from one place.",
|
||||
freeTrial: "Supports Homebrew, curl | sh, Windows PowerShell, and source builds",
|
||||
socialProof: "Bootstrap directly into Codex, OpenCode, and OpenClaw after install",
|
||||
stageLabel: "CLI surface",
|
||||
stageValue: "auth / skills / run",
|
||||
stageDescription: "Then move into jobs, artifacts, budget, project, models, and bootstrap for the full workflow.",
|
||||
heroPhrases: [
|
||||
"Text to image",
|
||||
"Image edit",
|
||||
"Image to video",
|
||||
"Motion transfer",
|
||||
"Batch ops",
|
||||
"Official billing",
|
||||
"auth login",
|
||||
"skills list",
|
||||
"run --wait",
|
||||
"jobs wait",
|
||||
"artifacts pull",
|
||||
"budget status",
|
||||
],
|
||||
scenesTag: "SCENARIOS",
|
||||
scenesTitle: "Designed around high-frequency AI production flows",
|
||||
@@ -540,31 +588,63 @@ const en: AppDictionary = {
|
||||
description: "Bring skills, quotas, projects, and billing together in one product surface.",
|
||||
},
|
||||
],
|
||||
flowTag: "INTEGRATION",
|
||||
flowTitle: "Three steps to launch the official console",
|
||||
flowTag: "QUICK START",
|
||||
flowTitle: "Three steps to start with popiartcli",
|
||||
flowSubtitle:
|
||||
"Start with the web experience, then connect auth, usage, and billing to popiartServer.",
|
||||
"This mirrors the real install and first-run path from the popiartcli README instead of inventing a separate web-only flow.",
|
||||
flowSteps: [
|
||||
{
|
||||
title: "Create and sign into a PopiArt account",
|
||||
description: "Use a product-level account instead of pushing provider credentials into the client.",
|
||||
title: "Install popiartcli",
|
||||
description: "Use Homebrew, the official install.sh, or PowerShell to get the CLI onto your local machine.",
|
||||
},
|
||||
{
|
||||
title: "Complete CLI or API setup from the docs",
|
||||
description: "Point your tooling to the shared endpoint and configure the official token flow.",
|
||||
title: "Run bootstrap for your agent environment",
|
||||
description: "Generate completion, default discovery profiles, and make PopiArt directly discoverable to Codex or OpenCode.",
|
||||
},
|
||||
{
|
||||
title: "Track skills, usage, and billing in the console",
|
||||
description: "Review usage by project, skill, and billing period from a single dashboard.",
|
||||
title: "Sign in and run official skills",
|
||||
description: "Use auth login, skills list, run, jobs wait, and artifacts pull to complete the first real workflow.",
|
||||
},
|
||||
],
|
||||
trustTag: "CONTROL",
|
||||
trustTitle: "Organized around product semantics instead of raw model calls",
|
||||
installTag: "INSTALL",
|
||||
installTitle: "Install popiartcli directly from the homepage",
|
||||
installSubtitle: "Install the CLI first, then optionally run bootstrap so PopiArt becomes discoverable inside your agent environment.",
|
||||
installMethods: [
|
||||
{
|
||||
badge: "RECOMMENDED",
|
||||
name: "Homebrew",
|
||||
description: "Best for macOS and Linux, and the cleanest upgrade path later.",
|
||||
command: "brew tap wtgoku-create/popi\nbrew install wtgoku-create/popi/popiart",
|
||||
note: "Upgrade with: brew upgrade wtgoku-create/popi/popiart",
|
||||
},
|
||||
{
|
||||
badge: "CLI ONLY",
|
||||
name: "curl | sh",
|
||||
description: "Download the released Go CLI binary directly from GitHub Releases.",
|
||||
command:
|
||||
"curl -fsSL https://raw.githubusercontent.com/wtgoku-create/popiartcli/main/install.sh | sh -s -- --cli-only",
|
||||
note: "Upgrade with: popiart update",
|
||||
},
|
||||
{
|
||||
badge: "WINDOWS",
|
||||
name: "PowerShell",
|
||||
description: "Use the official install.ps1 flow on Windows, with optional version pinning.",
|
||||
command:
|
||||
"irm https://raw.githubusercontent.com/wtgoku-create/popiartcli/main/install.ps1 | iex",
|
||||
note: "You can also pin a VERSION before running the installer.",
|
||||
},
|
||||
],
|
||||
bootstrapTitle: "Run bootstrap right after installation",
|
||||
bootstrapDescription: "Generate shell completion, a default discovery profile, and make PopiArt directly available to your coding agent.",
|
||||
bootstrapCommand:
|
||||
"popiart bootstrap --agent codex --completion zsh\npopiart bootstrap --agent codex --discoverable\npopiart skills list",
|
||||
trustTag: "CLI DESIGN",
|
||||
trustTitle: "Designed around agent workflows instead of scattered scripts",
|
||||
trustStats: [
|
||||
{ label: "Official skills", value: "24+" },
|
||||
{ label: "Project routing", value: "Per project" },
|
||||
{ label: "Unified auth", value: "1 account" },
|
||||
{ label: "Billing flows", value: "Built in" },
|
||||
{ label: "JSON-first output", value: "ok / data" },
|
||||
{ label: "Long-task polling", value: "jobs wait" },
|
||||
{ label: "Artifact recovery", value: "artifacts pull" },
|
||||
{ label: "Agent bootstrap", value: "bootstrap" },
|
||||
],
|
||||
},
|
||||
pricing: {
|
||||
@@ -623,23 +703,24 @@ const en: AppDictionary = {
|
||||
tag: "DOCUMENTATION",
|
||||
title: "PopiArt developer docs",
|
||||
intro:
|
||||
"This first pass recreates the information architecture of the reference site while aligning it with popiartcli and popiartServer.",
|
||||
"The homepage and docs now follow the real install chain, bootstrap flow, and command surface from popiartcli.",
|
||||
quickStartTitle: "Quick start",
|
||||
quickSteps: [
|
||||
{
|
||||
title: "1. Configure the endpoint",
|
||||
description: "Point both the console and CLI at the same product-layer backend.",
|
||||
code: "export POPIART_ENDPOINT=http://127.0.0.1:8080/v1",
|
||||
title: "1. Install popiartcli",
|
||||
description: "Use Homebrew first when possible, or fall back to install.sh / install.ps1.",
|
||||
code: "brew tap wtgoku-create/popi\nbrew install wtgoku-create/popi/popiart",
|
||||
},
|
||||
{
|
||||
title: "2. Sign in with a product token",
|
||||
description: "Keep provider credentials behind the backend and work through the product session layer.",
|
||||
code: "popiart auth login --key <your-product-token>",
|
||||
title: "2. Bootstrap your agent environment",
|
||||
description: "Generate completion, default discovery profiles, and make PopiArt directly discoverable.",
|
||||
code: "popiart bootstrap --agent codex --discoverable",
|
||||
},
|
||||
{
|
||||
title: "3. Run official skills",
|
||||
description: "Invoke skills by skill id or move to model-level calls when you need direct debugging.",
|
||||
code: "popiart skills list\npopiart run --skill popiskill-image-text2image-basic-v1",
|
||||
title: "3. Sign in and run official skills",
|
||||
description: "Authenticate, inspect the catalog, and run the first skill through the real job workflow.",
|
||||
code:
|
||||
"popiart auth login --key <your-product-token>\npopiart skills list\npopiart run popiskill-image-text2image-basic-v1 --input @params.json --wait",
|
||||
},
|
||||
],
|
||||
envTitle: "Environment variables",
|
||||
|
||||
Reference in New Issue
Block a user