opencode-copy-slash 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,109 @@
1
+ /**
2
+ * OpenCode Copy Plugin — /copy command to copy last assistant message to clipboard.
3
+ * Adapted from pi dev (github.com/earendil-works/pi).
4
+ */
5
+
6
+ const isAborted = (msg) => msg?.error?.name === "MessageAbortedError";
7
+
8
+ const extractText = (parts) => {
9
+ let text = "";
10
+ for (const part of parts || []) {
11
+ if (part.type === "text") text += part.text;
12
+ }
13
+ return text.trim() || null;
14
+ };
15
+
16
+ const copyToClipboard = async ($, text) => {
17
+ const p = process.platform;
18
+
19
+ if (p === "darwin") {
20
+ await $`echo ${text} | pbcopy`.quiet();
21
+ return;
22
+ }
23
+
24
+ if (p === "win32") {
25
+ try {
26
+ await $`powershell -Command "Set-Clipboard -Value ${text}"`.quiet();
27
+ return;
28
+ } catch {
29
+ await $`echo ${text} | clip`.quiet();
30
+ return;
31
+ }
32
+ }
33
+
34
+ // Linux: probe wl-copy → xclip → xsel
35
+ for (const [bin, args = ""] of [
36
+ ["wl-copy"],
37
+ ["xclip", "-selection clipboard"],
38
+ ["xsel", "--clipboard --input"],
39
+ ]) {
40
+ try {
41
+ await $`which ${bin}`.quiet().nothrow();
42
+ await $`echo ${text} | ${[bin, ...args.split(" ").filter(Boolean)]}`.quiet();
43
+ return;
44
+ } catch {
45
+ continue;
46
+ }
47
+ }
48
+
49
+ throw new Error(
50
+ "No clipboard tool available. Install wl-copy, xclip, or xsel.",
51
+ );
52
+ };
53
+
54
+ export const CopyPlugin = async ({ client, $ }) => {
55
+ return {
56
+ "command.execute.before": async (input, output) => {
57
+ if (input.command !== "copy") return;
58
+
59
+ try {
60
+ const result = await client.session.messages({
61
+ path: { id: input.sessionID },
62
+ });
63
+ const messages = result.data;
64
+
65
+ if (!messages?.length) {
66
+ output.parts.push({
67
+ type: "text",
68
+ text: "No messages in this session yet.",
69
+ });
70
+ return;
71
+ }
72
+
73
+ let text = null;
74
+ for (let i = messages.length - 1; i >= 0 && !text; i--) {
75
+ const msg = messages[i];
76
+ if (msg.info.role !== "assistant") continue;
77
+ if (isAborted(msg.info)) continue;
78
+ text = extractText(msg.parts);
79
+ }
80
+
81
+ if (!text) {
82
+ output.parts.push({
83
+ type: "text",
84
+ text: "No assistant messages with text content to copy.",
85
+ });
86
+ return;
87
+ }
88
+
89
+ const limit = 100_000;
90
+ const clipped = text.length > limit ? text.slice(0, limit) : text;
91
+
92
+ await copyToClipboard($, clipped);
93
+
94
+ const suffix = clipped.length < text.length
95
+ ? " (truncated at 100k characters)"
96
+ : "";
97
+ output.parts.push({
98
+ type: "text",
99
+ text: `Copied last assistant message to clipboard${suffix}.`,
100
+ });
101
+ } catch (error) {
102
+ output.parts.push({
103
+ type: "text",
104
+ text: `Copy error: ${error.message}`,
105
+ });
106
+ }
107
+ },
108
+ };
109
+ };
@@ -0,0 +1,15 @@
1
+ ---
2
+ description: Copy last assistant message to clipboard
3
+ disable-model-invocation: true
4
+ ---
5
+
6
+ Copy the last assistant message text to the system clipboard.
7
+
8
+ The `/copy` command is handled by the CopyPlugin which:
9
+ 1. Retrieves session messages via the OpenCode SDK
10
+ 2. Finds the last non-aborted assistant message
11
+ 3. Extracts text content from the message parts
12
+ 4. Copies the text to clipboard using platform-native tools (pbcopy/clip/xclip/wl-copy)
13
+ 5. Reports success or failure status
14
+
15
+ This command does not invoke the AI model — it runs purely as a client-side operation.
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "opencode-copy-slash",
3
+ "version": "1.0.0",
4
+ "description": "OpenCode plugin that adds /copy command to copy last assistant message to clipboard",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "opencode",
9
+ "opencode-plugin",
10
+ "copy",
11
+ "clipboard",
12
+ "slash-command"
13
+ ],
14
+ "exports": {
15
+ ".": "./.opencode/plugins/copy.js"
16
+ },
17
+ "files": [
18
+ ".opencode/",
19
+ "commands/"
20
+ ],
21
+ "peerDependencies": {
22
+ "@opencode-ai/sdk": ">=1.0.0"
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/foresttruong/plugin-copy-opencode"
27
+ }
28
+ }