community-publish

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Two independent actions

两种独立操作

This skill handles two completely different kinds of sharing. They are NOT the same action and NOT two stages of one action.
ActionWhat "share" means hereAudience canApplies to
publish_preview(preview_id)
Make a running preview visitable at
https://community.iamstarchild.com/{user_id}-{slug}
Open the URL in a browsertype=preview only
open_source(project_dir)
Push project source to the community GitHub repoFork the code and run their own copyAny type (task, preview, service, script)
Preview lifecycle (start / stop / health check) lives in the
preview
tool. This skill only handles the share side.

本Skill处理两种完全不同的分享类型。它们并非同一操作的不同阶段,而是完全独立的操作。
操作此处“分享”的含义用户可执行操作适用范围
publish_preview(preview_id)
让运行中的预览可通过
https://community.iamstarchild.com/{user_id}-{slug}
访问
在浏览器中打开该URL仅适用于type=preview
open_source(project_dir)
将项目源码推送至社区GitHub仓库分支代码并运行自己的副本任意类型(task、preview、service、script)
预览生命周期(启动/停止/健康检查)由
preview
工具负责。本Skill仅处理分享相关环节。

Routing — read user intent carefully

路由——仔细理解用户意图

The word "publish" is ambiguous. Default interpretation matters.
User saysActionWhy
"publish" / "share" / "make public" / "公开" / "发布" (no qualifier)
publish_preview(preview_id)
Default user intent for "publish" is public URL access, not source code
"publish the URL" / "share the link" / "let people visit" / "公开访问"
publish_preview(preview_id)
Same
"open source" / "open-source the code" / "share the code" / "let others fork" / "开源代码"
open_source(project_dir)
Explicit code-sharing intent
Ambiguous after rereadingAsk one question, don't guess"Do you want a public URL people can visit, or do you want the code on GitHub for others to fork?"
"fork" / "install someone's project"
fork(source)
Pull from catalog
"browse" / "see what others published"
list_open_source(...)
Catalog query
"unpublish the URL" / "take down the link"
unpublish_preview(slug)
Inverse of publish_preview
"remove the open source" / "delete from GitHub"
remove_open_source(slug)
Inverse of open_source
"list my public URLs"
list_published_previews()
User's own preview side
“publish”一词含义模糊,默认解读规则如下:
用户表述执行操作原因
"publish" / "share" / "make public" / "公开" / "发布" (无限定词)
publish_preview(preview_id)
用户提及“publish”时的默认意图是获取公开URL访问权限,而非分享源码
"publish the URL" / "share the link" / "let people visit" / "公开访问"
publish_preview(preview_id)
同上
"open source" / "open-source the code" / "share the code" / "let others fork" / "开源代码"
open_source(project_dir)
明确表达了分享代码的意图
重新阅读后仍存在歧义询问用户,不要猜测“您是想要一个可供他人访问的公开URL,还是希望将代码上传至GitHub供他人分支(fork)?”
"fork" / "install someone's project"
fork(source)
从目录中拉取项目
"browse" / "see what others published"
list_open_source(...)
查询目录
"unpublish the URL" / "take down the link"
unpublish_preview(slug)
publish_preview
的反向操作
"remove the open source" / "delete from GitHub"
remove_open_source(slug)
open_source
的反向操作
"list my public URLs"
list_published_previews()
用户自身的预览相关操作

Mentioning the other action

提及另一操作

After
publish_preview()
succeeds, if the project also has source code the user might want to share:
Public URL is up. Want to open-source the code as well, so others can fork and run their own copy?
After
open_source()
succeeds, only if the project type is
preview
AND there's a running preview:
Code is open-sourced. The preview is still running — want to publish the live URL too, so visitors can try it without forking?
For
task
/
script
/
service
: don't mention preview publish — there's nothing to expose.

