112 lines
2.9 KiB
JavaScript
Executable File
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.js';
|
|
|
|
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();
|