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
6 changes: 4 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"plugins": [
{
"name": "yopstack",
"description": "Claude Code plugin. opentofu + land-and-deploy + canary + setup-deploy. Provisioning, deploy, observability for agent-driven infra. No Yesterday-infra deps.",
"version": "0.0.1",
"description": "Claude Code plugin. opentofu + railway-deploy + butler-deploy + land-and-deploy + canary + setup-deploy. Provisioning, deploy, observability for agent-driven infra. No Yesterday-infra deps.",
"version": "0.0.2",
"source": "./",
"author": {
"name": "Yesterday",
Expand All @@ -22,6 +22,8 @@
"infrastructure",
"observability",
"opentofu",
"railway",
"itch.io",
"yesterday-ai"
]
}
Expand Down
6 changes: 4 additions & 2 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "yopstack",
"version": "0.0.1",
"description": "Yesterday Ops Stack -- generic infrastructure-provisioning, deployment, and observability skills for Claude Code agents. opentofu + land-and-deploy + canary + setup-deploy. Public, no Yesterday-infra dependencies.",
"version": "0.0.2",
"description": "Yesterday Ops Stack -- generic infrastructure-provisioning, deployment, and observability skills for Claude Code agents. opentofu + railway-deploy + butler-deploy + land-and-deploy + canary + setup-deploy. Public, no Yesterday-infra dependencies.",
"author": {
"name": "Yesterday",
"url": "https://github.com/Yesterday-AI"
Expand All @@ -16,6 +16,8 @@
"infrastructure",
"observability",
"opentofu",
"railway",
"itch.io",
"yesterday-ai"
],
"dependencies": [
Expand Down
32 changes: 32 additions & 0 deletions .ytstack/DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,35 @@ Plus: `opentofu` originally placed in yastack (agentic-foundation migration list
**How to apply:**
- yopstack skill list excludes `qa`.
- If a future need for ops-specific testing emerges (e.g. infra smoke tests post-deploy), reassess then.

---

## 2026-04-26: Lean SKILL.md + `references/` subfolder for tool-heavy skills

**Context:** During the railway-deploy consolidation (2026-04-26), three imported skills (`railway-cli`, `railway-deploy`, `railway-deploy-nextjs`) overlapped: ~700 lines combined, ~50% redundancy, ~3 contradictions on the actual CLI command shape. User asked to consolidate without making the resulting skill bloated.

**Options considered:**

- A) One monolithic SKILL.md with all CLI ref + Next.js recipe inline. Simple, but ~600+ lines load every invocation -- bloats agent context for routine "redeploy this service" tasks.
- B) Lean SKILL.md (decision-oriented: when-to-use, top gotchas, core workflows, command index) plus `references/` subfolder (full CLI reference, framework-specific recipes) loaded on demand.
- C) Keep three separate skills. Rejected -- selection conflicts (which skill wins for "deploy nextjs to railway"?), gotchas drift across copies.

**Chose:** B.

**Reason:** Matches how agents actually consume skills -- they need quick orientation + the 5-10 most common workflows in-context, and only need the full CLI surface area for edge cases. Keeping references separate also makes the gotchas/CLI table the single source of truth (one file to update when the upstream tool changes). 165-line SKILL.md vs 600+ inline is the difference between "always loaded" and "loaded when needed".

**How to apply:**

- New yopstack skills that wrap a CLI / framework with substantial surface area follow this layout:

```text
skills/<name>/
├── SKILL.md # lean: when-to-use + gotchas + core workflows + command index
└── references/ # loaded on demand
├── <tool>-reference.md # full CLI ref / API surface / config schema
└── <framework>-recipe.md # framework- or stack-specific deploy patterns
```

- SKILL.md must include an explicit "References" section pointing to each `references/*.md` so the agent discovers them.
- Skills with a small surface area (single-purpose tool, no framework variants) can stay single-file -- this pattern is for tool-heavy skills, not a blanket rule.
- Same pattern is portable to yastack / ytstack core skills if they ever bloat past ~250 lines.
18 changes: 11 additions & 7 deletions .ytstack/STATE.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
---
project: yopstack
slug: yopstack
last_updated: 2026-04-25T00:00:00Z
current_milestone: none (pre-migration, reactive mode)
last_updated: 2026-04-26T00:00:00Z
current_milestone: none (reactive mode -- skills landing ad-hoc)
active_slice: none
active_task: none
---

# State

**Status:** v0.0.1 scaffold. Plugin manifest + self-marketplace + documentation in place. **No skills migrated or wrapped yet.** Pre-work reactive mode -- waiting for `opentofu` migration from yastack + `vendor/gstack` subtree-add.
**Status:** v0.0.2. `opentofu` migrated (Phase 2, 2026-04-26). `railway-deploy` and `butler-deploy` added 2026-04-26 as native yopstack skills (not part of the agentic-foundation migration). 3 skills shipped, 3 pending gstack subtree.

## Skill source plan