publish_preview()
执行成功后,如果项目还有源码可供用户分享:
公开URL已上线。是否同时将代码开源,以便他人分支并运行自己的副本?
open_source()
执行成功后,仅当项目类型为
preview
且存在运行中的预览时:
代码已开源。预览仍在运行——是否同时发布实时URL,以便访客无需分支即可体验?
对于
task
/
script
/
service
: 无需提及预览发布——没有可暴露的内容。

Architecture

架构

                community.iamstarchild.com (single gateway domain)
            ┌─────────────────┴─────────────────┐
            │                                   │
   ┌────────▼─────────┐                ┌────────▼─────────┐
   │  /api/register   │                │/api/code-projects│
   │  /api/unregister │                │ /publish, /list, │
   │  /api/list       │                │ /unpublish, ...  │
   └────────┬─────────┘                └────────┬─────────┘
            │                                   │
   ┌────────▼─────────┐                ┌────────▼─────────┐
   │ In-memory route  │                │ GitHub repo:     │
   │ table (preview-> │                │ Starchild-ai-    │
   │ machine:port)    │                │ agent/community- │
   │                  │                │ projects         │
   │ Lives only while │                │                  │
   │ container is up. │                │ Permanent.       │
   └──────────────────┘                └──────────────────┘
     publish_preview()                    open_source()
Same gateway domain, separate API paths, separate datastores. A project can live in either side, both sides, or neither. When both exist, the gateway auto-links them so the frontend renders cross-references ("View Source" on preview cards, "Visit Live Demo" on code cards). Auto-link uses the
{user_id}-{slug}
pattern (with a fuzzy fallback within the same owner).

                community.iamstarchild.com (单一网关域名)
            ┌─────────────────┴─────────────────┐
            │                                   │
   ┌────────▼─────────┐                ┌────────▼─────────┐
   │  /api/register   │                │/api/code-projects│
   │  /api/unregister │                │ /publish, /list, │
   │  /api/list       │                │ /unpublish, ...  │
   └────────┬─────────┘                └────────┬─────────┘
            │                                   │
   ┌────────▼─────────┐                ┌────────▼─────────┐
   │ 内存路由表       │                │ GitHub仓库:      │
   │ (preview->       │                │ Starchild-ai-    │
   │ machine:port)    │                │ agent/community- │
   │                  │                │ projects         │
   │ 仅在容器运行时存在│                │                  │
   │                  │                │ 永久存储         │
   └──────────────────┘                └──────────────────┘
     publish_preview()                    open_source()
同一网关域名,不同API路径,不同数据存储。项目可存在于任意一侧、两侧或都不存在。当两侧都存在时,网关会自动关联它们,以便前端显示交叉引用(预览卡片上的“查看源码”,代码卡片上的“访问在线演示”)。自动关联使用
{user_id}-{slug}
模式(同一所有者下会有模糊匹配 fallback)。

publish_preview()
— public URL

publish_preview()
—— 公开URL

publish_preview(preview_id, slug="", title="")
Map a running preview to
https://community.iamstarchild.com/{user_id}-{slug}
.
  • preview_id
    : from
    preview(action='serve')
    . Must be
    status=running
    .
  • slug
    : URL suffix only (lowercase alphanumeric + hyphens, 3-50 chars). User_id prefix is added automatically — pass
    'my-app'
    , NOT
    '1463-my-app'
    .
  • title
    : display name for the listing.
Returns
{"ok": True, "url": "https://community.iamstarchild.com/{user_id}-{slug}", ...}
.
Constraints:
  • Max 20 published previews per user (gateway returns 429 over).
  • Preview must be running. Stops working when the container goes down (visitors see offline page).
  • Slug stays bound to the port — stop and re-serve the preview, the URL stays valid.
  • Only works inside the Starchild Fly container (needs
    FLY_MACHINE_ID
    ).
Companions:
  • unpublish_preview(slug)
    — remove the public URL. Slug accepts full
    {user_id}-{suffix}
    or just suffix.
  • list_published_previews()
    — all currently published preview URLs for this user.

