Mention/keyword sweep on social platforms for [REPLACE: KEYWORDS] — trends, sentiment, top posts
日本語の概要は準備中です。原文の説明を表示しています。
Package one of this agent's own skills as a standalone community pack and submit it to the aeon registry as a PR
インストール方法を見るインストールする前に、エージェントに与えられる指示の中身を確認できます。
${var} — The local skill to publish as a community pack: a skill slug (a directory name under
skills/), optionally followed by flags. Required. Examples:
token-movers— packageskills/token-movers/into a fresh public repo and submit it to the aeon registrytoken-movers --repo myorg/aeon-token-movers— override the pack repo name (defaultaeon-skill-pack-<slug>)token-movers --no-register— create and push the pack repo, but skip the registry PR againstaeonfun/aeontoken-movers --dry-run— build and validate the pack locally, write nothing to GitHub
If ${var} is empty, exit PACK_SUBMIT_NO_VAR:
./notify "pack-submit aborted: var empty — pass a skill slug e.g. \"token-movers\""
Then stop.
Today is ${today}. Your task is to take the existing skill named in ${var}, wrap it in a standalone community-pack repo (its own GitHub repo with a skills-pack.json manifest), and submit it to the aeon community registry - a PR against aeonfun/aeon that adds both surfaces the registry demands in one diff: a row in the Listed packs table in docs/community-skill-packs.md AND a matching entry in catalog/skill-packs.json. This is the inverse of install-skill: instead of pulling a community pack in, it pushes one of your own skills out for every other Aeon agent to install with bin/install-skill-pack.
A community pack is a public GitHub repo that holds one or more skills plus a skills-pack.json manifest that names and versions them. bin/install-skill-pack owner/repo reads that manifest and installs the skills. To be discoverable (listed by bin/install-skill-pack --list and the dashboard's Community Packs panel), the pack must also be registered in aeonfun/aeon's catalog/skill-packs.json + the Listed packs table in docs/community-skill-packs.md. So publishing is two moves: (a) stand up the pack repo, (b) open the registry PR. This skill does both. Full protocol: docs/community-skill-packs.md.
Parse and validate ${var}. The first whitespace-separated token is the skill slug; the rest are flags (--repo owner/name, --no-register, --dry-run). The slug must match ^[a-z0-9][a-z0-9-]*$ and resolve to a real directory:
SLUG=$(echo "${var}" | awk '{print $1}')
FLAGS=$(echo "${var}" | cut -s -d' ' -f2-)
if ! echo "$SLUG" | grep -qE '^[a-z0-9][a-z0-9-]*$'; then
./notify "pack-submit aborted: \"$SLUG\" is not a valid skill slug (lowercase kebab-case)"; exit 0
fi
if [ ! -f "skills/$SLUG/SKILL.md" ]; then
./notify "pack-submit aborted: skills/$SLUG/SKILL.md not found — run with a slug from \`ls skills/\`"; exit 0
fi
If validation fails, exit PACK_SUBMIT_BAD_VAR with the notify above and stop. Extract the boolean flags from $FLAGS and the optional --repo value.
Read the source skill's metadata. Everything the manifest and registry entry need is already declared in skills/$SLUG/SKILL.md's frontmatter — read it, don't invent it:
metadata.title; fall back to the top-level name:.description: (one line).metadata.category. Registry categories are an open vocabulary, but first-party-only values (core, evolution, basics) don't describe a third-party pack — if you see one of those, pick the closest community category (dev, crypto, productivity, research, social) from what the skill actually does. Otherwise pass the category through.metadata.requires. An entry ending in ? is optional → secrets_optional; an entry without ? is required → secrets_required. Strip the ?. Registry secrets_required must be UPPER_SNAKE env names.metadata.capabilities, copied verbatim (already the locked taxonomy; see docs/CAPABILITIES.md). Omit if absent.fm(){ sed -n '/^---$/,/^---$/p' "skills/$SLUG/SKILL.md"; }
TITLE=$(fm | sed -n 's/^[[:space:]]*title:[[:space:]]*//p' | head -1)
[ -z "$TITLE" ] && TITLE=$(fm | sed -n 's/^name:[[:space:]]*//p' | head -1)
DESC=$(fm | sed -n 's/^description:[[:space:]]*//p' | head -1)
CATEGORY=$(fm | sed -n 's/^[[:space:]]*category:[[:space:]]*//p' | head -1)
Collect requires:/capabilities: list items (lines under those keys beginning with -) into shell arrays; split requires into required (no ?) and optional (trailing ?, stripped).
Build the pack repo locally. Stage a clean working tree — the manifest at root, the full skill directory copied verbatim (including any helper scripts/config, not just SKILL.md), a README, and an MIT LICENSE:
PACK_DIR=$(mktemp -d)/pack
mkdir -p "$PACK_DIR/skills/$SLUG"
cp -R "skills/$SLUG/." "$PACK_DIR/skills/$SLUG/"
Write $PACK_DIR/skills-pack.json (build it with python3/jq, never string concatenation, so quoting is safe). Include only fields you actually have:
{
"name": "<TITLE>",
"version": "0.1.0",
"description": "<DESC>",
"author": "<operator github handle>",
"license": "MIT",
"homepage": "https://github.com/<owner>/<pack-repo>",
"skills": [
{
"slug": "<SLUG>",
"path": "skills/<SLUG>",
"description": "<DESC>",
"category": "<CATEGORY>",
"schedule": "0 12 * * *",
"default_enabled": false,
"secrets_required": [ ... ],
"secrets_optional": [ ... ],
"capabilities": [ ... ]
}
]
}
Write a README.md that names the skill, states its schedule assumption, lists required/optional secrets, and shows the one-line install (bin/install-skill-pack <owner>/<pack-repo>). Write a standard MIT LICENSE (year ${today}'s year, copyright the operator handle). Resolve the operator handle once: OWNER=$(gh api user --jq .login).
Pre-flight the pack. Run the repo's own validator against the staged directory — it enforces exactly what bin/install-skill-pack requires (valid JSON manifest, clean slug, no .. in paths, the SKILL.md present, locked-taxonomy capabilities):
./scripts/validate-pack.sh "$PACK_DIR" 2>&1 | tee /tmp/pack-validate.txt
Exit non-zero (an ERROR: line) → exit PACK_SUBMIT_INVALID_PACK, notify with the failing line, and stop. Do not push an invalid pack. Warnings are fine to proceed on; surface them in the notify.
If --dry-run was passed, stop here: notify the operator that the pack built and validated cleanly at $PACK_DIR, list the manifest fields, and exit PACK_SUBMIT_DRY_RUN without touching GitHub.
Create and push the pack repo. Default repo name aeon-skill-pack-$SLUG (or the --repo override). The pack must be public — the installer fetches its tarball, and a private pack can't be installed by anyone else:
PACK_REPO="${REPO_OVERRIDE:-aeon-skill-pack-$SLUG}" # owner defaults to $OWNER
gh repo view "$PACK_REPO" >/dev/null 2>&1 \
&& { ./notify "pack-submit aborted: repo $PACK_REPO already exists — pass --repo to pick another name"; exit 0; }
( cd "$PACK_DIR" && git init -q && git add -A \
&& git commit -q -m "Aeon community pack: $SLUG" \
&& gh repo create "$PACK_REPO" --public --source=. --push )
Capture the resulting owner/repo (FULL_REPO=$(gh repo view "$PACK_REPO" --json nameWithOwner --jq .nameWithOwner)). If repo creation fails (permission/name), exit PACK_SUBMIT_REPO_FAILED, notify with the gh error's shortest decisive line, and stop.
Submit the registry PR against aeonfun/aeon (skip this whole step if --no-register was passed - then jump to step 7 reporting only the pack repo). The registry lives in the canonical repo, so work against a fork, not this instance's checkout - this instance's catalog/skill-packs.json and docs/community-skill-packs.md can be stale:
WORK=$(mktemp -d)
gh repo fork aeonfun/aeon --clone=true --default-branch-only 2>/dev/null || true
git clone -q "https://github.com/$OWNER/aeon.git" "$WORK/aeon" || git clone -q https://github.com/aeonfun/aeon.git "$WORK/aeon"
cd "$WORK/aeon" && git checkout -b "pack-submit/$SLUG"
Make the two edits the validator (scripts/validate-skill-packs.mjs) checks for parity:
(a) catalog/skill-packs.json — append one object to .packs. Build it with jq from the values you resolved (mirror the pack's own manifest: skills is ["$SLUG"], trust_level is "community", aggregate secrets_required/capabilities from the skill):
jq --arg repo "$FULL_REPO" --arg name "$TITLE" --arg desc "$DESC" \
--arg author "$OWNER" --arg homepage "https://github.com/$FULL_REPO" \
--arg cat "$CATEGORY" --arg slug "$SLUG" \
'.packs += [ { repo:$repo, name:$name, description:$desc, author:$author,
license:"MIT", homepage:$homepage, category:$cat, trust_level:"community",
skills:[$slug] } ]' catalog/skill-packs.json > /tmp/reg.json \
&& mv /tmp/reg.json catalog/skill-packs.json
Add secrets_required / capabilities keys to that object only when the skill declares them (keep it in sync with the pack manifest). Do not use trust_level: trusted — that requires the repo to be in skills/security/trusted-sources.txt, and the validator rejects an unearned trusted.
(b) docs/community-skill-packs.md - add a table row under the | Pack | Skills | Description | header in the Listed packs section (the last section of the file). The table moved there from .github/README.md in #845; do not edit the README. The row format, matching the existing rows exactly:
| [<pack-repo-name>](https://github.com/<FULL_REPO>) | 1 | <one-line description, ≤110 chars>. |
Use python3 for a surgical insert. The row must land inside the table's contiguous block - insert it immediately after the last existing | [ row, never after a blank line or other text. The parity validator parses rows only until the first non-| line, so a row placed past the table is invisible to it and the PR fails CI with "in the registry but has no row in the Community Packs table". Verify with a re-read that the row sits among the other rows:
import re
lines = open("docs/community-skill-packs.md").read().split("\n")
sec = next(i for i,l in enumerate(lines) if re.match(r'^#+\s+Listed packs\s*$', l))
hdr = next(i for i in range(sec,len(lines)) if re.match(r'^\|\s*Pack\s*\|\s*Skills\s*\|\s*Description\s*\|', lines[i]))
i = hdr + 2; last = i
while i < len(lines) and lines[i].startswith("|"): last = i; i += 1 # last data row
lines.insert(last + 1, f"| [{PACK_NAME}](https://github.com/{FULL_REPO}) | 1 | {DESC} |")
open("docs/community-skill-packs.md","w").write("\n".join(lines))
Validate parity before committing — this is the exact CI gate the PR will hit:
node scripts/validate-skill-packs.mjs
A non-zero exit → fix the reported mismatch (skill count, a missing row, or a --path flag) and re-run until it prints validate-skill-packs: OK. Never open the PR on a red validator.
Then commit both files together, push the branch to your fork, and open the PR against the canonical repo:
git add catalog/skill-packs.json docs/community-skill-packs.md
git commit -m "feat: list $TITLE community pack ($FULL_REPO)"
git push -u origin "pack-submit/$SLUG"
PR_URL=$(gh pr create --repo aeonfun/aeon --title "feat: list $TITLE community pack" --body "$(cat <<BODY
## New community pack
**Pack:** [$FULL_REPO](https://github.com/$FULL_REPO)
**Skill:** \`$SLUG\` — $DESC
**Author:** @$OWNER · **License:** MIT · **Category:** $CATEGORY
Adds a row to the Listed packs table in \`docs/community-skill-packs.md\` and a matching \`catalog/skill-packs.json\` entry (both in this diff, per the publishing checklist). \`node scripts/validate-skill-packs.mjs\` passes locally.
Install once merged:
\`\`\`
bin/install-skill-pack $FULL_REPO
\`\`\`
BODY
)")
Capture PR_URL. If gh pr create fails because a PR already exists for the branch, capture the existing URL instead of erroring. This PR is not self-merging — it lands in someone else's repo and is reviewed by the aeon maintainers.
Log. Append to memory/logs/${today}.md:
### pack-submit
- Skill: {SLUG} ({TITLE})
- Pack repo: https://github.com/{FULL_REPO}
- Registry PR: {PR_URL or "skipped (--no-register)"}
- Secrets: {required list or "none"} · Capabilities: {list or "none"}
- Exit: PACK_SUBMIT_OK (or the code that applied)
Notify. Send one concise line via ./notify (≤4000 chars, clickable URLs):
*pack-submit — {TITLE}*
Pack repo: https://github.com/{FULL_REPO}
Registry PR: {PR_URL}
Install: `bin/install-skill-pack {FULL_REPO}`
{"Requires: X, Y" if any required secrets, else omit}
On --no-register, say the pack repo is live and give the exact PR checklist link (docs/community-skill-packs.md#pack-maintainers-publishing-checklist) so the operator can list it manually.
| Code | When | Action |
|---|---|---|
PACK_SUBMIT_OK | Pack repo pushed and registry PR opened (or --no-register completed) | Notify with pack repo + PR link |
PACK_SUBMIT_NO_VAR | ${var} empty | Notify abort reason; stop |
PACK_SUBMIT_BAD_VAR | Slug malformed or skills/<slug>/SKILL.md missing | Notify with the slug; stop |
PACK_SUBMIT_INVALID_PACK | validate-pack.sh reported an ERROR | Notify with the failing line; stop (nothing pushed) |
PACK_SUBMIT_DRY_RUN | --dry-run — built + validated, wrote nothing to GitHub | Notify with the staged path + manifest summary |
PACK_SUBMIT_REPO_FAILED | gh repo create failed (name taken, permission) | Notify with the gh error; stop |
PACK_SUBMIT_REGISTRY_FAILED | Fork/clone/validate/PR step failed after the pack repo was pushed | Notify: pack repo is live, registry PR did not open, with the failing step |
There is no network sandbox — git and gh reach GitHub directly. gh is authenticated in Actions (via GH_GLOBAL when set; the ambient GITHUB_TOKEN otherwise, which cannot create repos or cross-repo PRs — surface that as PACK_SUBMIT_REPO_FAILED rather than looping). Every irreversible outward write — creating the public pack repo (step 5) and opening the registry PR (step 6) — happens in-run and is fail-closed: a failed pre-flight (validate-pack.sh) or a failed parity check (validate-skill-packs.mjs) stops before any push. Confirm reachability with gh api repos/aeonfun/aeon --jq .full_name before deciding a fork/clone failure is real vs transient.
skills/. This skill packages and distributes; it does not author. To create a new skill, use create-skill.trust_level: trusted — that is earned via skills/security/trusted-sources.txt, and the validator rejects a self-declared trusted. Community packs use trust_level: community.validate-skill-packs.mjs — a broken registry entry takes down bin/install-skill-pack --list and the dashboard panel for everyone.docs/community-skill-packs.md and the skill-packs.json entry ship in one diff, with matching skill counts. That is what the CI gate enforces.requires:), never values.まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Mention/keyword sweep on social platforms for [REPLACE: KEYWORDS] — trends, sentiment, top posts
日本語の概要は準備中です。原文の説明を表示しています。
Watch Vercel deploys for [REPLACE: VERCEL_PROJECT] — alert on [REPLACE: ALERT_ON] in the last [REPLACE: LOOKBACK_HOURS] hours
日本語の概要は準備中です。原文の説明を表示しています。
First-touch review of newly opened PRs on [REPLACE: WATCHED_REPO] — verdict + welcoming comment + label
日本語の概要は準備中です。原文の説明を表示しています。
Summary of the [REPLACE: CHANNEL_PLATFORM] channel [REPLACE: CHANNEL_NAME] — top [REPLACE: TOP_N_THREADS] threads + open questions
日本語の概要は準備中です。原文の説明を表示しています。
Price and volume tracker for [REPLACE: TOKEN_SYMBOL] with anomaly alerts above [REPLACE: ALERT_THRESHOLD_PCT]% movement
日本語の概要は準備中です。原文の説明を表示しています。
Digest of the most interesting new posts on [REPLACE: TOPIC] from RSS feeds and the open web
日本語の概要は準備中です。原文の説明を表示しています。