Files
claude-remote/claude-remote.mjs
2026-03-18 22:30:22 +00:00

112 lines
2.9 KiB
JavaScript
Executable File

#!/usr/bin/env node
import { createInterface } from 'readline';
import { readdirSync, readlinkSync, readFileSync } from 'fs';
import { send_to_claude } from './paste.mjs';
const args = process.argv.slice(2);
function print_usage() {
console.error(`
Usage:
claude-remote <text> paste text and submit
claude-remote --no-submit <text> paste text without pressing Enter
claude-remote --focus-only focus the window without pasting
claude-remote --find-window print the detected window ID and exit
claude-remote --list-procs list all running processes with exe paths
claude-remote --window-id <id> <text> use specific window ID (decimal or 0x hex)
echo "text" | claude-remote read text from stdin
`.trim());
}
async function read_stdin() {
const rl = createInterface({ input: process.stdin });
const lines = [];
for await (const line of rl) {
lines.push(line);
}
return lines.join('\n');
}
async function main() {
if (args.includes('--help') || args.includes('-h')) {
print_usage();
process.exit(0);
}
if (args.includes('--list-procs')) {
for (const entry of readdirSync('/proc')) {
if (!/^\d+$/.test(entry)) {
continue;
}
try {
const exe = readlinkSync(`/proc/${entry}/exe`);
const raw = readFileSync(`/proc/${entry}/cmdline`, 'utf8');
const cmdline = raw.replace(/\0/g, ' ').trim();
console.log(`${entry}\t${exe}\t${cmdline}`);
} catch {
// process may have exited
}
}
return;
}
if (args.includes('--find-window')) {
try {
const id = await send_to_claude('', { focus_only: true, debug: true });
console.log(id);
} catch (err) {
console.error(`No Claude window found: ${err.message}`);
process.exit(1);
}
return;
}
const focus_only = args.includes('--focus-only');
const submit = !args.includes('--no-submit');
const window_id_idx = args.indexOf('--window-id');
const window_id = window_id_idx !== -1 ? args[window_id_idx + 1] : undefined;
const text_args = args.filter((a, i) => {
if (a === '--no-submit' || a === '--focus-only') { return false; }
if (a === '--window-id') { return false; }
if (i > 0 && args[i - 1] === '--window-id') { return false; }
return true;
});
if (focus_only) {
try {
const window_id = await send_to_claude('', { focus_only: true });
console.error(`Focused window ${window_id}`);
} catch (err) {
console.error(`Error: ${err.message}`);
process.exit(1);
}
return;
}
let text;
if (text_args.length > 0) {
text = text_args.join(' ');
} else if (!process.stdin.isTTY) {
text = await read_stdin();
} else {
print_usage();
process.exit(1);
}
if (!text.trim()) {
console.error('No text provided');
process.exit(1);
}
try {
const used_id = await send_to_claude(text, { submit, window_id });
console.error(`Sent to window ${used_id}`);
} catch (err) {
console.error(`Error: ${err.message}`);
process.exit(1);
}
}
main();