publish_preview(preview_id, slug="", title="")
将运行中的预览映射至
https://community.iamstarchild.com/{user_id}-{slug}
  • preview_id
    : 来自
    preview(action='serve')
    。必须处于
    status=running
    状态。
  • slug
    : 仅为URL后缀(小写字母数字+连字符,3-50个字符)。User_id前缀会自动添加——只需传入
    'my-app'
    ,而非
    '1463-my-app'
  • title
    : 列表中的显示名称。
返回
{"ok": True, "url": "https://community.iamstarchild.com/{user_id}-{slug}", ...}
约束条件:
  • 每个用户最多可发布20个预览(超出后网关返回429错误)。
  • 预览必须处于运行状态。容器停止后,URL将无法访问(访客会看到离线页面)。
  • Slug与端口绑定——停止并重新启动预览后,URL依然有效。
  • 仅在Starchild Fly容器内可用(需要
    FLY_MACHINE_ID
    )。
配套操作:
  • unpublish_preview(slug)
    —— 移除公开URL。Slug可接受完整的
    {user_id}-{suffix}
    或仅后缀。
  • list_published_previews()
    —— 当前用户所有已发布的预览URL。

open_source()
— push code to GitHub

open_source()
—— 将代码推送至GitHub

open_source(project_dir, version_bump="patch")
Push project source to
community-projects/projects/{type}s/{user_id}/{slug}/{version}/
on GitHub.
  • project_dir
    : e.g.
    output/projects/my-task
  • version_bump
    :
    patch
    |
    minor
    |
    major
    |
    none
  • Returns
    {"ok": True, "github_url": ..., "version": ..., "commit_sha": ...}
Companions:
  • fork(source, dest_dir=None)
    — install someone else's open-sourced project locally
    • source
      :
      "user_id/slug"
      or
      "user_id/slug@version"
    • For
      task
      type: registers as paused, returns
      next_step
      instructions
    • For
      preview
      type: returns ready-to-serve preview info
  • list_open_source(type=None, tag=None, user=None, q=None)
    — browse the GitHub catalog
  • get_open_source(source)
    — fetch one project's full metadata
  • remove_open_source(slug)
    — delete from GitHub catalog (owner only, removes ALL versions)
  • validate_open_source(project_dir)
    — pre-flight check before publishing
open_source(project_dir, version_bump="patch")
将项目源码推送至GitHub上的
community-projects/projects/{type}s/{user_id}/{slug}/{version}/
  • project_dir
    : 例如
    output/projects/my-task
  • version_bump
    :
    patch
    |
    minor
    |
    major
    |
    none
  • 返回
    {"ok": True, "github_url": ..., "version": ..., "commit_sha": ...}
配套操作:
  • fork(source, dest_dir=None)
    —— 将他人开源的项目安装至本地
    • source
      :
      "user_id/slug"
      "user_id/slug@version"
    • 对于
      task
      类型:注册为暂停状态,返回
      next_step
      说明
    • 对于
      preview
      类型:返回可直接启动的预览信息
  • list_open_source(type=None, tag=None, user=None, q=None)
    —— 浏览GitHub目录
  • get_open_source(source)
    —— 获取单个项目的完整元数据
  • remove_open_source(slug)
    —— 从GitHub目录中删除(仅所有者可操作,会移除所有版本)
  • validate_open_source(project_dir)
    —— 发布前的预检查

Project structure

项目结构

Every project under
output/projects/{slug}/
:
project.yaml      # metadata (name, version, type, env_required, sc_proxy)
PROJECT.md        # required sections: What / Required env / How to start / Outputs / Troubleshooting
.env.example      # all env vars with placeholder values
.gitignore        # secrets blacklist
src/
  ├── run.py       # for type=task (must start: # -*- task-system: v3 -*-)
  ├── index.html   # for type=preview (or app.py + frontend)
  ├── server.py    # for type=service
  └── main.py      # for type=script
