Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Collect and manage product feedback with Canny. Use when a user asks to set up a feature request board, prioritize product feedback, build a public roadmap, or let users vote on features.
.claude/skills/terminalskills-canny/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | -22% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 9% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -14% | 0% |
| case-04 | ✗→✓ | ▲ Improved | -19% | 0% |
| case-05 | ✗→✓ | ▲ Improved | -42% | 0% |
Canny collects, organizes, and prioritizes product feedback. Users submit feature requests, vote on ideas, and follow updates. Teams build public roadmaps and close the loop when features ship.
typescript// components/CannySdk.tsx — Identify logged-in users 'use client' import { useEffect } from 'react' export function CannyIdentify({ user }) { useEffect(() => { if (window.Canny && user) { window.Canny('identify', { appID: process.env.NEXT_PUBLIC_CANNY_APP_ID, user: { id: user.id, email: user.email, name: user.name, avatarURL: user.avatar, created: new Date(user.createdAt).toISOString(), customFields: { plan: user.plan, mrr: user.mrr }, }, }) } }, [user]) return null }
tsx// Embed the feedback widget in your app function FeedbackButton() { return ( <button data-canny-link data-board-token="your-board-token" className="fixed bottom-4 right-4 bg-blue-600 text-white px-4 py-2 rounded-full" > 💡 Feedback </button> ) }
typescript// lib/canny.ts — Programmatic feedback management const CANNY_API_KEY = process.env.CANNY_API_KEY! // Create a post (feature request) programmatically await fetch('https://canny.io/api/v1/posts/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ apiKey: CANNY_API_KEY, authorID: userId, boardID: 'board-id', title: 'Dark mode support', details: 'Would love a dark theme option for the dashboard.', }), }) // Retrieve top voted posts const response = await fetch('https://canny.io/api/v1/posts/list', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ apiKey: CANNY_API_KEY, boardID: 'board-id', sort: 'score', limit: 20, }), })
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-14 | fail→fail | 12,985 | 2,026 | -84% | 1 | 1 | 0% | 2,419 | 1,041 | -57% | 0 | 0 | — |
case-01 | fail→pass | 13,485 | 6,593 | -51% | 1 | 1 | 0% | 2,776 | 2,169 | -22% | 0 | 0 | — |
case-02 | fail→pass | 11,711 | 8,642 | -26% | 1 | 1 | 0% | 2,649 | 2,880 | +9% | 0 | 0 | — |
case-03 | fail→pass | 12,244 | 7,161 | -42% | 1 | 1 | 0% | 2,588 | 2,222 | -14% | 0 | 0 | — |
case-04 | fail→pass | 11,033 | 5,907 | -46% | 1 | 1 | 0% | 2,076 | 1,684 | -19% | 0 | 0 | — |
case-05 | fail→pass | 12,143 | 3,143 | -74% | 1 | 1 | 0% | 2,386 | 1,395 | -42% | 0 | 0 | — |
case-06 | fail→pass | 9,863 | 2,921 | -70% | 1 | 1 | 0% | 1,615 | 1,307 | -19% | 0 | 0 | — |
case-07 | pass→pass | 4,794 | 2,326 | -51% | 1 | 1 | 0% | 925 | 1,088 | +18% | 0 | 0 | — |
case-08 | fail→pass | 13,955 | 10,338 | -26% | 1 | 1 | 0% | 2,437 | 2,322 | -5% | 0 | 0 | — |
case-09 | fail→pass | 10,543 | 3,392 | -68% | 1 | 1 | 0% | 1,986 | 1,244 | -37% | 0 | 0 | — |
case-10 | pass→pass | 8,509 | 4,224 | -50% | 1 | 1 | 0% | 1,533 | 1,376 | -10% | 0 | 0 | — |
case-11 | pass→pass | 3,705 | 1,993 | -46% | 1 | 1 | 0% | 547 | 983 | +80% | 0 | 0 | — |
case-12 | fail→pass | 13,319 | 9,578 | -28% | 1 | 1 | 0% | 2,287 | 2,407 | +5% | 0 | 0 | — |
case-13 | pass→pass | 5,276 | 2,577 | -51% | 1 | 1 | 0% | 972 | 1,178 | +21% | 0 | 0 | — |
case-15 | pass→pass | 6,337 | 1,742 | -73% | 1 | 1 | 0% | 1,029 | 1,014 | -1% | 0 | 0 | — |
case-16 | pass→pass | 2,554 | 1,689 | -34% | 1 | 1 | 0% | 458 | 996 | +117% | 0 | 0 | — |
case-17 | pass→pass | 6,426 | 1,987 | -69% | 1 | 1 | 0% | 1,171 | 1,042 | -11% | 0 | 0 | — |
case-18 | fail→fail | 3,333 | 2,574 | -23% | 1 | 1 | 0% | 528 | 1,020 | +93% | 0 | 0 | — |
case-19 | pass→pass | 2,888 | 1,377 | -52% | 1 | 1 | 0% | 441 | 920 | +109% | 0 | 0 | — |
case-20 | pass→pass | 9,051 | 5,482 | -39% | 1 | 1 | 0% | 1,888 | 1,899 | +1% | 0 | 0 | — |
case-21 | pass→pass | 9,245 | 6,912 | -25% | 1 | 1 | 0% | 1,857 | 2,098 | +13% | 0 | 0 | — |
case-22 | pass→pass | 9,881 | 8,954 | -9% | 1 | 1 | 0% | 1,973 | 2,528 | +28% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +41 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.