-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsetup.ts
More file actions
102 lines (89 loc) · 4.6 KB
/
Copy pathsetup.ts
File metadata and controls
102 lines (89 loc) · 4.6 KB
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
/**
* @file setup.ts
* @description Interactive setup wizard — runs when ctrlnode is invoked with --setup.
* Prompts for workspace, optional provider API keys, pairing token; writes .env; persists BASE_PATH.
*/
import path from 'path';
import os from 'os';
import fs from 'fs';
import { createInterface } from 'readline';
import { execSync } from 'child_process';
import { mergeEnvFile, promptProviderApiKeys } from './setupEnv.js';
function ask(rl: ReturnType<typeof createInterface>, question: string): Promise<string> {
return new Promise(resolve => rl.question(question, answer => resolve(answer.trim())));
}
function persistBasePath(workspace: string): void {
if (process.platform === 'win32') {
try {
execSync(`powershell -Command "[System.Environment]::SetEnvironmentVariable('BASE_PATH', '${workspace}', 'User')"`, { stdio: 'ignore' });
} catch { /* non-fatal */ }
} else {
// Linux / macOS: append to shell RC
const rc = [
path.join(os.homedir(), '.zshrc'),
path.join(os.homedir(), '.bashrc'),
path.join(os.homedir(), '.profile'),
].find(f => fs.existsSync(f));
if (rc) {
const content = fs.readFileSync(rc, 'utf8');
const filtered = content.split('\n').filter(l => !l.includes('BASE_PATH')).join('\n');
fs.writeFileSync(rc, filtered + `\nexport BASE_PATH="${workspace}"\n`, 'utf8');
}
}
}
export async function runSetup(): Promise<void> {
const rl = createInterface({ input: process.stdin, output: process.stdout });
const askLine = (q: string) => ask(rl, q);
console.log('');
console.log('CtrlNode Setup');
console.log('--------------');
console.log('');
// ── Workspace ────────────────────────────────────────────────────────────────
console.log('Where is your workspace?');
console.log(' This is the root folder where ctrlnode will read and write files.');
console.log(' For security, the bridge cannot access anything outside this folder.');
console.log(' If you are a developer, point this to your source code root (e.g. ~/code).');
const defaultWorkspace = process.env.BASE_PATH || os.homedir();
const workspaceRaw = await askLine(`Workspace [${defaultWorkspace}]: `);
const workspace = workspaceRaw || defaultWorkspace;
console.log(` Workspace: ${workspace}\n`);
// ── Optional provider API keys ───────────────────────────────────────────────
const providerKeys = await promptProviderApiKeys(askLine);
// ── Pairing token ─────────────────────────────────────────────────────────────
console.log('Enter your pairing token.');
console.log(' Get it at: https://app.ctrlnode.ai (Settings → Bridge)');
const token = await askLine('Pairing token: ');
rl.close();
if (!token) {
console.error('No token entered. Exiting.');
process.exit(1);
}
// ── Write .env ────────────────────────────────────────────────────────────────
const envDir = path.join(workspace, '.ctrlnode');
const envFile = path.join(envDir, '.env');
fs.mkdirSync(envDir, { recursive: true });
mergeEnvFile(envFile, {
PAIRING_TOKEN: token,
...(providerKeys.cursorApiKey ? { CURSOR_API_KEY: providerKeys.cursorApiKey } : {}),
...(providerKeys.anthropicApiKey ? { ANTHROPIC_API_KEY: providerKeys.anthropicApiKey } : {}),
});
// ── Persist BASE_PATH in user environment ─────────────────────────────────────
persistBasePath(workspace);
const bin = path.basename(process.execPath || 'ctrlnode');
console.log('');
console.log(`Config saved to: ${envFile}`);
console.log(`BASE_PATH set to: ${workspace}`);
if (providerKeys.cursorApiKey) console.log(' CURSOR_API_KEY: saved');
if (providerKeys.anthropicApiKey) console.log(' ANTHROPIC_API_KEY: saved');
console.log('');
console.log('To start the bridge, either:');
console.log(' 1. Close this terminal and open a new one, then run:');
console.log(` ${bin}`);
console.log(' 2. Or in this terminal, run:');
if (process.platform === 'win32') {
console.log(` $env:BASE_PATH='${workspace}'; ${bin}`);
} else {
console.log(` BASE_PATH='${workspace}' ${bin}`);
}
console.log('');
}