typeWhat it isAuto-install behavior on forkEligible for
publish_preview()
?
task
Scheduled cron/interval jobRegistered as paused; user activates manuallyNo
preview
Web dashboard / app
preview(action='serve')
and return URL
Yes
service
Long-running background processShow command, ask user to confirmNo
script
One-shot scriptShow command for user to runNo
Only
preview
type has a live URL to expose. The other types are open-source-only.
output/projects/{slug}/
下的每个项目结构如下:
project.yaml      # 元数据(名称、版本、类型、env_required、sc_proxy)
PROJECT.md        # 必填章节:项目介绍 / 所需环境变量 / 启动方式 / 输出内容 / 故障排除
.env.example      # 所有环境变量及占位符值
.gitignore        # 敏感信息黑名单
src/
  ├── run.py       # type=task时使用(必须以# -*- task-system: v3 -*-开头)
  ├── index.html   # type=preview时使用(或app.py + 前端代码)
  ├── server.py    # type=service时使用
  └── main.py      # type=script时使用
类型说明分支(fork)时的自动安装行为是否支持
publish_preview()
task
定时/间隔执行的任务注册为暂停状态;用户需手动激活
preview
Web仪表盘/应用执行
preview(action='serve')
并返回URL
service
长期运行的后台进程显示命令,询问用户是否确认
script
一次性执行的脚本显示供用户运行的命令
preview
类型有可暴露的实时URL。其他类型仅支持开源。

Don't conflate the two list functions

不要混淆两个列表函数

list_published_previews()
returns live URLs (preview side).
list_open_source()
returns open-sourced code (GitHub side). Different datasets — never quote one number to answer a question about the other.

list_published_previews()
返回实时URL(预览侧)。
list_open_source()
返回开源代码(GitHub侧)。两者是不同的数据集——切勿用其中一个的数量来回答另一个相关的问题。

Usage from a bash block

在bash块中使用

bash
python3 - <<'EOF'
import sys
sys.path.insert(0, "/data/workspace/skills/community-publish")
from exports import (
    # Public URL (preview type only)
    publish_preview, unpublish_preview, list_published_previews,
    # Open source code (any project type)
    open_source, remove_open_source, fork,
    list_open_source, get_open_source, validate_open_source,
)
bash
python3 - <<'EOF'
import sys
sys.path.insert(0, "/data/workspace/skills/community-publish")
from exports import (
    # 公开URL(仅preview类型)
    publish_preview, unpublish_preview, list_published_previews,
    # 开源代码(任意项目类型)
    open_source, remove_open_source, fork,
    list_open_source, get_open_source, validate_open_source,
)

Publish a running preview to a public URL

将运行中的预览发布至公开URL

print(publish_preview(preview_id="price-dashboard-a3f1", slug="price-dashboard"))
print(publish_preview(preview_id="price-dashboard-a3f1", slug="price-dashboard"))

Open-source a task (no preview involved)

开源一个任务(无预览相关操作)

print(open_source("output/projects/my-daily-digest", version_bump="patch")) EOF

---
print(open_source("output/projects/my-daily-digest", version_bump="patch")) EOF

---

Behavioral rules

行为规则

  • Show the diff before
    open_source()
    . After
    validate_open_source
    , summarize what's about to be pushed (file list, version, type, tags, env_required) and ask for confirmation. Exception: explicit "publish without confirmation" or re-publish of a known good project.
  • Never auto-run setup.sh on fork. Show the command, let the user confirm.
  • Always collect env in one batch on fork. Read project's
    env_required
    , diff against
    workspace/.env
    , call
    request_env_input
    ONCE with the missing keys. Don't ask one-by-one.
  • Slug rules: lowercase alphanumeric + hyphens, 3-50 chars, no leading/trailing hyphen. Skill auto-strips duplicate
    {user_id}-
    prefix if you accidentally include it.
  • Version rules (
    open_source
    ): strict semver. Re-publishing same version is rejected. New version must be > current latest.
  • Type immutability (
    open_source
    ): once published as
    task
    , can't change to
    preview
    later. Pick a different slug.
  • URL ≠ code: a public URL going down (container off) does NOT remove the open-source code, and vice versa. They're independent.

  • open_source()
    前显示差异
    。执行
    validate_open_source
    后,总结即将推送的内容(文件列表、版本、类型、标签、所需环境变量)并请求确认。例外情况:明确要求“无需确认直接发布”或重新发布已知正常的项目。
  • 分支(fork)时切勿自动运行setup.sh。显示命令,由用户确认后执行。
  • 分支(fork)时一次性收集所有环境变量。读取项目的
    env_required
    ,与
    workspace/.env
    对比,调用
    request_env_input
    一次获取缺失的密钥。切勿逐个询问。
  • Slug规则:小写字母数字+连字符,3-50个字符,首尾不能为连字符。若意外包含重复的
    {user_id}-
    前缀,Skill会自动去除。
  • 版本规则
    open_source
    ):严格遵循语义化版本(semver)。禁止重新发布同一版本。新版本必须高于当前最新版本。
  • 类型不可变
    open_source
    ):一旦以
    task
    类型发布,后续无法改为
    preview
    类型。需使用不同的slug。
  • URL ≠ 代码:公开URL失效(容器停止)不会移除开源代码,反之亦然。两者相互独立。

