agentsclimarketplace

Fizzy skill

Skill cskwork/fizzy-skill

Use when working with a self-hosted Fizzy kanban board (e.g. fizzy.example.com) — install/auth fizzy-cli, list boards/cards, create/update/comment cards, or migrate a Jira issue (description + attachment URLs + comments) into one or more Fizzy cards. Covers Fizzy quirks (NO markdown rendering, silent pagination in comment list, single-account auto-select, magic-link in non-TTY) and Jira ADF → Fizzy plain-text conversion.From its SKILL.md

Install
npx -y skills add cskwork/fizzy-skill

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

4 things to look at

  • reads credentialsReads from 2 credential sources: `FIZZY_TOKEN` and 1 more.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
  • runs commandsInstructs the agent to run 8 commands, including `brew install tobiasbischoff/tap/fizzy-cli` and 7 more.
  • fetches URLsInstructs the agent to fetch 2 URLs, including https://github.com/tobiasbischoff/fizzy-cli.git and 1 more.

SKILL.md

11.1 KB, ~3.0k tokens by cl100k_base, as published. Nobody here has run it

fizzy

Operate tobiasbischoff/fizzy-cli against a self-hosted Fizzy instance. Single skill covers:

  1. Onboarding — install, base-URL, auth (PAT or magic-link), default account
  2. Daily ops — board/card/comment CRUD with the markdown gotchas baked in
  3. Jira → Fizzy migration — pull a Jira issue's description, attachments, and 14-comment thread into a card (+ sub-cards) without losing formatting

Quick decision

Need to set up fizzy-cli from scratch?         → §1 Onboarding
Need to create/update cards or comments?       → §2 Daily ops
Need to import a Jira issue into Fizzy?        → §3 Jira → Fizzy migration
Markdown looks broken after posting to Fizzy?  → §4 Markdown quirks

