Borrowing it
Nothing to install: this file belongs to macromania/agentop. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.
curl -O https://raw.githubusercontent.com/macromania/agentop/main/.github/skills/canvas-mindmap/SKILL.mdgit clone --depth 1 https://github.com/macromania/agentopWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/macromania/agentop/canvas-mindmap)<a href="https://agentmods.dev/skills/macromania/agentop/canvas-mindmap"><img src="https://agentmods.dev/badge/skills/macromania/agentop/canvas-mindmap/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/macromania/agentop/canvas-mindmap"><img src="https://agentmods.dev/badge/skills/macromania/agentop/canvas-mindmap.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00070 | $0.04113 |
| Opus 5.5 | $0.00028 | $0.01645 |
| Sonnet 5.5 | $0.00014 | $0.00823 |
| Haiku 4.5 | $0.00007 | $0.00411 |
Grade A, and why
canvas-mindmap scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2mo ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 612 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Canvas Mindmap with Gestures
Interactive pan/zoom canvas using @use-gesture/react and @react-spring/web for smooth mindmap visualization.
When to Use This Skill
- Building canvas-based UIs with pan/zoom
- Implementing mindmap or graph visualizations
- Adding gesture-based interactions
- Laying out hierarchical data with dagre
- Animating node transitions
- Rendering connection lines between nodes
Canvas Architecture
Core Canvas Component
// src/renderer/components/canvas/Canvas.tsx
import { useRef, useMemo, useCallback } from 'react';
import { useGesture } from '@use-gesture/react';
import { useSpring, animated } from '@react-spring/web';
import { useAtom, useAtomValue } from 'jotai';
import { canvasViewStateAtom } from '@/state/ui-atoms';
interface CanvasProps {
children: React.ReactNode;
width?: number;
height?: number;
minZoom?: number;
maxZoom?: number;
}
export function Canvas({
children,
width = 4000,
height = 4000,
minZoom = 0.1,
maxZoom = 2,
}: CanvasProps) {
const containerRef = useRef<HTMLDivElement>(null);
const [viewState, setViewState] = useAtom(canvasViewStateAtom);
// Spring animation for smooth transitions
const [springs, api] = useSpring(() => ({
x: viewState.x,
y: viewState.y,
scale: viewState.zoom,
config: { tension: 300, friction: 30 },
}));
// Clamp zoom value
const clampZoom = useCallback(
(zoom: number) => Math.min(maxZoom, Math.max(minZoom, zoom)),
[minZoom, maxZoom]
);
// Gesture binding
useGesture(
{
// Pan gesture
onDrag: ({ offset: [x, y], memo, first, event }) => {
// Ignore if dragging a node
if ((event.target as HTMLElement).closest('[data-draggable]')) {
return memo;
}
if (first) {
return { startX: viewState.x, startY: viewState.y };
}
api.start({ x, y, immediate: true });
return memo;
},
onDragEnd: ({ offset: [x, y] }) => {
setViewState((prev) => ({ ...prev, x, y }));
},
// Pinch zoom (trackpad/touch)
onPinch: ({ offset: [scale], origin: [ox, oy], memo, first }) => {
if (first) {
const rect = containerRef.current?.getBoundingClientRect();
if (!rect) return;
// Calculate origin relative to canvas
return {
originX: ox - rect.left,
originY: oy - rect.top,
startZoom: viewState.zoom,
startX: viewState.x,
startY: viewState.y,
};
}
const newZoom = clampZoom(scale);
// Zoom towards cursor position
const zoomRatio = newZoom / memo.startZoom;
const newX = memo.originX - (memo.originX - memo.startX) * zoomRatio;
const newY = memo.originY - (memo.originY - memo.startY) * zoomRatio;
api.start({ scale: newZoom, x: newX, y: newY });
return memo;
},
onPinchEnd: () => {
const { scale, x, y } = springs;
setViewState({
zoom: scale.get(),
x: x.get(),
y: y.get(),
});
},
// Scroll wheel zoom
onWheel: ({ delta: [, dy], event, ctrlKey }) => {
event.preventDefault();
// Only zoom with ctrl/cmd or pinch gesture
if (!ctrlKey) return;
const rect = containerRef.current?.getBoundingClientRect();
if (!rect) return;
const cursorX = event.clientX - rect.left;
const cursorY = event.clientY - rect.top;
setViewState((prev) => {
const zoomDelta = -dy * 0.001;
const newZoom = clampZoom(prev.zoom + prev.zoom * zoomDelta);
const zoomRatio = newZoom / prev.zoom;
return {
zoom: newZoom,
x: cursorX - (cursorX - prev.x) * zoomRatio,
y: cursorY - (cursorY - prev.y) * zoomRatio,
};
});
},
},
{
target: containerRef,
drag: {
from: () => [springs.x.get(), springs.y.get()],
filterTaps: true,
},
pinch: {
scaleBounds: { min: minZoom, max: maxZoom },
from: () => [springs.scale.get(), 0],
},
wheel: {
preventDefault: true,
eventOptions: { passive: false },
},
}
);
return (
<div
ref={containerRef}
className="relative w-full h-full overflow-hidden touch-none"
style={{ cursor: 'grab' }}
>
<animated.div
style={{
transform: springs.x.to(
(x) =>
`translate3d(${x}px, ${springs.y.get()}px, 0) scale(${springs.scale.get()})`
),
transformOrigin: '0 0',
width,
height,
}}
>
{children}
</animated.div>
</div>
);
}
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 2mo ago First seen · 612 lines · 70 tokens per session scan A f180d35e41c9
canvas-mindmap is a skill published in the GitHub repository macromania/agentop (11 stars, last pushed 7mo ago), licensed MIT. It adds 70 tokens to every session and 4,113 once invoked, about $0.0003 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
canvas-mindmap compared with skills from other repositories
| Mod | Type | Stars | Last push | Licence | Scan | Tokens | Works with |
|---|---|---|---|---|---|---|---|
| canvas-mindmapmacromania/agentop | Skill | 11 | 7mo ago | MIT | A | 70 | Claude Code, Codex |
| html-artifactslangchain-ai/open-swe | Skill | 11k | yesterday | MIT | A | 52 | Claude Code, Codex |
| surfsense-htmlMODSetter/SurfSense | Skill | 17k | yesterday | Apache-2.0 | A | 89 | Claude Code, Codex |
| skin-creatornetease-youdao/LobsterAI | Skill | 6.2k | yesterday | MIT | A | 48 | Claude Code, Codex |
| a2uiPrism-Shadow/penguin-harness | Skill | 3.2k | yesterday | Apache-2.0 | A | 203 | Claude Code, Codex |
| card-designZJU-REAL/Easel | Skill | 4.5k | 4d ago | Apache-2.0 | A | 113 | Claude Code, Codex |
| proto-bot-opsmakecindy/cindy | Skill | 9.3k | yesterday | Apache-2.0 | A | 38 | Claude Code, Codex |