Common gotchas

常见问题

SymptomCauseFix
publish_preview
:
Preview not found
Wrong preview_id, or preview was stoppedCheck
/data/previews.json
, restart with
preview(action='serve')
publish_preview
:
429 Too many published previews
Hit 20-per-user gateway cap
unpublish_preview()
something old first
publish_preview
:
FLY_MACHINE_ID not set
Running locally, not in Starchild containerURL publish only works in the production container
open_source
:
400 Validation failed: env names not in .env.example
Listed
MY_KEY
in
env_required
but forgot
.env.example
Add the missing key to
.env.example
open_source
:
400 Possible secret detected
Secret scanner found a real-looking API keyMove to env var;
.env.example
value should be
your-key-here
open_source
:
400 Version X must be greater than current latest Y
Same-version republish or downgradeBump in
project.yaml
(
version_bump="minor"
)
remove_open_source
:
403 Permission denied
Trying to remove someone else's projectOnly the owner can remove
Forked task doesn't runAuto-registered as pausedTell user:
scheduled_task(action='activate', job_id={id})

症状原因解决方法
publish_preview
:
Preview not found
preview_id错误,或预览已停止查看
/data/previews.json
,使用
preview(action='serve')
重启预览
publish_preview
:
429 Too many published previews
达到每个用户最多20个预览的网关限制先使用
unpublish_preview()
移除旧的预览
publish_preview
:
FLY_MACHINE_ID not set
在本地运行,而非Starchild容器内URL发布仅在生产容器内可用
open_source
:
400 Validation failed: env names not in .env.example
env_required
中列出了
MY_KEY
但未在
.env.example
中添加
将缺失的密钥添加至
.env.example
open_source
:
400 Possible secret detected
敏感信息扫描器检测到疑似真实API密钥移至环境变量;
.env.example
中的值应为
your-key-here
open_source
:
400 Version X must be greater than current latest Y
重新发布同一版本或版本降级
project.yaml
中升级版本(
version_bump="minor"
remove_open_source
:
403 Permission denied
尝试移除他人的项目仅所有者可移除项目
分支(fork)的任务无法运行自动注册为暂停状态告知用户:
scheduled_task(action='activate', job_id={id})

References

参考文件

  • lib/manifest.py
    — project.yaml parser/writer + semver helpers
  • lib/validate.py
    — local pre-publish validation (mirrors gateway-side checks)
  • lib/install.py
    — type-specific install handlers (task/preview/service/script)
  • lib/gateway.py
    — HTTP client for
    /api/register
    (URL side) and
    /api/code-projects/*
    (code side)
  • lib/manifest.py
    —— project.yaml解析/写入工具 + 语义化版本辅助函数
  • lib/validate.py
    —— 本地发布前验证(与网关侧检查一致)
  • lib/install.py
    —— 不同类型项目的安装处理器(task/preview/service/script)
  • lib/gateway.py
    ——
    /api/register
    (URL侧)和
    /api/code-projects/*
    (代码侧)的HTTP客户端