@phenx-inc/ctlsurf 0.1.1 → 0.1.2
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.
- package/bin/ctlsurf-worker.js +50 -3
- package/package.json +1 -1
- package/scripts/setup-mcp.sh +75 -7
package/bin/ctlsurf-worker.js
CHANGED
|
@@ -238,13 +238,57 @@ if (mode === 'desktop') {
|
|
|
238
238
|
try {
|
|
239
239
|
electronPath = require('electron')
|
|
240
240
|
} catch {
|
|
241
|
-
|
|
241
|
+
// Electron not installed — prompt to install or fall back
|
|
242
|
+
if (process.stdin.isTTY && !args.includes('--terminal')) {
|
|
243
|
+
console.log(`\n${B} ctlsurf${R}\n`)
|
|
244
|
+
console.log(` Electron is not installed. Desktop mode requires Electron.\n`)
|
|
245
|
+
console.log(` ${D}1)${R} Install Electron and launch desktop mode`)
|
|
246
|
+
console.log(` ${D}2)${R} Launch in terminal mode instead`)
|
|
247
|
+
console.log(` ${D}3)${R} Exit\n`)
|
|
248
|
+
|
|
249
|
+
const readline = require('readline')
|
|
250
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
|
|
251
|
+
rl.question(` Choice ${D}(1/2/3)${R}: `, (answer) => {
|
|
252
|
+
rl.close()
|
|
253
|
+
answer = answer.trim()
|
|
254
|
+
if (answer === '1') {
|
|
255
|
+
console.log(`\n${D}Installing Electron (this may take a minute)...${R}\n`)
|
|
256
|
+
try {
|
|
257
|
+
execSync('npm install electron --no-save', { cwd: ROOT, stdio: 'inherit' })
|
|
258
|
+
console.log(`\n${G}✓${R} Electron installed. Launching desktop mode...\n`)
|
|
259
|
+
try {
|
|
260
|
+
const ep = require('electron')
|
|
261
|
+
execFileSync(String(ep), [ROOT, ...args], {
|
|
262
|
+
stdio: 'inherit',
|
|
263
|
+
env: { ...process.env, CTLSURF_WORKER_CWD: process.env.CTLSURF_WORKER_CWD || process.cwd() }
|
|
264
|
+
})
|
|
265
|
+
} catch (err) {
|
|
266
|
+
process.exit(err.status || 0)
|
|
267
|
+
}
|
|
268
|
+
} catch (err) {
|
|
269
|
+
console.error(`\n${Y}!${R} Electron install failed: ${err.message}`)
|
|
270
|
+
console.error(` Try manually: cd ${ROOT} && npm install electron\n`)
|
|
271
|
+
process.exit(1)
|
|
272
|
+
}
|
|
273
|
+
} else if (answer === '2') {
|
|
274
|
+
console.log('')
|
|
275
|
+
runTerminal()
|
|
276
|
+
} else {
|
|
277
|
+
process.exit(0)
|
|
278
|
+
}
|
|
279
|
+
})
|
|
280
|
+
return
|
|
281
|
+
}
|
|
282
|
+
// Non-interactive: fall back silently
|
|
242
283
|
runTerminal()
|
|
243
284
|
process.exit(0)
|
|
244
285
|
}
|
|
245
286
|
|
|
246
287
|
try {
|
|
247
|
-
execFileSync(String(electronPath), [ROOT, ...args], {
|
|
288
|
+
execFileSync(String(electronPath), [ROOT, ...args], {
|
|
289
|
+
stdio: 'inherit',
|
|
290
|
+
env: { ...process.env, CTLSURF_WORKER_CWD: process.env.CTLSURF_WORKER_CWD || process.cwd() }
|
|
291
|
+
})
|
|
248
292
|
} catch (err) {
|
|
249
293
|
process.exit(err.status || 0)
|
|
250
294
|
}
|
|
@@ -259,7 +303,10 @@ function runTerminal() {
|
|
|
259
303
|
process.exit(1)
|
|
260
304
|
}
|
|
261
305
|
try {
|
|
262
|
-
execFileSync(process.execPath, [terminalPath, ...args], {
|
|
306
|
+
execFileSync(process.execPath, [terminalPath, ...args], {
|
|
307
|
+
stdio: 'inherit',
|
|
308
|
+
env: { ...process.env, CTLSURF_WORKER_CWD: process.env.CTLSURF_WORKER_CWD || process.cwd() }
|
|
309
|
+
})
|
|
263
310
|
} catch (err) {
|
|
264
311
|
process.exit(err.status || 0)
|
|
265
312
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phenx-inc/ctlsurf",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Agent-agnostic terminal and desktop app for ctlsurf — run Claude Code, Codex, or any coding agent with live session logging and remote control",
|
|
5
5
|
"main": "out/main/index.js",
|
|
6
6
|
"bin": {
|
package/scripts/setup-mcp.sh
CHANGED
|
@@ -199,10 +199,62 @@ if [ "$FOUND_CLAUDE_CLI" = false ] && [ "$FOUND_CLAUDE_VSCODE" = false ] && \
|
|
|
199
199
|
exit 1
|
|
200
200
|
fi
|
|
201
201
|
|
|
202
|
-
#
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
202
|
+
# Check for existing API key in environment or shell profile
|
|
203
|
+
EXISTING_KEY=""
|
|
204
|
+
EXISTING_URL=""
|
|
205
|
+
|
|
206
|
+
# Check env var
|
|
207
|
+
if [ -n "$CTLSURF_API_KEY" ]; then
|
|
208
|
+
EXISTING_KEY="$CTLSURF_API_KEY"
|
|
209
|
+
fi
|
|
210
|
+
|
|
211
|
+
# Check shell profile
|
|
212
|
+
if [ -z "$EXISTING_KEY" ]; then
|
|
213
|
+
for rc in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.bash_profile"; do
|
|
214
|
+
if [ -f "$rc" ]; then
|
|
215
|
+
KEY_FROM_RC=$(grep '^export CTLSURF_API_KEY=' "$rc" 2>/dev/null | tail -1 | sed 's/^export CTLSURF_API_KEY="//' | sed 's/"$//')
|
|
216
|
+
if [ -n "$KEY_FROM_RC" ]; then
|
|
217
|
+
EXISTING_KEY="$KEY_FROM_RC"
|
|
218
|
+
break
|
|
219
|
+
fi
|
|
220
|
+
fi
|
|
221
|
+
done
|
|
222
|
+
fi
|
|
223
|
+
|
|
224
|
+
# Check CTLSURF_URL from env or profile
|
|
225
|
+
if [ -n "$CTLSURF_URL" ]; then
|
|
226
|
+
EXISTING_URL="$CTLSURF_URL"
|
|
227
|
+
else
|
|
228
|
+
for rc in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.bash_profile"; do
|
|
229
|
+
if [ -f "$rc" ]; then
|
|
230
|
+
URL_FROM_RC=$(grep '^export CTLSURF_URL=' "$rc" 2>/dev/null | tail -1 | sed 's/^export CTLSURF_URL="//' | sed 's/"$//')
|
|
231
|
+
if [ -n "$URL_FROM_RC" ]; then
|
|
232
|
+
EXISTING_URL="$URL_FROM_RC"
|
|
233
|
+
break
|
|
234
|
+
fi
|
|
235
|
+
fi
|
|
236
|
+
done
|
|
237
|
+
fi
|
|
238
|
+
|
|
239
|
+
# Use existing credentials or prompt
|
|
240
|
+
if [ -n "$EXISTING_KEY" ]; then
|
|
241
|
+
MASKED_KEY="${EXISTING_KEY:0:8}...${EXISTING_KEY: -4}"
|
|
242
|
+
echo -e "${GREEN}✓ Found existing API key: ${MASKED_KEY}${NC}"
|
|
243
|
+
echo -n "Use this key? (Y/n): "
|
|
244
|
+
read USE_EXISTING < /dev/tty
|
|
245
|
+
if [ -z "$USE_EXISTING" ] || [ "$USE_EXISTING" = "y" ] || [ "$USE_EXISTING" = "Y" ]; then
|
|
246
|
+
API_KEY="$EXISTING_KEY"
|
|
247
|
+
else
|
|
248
|
+
echo ""
|
|
249
|
+
echo "Get your API key from: https://app.ctlsurf.com/settings (API Keys tab)"
|
|
250
|
+
echo -n "Enter your ctlsurf API key: "
|
|
251
|
+
read API_KEY < /dev/tty
|
|
252
|
+
fi
|
|
253
|
+
else
|
|
254
|
+
echo "Get your API key from: https://app.ctlsurf.com/settings (API Keys tab)"
|
|
255
|
+
echo -n "Enter your ctlsurf API key: "
|
|
256
|
+
read API_KEY < /dev/tty
|
|
257
|
+
fi
|
|
206
258
|
|
|
207
259
|
if [ -z "$API_KEY" ]; then
|
|
208
260
|
echo -e "${RED}ERROR: API key is required${NC}"
|
|
@@ -210,9 +262,25 @@ if [ -z "$API_KEY" ]; then
|
|
|
210
262
|
fi
|
|
211
263
|
|
|
212
264
|
echo ""
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
265
|
+
|
|
266
|
+
if [ -n "$EXISTING_URL" ]; then
|
|
267
|
+
# Strip /api/mcp suffix for display
|
|
268
|
+
DISPLAY_URL=$(echo "$EXISTING_URL" | sed 's|/api/mcp$||' | sed 's|/api$||')
|
|
269
|
+
echo -e "${GREEN}✓ Found existing server URL: ${DISPLAY_URL}${NC}"
|
|
270
|
+
echo -n "Use this URL? (Y/n): "
|
|
271
|
+
read USE_EXISTING_URL < /dev/tty
|
|
272
|
+
if [ -z "$USE_EXISTING_URL" ] || [ "$USE_EXISTING_URL" = "y" ] || [ "$USE_EXISTING_URL" = "Y" ]; then
|
|
273
|
+
SERVER_URL="$DISPLAY_URL"
|
|
274
|
+
else
|
|
275
|
+
echo -n "Server URL [https://app.ctlsurf.com]: "
|
|
276
|
+
read SERVER_URL < /dev/tty
|
|
277
|
+
SERVER_URL=${SERVER_URL:-https://app.ctlsurf.com}
|
|
278
|
+
fi
|
|
279
|
+
else
|
|
280
|
+
echo -n "Server URL [https://app.ctlsurf.com]: "
|
|
281
|
+
read SERVER_URL < /dev/tty
|
|
282
|
+
SERVER_URL=${SERVER_URL:-https://app.ctlsurf.com}
|
|
283
|
+
fi
|
|
216
284
|
# Normalize URL
|
|
217
285
|
SERVER_URL="${SERVER_URL%/}"
|
|
218
286
|
SERVER_URL="${SERVER_URL%/api}"
|