Inputs (env)

  • FIZZY_HOST — base URL (e.g. https://fizzy.example.com)
  • FIZZY_EMAIL — account email
  • FIZZY_TOKEN (preferred) OR magic-link from inbox

For Jira import: acli must be authenticated to the source site (acli auth status → ✓).


§1 Onboarding

1.1 Install

Homebrew (documented):

brew install tobiasbischoff/tap/fizzy-cli

If brew is blocked, build from source:

git clone https://github.com/tobiasbischoff/fizzy-cli.git ~/.local/src/fizzy-cli
cd ~/.local/src/fizzy-cli && go build -o ~/.local/bin/fizzy-cli ./cmd/fizzy-cli

Pitfall — go install does NOT work. go.mod declares module fizzy-cli (short form), so go install github.com/... fails. Always clone + go build -o.

1.2 Point at the host

fizzy-cli config set --base-url "$FIZZY_HOST"
fizzy-cli config show

Config: macOS ~/Library/Application Support/fizzy/config.json, Linux ~/.config/fizzy/config.json.

1.3 Authenticate

A. PAT (preferred, idempotent):

fizzy-cli auth login --token "$FIZZY_TOKEN"
fizzy-cli auth status   # → "Authenticated using token."

B. Magic-link in non-TTY (Claude Code / CI):

fizzy-cli auth login --email --code is broken in non-TTY — each call re-issues a code, invalidating any pasted one. Workaround: see references/magic-link-curl-two-step.md.

1.4 Pick default account

fizzy-cli account list
fizzy-cli account set <SLUG>    # required even with only one account

Pitfall — single-account auto-select is NOT done by the CLI. Skipping this makes board list etc. error cryptically.

1.5 Verify

fizzy-cli board list
fizzy-cli card create --board-id <ID> --title "fizzy setup test" --description "ok" --status published
fizzy-cli card list --board-id <ID> | head -3

§2 Daily ops

GoalCommand
List boardsfizzy-cli board list
List cardsfizzy-cli card list --board-id <ID>
Get cardfizzy-cli card get <N>
Create cardfizzy-cli card create --board-id <ID> --title T --description D --status published
Update cardfizzy-cli card update <N> --description D
Attach main imagefizzy-cli card update <N> --image <local-path> (one image per card)
List comments (JSON)fizzy-cli --json comment list <N>
Add commentfizzy-cli comment create <N> --body "text"
Delete commentfizzy-cli comment delete <N> <comment-id>

--json is a global flag — it must come before the subcommand (fizzy-cli --json comment list 36), not after.

Filter user-only comments

fizzy-cli --json comment list <N> \
  | jq -r '.[] | select(.creator.name != null) | .id'

(Status-change comments have creator: {name: "System"}, sort of — filter on a known username instead.)

Card description / comment body — markdown rules

Fizzy renders CommonMark strictly: single \n is collapsed; only blank lines start a new paragraph. See §4.


§3 Jira → Fizzy migration

End-to-end migrator: pulls issue + comments via Atlassian MCP, converts ADF → Fizzy-friendly markdown, creates parent card + optional sub-cards, posts every comment, retries on timeout.

# Prereq: Fizzy authenticated (§1), Atlassian MCP available, acli logged in
python3 ~/.claude/skills/fizzy/scripts/jira_to_fizzy.py \
  --issue PROJ-123 \
  --board <fizzy-board-id> \
  --site your-site.atlassian.net \
  --split-numbered   # auto-create sub-cards from "1.", "2.", "3." in description

What it does (see scripts/jira_to_fizzy.py for the full flow):

  1. Fetches the issue + comments JSON via mcp__claude_ai_Atlassian__getJiraIssue (or reads a cached JSON file with --from-json PATH).
  2. Converts every ADF body to Fizzy-friendly markdown via scripts/adf_to_md.py.
  3. Creates the parent card (compact summary + Jira URL + link to attachments).
  4. If --split-numbered, creates one sub-card per top-level numbered item in the description.
  5. Posts every Jira comment as **[YYYY-MM-DD] author**\n\n<body>.
  6. Retries each fizzy-cli call up to 3× on context deadline exceeded.

Attachment handling (images): Atlassian's acli OAuth scope lacks read:attachment-content:jira, so URL-based downloads return 401. Use a user-issued Personal Access Token (PAT) with Basic auth (scripts/atlassian_attachments.py).

Setup once:

  1. Issue a PAT at https://id.atlassian.com/manage-profile/security/api-tokens
  2. Save to ~/.config/fizzy/.env (chmod 600):
    [email protected]
    ATLASSIAN_PAT=ATATT3...
    ATLASSIAN_SITE=your-site.atlassian.net
    

Download + attach:

# Download every attachment to /tmp/fizzy-attachments/
python3 ~/.claude/skills/fizzy/scripts/atlassian_attachments.py \
    download-issue --from-json /tmp/issue.json

# Then attach a representative image as the card's main image (one per card)
fizzy-cli card update <N> --image /tmp/fizzy-attachments/<id>_<name>.png

Note: Fizzy strips <img> from description bodies, so embed-in-description is impossible — only the card's main image slot works (one image per card).

Idempotency: to re-run cleanly, first wipe stale user comments:

python3 ~/.claude/skills/fizzy/scripts/jira_to_fizzy.py --card <N> --wipe-user-comments <username>

§4 Rendering — Fizzy accepts HTML, NOT markdown

CRITICAL discovery (2026-05-21): Fizzy server takes the body as HTML and auto-converts it to a Fizzy-rendered string. Markdown is NOT parsed — **bold** appears as literal asterisks. Send hybrid HTML for the best result.

What Fizzy auto-renders well (use these tags)

TagResult in UI
<p>...</p>paragraph with blank-line separation
<ul><li>X</li></ul>• X (auto bullet)
<ol><li>X</li></ol>1. X (auto numbering)
nested <ul> inside <li> • X (auto 2-space indent)
<blockquote>X</blockquote>“X” (auto curly quotes)
<br>line break inside paragraph

What Fizzy STRIPS (encode in text yourself)

TagFizzy behaviorWorkaround
<h1>…<h6>shown as plain text, no markerwrap: <p>▶ <strong>title</strong></p> (use emoji prefix as marker)
<strong> / <em>strippeduse emoji or 「 」 symbols if emphasis matters
<hr>disappearsemit <p>━━━━━━━━━━━━━━━━━━━━</p>
<a href="X">label</a>text only, URL is goneemit <p>label: X</p> or <p>🔗 X</p>
<img>disappearsemit <p>이미지: <url></p> (no emoji)
<pre>/<code>strippedemit <p>코드:</p><p>…</p><p>---</p>
<table>all cells concatenated, no structureemit rows as <p>| a | b |</p>

Other quirks

QuirkSymptomFix
comment list silent paginationOnly ~3 items per call; the rest are invisibleLoop list+delete until empty when wiping; never assume length == total
Bash heredoc + ( / backtickunexpected EOF or command not foundBuild bodies in Python with subprocess.run([cmd, '--description', text])
--json after subcommandSilently ignoredPlace it before subcommand: fizzy-cli --json comment list 36
Single-account auto-defaultboard list errors after fresh authRun fizzy-cli account set <SLUG> even with one account
--image PATHLocal file path only, one main image per cardDownload first; extras → inline URLs in description

Recommended layout for migrated cards

POLICY — No emoji in deliverables. Cards, comments, reports are business artifacts. Use bracket labels ([목적], [상세 작업]) and box-drawing rules (━, ·) only. No pictographic emoji (📌 🎯 ✅ 📎 etc.). Geometric arrows (▶ ▸ ■) are also discouraged because some clients render them with emoji presentation.

<p>━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</p>
<p>[KEY] 제목 영역</p>
<p>프로젝트: MyProject  ·  타입: Bug  ·  상태: 진행 중  ·  담당: 홍길동</p>
<p>Jira: https://...</p>
<p>━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</p>
<p>[개요]</p>
<p>본문 단락 1</p>
<ul><li>핵심 1</li><li>핵심 2</li></ul>
<p>[첨부 (로그인 필요)]</p>
<ul><li>오류 화면: https://...</li></ul>

This is what scripts/adf_to_fizzy.py + header_block() / section() produce automatically.

Common mistakes

  • Sending markdown and hoping it renders — Fizzy treats **X** as literal text. Use HTML or wrap content with adf_to_fizzy.
  • Trusting comment list length — it's page 1 (~3 items) only. Loop until empty when wiping.
  • Filtering by creator.name != "System" — some events have empty creator.name. Match on a specific username.
  • **Posting via bash -c with --description "...\x`..."** — backticks trigger command substitution. Always use Python subprocess.run([...])`.
  • <a href> for important URLs — Fizzy strips the href. Always print the URL as visible text.
  • <table> for important tabular data — cells get concatenated with no separator. Build the table yourself with <p>| a | b |</p> rows.

Files

  • scripts/adf_to_fizzy.py — (recommended) ADF → Fizzy hybrid HTML with auto-renderable tags + text fallbacks for stripped ones. Provides adf_to_fizzy(), header_block(), section(), HR.
  • scripts/adf_to_plain.py — ADF → pure plain text (use only when you specifically want to avoid HTML).
  • scripts/adf_to_md.py — ADF → markdown (for non-Fizzy targets; do NOT send to Fizzy).
  • scripts/jira_to_fizzy.py — end-to-end Jira issue → Fizzy card(s) migrator with retry + pagination-safe wipe, using hybrid HTML.
  • references/magic-link-curl-two-step.md — non-TTY magic-link workaround.
  • references/operations.md — extended fizzy-cli command reference.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.