Token导航 LogoToken导航

Agent Skill · 开发

show-gallery(展示画廊)

show-gallery 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

show-gallery 是开发类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为操作浏览器;许可证信息还不明确,第三方扫描有提醒项,按安装量在开发类的 21,746 个 Skill 里排第 19,191。

总安装 288周安装 12GitHub Stars 21下载 96核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:show-gallery(展示画廊)
来源仓库:https://github.com/thepexcel/agent-skills
仓库路径:skills/show-gallery
安装命令:
npx skills add https://github.com/thepexcel/agent-skills --skill show-gallery
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/thepexcel/agent-skills --skill show-gallery

这个 Skill 是做什么的

开发类 Skill 面向写代码、改代码和排查问题,一般会读写仓库文件,部分还会执行构建或测试命令。

show-gallery 用于构建和管理作品展示页面或数字画廊。适合在 Codex、Claude、Cursor、Gemini CLI 中组织图片、视频与描述文案。支持响应式布局与分类浏览,提升观赏体验。

安装命令:npx skills add https://github.com/thepexcel/agent-skills --skill show-gallery。上传内容需提前压缩优化,避免加载缓慢影响用户体验。

来源仓库内路径:skills/show-gallery

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/thepexcel/agent-skills --skill show-gallery;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要操作浏览器,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

show-gallery 怎么安装?

在终端执行 npx skills add https://github.com/thepexcel/agent-skills --skill show-gallery。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

show-gallery 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

show-gallery 需要什么权限?

权限级别是操作浏览器。该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

show-gallery 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

show-gallery 用的人多吗?

公开数据是累计安装 288 次,近一周安装 12 次,下载 96 次,GitHub 21 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

show-gallery 安全吗?

第三方扫描有提醒项,说明存在需要人工确认的行为。安装前请打开源码看清它读了什么、联网到哪里。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理开发类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

开发类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
skill-vetter

技能审查员 · OpenClaw

8,779,018986操作浏览器MIT-0通过
ontology

本体论 · OpenClaw

6,636,960576只读MIT-0通过
entra-app-registration

内部应用程序注册 · Codex、Claude

6,631,872764接触敏感数据未明确通过
entra-app-registration

内部应用程序注册 · Codex、Claude

3,757,680201接触敏感数据未明确通过
nano-banana-pro

纳米香蕉专业版 · OpenClaw

3,526,898364接触敏感数据MIT-0有提醒
show-gallery

展示画廊 · 本页

28821操作浏览器未明确有提醒

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

/show-gallery — Universal Media Browser

Browse generated images & videos from any local folder. Click to enlarge, copy path to clipboard.

Quick Flow

พี่ระ: "โชว์รูปใน output-fal/" หรือ "show gallery D:/path/to/folder"
→ สร้าง gallery.html ใน target folder
→ preview_start server ที่ serve folder นั้น
→ navigate to /gallery.html
→ screenshot ให้พี่ระดู

เมื่อถูกเรียก

Step 1: ระบุ folder

  • ถ้าพี่ระระบุ path → ใช้เลย
  • ถ้าไม่ระบุ → ถามว่า folder ไหน หรือใช้ folder ล่าสุดที่ gen

Step 2: สร้าง gallery.html

ใช้ Gallery HTML Template ด้านล่าง — Write ไฟล์ gallery.html ลงใน target folder ต้องแก้ GALLERY_ROOT ให้เป็น absolute path ของ folder (ใช้ / ไม่ใช่ \)

Step 3: เปิด Preview

  1. เช็ค .claude/launch.json ว่ามี server ที่ serve folder นี้อยู่หรือยัง
  2. ถ้าไม่มี → เพิ่ม config ใหม่ (port ถัดไป เช่น 8125, 8126...)
  3. preview_start → preview_eval: window.location.href = '/gallery.html'
  4. รอ 1-2 วิ → preview_screenshot ให้พี่ระดู

Step 4: Interaction

พี่ระจะ copy path จากหน้า gallery แล้ว paste มาใน chat บอกว่าจะทำอะไรกับรูป/วิดีโอนั้น


Gallery HTML Template

