summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/utils/commandUtils.ts
diff options
context:
space:
mode:
authorDevansh Sharma <[email protected]>2025-07-20 20:57:41 +0200
committerGitHub <[email protected]>2025-07-20 18:57:41 +0000
commit8f85ac7de027326c0440cc21122d6439687fab44 (patch)
tree10d98a1659313f66670e904915e8fa2c81a83cf0 /packages/cli/src/ui/utils/commandUtils.ts
parenta01b1219a3e814c370f6827b81c9118f2cbc7a64 (diff)
feat: Added /copy command for copying output to clipboard with new Command Service approach (#3706)
Co-authored-by: Abhi <[email protected]> Co-authored-by: N. Taylor Mullen <[email protected]>
Diffstat (limited to 'packages/cli/src/ui/utils/commandUtils.ts')
-rw-r--r--packages/cli/src/ui/utils/commandUtils.ts56
1 files changed, 56 insertions, 0 deletions
diff --git a/packages/cli/src/ui/utils/commandUtils.ts b/packages/cli/src/ui/utils/commandUtils.ts
index aadd035e..4280388f 100644
--- a/packages/cli/src/ui/utils/commandUtils.ts
+++ b/packages/cli/src/ui/utils/commandUtils.ts
@@ -4,6 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
+import { spawn } from 'child_process';
+
/**
* Checks if a query string potentially represents an '@' command.
* It triggers if the query starts with '@' or contains '@' preceded by whitespace
@@ -24,3 +26,57 @@ export const isAtCommand = (query: string): boolean =>
* @returns True if the query looks like an '/' command, false otherwise.
*/
export const isSlashCommand = (query: string): boolean => query.startsWith('/');
+
+//Copies a string snippet to the clipboard for different platforms
+export const copyToClipboard = async (text: string): Promise<void> => {
+ const run = (cmd: string, args: string[]) =>
+ new Promise<void>((resolve, reject) => {
+ const child = spawn(cmd, args);
+ let stderr = '';
+ child.stderr.on('data', (chunk) => (stderr += chunk.toString()));
+ child.on('error', reject);
+ child.on('close', (code) => {
+ if (code === 0) return resolve();
+ const errorMsg = stderr.trim();
+ reject(
+ new Error(
+ `'${cmd}' exited with code ${code}${errorMsg ? `: ${errorMsg}` : ''}`,
+ ),
+ );
+ });
+ child.stdin.on('error', reject);
+ child.stdin.write(text);
+ child.stdin.end();
+ });
+
+ switch (process.platform) {
+ case 'win32':
+ return run('clip', []);
+ case 'darwin':
+ return run('pbcopy', []);
+ case 'linux':
+ try {
+ await run('xclip', ['-selection', 'clipboard']);
+ } catch (primaryError) {
+ try {
+ // If xclip fails for any reason, try xsel as a fallback.
+ await run('xsel', ['--clipboard', '--input']);
+ } catch (fallbackError) {
+ const primaryMsg =
+ primaryError instanceof Error
+ ? primaryError.message
+ : String(primaryError);
+ const fallbackMsg =
+ fallbackError instanceof Error
+ ? fallbackError.message
+ : String(fallbackError);
+ throw new Error(
+ `All copy commands failed. xclip: "${primaryMsg}", xsel: "${fallbackMsg}". Please ensure xclip or xsel is installed and configured.`,
+ );
+ }
+ }
+ return;
+ default:
+ throw new Error(`Unsupported platform: ${process.platform}`);
+ }
+};