From 48467f3a81347375c3a574e3ce1e9b21053b0186 Mon Sep 17 00:00:00 2001 From: mpmedia Date: Tue, 26 May 2026 09:45:39 -0500 Subject: [PATCH] fix: decode double-encoded base64 in SKILL.md --- SKILL.md | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/SKILL.md b/SKILL.md index c549283..106f3a1 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1 +1,129 @@ -LS0tCm5hbWU6IG1wbS11cmwtc2hvcnRlbmVyCmRlc2NyaXB0aW9uOiBNYW5hZ2VzIHNob3J0IFVSTHMgb24gTVBNJ3MgbXBtLnRvIFlPVVJMUyBpbnN0YW5jZS4gVXNlIHRoaXMgc2tpbGwgd2hlbmV2ZXIgdGhlIHVzZXIgd2FudHMgdG8gY3JlYXRlLCBsb29rIHVwLCBleHBhbmQsIHVwZGF0ZSwgb3IgZGVsZXRlIHNob3J0IGxpbmtzIGF0IG1wbS50by4gVHJpZ2dlcnMgb24gcGhyYXNlcyBsaWtlICJjcmVhdGUgYSBzaG9ydCBsaW5rIiwgIm1ha2UgYSBzaG9ydCBVUkwgZm9yIiwgIndoYXQgZG9lcyBtcG0udG8vWCBnbyB0byIsICJkZWxldGUgdGhlIG1wbS50byBsaW5rIiwgInVwZGF0ZSB0aGUgc2hvcnQgY29kZSIsICJsaXN0IG91ciBzaG9ydCBVUkxzIiwgImFkZCBhIHNob3J0IGxpbmsiLCAibXBtIGxpbmsiLCAic2hvcnQgY29kZSIsICJzaG9ydGNvZGUiLCAic2hvcnRlbiB0aGlzIFVSTCIsIG9yIGFueSBtZW50aW9uIG9mIG1wbS50byBVUkxzLiBBbHNvIHVzZSB3aGVuIHRoZSB1c2VyIHNheXMgdGhpbmdzIGxpa2UgImNhbiB5b3Ugc2hvcnRlbiB0aGF0IiBvciAic2V0IHVwIGEgbGluayBmb3IgdGhlIG5ldyBjYW1wYWlnbiIuCi0tLQoKIyBNUE0gVVJMIFNob3J0ZW5lcgoKTWFuYWdlcyBzaG9ydCBVUkxzIG9uIE1QTSdzIFlPVVJMUyBpbnN0YW5jZSBhdCBgaHR0cHM6Ly9tcG0udG9gLiBTdXBwb3J0cyBmdWxsIENSVUQg4oCUIGNyZWF0ZSwgcmVhZC9saXN0LCB1cGRhdGUsIGFuZCBkZWxldGUg4oCUIHVzaW5nIG9ubHkgdGhlIEFQSSBzaWduYXR1cmUgdG9rZW4uIE5vIHVzZXJuYW1lIG9yIHBhc3N3b3JkIGlzIHN0b3JlZC4KCiMjIEhvdyBpdCB3b3JrcwoKLSAqKkNyZWF0ZSAmIFJlYWQqKiBhbHdheXMgdXNlIHRoZSBZT1VSTFMgQVBJIHdpdGggdGhlIHNpZ25hdHVyZSB0b2tlbiDigJQgbm8gcGFzc3dvcmQgbmVlZGVkLgotICoqVXBkYXRlICYgRGVsZXRlKiogdXNlIG9uZSBvZiB0d28gbWV0aG9kcywgdHJpZWQgaW4gb3JkZXI6CiAgMS4gKipBUEkgKyBwbHVnaW4qKiAocHJlZmVycmVkKTogSWYgdGhlIGBtcG0tYXBpLWV4dHJhc2AgcGx1Z2luIGlzIGFjdGl2ZSBvbiB0aGUgc2VydmVyLCB0aGUgc2lnbmF0dXJlIHRva2VuIGhhbmRsZXMgZXZlcnl0aGluZy4KICAyLiAqKkFkbWluIHNlc3Npb24gZmFsbGJhY2sqKjogSWYgdGhlIHBsdWdpbiBpc24ndCBpbnN0YWxsZWQsIHRoZSBzY3JpcHQgbG9ncyBpbnRvIHRoZSBZT1VSTFMgYWRtaW4gaW50ZXJmYWNlIHVzaW5nIGEgc3RvcmVkIHVzZXJuYW1lICsgcGFzc3dvcmQuCgpUaGUgYnVuZGxlZCBzY3JpcHQgYHNjcmlwdHMveW91cmxzX21hbmFnZXIucHlgIGhhbmRsZXMgdGhlIHN3aXRjaGluZyBhdXRvbWF0aWNhbGx5IOKAlCB5b3UgZG9uJ3QgbmVlZCB0byB0aGluayBhYm91dCB3aGljaCBtZXRob2QgaXMgaW4gdXNlLgoKLS0tCgojIyBPbmUtdGltZSBwbHVnaW4gaW5zdGFsbGF0aW9uIChyZWNvbW1lbmRlZCkKCkluc3RhbGxpbmcgdGhlIHBsdWdpbiBtZWFucyBvbmx5IHRoZSBzaWduYXR1cmUgdG9rZW4gaXMgZXZlciBuZWVkZWQuIE5vIHBhc3N3b3JkcyBpbiBLZXljaGFpbi4KClNlZSBgcGx1Z2luL0lOU1RBTEwubWRgIGZvciBpbnN0cnVjdGlvbnMgdG8gcGFzcyB0byB5b3VyIHNlcnZlciBhZG1pbi4KCi0tLQoKIyMgRmlyc3QtdGltZSBjcmVkZW50aWFsIHNldHVwCgpSdW4gb25jZToKCmBgYGJhc2gKcHl0aG9uMyA8U0tJTExfRElSPi9zY3JpcHRzL3lvdXJsc19tYW5hZ2VyLnB5IHNldHVwCmBgYAoKLSAqKlNpZ25hdHVyZSB0b2tlbioqIOKAlCBhbHdheXMgcmVxdWlyZWQKLSAqKkFkbWluIHVzZXJuYW1lICsgcGFzc3dvcmQqKiDigJQgb3B0aW9uYWw7IG9ubHkgbmVlZGVkIGlmIHRoZSBwbHVnaW4gaXMgbm90IGluc3RhbGxlZAoKQ3JlZGVudGlhbHMgYXJlIHN0b3JlZCBpbiBtYWNPUyBLZXljaGFpbiB1bmRlciBzZXJ2aWNlIGBtcG0udG8teW91cmxzYC4gVG8gdmVyaWZ5IGFuZCB0ZXN0IHRoZSBsaXZlIGNvbm5lY3Rpb246CgpgYGBiYXNoCnB5dGhvbjMgPFNLSUxMX0RJUj4vc2NyaXB0cy95b3VybHNfbWFuYWdlci5weSBjaGVjawpgYGAKClRoZSBgY2hlY2tgIGNvbW1hbmQgYWxzbyB0ZWxscyB5b3Ugd2hldGhlciB0aGUgcGx1Z2luIGlzIGFjdGl2ZS4KCi0tLQoKIyMgT3BlcmF0aW9ucwoKUmVwbGFjZSBgPFNLSUxMX0RJUj5gIHdpdGggdGhlIGFjdHVhbCBwYXRoIHRvIHRoaXMgc2tpbGwncyBkaXJlY3RvcnkuCgojIyMgQ3JlYXRlIGEgc2hvcnQgVVJMCgpgYGBiYXNoCnB5dGhvbjMgPFNLSUxMX0RJUj4vc2NyaXB0cy95b3VybHNfbWFuYWdlci5weSBjcmVhdGUgXAogIC0tdXJsICJodHRwczovL3RoZS1sb25nLXVybC5jb20vcGF0aCIgXAogIFstLWtleXdvcmQgIm15Y29kZSJdIFwKICBbLS10aXRsZSAiSHVtYW4tcmVhZGFibGUgdGl0bGUiXQpgYGAKCi0gYC0ta2V5d29yZGAgaXMgb3B0aW9uYWw7IFlPVVJMUyBhdXRvLWdlbmVyYXRlcyBvbmUgaWYgb21pdHRlZAotIGAtLXRpdGxlYCBpcyBvcHRpb25hbCBidXQgZ29vZCBwcmFjdGljZQotIFJldHVybnMgdGhlIG5ldyBzaG9ydCBVUkwgYW5kIGNvbmZpcm1hdGlvbgoKIyMjIFJlYWQgLyBsb29rIHVwIGEgc2hvcnQgVVJMCgpgYGBiYXNoCnB5dGhvbjMgPFNLSUxMX0RJUj4vc2NyaXB0cy95b3VybHNfbWFuYWdlci5weSByZWFkIC0ta2V5d29yZCAibXljb2RlIgpgYGAKClJldHVybnM6IGxvbmcgVVJMLCB0aXRsZSwgY2xpY2sgY291bnQsIGRhdGUgY3JlYXRlZC4KCiMjIyBMaXN0IHNob3J0IFVSTHMKCmBgYGJhc2gKcHl0aG9uMyA8U0tJTExfRElSPi9zY3JpcHRzL3lvdXJsc19tYW5hZ2VyLnB5IGxpc3QgWy0tbGltaXQgNTBdIFstLWZpbHRlciB0b3B8Ym90dG9tfGxhc3R8cmFuZF0KYGBgCgpEZWZhdWx0cyB0byB0aGUgNTAgbW9zdC1jbGlja2VkIGxpbmtzLiBVc2UgYC0tZmlsdGVyIGxhc3RgIHRvIHNlZSB0aGUgbW9zdCByZWNlbnRseSBjcmVhdGVkLgoKIyMjIFVwZGF0ZSBhIHNob3J0IFVSTAoKYGBgYmFzaApweXRob24zIDxTS0lMTF9ESVI+L3NjcmlwdHMveW91cmxzX21hbmFnZXIucHkgdXBkYXRlIFwKICAtLWtleXdvcmQgIm15Y29kZSIgXAogIFstLXVybCAiaHR0cHM6Ly9uZXctZGVzdGluYXRpb24uY29tIl0gXAogIFstLW5ld2tleXdvcmQgIm5ld2NvZGUiXSBcCiAgWy0tdGl0bGUgIlVwZGF0ZWQgVGl0bGUiXQpgYGAKClJlcXVpcmVzIGFkbWluIGNyZWRlbnRpYWxzLiBBdCBsZWFzdCBvbmUgb2YgYC0tdXJsYCwgYC0tbmV3a2V5d29yZGAsIG9yIGAtLXRpdGxlYCBtdXN0IGJlIHByb3ZpZGVkLgoKIyMjIERlbGV0ZSBhIHNob3J0IFVSTAoKYGBgYmFzaApweXRob24zIDxTS0lMTF9ESVI+L3NjcmlwdHMveW91cmxzX21hbmFnZXIucHkgZGVsZXRlIC0ta2V5d29yZCAibXljb2RlIgpgYGAKClJlcXVpcmVzIGFkbWluIGNyZWRlbnRpYWxzLiBBc2tzIGZvciBjb25maXJtYXRpb24gYmVmb3JlIGRlbGV0aW5nIHVubGVzcyBgLS1mb3JjZWAgaXMgcGFzc2VkLgoKLS0tCgojIyBQcmVzZW50aW5nIHJlc3VsdHMKCkFmdGVyIHJ1bm5pbmcgYW55IG9wZXJhdGlvbiwgcHJlc2VudCByZXN1bHRzIGNvbnZlcnNhdGlvbmFsbHk6CgotICoqQ3JlYXRlKio6ICJEb25lISBgbXBtLnRvL215Y29kZWAgbm93IHBvaW50cyB0byBbbG9uZyBVUkxdLiIKLSAqKlJlYWQqKjogU2hvdyBzaG9ydCBVUkwsIGRlc3RpbmF0aW9uLCB0aXRsZSwgY2xpY2sgY291bnQsIGFuZCBhZ2UuCi0gKipMaXN0Kio6IFJlbmRlciBhcyBhIGNsZWFuIHRhYmxlIHdpdGggY29sdW1uczogU2hvcnQgQ29kZSB8IERlc3RpbmF0aW9uIHwgQ2xpY2tzIHwgQ3JlYXRlZC4KLSAqKlVwZGF0ZSoqOiBDb25maXJtIHdoYXQgY2hhbmdlZC4KLSAqKkRlbGV0ZSoqOiBDb25maXJtIGRlbGV0aW9uLgoKSWYgYW4gb3BlcmF0aW9uIGZhaWxzLCByZWFkIHRoZSBlcnJvciBvdXRwdXQgYW5kIGV4cGxhaW4gaXQgY2xlYXJseSB0byB0aGUgdXNlciDigJQgZG9uJ3QganVzdCBkdW1wIHRoZSByYXcgZXJyb3IuCgotLS0KCiMjIFRyb3VibGVzaG9vdGluZwoKfCBFcnJvciB8IExpa2VseSBjYXVzZSB8IEZpeCB8CnwtLS18LS0tfC0tLXwKfCBgTm8gc2lnbmF0dXJlIHRva2VuYCB8IEZpcnN0LXRpbWUgdXNlIHwgUnVuIGBzZXR1cGAgfAp8IGAnZGVsZXRlJy8ndXBkYXRlJyBhY3Rpb24gbm90IHJlY29nbmlzZWRgIHwgUGx1Z2luIG5vdCBpbnN0YWxsZWQgfCBTY3JpcHQgd2lsbCBhdXRvLWZhbGwgYmFjayB0byBhZG1pbiBzZXNzaW9uIGlmIGNyZWRlbnRpYWxzIGFyZSBzdG9yZWQgfAp8IGBQbHVnaW4gbm90IGFjdGl2ZTsgbm8gYWRtaW4gY3JlZGVudGlhbHNgIHwgTmVpdGhlciBtZXRob2QgYXZhaWxhYmxlIHwgSW5zdGFsbCBwbHVnaW4gT1IgcnVuIGBzZXR1cGAgdG8gYWRkIHVzZXJuYW1lICsgcGFzc3dvcmQgfAp8IGBBZG1pbiBsb2dpbiBmYWlsZWRgIHwgV3JvbmcgcGFzc3dvcmQgfCBSZS1ydW4gYHNldHVwYCB0byB1cGRhdGUgc3RvcmVkIGNyZWRlbnRpYWxzIHwKfCBgS2V5d29yZCBhbHJlYWR5IGV4aXN0c2AgfCBTaG9ydCBjb2RlIHRha2VuIHwgQ2hvb3NlIGEgZGlmZmVyZW50IGAtLWtleXdvcmRgIHwKfCBgU2hvcnQgVVJMIG5vdCBmb3VuZGAgfCBLZXl3b3JkIGRvZXNuJ3QgZXhpc3QgfCBDaGVjayBzcGVsbGluZzsgdXNlIGBsaXN0YCB0byBicm93c2UgfAp8IGByZXF1ZXN0c2AgbW9kdWxlIG5vdCBmb3VuZCB8IE1pc3NpbmcgZGVwZW5kZW5jeSB8IFJ1biBgcGlwMyBpbnN0YWxsIHJlcXVlc3RzIC0tYnJlYWstc3lzdGVtLXBhY2thZ2VzYCB8Cg== \ No newline at end of file +--- +name: mpm-url-shortener +description: Manages short URLs on MPM's mpm.to YOURLS instance. Use this skill whenever the user wants to create, look up, expand, update, or delete short links at mpm.to. Triggers on phrases like "create a short link", "make a short URL for", "what does mpm.to/X go to", "delete the mpm.to link", "update the short code", "list our short URLs", "add a short link", "mpm link", "short code", "shortcode", "shorten this URL", or any mention of mpm.to URLs. Also use when the user says things like "can you shorten that" or "set up a link for the new campaign". +--- + +# MPM URL Shortener + +Manages short URLs on MPM's YOURLS instance at `https://mpm.to`. Supports full CRUD — create, read/list, update, and delete — using only the API signature token. No username or password is stored. + +## How it works + +- **Create & Read** always use the YOURLS API with the signature token — no password needed. +- **Update & Delete** use one of two methods, tried in order: + 1. **API + plugin** (preferred): If the `mpm-api-extras` plugin is active on the server, the signature token handles everything. + 2. **Admin session fallback**: If the plugin isn't installed, the script logs into the YOURLS admin interface using a stored username + password. + +The bundled script `scripts/yourls_manager.py` handles the switching automatically — you don't need to think about which method is in use. + +--- + +## One-time plugin installation (recommended) + +Installing the plugin means only the signature token is ever needed. No passwords in Keychain. + +See `plugin/INSTALL.md` for instructions to pass to your server admin. + +--- + +## First-time credential setup + +Run once: + +```bash +python3 /scripts/yourls_manager.py setup +``` + +- **Signature token** — always required +- **Admin username + password** — optional; only needed if the plugin is not installed + +Credentials are stored in macOS Keychain under service `mpm.to-yourls`. To verify and test the live connection: + +```bash +python3 /scripts/yourls_manager.py check +``` + +The `check` command also tells you whether the plugin is active. + +--- + +## Operations + +Replace `` with the actual path to this skill's directory. + +### Create a short URL + +```bash +python3 /scripts/yourls_manager.py create \ + --url "https://the-long-url.com/path" \ + [--keyword "mycode"] \ + [--title "Human-readable title"] +``` + +- `--keyword` is optional; YOURLS auto-generates one if omitted +- `--title` is optional but good practice +- Returns the new short URL and confirmation + +### Read / look up a short URL + +```bash +python3 /scripts/yourls_manager.py read --keyword "mycode" +``` + +Returns: long URL, title, click count, date created. + +### List short URLs + +```bash +python3 /scripts/yourls_manager.py list [--limit 50] [--filter top|bottom|last|rand] +``` + +Defaults to the 50 most-clicked links. Use `--filter last` to see the most recently created. + +### Update a short URL + +```bash +python3 /scripts/yourls_manager.py update \ + --keyword "mycode" \ + [--url "https://new-destination.com"] \ + [--newkeyword "newcode"] \ + [--title "Updated Title"] +``` + +Requires admin credentials. At least one of `--url`, `--newkeyword`, or `--title` must be provided. + +### Delete a short URL + +```bash +python3 /scripts/yourls_manager.py delete --keyword "mycode" +``` + +Requires admin credentials. Asks for confirmation before deleting unless `--force` is passed. + +--- + +## Presenting results + +After running any operation, present results conversationally: + +- **Create**: "Done! `mpm.to/mycode` now points to [long URL]." +- **Read**: Show short URL, destination, title, click count, and age. +- **List**: Render as a clean table with columns: Short Code | Destination | Clicks | Created. +- **Update**: Confirm what changed. +- **Delete**: Confirm deletion. + +If an operation fails, read the error output and explain it clearly to the user — don't just dump the raw error. + +--- + +## Troubleshooting + +| Error | Likely cause | Fix | +|---|---|---| +| `No signature token` | First-time use | Run `setup` | +| `'delete'/'update' action not recognised` | Plugin not installed | Script will auto-fall back to admin session if credentials are stored | +| `Plugin not active; no admin credentials` | Neither method available | Install plugin OR run `setup` to add username + password | +| `Admin login failed` | Wrong password | Re-run `setup` to update stored credentials | +| `Keyword already exists` | Short code taken | Choose a different `--keyword` | +| `Short URL not found` | Keyword doesn't exist | Check spelling; use `list` to browse | +| `requests` module not found | Missing dependency | Run `pip3 install requests --break-system-packages` |