| Skill | Source | Status |
|---|---|---|
| opentofu | yastack/skills/opentofu (originally agentic-foundation) | pending migration |
| opentofu | yastack/skills/opentofu (originally agentic-foundation) | shipped 2026-04-26 |
| railway-deploy | added in yopstack (consolidated from 3 imported skills) | shipped 2026-04-26 |
| butler-deploy | added in yopstack (generified from a game project) | shipped 2026-04-26 |
| land-and-deploy | vendor/gstack/land-and-deploy (subtree TBD) | pending wrap |
| canary | vendor/gstack/canary (subtree TBD) | pending wrap |
| setup-deploy | vendor/gstack/setup-deploy (subtree TBD) | pending wrap |
Expand All @@ -34,10 +36,12 @@ active_task: none

## Recent changes

- 2026-04-26: `railway-deploy` consolidated from three imported skills (`railway-cli` + `railway-deploy` + `railway-deploy-nextjs`) into one lean SKILL.md + `references/cli-reference.md` (full CLI) + `references/nextjs-prisma.md` (framework recipe). Established the lean-SKILL+references pattern as a yopstack convention (DECISIONS 2026-04-26).
- 2026-04-26: `butler-deploy` audited and generified -- removed pixelrealm/pixelforgestudios hardcoding and project-specific npm-script narrative; now ships generic butler push patterns + CI auth note + channel-per-platform recipe.
- 2026-04-26: docs aligned -- README "What's in it" table grew to 6 skills, skills/README.md table updated, plugin.json + marketplace.json descriptions/keywords updated (added `railway` + `itch.io`). Patch bump 0.0.1 -> 0.0.2.
- 2026-04-26: `opentofu` landed (Phase 2 migration from yastack/agentic-foundation).
- 2026-04-25: scaffolded as standalone public repo (analog yastack pattern). Plugin manifest, self-marketplace, README/CLAUDE/LICENSE/NOTICE, Yesterday wordmark logo, minimal `.ytstack/` (PROJECT + DECISIONS + STATE) per dogfooding precedent. Listed in both `Yesterday-AI/ystacks` (public catalog) and own self-marketplace.

## Next action

Awaiting `opentofu` migration from yastack + `vendor/gstack` subtree-add. When ready: scaffold M001-Migration milestone here, sliced by skill-cluster (provisioning, deploy-execution, observability), executed via TDD/verify/summarize loop per migrated/wrapped skill.

No user-side actions blocking; no agent-side actions queued until migration begins.
`vendor/gstack` subtree-add still pending -- needed before `land-and-deploy`, `canary`, `setup-deploy` can be wrapped via the ytstack-style shell-exec inject pattern. No user-side actions blocking; reactive mode continues for ad-hoc skill drops.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,24 @@ The ops layer of the Yesterday plugin family. Skills for the deploy-arc that com

## What's in it

4 generic skills:
6 generic skills:

| Skill | Source | Purpose |
|---|---|---|
| opentofu | **migrated from agentic-foundation (Phase 2)** | Autonomous infrastructure provisioning |
| land-and-deploy | gstack | Merge + deploy + canary-checks prod + offer revert |
| canary | gstack | Post-deploy visual monitor (console errors, perf regressions, broken links) |
| setup-deploy | gstack | Initialize deploy infrastructure |
| railway-deploy | added in yopstack | Deploy/manage/debug services on Railway via CLI |
| butler-deploy | added in yopstack | Publish HTML5 game builds to itch.io via butler |
| land-and-deploy | gstack (pending) | Merge + deploy + canary-checks prod + offer revert |
| canary | gstack (pending) | Post-deploy visual monitor (console errors, perf regressions, broken links) |
| setup-deploy | gstack (pending) | Initialize deploy infrastructure |

Plus one cross-marketplace dependency (auto-pulled via plugin.json):

| Plugin | Purpose |
|---|---|
| [skill-creator](https://github.com/Yesterday-AI/ystacks/tree/main/plugins/skill-creator) | Meta-skill for creating new agent skills |

**Status:** Phase 2 of the agentic-foundation -> ystacks migration. `opentofu` landed 2026-04-26. The three gstack ops skills (`land-and-deploy`, `canary`, `setup-deploy`) wait on the `vendor/gstack` subtree.
**Status:** Phase 2 of the agentic-foundation -> ystacks migration. `opentofu` landed 2026-04-26; `railway-deploy` and `butler-deploy` added 2026-04-26 as native yopstack skills. The three gstack ops skills (`land-and-deploy`, `canary`, `setup-deploy`) wait on the `vendor/gstack` subtree.

## Install

Expand Down
4 changes: 4 additions & 0 deletions skills/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
| Skill | Status | One-liner |
|---|---|---|
| `opentofu` | migrated 2026-04-26 (Phase 2) | Autonomous IaC via OpenTofu (Terraform fork) -- init, plan, apply, destroy, import |
| `railway-deploy` | added 2026-04-26 | Deploy/manage/debug services on Railway via CLI -- auth, projects, services, env, networking, logs |
| `butler-deploy` | added 2026-04-26 | Publish HTML5 game builds to itch.io via butler CLI -- install, login, push, channel-per-platform |
| `land-and-deploy` | pending gstack vendor | Merge + deploy + canary checks + revert flow |
| `canary` | pending gstack vendor | Post-deploy visual monitor |
| `setup-deploy` | pending gstack vendor | Initialize deploy infrastructure |

`railway-deploy` keeps its bulk in `references/` (full CLI ref + Next.js+Prisma recipe) so `SKILL.md` stays lean.

See parent [README.md](../README.md#whats-in-it) for cross-marketplace plugin imports (`skill-creator`) auto-pulled via `plugin.json`.

Per the [agentic-foundation MIGRATION-TRIAGE.md](https://github.com/Yesterday-AI/agentic-foundation/blob/main/MIGRATION-TRIAGE.md) (FROZEN v8).
136 changes: 136 additions & 0 deletions skills/butler-deploy/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
---
name: butler-deploy
description: >
Publish or update an HTML5 game on itch.io via the butler CLI. Covers
install, login, channel push with versioning, and first-time page setup.
Use when deploying a web game build (e.g. dist/) to an itch.io channel.
---

# Butler Deploy

Push HTML5 game builds to itch.io with the [butler CLI](https://itchio.itch.io/butler).
Butler does delta uploads (only changed files after the first push) and the
game is live the moment the push completes.

## When to use

- First-time publish of a web build to itch.io
- Updating an existing itch.io page with a new build
- Wiring an itch.io deploy step into CI

## Prerequisites

### 1. Install butler (one-time, per machine)

```bash
# macOS
brew install butler

# Linux
curl -L -o butler.zip https://broth.itch.ovh/butler/linux-amd64/LATEST/archive/default
unzip butler.zip
mv butler /usr/local/bin/butler

# Windows
scoop install butler
# or download from https://itchio.itch.io/butler
```

### 2. Authenticate (one-time, per machine)

```bash
butler login
# Opens browser → authorize → return to terminal.
```

For CI: set `BUTLER_API_KEY` instead (generate at
<https://itch.io/user/settings/api-keys>). No `butler login` needed.

### 3. Create the itch.io page (one-time, in browser)

Butler refuses the first push if the target page does not exist.

1. <https://itch.io/dashboard> → **Create new project**
2. Settings:
- **Kind:** HTML
- **Viewport size:** match your build (e.g. 1280×720)
- **"This file will be played in the browser"**: checked
3. Save as **Draft** (publish after verifying the first push).

After the page exists, all future deploys are fully scripted.

## Core command

```bash
butler push <build-dir> <user>/<game>:<channel> --userversion <version>
```

| Argument | Example | Meaning |
|----------|---------|---------|
| `<build-dir>` | `dist/` | local directory to upload |
| `<user>/<game>` | `acme/spacelander` | itch.io target |
| `<channel>` | `html5` | upload channel (`html5`, `windows`, `linux`, `osx`, …) |
| `--userversion` | `1.4.2` | stamps the upload (optional but recommended) |

Example:

```bash
butler push dist/ acme/spacelander:html5 --userversion 1.4.2
```

## Common patterns

### Build then push

Wire build + push together — pick whichever fits your stack:

```bash
# Direct
npm run build && butler push dist/ acme/spacelander:html5 --userversion "$(node -p "require('./package.json').version")"

# Make
make build && butler push build/web acme/spacelander:html5

# Project npm script (optional convenience)
# package.json: "deploy": "butler push dist/ $ITCH_GAME:html5 --userversion $npm_package_version"
ITCH_GAME=acme/spacelander npm run deploy
```

### Channel-per-platform

```bash
butler push dist/web acme/spacelander:html5
butler push dist/win acme/spacelander:windows
butler push dist/linux acme/spacelander:linux
butler push dist/osx acme/spacelander:osx
```

### Verify after push

```bash
butler status acme/spacelander # all channels, latest version + state
butler status acme/spacelander:html5 # one channel
```

## Useful butler commands

```bash
butler login # interactive auth (browser)
butler logout
butler push <dir> <user>/<game>:<channel> [--userversion VER] [--ignore PATTERN]
butler status <user>/<game>[:<channel>]
butler fetch <user>/<game>:<channel> <out-dir> # download a build
butler validate <dir> # sanity-check a build dir
butler --version
```

## Troubleshooting

| Symptom | Likely cause | Fix |
|---------|--------------|-----|
| `butler: command not found` | not installed | install per step 1 |
| `404 Not found` on first push | itch.io page doesn't exist | create the project page in browser first |
| `401 Unauthorized` | not logged in / bad API key | `butler login`, or fix `BUTLER_API_KEY` |
| `403 Forbidden` | account doesn't own the target | check `<user>/<game>` slug matches a project you own |
| Push silently uploads everything every time | `dist/` content non-deterministic (timestamps, build hashes) | rebuild with stable filenames, or `--ignore` volatile files |
| `--userversion` shows up empty on itch.io | flag value missing/empty | confirm the version env / `package.json` field is set before invoking |
Loading
Loading