Token导航 LogoToken导航

Agent Skill · 研究检索

pasteboard-textinsertion(粘贴板文本插入)

pasteboard-textinsertion 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

pasteboard-textinsertion 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描有未通过项,按安装量在研究检索类的 73,675 个 Skill 里排第 71,838。

总安装 192周安装 8GitHub Stars 公开资料未说明下载 64核验 2026-05-01

安装说明

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

安装方式

通过对话安装

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

请帮我安装这个 Agent Skill:pasteboard-textinsertion(粘贴板文本插入)
来源仓库:https://github.com/makgunay/claude-swift-skills
仓库路径:skills/pasteboard-textinsertion
安装命令:
npx skills add https://github.com/makgunay/claude-swift-skills --skill pasteboard-textinsertion
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

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

skills.shnpx skills
npx skills add https://github.com/makgunay/claude-swift-skills --skill pasteboard-textinsertion

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

用于查找、检索和筛选相关信息。pasteboard-textinsertion 属于研究检索类 Skill,可作为该场景下的辅助能力补充。适合根据关键词或任务场景快速定位候选结果。可结合来源仓库和原始 README 核验具体用法。安装前建议确认权限范围和维护状态。注意是否会触发联网或文件读写操作。

来源仓库内路径:skills/pasteboard-textinsertion

上手步骤

4 步
  1. 1

    确认自己的宿主工具

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

  2. 2

    拿到安装命令

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

  3. 3

    安装后重启宿主

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

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

pasteboard-textinsertion 怎么安装?

在终端执行 npx skills add https://github.com/makgunay/claude-swift-skills --skill pasteboard-textinse…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

pasteboard-textinsertion 支持哪些 AI 工具?

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

pasteboard-textinsertion 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

pasteboard-textinsertion 是免费的吗?

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

pasteboard-textinsertion 用的人多吗?

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

pasteboard-textinsertion 安全吗?

第三方扫描有未通过项,风险较高。除非你确认过源码,否则不建议直接安装到常用环境。

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

值得选的地方

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

先想清楚的地方

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

适不适合你

更适合

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

不太适合

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

研究检索类 Skill 对比

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

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
pasteboard-textinsertion

粘贴板文本插入 · 本页

192—需要联网未明确未通过

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

SKILL.md 原文

Pasteboard & Text Insertion

Insert text INTO other applications. The core capability of prompt managers and text expanders.

Critical Constraints

  • ❌ DO NOT forget to save/restore clipboard contents → ✅ Preserve user's clipboard before overwriting
  • ❌ DO NOT skip the delay between clipboard set and paste simulation → ✅ Add 50ms delay minimum
  • ❌ DO NOT use only one insertion method → ✅ Build a fallback chain: Paste → Typing → Accessibility
  • ❌ DO NOT use Accessibility API without permission check → ✅ Always check AXIsProcessTrusted() first

Insertion Methods (Ranked)

MethodReliabilitySpeedSandboxBest For
Clipboard + Paste★★★★★Fast✅Default method
CGEvent Typing★★★★☆Slow⚠️ Needs AccessibilityPaste-blocking apps
Accessibility API★★★☆☆Fast⚠️ Needs AccessibilityText fields only

Method 1: Clipboard + Simulated Paste (Default)

import AppKit
import Carbon

class TextInserter {
    func insertViaPaste(_ text: String, completion: (() -> Void)? = nil) {
        let pasteboard = NSPasteboard.general
        let previousContents = pasteboard.string(forType: .string)

        pasteboard.clearContents()
        pasteboard.setString(text, forType: .string)

        DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
            self.simulateKeyPress(keyCode: 0x09, modifiers: .maskCommand)  // Cmd+V

            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                if let previous = previousContents {
                    pasteboard.clearContents()
                    pasteboard.setString(previous, forType: .string)
                }
                completion?()
            }
        }
    }

    func simulateKeyPress(keyCode: CGKeyCode, modifiers: CGEventFlags) {
        let source = CGEventSource(stateID: .hidSystemState)
        let keyDown = CGEvent(keyboardEventSource: source, virtualKey: keyCode, keyDown: true)
        keyDown?.flags = modifiers
        keyDown?.post(tap: .cghidEventTap)
        let keyUp = CGEvent(keyboardEventSource: source, virtualKey: keyCode, keyDown: false)
        keyUp?.flags = modifiers
        keyUp?.post(tap: .cghidEventTap)
    }
}

Method 2: CGEvent Character Typing (Fallback)

extension TextInserter {
    func insertViaTyping(_ text: String, delayPerChar: TimeInterval = 0.01) {
        let source = CGEventSource(stateID: .hidSystemState)
        for char in text {
            let str = String(char)
            if let event = CGEvent(keyboardEventSource: source, virtualKey: 0, keyDown: true) {
                var unichar = str.utf16.first!
                event.keyboardSetUnicodeString(stringLength: 1, unicodeString: &unichar)
                event.post(tap: .cghidEventTap)
            }
            if let event = CGEvent(keyboardEventSource: source, virtualKey: 0, keyDown: false) {
                event.post(tap: .cghidEventTap)
            }
            Thread.sleep(forTimeInterval: delayPerChar)
        }
    }
}

Method 3: Accessibility API (Direct)

import ApplicationServices

extension TextInserter {
    func insertViaAccessibility(_ text: String) -> Bool {
        guard AXIsProcessTrusted() else { return false }
        let systemWide = AXUIElementCreateSystemWide()
        var focusedElement: CFTypeRef?
        guard AXUIElementCopyAttributeValue(systemWide, kAXFocusedUIElementAttribute as CFString,
                                            &focusedElement) == .success,
              let element = focusedElement as! AXUIElement? else { return false }

        // Verify it's a text field
        var role: CFTypeRef?
        AXUIElementCopyAttributeValue(element, kAXRoleAttribute as CFString, &role)
        guard let roleStr = role as? String,
              roleStr == kAXTextFieldRole || roleStr == kAXTextAreaRole else { return false }

        // Get current value + selection, insert at selection
        var currentValue: CFTypeRef?
        AXUIElementCopyAttributeValue(element, kAXValueAttribute as CFString, &currentValue)
        let current = (currentValue as? String) ?? ""

        var selectedRange: CFTypeRef?
        AXUIElementCopyAttributeValue(element, kAXSelectedTextRangeAttribute as CFString, &selectedRange)

        var newValue = current
        if let range = selectedRange as? AXValue {
            var cfRange = CFRange()
            AXValueGetValue(range, .cfRange, &cfRange)
            let start = current.index(current.startIndex, offsetBy: cfRange.location)
            let end = current.index(start, offsetBy: cfRange.length)
            newValue.replaceSubrange(start..<end, with: text)
        } else {
            newValue += text
        }

        return AXUIElementSetAttributeValue(element, kAXValueAttribute as CFString,
                                            newValue as CFTypeRef) == .success
    }
}

Variable Expansion System

class VariableExpander {
    static let builtInVariables: [(pattern: String, replacement: () -> String)] = [
        ("{{cursor}}", { "" }),  // Handled specially for cursor positioning
        ("{{clipboard}}", { NSPasteboard.general.string(forType: .string) ?? "" }),
        ("{{date}}", { DateFormatter.localizedString(from: Date(), dateStyle: .medium, timeStyle: .none) }),
        ("{{time}}", { DateFormatter.localizedString(from: Date(), dateStyle: .none, timeStyle: .short) }),
        ("{{datetime}}", { DateFormatter.localizedString(from: Date(), dateStyle: .medium, timeStyle: .short) }),
        ("{{iso_date}}", { ISO8601DateFormatter().string(from: Date()) }),
        ("{{username}}", { NSFullUserName() }),
        ("{{uuid}}", { UUID().uuidString }),
    ]

    func expand(_ text: String) -> (text: String, cursorOffset: Int?) {
        var result = text
        var cursorOffset: Int? = nil

        for (pattern, replacement) in Self.builtInVariables {
            if pattern == "{{cursor}}" {
                if let range = result.range(of: pattern) {
                    cursorOffset = result.distance(from: result.startIndex, to: range.lowerBound)
                    result.replaceSubrange(range, with: "")
                }
            } else {
                result = result.replacingOccurrences(of: pattern, with: replacement())
            }
        }
        return (result, cursorOffset)
    }
}

User-Prompted Variables

// Format: {{?variableName:Enter your name:DefaultValue}}
func findUserVariables(in text: String) -> [(name: String, prompt: String, defaultValue: String)] {
    let pattern = #"\{\{\?(\w+):([^:]+):?([^}]*)\}\}"#
    let regex = try! NSRegularExpression(pattern: pattern)
    return regex.matches(in: text, range: NSRange(text.startIndex..., in: text)).compactMap { match in
        guard let nameRange = Range(match.range(at: 1), in: text),
              let promptRange = Range(match.range(at: 2), in: text) else { return nil }
        let defaultRange = Range(match.range(at: 3), in: text)
        return (String(text[nameRange]), String(text[promptRange]), defaultRange.map { String(text[$0]) } ?? "")
    }
}

Cursor Positioning After Insertion

func insertWithCursor(_ text: String, inserter: TextInserter) {
    let (expanded, cursorOffset) = VariableExpander().expand(text)
    inserter.insertViaPaste(expanded) {
        if let offset = cursorOffset {
            let moveCount = expanded.count - offset
            for _ in 0..<moveCount {
                inserter.simulateKeyPress(keyCode: 0x7B, modifiers: [])  // Left arrow
            }
        }
    }
}

References

平台分布

Codex

35.59%
按下载量换算23

Claude

31.3%
按下载量换算20

Cursor

20.17%
按下载量换算13

Gemini CLI

9.89%
按下载量换算6

安全审计

Gen Agent Trust Hub

未通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

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

继续浏览同类 Skills