Steps
用條件、轉換、腳本和一個最終輸出組成線性流程。在獨立檢查器中設定每一步,並比較測試前後的值。
用視覺化步驟或程式碼建立工作流程,選擇支援的剪貼簿類型,並直接在 Pasteon 內建操作旁執行。
Workflow 是儲存的處理配方;只有目前剪貼簿項目符合你選擇的輸入條件時,它的 Action 才會出現在 Pasteon。
用條件、轉換、腳本和一個最終輸出組成線性流程。在獨立檢查器中設定每一步,並比較測試前後的值。
使用指定直譯器、參數、工作目錄和逾時執行內嵌程式碼或外部腳本。單一結果用 Simple,執行時選擇用 Script Filter。
這個範例會清理複製文字的空白、統一命名格式,並把結果送回你正在使用的 App。
開啟「設定 → Workflows」,新增工作流程,填寫名稱和圖示,再選擇它應該在哪些剪貼簿類型下出現。
加入清理文字、轉換命名格式等步驟並拖曳排序。Output 固定在末端,讓流程保持可預期。
測試不會真的複製、貼上或開啟內容。你可以查看每一步的前後值、耗時與驗證狀態。
工作流程會直接顯示在內建 Primary Actions 之後。點按或按 Enter 貼上結果;按住 Command 則只複製。
步驟由上而下執行。條件決定 Action 何時可用,轉換更新目前值,一個輸出決定 Pasteon 如何處理結果。
Pasteon 透過 stdin 傳送版本化 JSON,並從 stdout 讀取協定 JSON。日誌寫入 stderr;逾時、取消與輸出限制讓執行保持可控。
當一個 Action 只需產生一份文字、檔案或 URL 結果時,使用 Simple 模式。
{
"version": 1,
"result": {
"type": "text",
"value": "Ready to paste"
}
}Filter 階段只回傳輕量候選資訊。使用者選擇其中一項後,Pasteon 才執行 execute。
{
"version": 1,
"actions": [
{
"id": "swift",
"title": "Generate Swift Model",
"argument": { "language": "swift" }
}
]
}腳本收到 phase「filter」,最多回傳 20 個候選 Action。
Pasteon 顯示標題、說明、圖示與 JSON 參數,不預先計算最終結果。
被選取的 actionId 與 argument 回傳腳本,只計算目前這一項。
stdout 只能輸出協定 JSON,診斷資訊請寫入 stderr。內嵌程式碼與外部腳本使用同一套輸入輸出契約。
編寫 Code Workflow 或產生 .pasteon-workflow 檔案時可查閱這裡。欄位名稱與限制和目前 Pasteon Runner 一致。
這些值決定 Workflow 在哪些內容下出現,以及 Pasteon 如何啟動腳本。
| 欄位 | 類型 | 是否必需 | 用途 |
|---|---|---|---|
id | UUID | Yes | Stable Workflow identifier used for updates, Filter sessions, import conflict detection, and workflowID input. |
defaultIntroducedVersion | Integer | null | Bundled only | Catalog version that introduced a bundled default. It lets upgrades install only newly added defaults without restoring ones a user deleted. |
name | String | Yes | The Workflow and Action name shown in Settings and the Pasteon action list. |
nameLocalizationKey | String | null | Bundled only | Optional String Catalog key used to localize the name of a bundled Workflow. User edits clear this key. |
summary | String | No | A short explanation displayed beside the Action. It does not affect execution. |
summaryLocalizationKey | String | null | Bundled only | Optional localization key for the bundled Workflow summary. |
symbolName | SF Symbol name | Yes | The icon used by the Workflow Action. Invalid candidate icons fall back to this symbol. |
isEnabled | Boolean | Yes | Disabled Workflows remain saved but do not generate Actions. |
requiresTrustConfirmation | Boolean | null | Imported | Marks imported code as untrusted. Pasteon sets this to true and disables the Workflow until the user confirms it. |
sortOrder | Number | Yes | Controls the order of Custom Workflow Actions after built-in Primary Actions. |
mode | simple | scriptFilter | Yes | Simple executes immediately. Script Filter runs filter first, then execute after a candidate is chosen. |
supportedTypes | PasteType[] | Yes | Clipboard types where the Action may appear: text, markdown, html, json, url, color, date, timestamp, fileURL, imageURL, videoURL, image, or appObject. |
editorMode | steps | code | No | Selects the visual linear editor or script editor. Older Workflow files without this field use Code. |
script.source | inline | external | Code | Inline stores code inside the Workflow. External references a script on disk. |
script.code | String | Inline | The inline script body. Pasteon writes it to a temporary file for each run. |
script.codeResource | Resource name | null | Bundled only | Bundle resource containing code for a default Workflow. Exported user Workflows carry resolved inline code instead. |
script.scriptPath | File path | External | Path to the external script. Tilde paths are expanded. Missing files keep the configuration but prevent an Action from appearing. |
script.interpreterPath | Executable path | Inline | Executable used to run the script, such as /bin/zsh or the result of which node. External executable scripts may leave it empty. |
script.arguments | String[] | No | Arguments passed as an array before the generated or external script path. Pasteon does not join them into a shell command. |
script.workingDirectory | Directory path | No | Current directory for the process. When empty, external scripts use their folder and inline scripts use the temporary input folder. |
script.filterTimeout | Seconds | Filter | Maximum Filter duration. Values are clamped to 1–120 seconds; the default is 5. |
script.executeTimeout | Seconds | Yes | Maximum Execute duration. Values are clamped to 1–120 seconds; the default is 15. |
steps | WorkflowStep[] | null | Steps | Ordered linear step definitions. Steps mode requires Simple mode and exactly one final output. OCR enables image input; PNG File and Open in Finder apply stricter input-type rules. |
variables | WorkflowVariableDefinition[] | null | No | Reusable Text or Secret values available to Steps templates and Code Workflow stdin. Names must be unique within the Workflow. |
只有使用者執行 Workflow 後才會建立輸入;二進位資料會寫成暫存檔,不會嵌入 JSON。
| 欄位 | 類型 | 是否必需 | 用途 |
|---|---|---|---|
version | Integer | Yes | Workflow protocol version. The current and only supported value is 1. |
workflowID | UUID String | Yes | Stable identifier of the Workflow being run. |
phase | filter | execute | Yes | Tells a shared script which stage to run. Simple Workflows receive execute only. |
paste.id | UUID String | Yes | Identifier of the selected Pasteon history item. |
paste.type | PasteType | Yes | The derived clipboard content type used for Workflow visibility and script logic. |
paste.text | String | null | No | Text form of the selected content when available. Files and binary images may not have text. |
paste.sourceAppBundleIdentifier | String | null | No | Bundle identifier of the app where the clipboard item was originally copied. |
paste.representations | Representation[] | Yes | All available pasteboard representations. Text may be inline; binary data is exposed by file path. |
targetApp.bundleIdentifier | String | null | No | Bundle identifier of the frontmost app that will receive the result. |
targetApp.name | String | null | No | Localized display name of the frontmost target app. |
directories.input | Directory path | Yes | Temporary run directory containing the inline script and materialized binary inputs. Removed after the run. |
directories.output | Directory path | Yes | Directory where the script should create returned files. Unused output directories are cleaned after 24 hours. |
variables | Record<String, String> | Yes | Resolved variables keyed by name. Text and Secret values are available during both Filter and Execute. |
actionID | String | null | Execute after Filter | ID of the candidate chosen from Filter output. Null during filter and for Simple Workflows. |
argument | JSON value | null | Execute after Filter | The selected candidate’s argument, returned unchanged so execute can compute only that choice. |
{
"version": 1,
"workflowID": "5F604A89-7AC2-45D9-B48C-BB540B60CA67",
"phase": "execute",
"paste": {
"id": "D0A4E45A-61F6-4DAF-BC1E-4E17A23AA5C0",
"type": "json",
"text": "{\"name\":\"Pasteon\"}",
"sourceAppBundleIdentifier": "com.apple.Safari",
"representations": [
{
"type": "public.utf8-plain-text",
"value": "{\"name\":\"Pasteon\"}",
"path": null,
"fileName": null,
"fileSize": 18,
"temporary": false
}
]
},
"targetApp": {
"bundleIdentifier": "com.apple.dt.Xcode",
"name": "Xcode"
},
"directories": {
"input": "/tmp/Pasteon/WorkflowInputs/RUN_ID",
"output": "~/Library/Application Support/Pasteon/WorkflowOutputs/RUN_ID"
},
"variables": {
"API_BASE_URL": "https://api.example.com",
"API_TOKEN": "••••••••"
},
"actionID": "swift",
"argument": { "language": "swift" }
}Each example reads the complete stdin payload, accesses paste.text and a PREFIX Workflow variable, then writes one valid Simple Workflow result to stdout.
Use file descriptor 0 with the Node.js standard library.
/opt/homebrew/bin/nodeconst fs = require("node:fs");
const payload = JSON.parse(fs.readFileSync(0, "utf8"));
const text = payload.paste?.text ?? "";
const prefix = payload.variables?.PREFIX ?? "";
process.stdout.write(JSON.stringify({
version: 1,
result: { type: "text", value: prefix + text }
}));Use json.load with sys.stdin and json.dump with sys.stdout.
/opt/homebrew/bin/python3import json
import sys
payload = json.load(sys.stdin)
text = payload.get("paste", {}).get("text") or ""
prefix = payload.get("variables", {}).get("PREFIX", "")
json.dump({
"version": 1,
"result": {"type": "text", "value": prefix + text}
}, sys.stdout)Read $stdin, parse with JSON, and write only protocol JSON.
/opt/homebrew/bin/rubyrequire "json"
payload = JSON.parse($stdin.read)
text = payload.dig("paste", "text") || ""
prefix = payload.dig("variables", "PREFIX") || ""
$stdout.write(JSON.generate({
version: 1,
result: { type: "text", value: prefix + text }
}))Read the STDIN stream and use PHP’s built-in JSON functions.
/opt/homebrew/bin/php<?php
$payload = json_decode(stream_get_contents(STDIN), true);
$text = $payload["paste"]["text"] ?? "";
$prefix = $payload["variables"]["PREFIX"] ?? "";
echo json_encode([
"version" => 1,
"result" => ["type" => "text", "value" => $prefix . $text]
]);Read FileHandle.standardInput and decode with Foundation.
/usr/bin/swiftimport Foundation
let data = FileHandle.standardInput.readDataToEndOfFile()
let payload = try JSONSerialization.jsonObject(with: data) as? [String: Any]
let paste = payload?["paste"] as? [String: Any]
let variables = payload?["variables"] as? [String: String]
let text = paste?["text"] as? String ?? ""
let prefix = variables?["PREFIX"] ?? ""
let response: [String: Any] = [
"version": 1,
"result": ["type": "text", "value": prefix + text]
]
let output = try JSONSerialization.data(withJSONObject: response)
FileHandle.standardOutput.write(output)Zsh reads the raw payload; jq performs JSON parsing and encoding.
/bin/zsh#!/bin/zsh
set -euo pipefail
payload="$(cat)"
text="$(printf '%s' "$payload" | jq -r '.paste.text // ""')"
prefix="$(printf '%s' "$payload" | jq -r '.variables.PREFIX // ""')"
jq -n --arg value "$prefix$text" '{
version: 1,
result: {type: "text", value: $value}
}'Pasteon does not bundle language runtimes or jq. Set interpreterPath to an executable that exists on the current Mac. Homebrew paths differ between Apple silicon and Intel Macs; use “which node”, “which python3”, or the equivalent to find the correct path.
Every step has identity, behavior, enabled state, and one shared configuration object. Only fields used by the selected kind affect execution.
| 欄位 | 類型 | 是否必需 | 用途 |
|---|---|---|---|
steps[].id | UUID | Yes | Stable identity used by selection, drag ordering, validation, and per-step test results. |
steps[].kind | WorkflowStepKind | Yes | Selects the condition, transform, script, or output operation. |
steps[].isEnabled | Boolean | Yes | Disabled non-output steps are skipped. The final Output cannot be disabled. |
configuration.pattern | String | Match / Replace | Text, app identifier fragment, or regular expression to test or replace. |
configuration.replacement | String | Replace | Replacement text. In Regex mode it follows NSRegularExpression replacement template rules. |
configuration.matchMode | contains | equals | startsWith | endsWith | regularExpression | Match / Replace | Controls how pattern is compared. Replace uses plain replacement unless regularExpression is selected. |
configuration.isCaseSensitive | Boolean | Match / Replace | When false, text comparison and Regex replacement are case-insensitive. |
configuration.trimMode | whitespaceAndNewlines | whitespace | newlines | Trim | Selects which characters are removed from both ends. |
configuration.caseStyle | camel | pascal | snake | screamingSnake | kebab | train | dot | Change Case | Target naming convention for the current text. |
configuration.template | String | Template | Text template containing supported placeholders such as {{input}} and {{date}}. |
configuration.fileName | String | Output File | Output file name, with template variables allowed. Directory components are discarded for safety. |
configuration.script | ScriptConfiguration | Run Script | Script settings for this step. A Run Script step must return a text result for the next visual step. |
textConditionShow and run only when the current text matches pattern.
sourceAppConditionMatch the bundle identifier of the app that created the clip.
targetAppConditionMatch the bundle identifier of the frontmost destination app.
trimTextRemove selected whitespace characters from both ends.
replaceTextPerform plain or regular-expression replacement.
changeCaseConvert the current text to the configured naming style.
urlEncode / urlDecodePercent-encode or decode the current text.
jsonPretty / jsonMinifyParse JSON, sort keys, then pretty-print or compact it.
templateReplace supported placeholders in a text template.
runScriptRun a Simple Code Workflow step that must return text.
recognizeTextUse macOS Vision OCR on Clipboard Image or ImageURL input and pass the recognized text to the following steps.
outputText / outputFile / outputOpenURLReturn text, create a text file, or open a supported URL. Exactly one output is kept at the end of a valid Steps Workflow.
outputPNGFileConvert Clipboard Image or ImageURL input to a PNG file. Other input types make the Workflow invalid.
outputRevealInFinderReveal a local FileURL, ImageURL, or VideoURL in Finder. Workflow testing reports the path without opening Finder.
每個 representation 代表一種 Pasteboard 資料;文字使用 value,檔案或二進位資料使用 path。
| 欄位 | 類型 | 是否必需 | 用途 |
|---|---|---|---|
type | UTI String | Yes | Pasteboard type identifier, such as public.utf8-plain-text, public.file-url, public.png, or public.html. |
value | String | null | No | Inline UTF-8 value for text-like representations or the original file URL string. |
path | File path | null | No | Original local file path or temporary path created for binary representation data. |
fileName | String | null | No | Original or generated safe file name associated with the representation. |
fileSize | Int64 | Yes | Representation size in bytes, using stored metadata when available. |
temporary | Boolean | Yes | True when Pasteon wrote binary data into directories.input for this run. Do not retain that path. |
Filter 只描述候選項,不應提前產生所有最終結果。
| 欄位 | 類型 | 是否必需 | 用途 |
|---|---|---|---|
version | Integer | Yes | Must equal the supported protocol version: 1. |
actions | Action[] | Yes | Non-empty candidate list. Pasteon validates and displays at most the first 20 items. |
actions[].id | String | Yes | Candidate identifier returned as actionID during execute. After trimming, length must be 1–120 characters. |
actions[].title | String | Yes | Visible candidate title. After trimming, length must be 1–120 characters. |
actions[].subtitle | String | null | No | Secondary explanation shown beside the candidate. Pasteon keeps the first 240 characters. |
actions[].icon | SF Symbol | null | No | SF Symbol name for the candidate. Invalid symbols fall back to the parent Workflow icon. |
actions[].argument | JSON value | null | No | Opaque JSON value sent back unchanged during execute. It may be an object, array, string, number, boolean, or null. |
Execute 必須只回傳一個 result,並只填寫該 type 需要的欄位。
| 欄位 | 類型 | 是否必需 | 用途 |
|---|---|---|---|
version | Integer | Yes | Must equal the supported protocol version: 1. |
result | Object | Yes | The one final result Pasteon should apply. |
result.type | text | files | openURL | revealFile | Yes | Selects validation and the normal versus Command-mode behavior. |
result.value | String | text | Non-empty text to paste normally or copy when Command mode is active. |
result.paths | String[] | files | revealFile | For files, a non-empty list whose relative paths resolve inside directories.output and must exist. For revealFile, the first path is the local item to reveal. |
result.url | String | openURL | Valid http, https, or mailto URL. Normal mode opens it; Command mode copies it. |
revealFile behavior | Local file action | revealFile | Normal Action execution reveals the first path in Finder and hides Pasteon. Command mode does not change this result into copy-only behavior. |
{
"version": 1,
"result": {
"type": "files",
"paths": ["GeneratedModel.swift"]
}
}Runner 不會拼接 Shell 指令,會持續讀取 stdout 與 stderr,並在離開工作階段時終止工作。
stdout must contain one protocol JSON document and no log lines. Exceeding the limit terminates the process.
Write logs and diagnostics to stderr. It is captured for testing and errors.
Filter and Execute have separate configurable timeouts. Pasteon terminates an overdue process.
A non-zero process exit is treated as failure, with captured stderr included in the error.
Switching Paste items, returning from Filter results, editing or deleting the Workflow, or closing the window cancels the run.
Arguments are passed as an array. Pasteon does not expand pipes, wildcards, variables, or other shell syntax.
Workflow output directories older than 24 hours are removed during application cleanup.
Scripts execute locally with the current macOS user’s access. Review imported code before enabling it.
Define values once in Settings and reuse them in visual Steps or Code Workflows. Text values are stored with the Workflow. Secret values are stored in the macOS Keychain and removed from exported files.
| 欄位 | 類型 | 是否必需 | 用途 |
|---|---|---|---|
variables[].id | UUID | Yes | Stable identity used to associate a Secret with its Keychain value. Copying a Workflow creates new variable IDs. |
variables[].name | String | Yes | Case-sensitive lookup name. It must match [A-Za-z_][A-Za-z0-9_]* and be unique within the Workflow. |
variables[].kind | text | secret | Yes | Text stores its value in the Workflow. Secret stores its value in the macOS Keychain. |
variables[].value | String | Text only | Text value saved and exported with the Workflow. Secret definitions always export this field as an empty string. |
{
"variables": [
{
"id": "C3EEAF0E-0AD8-4A26-924C-CB867088D955",
"name": "API_BASE_URL",
"kind": "text",
"value": "https://api.example.com"
},
{
"id": "7E05B2EE-E745-4558-A267-E63B7D1E2235",
"name": "API_TOKEN",
"kind": "secret",
"value": ""
}
]
}Template 與檔名步驟會替換這些完整預留位置。
{{input}}Current text from the previous step.{{sourceApp}}Source app bundle identifier, or an empty string.{{targetApp}}Frontmost target app bundle identifier, or an empty string.{{clipboardType}}Current PasteType raw value.{{date}}Current date and time in ISO 8601 format.{{variables.NAME}}Value of the user-defined Text or Secret variable with the matching case-sensitive name.除了 stdin JSON,Code Workflow 也能讀取這些環境變數。
PASTEON_WORKFLOW_IDUUID of the current Workflow.PASTEON_WORKFLOW_PHASEfilter or execute.PASTEON_INPUT_DIRPath matching directories.input.PASTEON_OUTPUT_DIRPath matching directories.output.Exports are readable versioned JSON. A file may contain one Workflow or the full Workflow list.
| 欄位 | 類型 | 是否必需 | 用途 |
|---|---|---|---|
version | Integer | Yes | Envelope protocol version. Import currently accepts version 1. |
installedDefaultsVersion | Integer | null | No | Internal default-catalog state. User exports write null and imports do not use it to enable defaults. |
workflows | WorkflowDefinition[] | Yes | One or more complete Workflow definitions. A bare single WorkflowDefinition is also accepted for compatibility. |
同一個腳本處理 Filter 與 Execute,且只計算使用者選擇的結果。
直譯器: /opt/homebrew/bin/nodeasync function main() {
let input = "";
process.stdin.setEncoding("utf8");
for await (const chunk of process.stdin) input += chunk;
const payload = JSON.parse(input);
const text = payload.paste?.text ?? "";
let response;
if (payload.phase === "filter") {
response = {
version: 1,
actions: [
{
id: "uppercase",
title: "Convert to Uppercase",
subtitle: "Uppercase the copied text",
icon: "textformat",
argument: null
},
{
id: "wrap",
title: "Wrap in Brackets",
subtitle: "Add [ and ]",
icon: "curlybraces",
argument: { prefix: "[", suffix: "]" }
}
]
};
} else {
const argument = payload.argument ?? {};
const value =
payload.actionID === "uppercase"
? text.toUpperCase()
: (argument.prefix ?? "") + text + (argument.suffix ?? "");
response = {
version: 1,
result: { type: "text", value }
};
}
process.stdout.write(JSON.stringify(response));
}
main().catch((error) => {
process.stderr.write(`${error.stack ?? error.message}\n`);
process.exit(1);
});使用 Mac 上 “which node” 回傳的路徑。診斷請使用 console.error,不要用會寫入 stdout 的 console.log。
一般執行會立即處理結果。Command 點按或 Command + Enter 會將文字、檔案和 URL 切換為只複製。
text回傳產生的文字、清理後內容、範本、程式碼或任何字串。
files在提供的輸出目錄建立檔案,並將路徑回傳給 Pasteon。
openURL一般模式開啟支援的網頁或郵件連結,Command 模式複製 URL。
revealFile在 Finder 中定位回傳的本機檔案;測試 Workflow 時只顯示路徑。
Pasteon 預設啟用這些工作流程。你可以像其他 Workflow 一樣檢查、編輯、停用、複製、匯出或刪除。
Script Filter.json.txt.mdopenURLScript FilterSimpleScript FilterOCR → 文字圖片 → .pngrevealFileWorkflow 檔案保持可讀和可攜。匯入的 Workflow 預設停用,檢查並信任程式碼後才能啟用。
不需要。Steps 模式透過線性視覺化編輯器提供常用條件、文字轉換、範本、腳本和輸出;需要自訂行為時再使用 Code。
Simple 執行一次並回傳一個結果。Script Filter 先回傳輕量候選項,再於獨立 execute 階段執行使用者選擇的項目。
啟用的 Workflow 會在目前剪貼簿項目符合輸入類型與視覺化條件時,顯示在內建 Primary Actions 之後。
腳本使用你設定的直譯器和工作目錄在本機執行。匯入的 Workflow 在你檢查並啟用前不會執行。
是。Pasteon Pro 支援建立、測試、匯入、匯出和執行自訂 Workflow。
下載 Pasteon for Mac,從視覺化 Workflow 開始,只有流程真正需要時才進入腳本。