-
Notifications
You must be signed in to change notification settings - Fork 917
/
Copy pathclaude.js
executable file
·127 lines (107 loc) · 3.7 KB
/
claude.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env node
// Dependencies:
// This script requires the following software to be installed:
// - `node` https://nodejs.org
// - `chrome-cli` https://github.com/prasmussen/chrome-cli
// Install via homebrew: `brew install node chrome-cli`
// This script needs to run JavaScript in your browser, which requires your permission.
// To do so, open Chrome and find the menu bar item:
// View > Developer > Allow JavaScript from Apple Events
// Required parameters:
// @raycast.schemaVersion 1
// @raycast.title Ask Claude
// @raycast.mode silent
// @raycast.packageName Claude
// Optional parameters:
// @raycast.icon ✨
// @raycast.argument1 { "type": "text", "placeholder": "Prompt"}
// Documentation:
// @raycast.description Open Claude in Chrome browser and submit a prompt
// @raycast.author Nimo Beeren
// @raycast.authorURL https://github.com/nimobeeren
const { execSync } = require("child_process");
const prompt = process.argv[2];
process.env.OUTPUT_FORMAT = "json";
/** Escape a string so that it can be used in JavaScript code when wrapped in double quotes. */
function escapeJsString(str) {
return str.replaceAll(`\\`, `\\\\`).replaceAll(`"`, `\\"`);
}
/** Escape a string so that it can be used in a shell command when wrapped in single quotes. */
function escapeShellString(str) {
return str.replaceAll(`'`, `'"'"'`);
}
try {
execSync("which chrome-cli");
} catch {
console.error(
"chrome-cli is required to run this script (https://github.com/prasmussen/chrome-cli)"
);
process.exit(1);
}
// Find the Claude tab if one is already open
let tabs = JSON.parse(execSync("chrome-cli list tabs")).tabs;
let claudeTab = tabs.find((tab) => tab.url.startsWith("https://claude.ai/"));
// If there is a Claude tab open, get its info. Otherwise, open Claude in a new
// window.
let claudeTabInfo;
if (claudeTab) {
// Open a new Claude session in the existing tab and focus it
execSync(`chrome-cli open 'https://claude.ai/new' -t ${claudeTab.id}`);
// Get tab info
claudeTabInfo = JSON.parse(execSync(`chrome-cli info -t ${claudeTab.id}`));
} else {
// Open a Claude session in a new tab, focus it and return the tab info
claudeTabInfo = JSON.parse(
execSync("chrome-cli open 'https://claude.ai/new'")
);
}
// Wait for the tab to be loaded, then execute the script
let interval = setInterval(() => {
if (claudeTabInfo.loading) {
claudeTabInfo = JSON.parse(
execSync(`chrome-cli info -t ${claudeTabInfo.id}`)
);
} else {
clearInterval(interval);
executeScript();
}
}, 100);
function executeScript() {
const script = async function (prompt) {
// Wait for prompt element to be on the page
let promptElement;
await new Promise((resolve) => {
let interval = setInterval(() => {
promptElement = document.querySelector(
'[aria-label="Write your prompt to Claude"] > div'
);
if (promptElement) {
clearInterval(interval);
resolve();
}
}, 100);
});
// Set the prompt
const p = document.createElement("p");
p.textContent = prompt;
promptElement.replaceChildren(p);
// Wait for submit button to be on the page
let submitButton;
await new Promise((resolve) => {
let interval = setInterval(() => {
submitButton = document.querySelector('[aria-label="Send Message"]');
if (submitButton) {
clearInterval(interval);
resolve();
}
}, 100);
});
// Submit the prompt
submitButton.click();
};
const functionString = escapeShellString(script.toString());
const promptString = escapeShellString(escapeJsString(prompt));
execSync(
`chrome-cli execute '(${functionString})("${promptString}")' -t ${claudeTabInfo.id}`
);
}