Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

shibarmy-collab

DAO-native community collaboration skill for the Shibarmy Librarian.

When Doggy DAO proposals pass, they contain GitHub repo URLs pointing to real projects that need contributors. This OpenClaw skill lets any Shibarmy member's local Librarian agent discover those projects, claim tasks, coordinate with the pack, and ship PRs — all driven by DAO votes with zero central authority.

How it works

 ┌──────────────┐     ┌──────────────┐     ┌──────────────┐
 │  Doggy DAO   │────▶│  GitHub Repo │────▶│  Your Fork   │
 │  (Snapshot)  │     │  (Lead's)    │     │  (Your work) │
 └──────────────┘     └──────────────┘     └──────────────┘
        │                     │                     │
        │   dao-watch.sh      │  project-join.sh    │  git push + PR
        ▼                     ▼                     ▼
 ┌─────────────────────────────────────────────────────────┐
 │              ntfy.sh community channel                  │
 │         channel-post.sh / channel-read.sh               │
 └─────────────────────────────────────────────────────────┘

The flow, step by step

  1. DAO votes — A proposal passes on Doggy DAO with a GitHub repo URL embedded in the proposal body
  2. Discoverdao-watch.sh queries the Snapshot.org GraphQL API for the shibainu.eth space, finds closed proposals that passed, and extracts GitHub URLs from their body text
  3. Joinproject-join.sh lists open Issues on the project repo (via GitHub API) and posts a claim comment when you pick a task
  4. Build — Fork the repo, create a branch, write code, open a PR — standard open-source workflow
  5. Communicatechannel-post.sh and channel-read.sh keep the pack in sync via ntfy.sh (zero-auth pub/sub)
  6. Dashboardcollab-status.sh combines all of the above into one view

Requirements

Requirement Why Required by
POSIX shell (sh) All scripts are POSIX-compliant, no bash-isms everything
curl HTTP requests to Snapshot API, GitHub API, ntfy.sh everything
git Fork/branch/PR workflow project-join.sh
awk, sed JSON parsing (no jq dependency) dao-watch.sh, project-join.sh
GITHUB_TOKEN env var GitHub personal access token for Issue comments project-join.sh (claim only)

What does NOT require a token: Listing DAO proposals, listing open Issues (public repos), reading/writing to the ntfy.sh channel, viewing the dashboard. The token is only needed when you want to comment on an Issue to claim a task.

Installation

Into an existing Librarian (OpenClaw)

# Drop into your skills directory
cp -r shibarmy-collab/ ~/.openclaw/skills/shibarmy-collab/

# Or symlink for development
ln -s "$(pwd)/shibarmy-collab" ~/.openclaw/skills/shibarmy-collab

The Librarian auto-detects the skill via SKILL.md frontmatter. The name field must match the directory name (shibarmy-collab).

Standalone usage

Every script works independently from the command line:

# See what the DAO has approved
./scripts/dao-watch.sh --list

# Preview without network calls
./scripts/dao-watch.sh --dry-run

# Join a project (token needed to claim, not to browse)
export GITHUB_TOKEN="ghp_your_token_here"
./scripts/project-join.sh --repo https://github.com/org/project --member yourname

# Post a progress update
./scripts/channel-post.sh --type update --project myproject --member yourname \
  --message "Finished the auth module, PR incoming"

# Read recent channel activity
./scripts/channel-read.sh --since 6h

# Full dashboard
./scripts/collab-status.sh

How each script works (in detail)

dao-watch.sh — DAO proposal discovery

What it does: Finds Doggy DAO proposals that passed and contain a GitHub repo URL.

Data source strategy (ordered by reliability):

  1. Primary: Snapshot.org GraphQL API — Queries hub.snapshot.org/graphql for the shibainu.eth space. Returns structured JSON with proposal titles, bodies, vote scores, and state. This is reliable because Snapshot is the actual voting platform.

  2. Fallback: HTML scrape of shib.io — If Snapshot is unreachable, falls back to fetching the DAO page HTML. Important limitation: shib.io is likely a JavaScript SPA (React/Next.js), which means curl will only get the empty HTML shell, not the rendered proposal content. This fallback exists for resilience but may return zero results on SPA pages.

Caching: Results are cached to /tmp/shibarmy-dao-cache.txt with a 30-minute TTL. If both live sources fail, a stale cache is used as a last resort. The cache file includes a SOURCE: tag so the parser knows which format to expect.

Parsing approach: The Snapshot JSON is parsed with awk (no jq dependency required). For each closed proposal, it extracts the title, ID (truncated to 8 chars for display), and scans the body text for github.com/owner/repo URLs. Only proposals with a GitHub URL are shown.

dao-watch.sh --list           # All passed proposals with repo URLs
dao-watch.sh --latest         # Most recently passed only
dao-watch.sh --dry-run        # Show sources and cache status
dao-watch.sh --help           # Full usage

Environment overrides:

Variable Default Purpose
SHIBARMY_DAO_URL shib.io DAO page Override HTML fallback URL
SHIBARMY_SNAPSHOT_SPACE shibainu.eth Override Snapshot space ID

project-join.sh — Task claiming

What it does: Lists open Issues on a GitHub repo, lets you claim one by posting a comment, and notifies the ntfy.sh channel.

How GitHub API calls work:

  • GET requests (list/search issues): Work without GITHUB_TOKEN on public repos. You get 60 requests/hour unauthenticated vs 5,000 authenticated.
  • POST requests (claim comment): Require GITHUB_TOKEN. The script checks for the token before attempting writes and gives a clear error if missing.

JSON parsing: GitHub API returns nested JSON (issues contain user objects, label arrays, etc.). The parser uses tr ',' '\n' to put each field on its own line, then sed extracts only top-level "number" and "title" fields. A stateful awk script pairs each number with its following title, skipping nested duplicates.

Input sanitization: The --member handle is sanitized before being embedded in the JSON comment body — quotes, backslashes, and control characters are stripped to prevent JSON injection.

project-join.sh --repo <url>                        # List open issues
project-join.sh --repo <url> --task "title"         # Claim a specific task
project-join.sh --repo <url> --task "title" --member alice
project-join.sh --repo <url> --dry-run              # Preview actions

channel-post.sh — Post to community channel

What it does: Posts a tagged message to the ntfy.sh topic with appropriate priority.

ntfy.sh API usage:

POST https://ntfy.sh/{topic}
Headers:
  Title: Shibarmy [{TYPE}] {project}
  Priority: low|default|high
  Tags: dog,memo (comma-separated emoji shortcodes)
Body: [{TYPE}] @{member} on {project}: {message}

Priority mapping:

--type ntfy.sh priority Numeric Behavior
update low 2 Normal delivery, no sound on mobile
help default 3 Normal notification
blocker high 4 Highlighted, sound on mobile
channel-post.sh --type update --project myrepo --message "PR ready" --member alice
channel-post.sh --type blocker --project myrepo --message "CI broken"
channel-post.sh --type help --project myrepo --message "Need reviewer"
channel-post.sh --dry-run --type update --project x --message y

channel-read.sh — Read from community channel

What it does: Polls ntfy.sh for recent messages and displays them with priority indicators.

ntfy.sh polling API:

GET https://ntfy.sh/{topic}/json?poll=1&since={duration}

The poll=1 parameter means "return immediately with available messages" (no long-polling). Each message is a single JSON line with fields: event, message, title, time (Unix timestamp), priority (1-5).

Output format:

!! 2026-04-06 14:30 [Title] message     (priority 4-5: blocker/urgent)
-- 2026-04-06 13:15 [Title] message     (priority 3: normal)
.. 2026-04-06 12:00 [Title] message     (priority 1-2: low/update)

Timestamp handling: Uses date -d @timestamp on Linux, falls back to date -r timestamp on macOS. Both are tested in the script.

Filtering: The --filter flag matches [TYPE] tags in message bodies (e.g., [BLOCKER], [HELP], [UPDATE], [JOIN]). This is a simple string match, not a structured query.

channel-read.sh                          # Last 1 hour, all types
channel-read.sh --since 6h              # Last 6 hours
channel-read.sh --since 24h --filter blocker   # Blockers in last day
channel-read.sh --dry-run               # Show what would be fetched

collab-status.sh — Combined dashboard

What it does: Runs dao-watch.sh --list, channel-read.sh --since 6h, and filtered channel reads for help/blocker messages. Combines the output into a formatted dashboard.

How it works internally:

  1. Resolves its own directory with $(cd "$(dirname "$0")" && pwd) so it can find sibling scripts regardless of where you run it from
  2. Checks that each script exists and is executable before calling
  3. Suppresses stderr from child scripts (you can run them individually for debug output)
  4. Shows the ntfy.sh topic name and current timestamp in the footer
collab-status.sh            # Full dashboard
collab-status.sh --dry-run  # Show what commands would run

ntfy.sh setup

This skill uses ntfy.sh as a public, no-auth message bus.

  • Default topic: shibarmy-librarian
  • Override: Set the SHIBARMY_TOPIC environment variable
  • No accounts needed — anyone can read or post
  • Subscribe in browser: Visit https://ntfy.sh/shibarmy-librarian
  • Subscribe on phone: Install the ntfy app (Android/iOS) and add the topic
  • Subscribe via curl: curl -s ntfy.sh/shibarmy-librarian/json?poll=1&since=1h

Why ntfy.sh?

Feature ntfy.sh Slack/Discord Telegram
Auth required to read No Yes Yes
Auth required to post No Yes (webhook/bot) Yes (bot)
Account needed No Yes Yes
curl-friendly Yes Partial Partial
Mobile push Yes (via app) Yes Yes
Self-hostable Yes No No
Free tier limits 250 msgs/day N/A N/A

The tradeoff: no message persistence guarantees and no threading. For coordination messages (status updates, help requests), this is fine — they're ephemeral by nature.

Message format convention

All messages follow this pattern for reliable filtering:

[TYPE] @member on project: actual message text

Where TYPE is one of: JOIN, UPDATE, BLOCKER, HELP

Environment variables

Variable Required Default Used by
GITHUB_TOKEN Only for claiming tasks (none) project-join.sh
SHIBARMY_TOPIC No shibarmy-librarian all channel scripts
SHIBARMY_DAO_URL No shib.io DAO page dao-watch.sh
SHIBARMY_SNAPSHOT_SPACE No shibainu.eth dao-watch.sh

Known limitations and honest caveats

  1. Snapshot space ID: The default space is shibainu.eth. If Doggy DAO moves to a different Snapshot space or a different voting platform entirely, you'll need to update SHIBARMY_SNAPSHOT_SPACE or modify the script.

  2. HTML fallback is unreliable: The shib.io fallback scraper will likely return nothing if the page is rendered client-side (SPA). It exists as a best-effort fallback, not a reliable source. Snapshot API is the real workhorse.

  3. JSON parsing without jq: We parse GitHub API and Snapshot JSON using sed/awk to avoid requiring jq. This works for the specific fields we need (issue numbers, titles, proposal bodies) but would break on exotic edge cases like titles containing escaped quotes. If you have jq available, a future version could detect and prefer it.

  4. ntfy.sh is public: Anyone who knows the topic name can read and post. This is a feature (zero-barrier coordination) and a limitation (no access control). For sensitive projects, use a randomized topic name via SHIBARMY_TOPIC.

  5. No quorum verification: dao-watch.sh treats all closed Snapshot proposals as "passed." It doesn't verify quorum thresholds or check if the winning choice was "For" vs "Against." A proper implementation would inspect scores and choices arrays. This is noted as a future improvement.

  6. Rate limits without token: GitHub allows 60 unauthenticated API requests per hour per IP. If you're browsing issues frequently without a token, you may hit this. Set GITHUB_TOKEN to get 5,000/hour.

File structure

shibarmy-collab/
├── SKILL.md                  # OpenClaw skill definition (AgentSkills.io spec)
├── README.md                 # This file
├── LICENSE                   # MIT License
├── scripts/
│   ├── dao-watch.sh          # Snapshot API → passed proposals with GitHub URLs
│   ├── project-join.sh       # GitHub Issues → claim task → notify channel
│   ├── channel-post.sh       # ntfy.sh POST with typed priority
│   ├── channel-read.sh       # ntfy.sh GET with filtering
│   └── collab-status.sh      # Dashboard combining all of the above
├── templates/
│   ├── update.md             # Progress update template
│   ├── blocker.md            # Blocker report template
│   └── help-wanted.md        # Help request template
├── .learnings/
│   └── LEARNINGS.md          # Architecture decisions and evolution notes
└── examples/
    └── sample-session.md     # Full walkthrough: DAO vote → join → code → PR

POSIX compatibility notes

All scripts use #!/bin/sh and avoid:

  • [[ ]] (use [ ] instead)
  • Arrays (use positional parameters or pipe chains)
  • local keyword (use subshells or unique variable names)
  • Process substitution <() (use pipes or temp files)
  • IGNORECASE in awk (use tolower() for case-insensitive matching)
  • source (use . if needed)

Tested patterns: stat -c %Y (Linux) with stat -f %m (macOS) fallback for file timestamps. date -d @ts (Linux) with date -r ts (macOS) fallback for epoch conversion.

Philosophy

  • The DAO is the source of truth. No config files, no job codes, no coordinator accounts. If a proposal passed and has a GitHub URL, that's a live project.
  • Open-source norms. Issues, forks, PRs — the workflow every developer already knows.
  • No gatekeepers. ntfy.sh needs no auth. Public GitHub repos are browsable without tokens. The barrier to entry is curl and git.
  • POSIX portable. Runs on macOS, Linux, Alpine, CI runners, WSL — anything with a POSIX shell.
  • Honest about limitations. Every script has --dry-run. The README tells you what won't work and why.

Contributing

This skill itself is a Doggy DAO project. Check the Issues tab, claim a task, and send a PR. Use the skill to contribute to the skill.

License

MIT — see LICENSE for details.

About

Librarian collab skill ShibDAO

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages