publish skill
Publish oh-my-opencode to npm by triggering the GitHub Actions publish workflow and verifying its artifacts. Ship-only: never runs pre-publish-review or re-reviews merged code unless the user explicitly asks. Argument: <patch|minor|major|explicit-semver>. Triggers: publish, release, deploy, npm publish.
Is the publish skill safe?
Clean: nothing in its files matched our rules. We read 1 file in the folder on 2026-09-28.
No findings.
Install the publish skill
A skill is a folder. Copy it into your agent's skills folder and the agent loads it when the task matches its description.
git clone --depth 1 https://github.com/code-yeongyu/oh-my-openagent.git /tmp/oh-my-openagent mkdir -p ~/.claude/skills cp -r /tmp/oh-my-openagent/.agents/skills/publish ~/.claude/skills/publish
In the Claude apps, zip the folder and upload it from the Skills settings. The folder on GitHub
The instructions your agent would load
SKILL.md as published, without the frontmatter. Read it on GitHub
You are the release manager for oh-my-opencode. Execute the FULL publish workflow from start to finish.
CRITICAL: PUBLISH IS SHIP-ONLY — GO STRAIGHT TO THE WORKFLOW
origin/dev is already gated: every PR and push ran CI (test/typecheck/codex-compatibility on 3 OSes), and the publish workflow re-runs those same gates before anything is published.
- NEVER run /pre-publish-review, /review-work, or any code re-review as part of a publish request. Those run ONLY when the user explicitly asks for a review.
- NEVER "fix" code, open PRs, or enter fix-and-re-audit loops during a publish. If the workflow fails or something looks broken, report it and STOP — a publish is the wrong place to repair the tree.
- A publish request with a bump type goes from Step 0 to Step 3 (trigger) in minutes. The only human-scale work is release notes, drafted while CI runs.
CRITICAL: FULL WORKFLOW MEANS THREE RELEASE SURFACES
Publishing is complete only after all release surfaces are verified:
The publish workflow must not be reported complete while any of oh-my-opencode, oh-my-openagent, lazycodex-ai, or code-yeongyu/lazycodex verification is unresolved.
CRITICAL: FULL WORKFLOW MEANS DISCORD TOO
Publishing is not complete until the Discord release announcement has been attempted.
- DO NOT stop after creating the GitHub release.
- DO NOT stop after drafting or applying release notes.
- DO NOT wait for a second user acknowledgement if the user already confirmed the publish.
- After the release notes are finalized, immediately run Step 7.5 and post to Discord.
- If Discord posting fails after authentication/retry, report the failure clearly and continue the remaining verification steps. A skipped Discord step is a workflow failure.
CRITICAL: NO EARLY TURN-END AFTER TRIGGER (COMPLETION CONTRACT)
Once gh workflow run publish succeeds, the publish is NOT done. A prior session forgot this: it triggered the workflow and ended its turn, leaving the release unverified, the enhanced summary unwritten, and the Discord announcement unsent. That mistake is why this section exists.
After Step 3 (trigger), you MUST drive the run to a terminal conclusion AND complete every post-trigger step before ending your turn. You may NOT end the turn, hand off, or stop for the day while ANY of these is unresolved:
- Run conclusion — gh run view --json conclusion must return success (poll while drafting notes; never sleep idle).
- Release exists — Step 5: gh release view v${NEW_VERSION} resolves.
- Enhanced summary applied — Step 6 + Step 7: draft (mandatory for patch/minor/major) AND gh release edit --notes-file applied. "Patch is optional" is wrong; patch summaries are MANDATORY.
- Discord announced — Step 7.5: agent-discordbot message send attempted; either a message id is recorded OR a clear failure is reported to the user. A skipped Discord step is a workflow failure.
- npm verified — Step 8: npm view oh-my-opencode version (and oh-my-openagent, lazycodex-ai) shows ${NEW_VERSION}.
Only after all five are green may you end the turn. If the run fails, run gh run view --log-failed, report it, and STOP (do not repair the tree mid-publish). If a post-trigger step fails for an external reason (npm propagation, Discord auth), report it clearly and continue the remaining steps — do not let one failure abort the rest.
This contract applies to the slash-command copies (.agents/command/publish.md, .opencode/command/publish.md) too; they are kept byte-identical to this skill per the .agents/AGENTS.md drift rule.
CRITICAL: ARGUMENT REQUIREMENT
You MUST receive one release selector from the user. Valid options:
- patch: Bug fixes, backward-compatible (1.1.7 → 1.1.8)
- minor: New features, backward-compatible (1.1.7 → 1.2.0)
- major: Breaking changes (1.1.7 → 2.0.0)
- An explicit valid semantic version, including a prerelease such as 5.0.0-beta.9
If the user did not provide a release selector, STOP IMMEDIATELY and ask:
"To proceed with deployment, specify patch, minor, major, or an explicit semantic version such as 5.0.0-beta.9."
Reject any other value. Do not infer or repair malformed versions.
STEP 0: REGISTER TODO LIST (MANDATORY FIRST ACTION)
Before doing ANYTHING else, create a detailed todo list using TodoWrite:
[
{ "id": "confirm-release-input", "content": "Confirm release selector with user (patch/minor/major or explicit semver)", "status": "in_progress", "priority": "high" },
{ "id": "check-uncommitted", "content": "Check for uncommitted changes and commit if needed", "status": "pending", "priority": "high" },
{ "id": "sync-remote", "content": "Sync with remote (pull --rebase && push if unpushed commits)", "status": "pending", "priority": "high" },
{ "id": "run-workflow", "content": "Trigger GitHub Actions publish workflow", "status": "pending", "priority": "high" },
{ "id": "wait-workflow", "content": "Wait for workflow completion (poll every 30s)", "status": "pending", "priority": "high" },
{ "id": "verify-and-preview", "content": "Verify release created + preview auto-generated changelog & contributor thanks", "status": "pending", "priority": "high" },
{ "id": "draft-summary", "content": "Draft enhanced release summary (mandatory for all release types)", "status": "pending", "priority": "high" },
{ "id": "apply-summary", "content": "Prepend enhanced summary to release", "status": "pending", "priority": "high" },
{ "id": "discord-announce", "content": "MANDATORY: posMark each todo as inprogress when starting, completed when done. ONE AT A TIME.**
STEP 1: CONFIRM AND CLASSIFY THE RELEASE SELECTOR
If the user already supplied the selector in the command argument or message, that IS the confirmation. Parse it exactly once:
RELEASE_INPUT="${ARGUMENTS}"
if [[ "$RELEASE_INPUT" =~ ^(patch|minor|major)$ ]]; then
RELEASE_KIND=bump
elif [[ "$RELEASE_INPUT" =~ ^([0-9]+\.){2}[0-9]+(-[0-9A-Za-z]+(\.[0-9A-Za-z]+)*)?$ ]]; then
RELEASE_KIND=version
else
echo "Invalid release selector: $RELEASE_INPUT" >&2
exit 1
fiOnly ask and wait when no selector was provided.
STEP 2: CHECK UNCOMMITTED CHANGES
Run: git status --porcelain
- If there are uncommitted changes, warn user and ask if they want to commit first
- If clean, proceed
STEP 2.5: SYNC WITH REMOTE (MANDATORY)
Check if there are unpushed commits:
git log @{u}..HEAD --onelineIf there are unpushed commits, you MUST sync before triggering workflow:
git pull --rebase && git pushThis ensures the GitHub Actions workflow runs on the latest code including all local commits.
STEP 3: TRIGGER GITHUB ACTIONS WORKFLOW
Dispatch from dev, pass bump selectors through bump, and pass exact versions through version. The required bump input remains patch for explicit-version dispatches but is ignored by the workflow because version takes precedence.
if [ "$RELEASE_KIND" = bump ]; then
RUN_URL="$(gh workflow run publish.yml --ref dev -f "bump=${RELEASE_INPUT}")"
else
RUN_URL="$(gh workflow run publish.yml --ref dev -f bump=patch -f "version=${RELEASE_INPUT}")"
fi
if ! [[ "$RUN_URL" =~ ^https://github.com/code-yeongyu/oh-my-openagent/actions/runs/[0-9]+$ ]]; then
echo "Publish dispatch did not return an exact workflow run URL: $RUN_URL" >&2
exit 1
fi
RUN_ID="${RUN_URL##*/}"
if ! [[ "$RUN_ID" =~ ^[0-9]+$ ]]; then
echo "Publish dispatch returned an invalid run ID: $RUN_ID" >&2
exit 1
fi
gh run view "${RUN_ID}" --json databaseId,status,url --jq '{databaseId,status,url}'The returned run ID owns this release attempt. Never replace it with a latest-run lookup.
STEP 4: WAIT FOR WORKFLOW COMPLETION
The publish run is a single workflow with sequential stages. Expected timeline (from recent real runs, ~30 min total):
Poll job-level status every 30 seconds and report stage transitions to the user:
gh run view "${RUN_ID}" --json status,conclusion,jobs --jq '{status, conclusion, stage: ([.jobs[] | select(.status=="in_progress") | .name] | join(", "))}'IMPORTANT: Use polling loop, NOT sleep commands. Use the waiting time to draft the enhanced release summary (Step 6) — do not sit idle, and do not start any review activity.
If conclusion is failure, show error and stop:
gh run view "${RUN_ID}" --log-failedSTEP 5: VERIFY RELEASE & PREVIEW AUTO-GENERATED CONTENT
Two goals: confirm the release exists, then show the user what the workflow already generated.
# Pull latest (workflow committed version bump)
git pull --rebase
NEW_VERSION=$(node -p "require('./package.json').version")
# Verify release exists on GitHub
gh release view "v${NEW_VERSION}" --json tagName,url --jq '{tag: .tagName, url: .url}'Release notes are written BEFORE the release, not after.
The release body is extracted from the CHANGELOG.md section for this version. Author the user-facing notes under ## [Unreleased] and land them before dispatching /publish; release-state preparation stamps that heading into ## [] - and commits it with the release state, so the published commit already carries its own notes.
Preview exactly what the release body will be:
bun run script/generate-changelog.ts > /tmp/contributors.md
bun run script/print-release-notes.ts "${NEW_VERSION}" /tmp/contributors.mdAfter running the preview, present the output to the user and say:
This is the exact body the release will publish: the notes you authored under [Unreleased],
then contributor thank-yous for non-team contributors, then the install footer.
More skills from code-yeongyu/oh-my-openagent
- Aast-grepSearches and rewrites code by AST shape across 25 languages. Use when the target is a syntax pattern (every call/class/import shaped like X, a codemod, a YAML rule) rather than literal text; for plain strings, comments, or filenames, use rg.
- AbrowserDrives a real browser through the omowright library from the js eval kernel: sites the user is already signed into, forms and clicks, JS-rendered pages, screenshots, web QA, extension popups, a human handoff for login, CAPTCHA or OTP, and a browser you own for scraping, bot-scored targets, network capture and QA traces. Use for any interactive browser task; not for a plain search or an unblocked static fetch.
- Acodex-qaQA the omo Codex Light edition (lazycodex / packages/omo-codex) itself, in strict isolation so ONLY our plugin is exercised, never the user's real ~/.codex. The first-party method drives the real `codex app-server` against an isolated CODEX_HOME plus a LOCAL mock model (no real API call), and proves a plugin hook fired by asserting hook/started + hook/completed notifications. Also: isolated install verification, per-component hook probes, a tmux TUI smoke, and runtime log observation (RUST_LOG / logs SQLite / /debug-config). Ships tested helper scripts each with a --self-test. Use whenever someone changes anything under packages/omo-codex or wants to QA, smoke-test, verify, or debug the Codex plugin, its hooks/components, the installer/config.toml, the app-server flow, or the Codex TUI. Triggers: codex qa, qa codex, codex-qa, test codex plugin, verify codex hook, codex app-server, lazycodex qa, isolated CODEX_HOME, prove codex hook fired, codex tui test.
- Acoding-agent-sessionsFinds, reads, and reconstructs coding-agent sessions across Codex, Claude, OpenCode, OMO/Senpi, and other local agent logs. Use when asked to find or search past sessions, transcripts, or subagent runs, or to recover what an earlier session did.
- Acomment-checkerUse when Codex needs to understand or respond to automatic comment-checker feedback emitted after an edit-like PostToolUse hook.
- Adag-libraryStores a DAG definition once and re-runs it by name, instead of pasting the definition into every run. Use when the user wants to save a DAG, run a saved one, or schedule the same multi-agent graph repeatedly.
- Ddata-scientistProcesses and analyzes data with resident-kernel engines (DuckDB, Polars) and one-shot tools. Use for CSV/parquet/JSON analysis, group-by/join/aggregation, time series, distributions, cleaning, or plotting a dataset.
- AdebuggingRuns a hypothesis-driven debugging loop across any language or binary, escalating to orthogonal oracle angles and locking the fix with a failing test. Use for crashes, silent failures, hangs, wrong responses, memory leaks, async misbehavior, or reverse engineering.
- Adev-browserBrowser automation with persistent page state. Use when users ask to navigate websites, fill forms, take screenshots, extract web data, test web apps, or automate browser workflows. Trigger phrases include "go to [url]", "click on", "fill out the form", "take a screenshot", "scrape", "automate", "test the website", "log into", or any browser interaction request.
- CfrontendBuilds, styles, and polishes web UI and UX. Use for any frontend, page, component, styling, layout, animation, or visual-quality task, or when asked to make an interface look or feel a certain way.
- AfrontendBuilds, styles, and polishes web UI and UX. Use for any frontend, page, component, styling, layout, animation, or visual-quality task, or when asked to make an interface look or feel a certain way.
- Aget-unpublished-changesCompare HEAD with the latest published npm versions and list all unpublished changes by release layer. Triggers: unpublished changes, changelog, what changed, whats new.