Copy ทั้ง block ด้านล่าง แล้ว Write เป็น gallery.html ใน target folder แก้ GALLERY_ROOT บรรทัดเดียว
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<title>Gallery</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{background:#1a1a1a;color:#fff;font-family:system-ui,sans-serif;padding:12px}
.header{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;flex-wrap:wrap;gap:8px}
.header h1{font-size:14px;color:#aaa;font-weight:400}
.header .count{font-size:13px;color:#666}
.controls{display:flex;gap:6px;align-items:center}
.controls button{background:#333;border:1px solid #555;color:#ccc;padding:4px 10px;border-radius:4px;cursor:pointer;font-size:12px}
.controls button:hover{background:#444}
.controls button.active{background:#555;color:#fff;border-color:#888}
.grid{display:grid;gap:8px}
.grid.cols-2{grid-template-columns:repeat(2,1fr)}
.grid.cols-3{grid-template-columns:repeat(3,1fr)}
.grid.cols-4{grid-template-columns:repeat(4,1fr)}
.card{position:relative;border-radius:6px;overflow:hidden;background:#222;cursor:pointer}
.card:hover{outline:2px solid #ffd700}
.card img,.card video{width:100%;display:block;aspect-ratio:2/3;object-fit:cover}
.card .info{position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,.85));padding:6px 8px}
.card .fname{font-size:11px;color:#ddd;word-break:break-all}
.card .meta{font-size:10px;color:#888;margin-top:2px}
.card .copy-btn{position:absolute;top:6px;right:6px;background:rgba(0,0,0,.7);border:1px solid #555;color:#ccc;padding:3px 8px;border-radius:4px;font-size:11px;cursor:pointer;opacity:0;transition:opacity .2s}
.card:hover .copy-btn{opacity:1}
.card .copy-btn.copied{background:#2a5a2a;border-color:#4a4;color:#8f8}
.card .badge{position:absolute;top:6px;left:6px;background:rgba(0,0,0,.7);color:#ffd700;padding:2px 6px;border-radius:3px;font-size:10px;font-weight:700}
.modal{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.95);z-index:100;justify-content:center;align-items:center;flex-direction:column;cursor:pointer}
.modal.active{display:flex}
.modal img,.modal video{max-height:85vh;max-width:95vw;object-fit:contain;border-radius:6px}
.modal .path-bar{margin-top:8px;padding:6px 14px;background:#333;border-radius:4px;font-size:12px;color:#aaa;cursor:pointer;user-select:all}
.modal .path-bar:hover{background:#444;color:#fff}
.modal .caption{margin-top:6px;font-size:11px;color:#888;max-width:80vw;text-align:center;max-height:60px;overflow:auto}
.toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);background:#2a5a2a;color:#8f8;padding:8px 20px;border-radius:6px;font-size:13px;opacity:0;transition:opacity .3s;z-index:200;pointer-events:none}
.toast.show{opacity:1}
</style>
</head>
<body>

<div class="header">
  <h1 id="title">Gallery</h1>
  <span class="count" id="count"></span>
  <div class="controls">
    <button onclick="setCols(2)">2</button>
    <button onclick="setCols(3)" class="active">3</button>
    <button onclick="setCols(4)">4</button>
    <span style="color:#555">|</span>
    <button onclick="filterType('all')" class="active" id="btn-all">All</button>
    <button onclick="filterType('image')" id="btn-image">IMG</button>
    <button onclick="filterType('video')" id="btn-video">VID</button>
  </div>
</div>
<div class="grid cols-3" id="grid"></div>

<div class="modal" id="modal">
  <img id="modal-img" style="display:none">
  <video id="modal-vid" controls style="display:none"></video>
  <div class="path-bar" id="modal-path" onclick="event.stopPropagation();copyPath(this.dataset.path)"></div>
  <div class="caption" id="modal-caption"></div>
</div>

<div class="toast" id="toast">Copied!</div>

<script>
// ====== CONFIG — แก้ตรงนี้ ======
const GALLERY_ROOT = 'D:/ClaudeMediaGen/output-fal';
// =================================

const IMG_EXT = /\.(png|jpg|jpeg|webp|gif)$/i;
const VID_EXT = /\.(mp4|webm|mov)$/i;
let allItems = [];
let currentFilter = 'all';
const captions = {};

async function loadGallery() {
  const resp = await fetch('./');
  const html = await resp.text();
  const links = [...html.matchAll(/href="([^"]+)"/g)].map(m => decodeURIComponent(m[1]));
  const mediaFiles = links.filter(f => IMG_EXT.test(f) || VID_EXT.test(f)).sort();

  // Load .txt captions
  const txtFiles = links.filter(f => f.endsWith('.txt'));
  await Promise.all(txtFiles.map(async t => {
    try {
      const r = await fetch(t);
      captions[t.replace('.txt','')] = (await r.text()).slice(0, 200);
    } catch(e) {}
  }));

  allItems = mediaFiles.map(f => {
    const isVid = VID_EXT.test(f);
    const baseName = f.replace(/\.[^.]+$/, '');
    return { file: f, isVideo: isVid, caption: captions[baseName] || '' };
  });

  renderGrid();
}

function renderGrid() {
  const grid = document.getElementById('grid');
  const filtered = currentFilter === 'all' ? allItems
    : currentFilter === 'image' ? allItems.filter(i => !i.isVideo)
    : allItems.filter(i => i.isVideo);

  document.getElementById('count').textContent =
    `${filtered.length}/${allItems.length} items (${allItems.filter(i=>!i.isVideo).length} img, ${allItems.filter(i=>i.isVideo).length} vid)`;

  grid.innerHTML = '';
  filtered.forEach((item, i) => {
    const card = document.createElement('div');
    card.className = 'card';
    const absPath = GALLERY_ROOT + '/' + item.file;
    const sizeLabel = item.isVideo ? 'VIDEO' : '';

    if (item.isVideo) {
      card.innerHTML = `
        <video src="${item.file}" muted preload="metadata"></video>
        ${sizeLabel ? `<span class="badge">${sizeLabel}</span>` : ''}
        <button class="copy-btn" onclick="event.stopPropagation();copyPath('${absPath}',this)">Copy Path</button>
        <div class="info"><div class="fname">${item.file}</div></div>`;
    } else {
      card.innerHTML = `
        <img src="${item.file}" loading="lazy">
        <button class="copy-btn" onclick="event.stopPropagation();copyPath('${absPath}',this)">Copy Path</button>
        <div class="info"><div class="fname">${item.file}</div></div>`;
    }

    card.onclick = () => openModal(item, absPath);
    grid.appendChild(card);
  });

  if (filtered.length === 0) {
    grid.innerHTML = '<p style="grid-column:1/-1;text-align:center;color:#666;padding:40px">No media files found</p>';
  }
}

function openModal(item, absPath) {
  const modal = document.getElementById('modal');
  const mImg = document.getElementById('modal-img');
  const mVid = document.getElementById('modal-vid');
  const mPath = document.getElementById('modal-path');
  const mCap = document.getElementById('modal-caption');

  if (item.isVideo) {
    mImg.style.display = 'none';
    mVid.style.display = 'block';
    mVid.src = item.file;
    mVid.play();
  } else {
    mVid.style.display = 'none';
    mVid.pause();
    mImg.style.display = 'block';
    mImg.src = item.file;
  }

  mPath.textContent = absPath;
  mPath.dataset.path = absPath;
  mCap.textContent = item.caption;
  modal.classList.add('active');
  modal.onclick = (e) => {
    if (e.target === modal) { modal.classList.remove('active'); mVid.pause(); }
  };
}

function copyPath(path, btn) {
  navigator.clipboard.writeText(path).then(() => {
    showToast('Copied: ' + path);
    if (btn) { btn.textContent = 'Copied!'; btn.classList.add('copied'); setTimeout(() => { btn.textContent = 'Copy Path'; btn.classList.remove('copied'); }, 1500); }
  });
}

function showToast(msg) {
  const t = document.getElementById('toast');
  t.textContent = msg;
  t.classList.add('show');
  setTimeout(() => t.classList.remove('show'), 2000);
}

function setCols(n) {
  const grid = document.getElementById('grid');
  grid.className = 'grid cols-' + n;
  document.querySelectorAll('.controls button').forEach(b => {
    if (['2','3','4'].includes(b.textContent)) b.classList.toggle('active', b.textContent == n);
  });
}

function filterType(type) {
  currentFilter = type;
  ['all','image','video'].forEach(t => {
    document.getElementById('btn-'+t)?.classList.toggle('active', t === type);
  });
  renderGrid();
}

loadGallery();
</script>
</body>
</html>

Prompt Rules (สำหรับ Claude เมื่อ invoke skill นี้)

  1. สร้าง gallery.html ใน target folder — copy template จากด้านบน
  2. แก้ GALLERY_ROOT ให้ตรงกับ absolute path ของ folder (forward slashes)
  3. แก้ <title> ให้สื่อกับเนื้อหา
  4. เช็ค launch.json — ถ้าไม่มี server ที่ serve folder นี้ → เพิ่ม config ใหม่
  5. preview_start → navigate /gallery.html → preview_screenshot ให้พี่ระดู
  6. ถ้า screenshot timeout → ลอง preview_snapshot แทน แล้วบอกพี่ระเปิดดูใน Preview panel

Browse Folder Mode

เมื่อพี่ระบอก "browse folder" หรือ "ดู folder" โดยไม่ระบุ path:

  • แสดง list ของ output folders ที่มี media files
  • ให้พี่ระเลือก folder
  • แล้วสร้าง gallery ตาม flow ปกติ

Related Skills

  • /gen-character-image — ใช้ gallery หลัง gen character
  • /kie-ai — ใช้ gallery หลัง gen จาก Kie.ai
  • /fal-ai — ใช้ gallery หลัง gen จาก fal.ai
  • /comfyui-user — ใช้ gallery หลัง gen จาก ComfyUI
  • /image-analysis — วิเคราะห์รูปที่เลือกจาก gallery

平台分布

Codex

37.34%
按下载量换算36

Claude

30.49%
按下载量换算29

Cursor

19.67%
按下载量换算19

Gemini CLI

8.61%
按下载量换算8

安全审计

Gen Agent Trust Hub

可疑

Socket

通过

Snyk

通过

权限和风险

操作浏览器

该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在提醒或未通过项,安装前请自行复核。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills