adhdev 0.1.0

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/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # adhdev
2
+
3
+ **ADHDev CLI** — Setup wizard for the ADHDev platform. Detect, install, and configure IDE + AI agent extensions.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npx adhdev
9
+ ```
10
+
11
+ Or install globally:
12
+
13
+ ```bash
14
+ npm install -g adhdev
15
+ adhdev setup
16
+ ```
17
+
18
+ ## Commands
19
+
20
+ | Command | Description |
21
+ |---------|-------------|
22
+ | `adhdev setup` | Interactive setup wizard |
23
+ | `adhdev status` | Show current configuration |
24
+ | `adhdev detect` | Detect installed IDEs |
25
+ | `adhdev reset` | Reset all configuration |
26
+
27
+ ## Supported IDEs
28
+
29
+ - ✅ VS Code
30
+ - ✅ Cursor
31
+ - ✅ Antigravity
32
+ - 🔜 JetBrains (coming soon)
33
+
34
+ ## What it does
35
+
36
+ 1. **Detects** installed IDEs on your system
37
+ 2. **Installs** the ADHDev Bridge extension
38
+ 3. **Configures** connection to your ADHDev dashboard
39
+ 4. **Verifies** the setup is working
40
+
41
+ ## License
42
+
43
+ MIT
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,752 @@
1
+ #!/usr/bin/env node
2
+ #!/usr/bin/env node
3
+
4
+ // src/index.ts
5
+ import { Command } from "commander";
6
+ import chalk2 from "chalk";
7
+
8
+ // src/wizard.ts
9
+ import chalk from "chalk";
10
+ import inquirer from "inquirer";
11
+ import ora from "ora";
12
+
13
+ // src/detector-impl.ts
14
+ import { execSync } from "child_process";
15
+ import { existsSync } from "fs";
16
+ import { platform, homedir } from "os";
17
+ var IDE_DEFINITIONS = [
18
+ {
19
+ id: "vscode",
20
+ name: "Visual Studio Code",
21
+ displayName: "VS Code",
22
+ icon: "\u{1F499}",
23
+ extensionSupport: "full",
24
+ cli: "code",
25
+ paths: {
26
+ darwin: ["/Applications/Visual Studio Code.app"],
27
+ win32: [
28
+ "C:\\Program Files\\Microsoft VS Code\\Code.exe",
29
+ "C:\\Users\\*\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe"
30
+ ],
31
+ linux: ["/usr/share/code", "/snap/code/current"]
32
+ }
33
+ },
34
+ {
35
+ id: "cursor",
36
+ name: "Cursor",
37
+ displayName: "Cursor",
38
+ icon: "\u26A1",
39
+ extensionSupport: "full",
40
+ cli: "cursor",
41
+ paths: {
42
+ darwin: ["/Applications/Cursor.app"],
43
+ win32: [
44
+ "C:\\Users\\*\\AppData\\Local\\Programs\\cursor\\Cursor.exe"
45
+ ],
46
+ linux: ["/opt/Cursor", "/usr/share/cursor"]
47
+ }
48
+ },
49
+ {
50
+ id: "vscodium",
51
+ name: "VSCodium",
52
+ displayName: "VSCodium",
53
+ icon: "\u{1F49A}",
54
+ extensionSupport: "full",
55
+ cli: "codium",
56
+ paths: {
57
+ darwin: ["/Applications/VSCodium.app"],
58
+ win32: ["C:\\Program Files\\VSCodium\\VSCodium.exe"],
59
+ linux: ["/usr/share/codium", "/snap/codium/current"]
60
+ }
61
+ },
62
+ {
63
+ id: "windsurf",
64
+ name: "Windsurf",
65
+ displayName: "Windsurf",
66
+ icon: "\u{1F3C4}",
67
+ extensionSupport: "full",
68
+ cli: "windsurf",
69
+ paths: {
70
+ darwin: ["/Applications/Windsurf.app"],
71
+ win32: [],
72
+ linux: []
73
+ }
74
+ },
75
+ {
76
+ id: "vscode-insiders",
77
+ name: "Visual Studio Code - Insiders",
78
+ displayName: "VS Code Insiders",
79
+ icon: "\u{1F49A}",
80
+ extensionSupport: "full",
81
+ cli: "code-insiders",
82
+ paths: {
83
+ darwin: ["/Applications/Visual Studio Code - Insiders.app"],
84
+ win32: [
85
+ "C:\\Program Files\\Microsoft VS Code Insiders\\Code - Insiders.exe"
86
+ ],
87
+ linux: ["/usr/share/code-insiders"]
88
+ }
89
+ },
90
+ {
91
+ id: "antigravity",
92
+ name: "Antigravity",
93
+ displayName: "Antigravity",
94
+ icon: "\u{1F680}",
95
+ extensionSupport: "full",
96
+ cli: "antigravity",
97
+ paths: {
98
+ darwin: ["/Applications/Antigravity.app"],
99
+ win32: [
100
+ "C:\\Users\\*\\AppData\\Local\\Programs\\antigravity\\Antigravity.exe"
101
+ ],
102
+ linux: ["/opt/Antigravity", "/usr/share/antigravity"]
103
+ }
104
+ }
105
+ ];
106
+ function findCliCommand(command) {
107
+ try {
108
+ const result = execSync(
109
+ platform() === "win32" ? `where ${command}` : `which ${command}`,
110
+ { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }
111
+ ).trim();
112
+ return result.split("\n")[0] || null;
113
+ } catch {
114
+ return null;
115
+ }
116
+ }
117
+ function getIdeVersion(cliCommand) {
118
+ try {
119
+ const result = execSync(`"${cliCommand}" --version`, {
120
+ encoding: "utf-8",
121
+ timeout: 1e4,
122
+ stdio: ["pipe", "pipe", "pipe"]
123
+ }).trim();
124
+ return result.split("\n")[0] || null;
125
+ } catch {
126
+ return null;
127
+ }
128
+ }
129
+ function checkPathExists(paths) {
130
+ const os = platform();
131
+ for (const p of paths) {
132
+ if (p.includes("*")) {
133
+ const parts = p.split("*");
134
+ const homeDir = homedir();
135
+ const resolved = parts.join(homeDir.split(/[/\\]/).pop() || "");
136
+ if (existsSync(resolved)) return resolved;
137
+ } else {
138
+ if (existsSync(p)) return p;
139
+ }
140
+ }
141
+ return null;
142
+ }
143
+ async function detectIDEs() {
144
+ const os = platform();
145
+ const results = [];
146
+ for (const def of IDE_DEFINITIONS) {
147
+ const cliPath = findCliCommand(def.cli);
148
+ const appPath = checkPathExists(def.paths[os] || []);
149
+ const installed = !!(cliPath || appPath);
150
+ const version = cliPath ? getIdeVersion(cliPath) : null;
151
+ results.push({
152
+ id: def.id,
153
+ name: def.name,
154
+ displayName: def.displayName,
155
+ installed,
156
+ path: appPath || cliPath,
157
+ cliCommand: cliPath ? def.cli : null,
158
+ version,
159
+ icon: def.icon,
160
+ extensionSupport: def.extensionSupport
161
+ });
162
+ }
163
+ return results;
164
+ }
165
+
166
+ // src/installer.ts
167
+ import { execSync as execSync2, exec } from "child_process";
168
+ var EXTENSION_CATALOG = [
169
+ // Bridge extension (always installed)
170
+ {
171
+ id: "adhdev",
172
+ name: "ADHDev",
173
+ displayName: "ADHDev Bridge",
174
+ marketplaceId: "adhdev.adhdev-bridge",
175
+ // placeholder
176
+ description: "Connects your IDE to the ADHDev cloud for remote control",
177
+ category: "bridge",
178
+ icon: "\u{1F309}",
179
+ recommended: true
180
+ },
181
+ // AI Agent extensions
182
+ {
183
+ id: "roo-code",
184
+ name: "Roo Code",
185
+ displayName: "Roo Code (Roo Cline)",
186
+ marketplaceId: "rooveterinaryinc.roo-cline",
187
+ description: "Open-source AI coding assistant with multiple modes",
188
+ category: "ai-agent",
189
+ icon: "\u{1F998}",
190
+ recommended: true,
191
+ website: "https://roocode.com"
192
+ },
193
+ {
194
+ id: "github-copilot",
195
+ name: "GitHub Copilot",
196
+ displayName: "GitHub Copilot",
197
+ marketplaceId: "github.copilot",
198
+ description: "AI pair programmer by GitHub",
199
+ category: "ai-agent",
200
+ icon: "\u{1F916}",
201
+ recommended: true,
202
+ requiresApiKey: true,
203
+ apiKeyName: "GitHub account",
204
+ website: "https://github.com/features/copilot"
205
+ },
206
+ {
207
+ id: "copilot-chat",
208
+ name: "GitHub Copilot Chat",
209
+ displayName: "GitHub Copilot Chat",
210
+ marketplaceId: "github.copilot-chat",
211
+ description: "Chat interface for GitHub Copilot",
212
+ category: "ai-agent",
213
+ icon: "\u{1F4AC}",
214
+ recommended: true,
215
+ requiresApiKey: true,
216
+ apiKeyName: "GitHub account"
217
+ },
218
+ {
219
+ id: "cline",
220
+ name: "Cline",
221
+ displayName: "Cline",
222
+ marketplaceId: "saoudrizwan.claude-dev",
223
+ description: "Autonomous AI coding agent in your IDE",
224
+ category: "ai-agent",
225
+ icon: "\u{1F9E0}",
226
+ recommended: false,
227
+ requiresApiKey: true,
228
+ apiKeyName: "Anthropic/OpenAI API key"
229
+ },
230
+ {
231
+ id: "continue",
232
+ name: "Continue",
233
+ displayName: "Continue",
234
+ marketplaceId: "continue.continue",
235
+ description: "Open-source AI code assistant with custom models",
236
+ category: "ai-agent",
237
+ icon: "\u25B6\uFE0F",
238
+ recommended: false
239
+ },
240
+ {
241
+ id: "aider",
242
+ name: "Aider",
243
+ displayName: "Aider",
244
+ marketplaceId: "aider.aider",
245
+ description: "AI pair programming in your terminal",
246
+ category: "ai-agent",
247
+ icon: "\u{1F527}",
248
+ recommended: false,
249
+ requiresApiKey: true,
250
+ apiKeyName: "OpenAI/Anthropic API key"
251
+ }
252
+ ];
253
+ function isExtensionInstalled(ide, marketplaceId) {
254
+ if (!ide.cliCommand) return false;
255
+ try {
256
+ const result = execSync2(`"${ide.cliCommand}" --list-extensions`, {
257
+ encoding: "utf-8",
258
+ timeout: 15e3,
259
+ stdio: ["pipe", "pipe", "pipe"]
260
+ });
261
+ const installed = result.trim().split("\n").map((e) => e.trim().toLowerCase());
262
+ return installed.includes(marketplaceId.toLowerCase());
263
+ } catch {
264
+ return false;
265
+ }
266
+ }
267
+ async function installExtension(ide, extension) {
268
+ if (!ide.cliCommand) {
269
+ return {
270
+ extensionId: extension.id,
271
+ marketplaceId: extension.marketplaceId,
272
+ success: false,
273
+ alreadyInstalled: false,
274
+ error: `No CLI command found for ${ide.displayName}. Please install it manually.`
275
+ };
276
+ }
277
+ const alreadyInstalled = isExtensionInstalled(ide, extension.marketplaceId);
278
+ if (alreadyInstalled) {
279
+ return {
280
+ extensionId: extension.id,
281
+ marketplaceId: extension.marketplaceId,
282
+ success: true,
283
+ alreadyInstalled: true
284
+ };
285
+ }
286
+ return new Promise((resolve) => {
287
+ const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
288
+ exec(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
289
+ if (error) {
290
+ resolve({
291
+ extensionId: extension.id,
292
+ marketplaceId: extension.marketplaceId,
293
+ success: false,
294
+ alreadyInstalled: false,
295
+ error: stderr || error.message
296
+ });
297
+ } else {
298
+ resolve({
299
+ extensionId: extension.id,
300
+ marketplaceId: extension.marketplaceId,
301
+ success: true,
302
+ alreadyInstalled: false
303
+ });
304
+ }
305
+ });
306
+ });
307
+ }
308
+ async function installExtensions(ide, extensions, onProgress) {
309
+ const results = [];
310
+ for (let i = 0; i < extensions.length; i++) {
311
+ const ext = extensions[i];
312
+ const result = await installExtension(ide, ext);
313
+ results.push(result);
314
+ onProgress?.(i + 1, extensions.length, ext, result);
315
+ }
316
+ return results;
317
+ }
318
+ function getAIExtensions() {
319
+ return EXTENSION_CATALOG.filter((e) => e.category === "ai-agent");
320
+ }
321
+ function launchIDE(ide, workspacePath) {
322
+ if (!ide.cliCommand) return false;
323
+ try {
324
+ const args = workspacePath ? `"${workspacePath}"` : "";
325
+ exec(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
326
+ return true;
327
+ } catch {
328
+ return false;
329
+ }
330
+ }
331
+
332
+ // src/config.ts
333
+ import { homedir as homedir2 } from "os";
334
+ import { join } from "path";
335
+ import { existsSync as existsSync2, mkdirSync, readFileSync, writeFileSync } from "fs";
336
+ var DEFAULT_CONFIG = {
337
+ serverUrl: "https://api.adhdev.io",
338
+ apiToken: null,
339
+ selectedIde: null,
340
+ installedExtensions: [],
341
+ autoConnect: true,
342
+ notifications: true,
343
+ setupCompleted: false,
344
+ setupDate: null
345
+ };
346
+ function getConfigDir() {
347
+ const dir = join(homedir2(), ".adhdev");
348
+ if (!existsSync2(dir)) {
349
+ mkdirSync(dir, { recursive: true });
350
+ }
351
+ return dir;
352
+ }
353
+ function getConfigPath() {
354
+ return join(getConfigDir(), "config.json");
355
+ }
356
+ function loadConfig() {
357
+ const configPath = getConfigPath();
358
+ if (!existsSync2(configPath)) {
359
+ return { ...DEFAULT_CONFIG };
360
+ }
361
+ try {
362
+ const raw = readFileSync(configPath, "utf-8");
363
+ const parsed = JSON.parse(raw);
364
+ return { ...DEFAULT_CONFIG, ...parsed };
365
+ } catch {
366
+ return { ...DEFAULT_CONFIG };
367
+ }
368
+ }
369
+ function saveConfig(config) {
370
+ const configPath = getConfigPath();
371
+ const dir = getConfigDir();
372
+ if (!existsSync2(dir)) {
373
+ mkdirSync(dir, { recursive: true });
374
+ }
375
+ writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
376
+ }
377
+ function updateConfig(updates) {
378
+ const config = loadConfig();
379
+ const updated = { ...config, ...updates };
380
+ saveConfig(updated);
381
+ return updated;
382
+ }
383
+ function markSetupComplete(ideId, extensions) {
384
+ return updateConfig({
385
+ selectedIde: ideId,
386
+ installedExtensions: extensions,
387
+ setupCompleted: true,
388
+ setupDate: (/* @__PURE__ */ new Date()).toISOString()
389
+ });
390
+ }
391
+ function isSetupComplete() {
392
+ const config = loadConfig();
393
+ return config.setupCompleted;
394
+ }
395
+ function resetConfig() {
396
+ saveConfig({ ...DEFAULT_CONFIG });
397
+ }
398
+ function generateConnectionToken() {
399
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
400
+ let token = "db_";
401
+ for (let i = 0; i < 32; i++) {
402
+ token += chars.charAt(Math.floor(Math.random() * chars.length));
403
+ }
404
+ return token;
405
+ }
406
+
407
+ // src/wizard.ts
408
+ var LOGO = `
409
+ ${chalk.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")}
410
+ ${chalk.cyan("\u2551")} ${chalk.bold.white("\u{1F309} ADHDev Setup Wizard")} ${chalk.cyan("\u2551")}
411
+ ${chalk.cyan("\u2551")} ${chalk.gray("Agent Dashboard Hub for your IDE")} ${chalk.cyan("\u2551")}
412
+ ${chalk.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")}
413
+ `;
414
+ var DIVIDER = chalk.gray("\u2500".repeat(44));
415
+ async function runWizard(options = {}) {
416
+ console.log(LOGO);
417
+ if (isSetupComplete() && !options.force) {
418
+ const config = loadConfig();
419
+ console.log(chalk.green("\u2713") + " ADHDev is already set up!");
420
+ console.log(chalk.gray(` IDE: ${config.selectedIde}`));
421
+ console.log(chalk.gray(` Extensions: ${config.installedExtensions.length} installed`));
422
+ console.log();
423
+ const { action } = await inquirer.prompt([
424
+ {
425
+ type: "list",
426
+ name: "action",
427
+ message: "What would you like to do?",
428
+ choices: [
429
+ { name: "\u{1F504} Reconfigure (run setup again)", value: "reconfigure" },
430
+ { name: "\u2795 Add more extensions", value: "add-extensions" },
431
+ { name: "\u{1F50C} Reconnect to server", value: "reconnect" },
432
+ { name: "\u274C Exit", value: "exit" }
433
+ ]
434
+ }
435
+ ]);
436
+ if (action === "exit") return;
437
+ if (action === "add-extensions") {
438
+ await addExtensionsFlow();
439
+ return;
440
+ }
441
+ if (action === "reconnect") {
442
+ await reconnectFlow();
443
+ return;
444
+ }
445
+ }
446
+ console.log(chalk.bold("\n\u{1F4CD} Step 1/4 \u2014 Detecting installed IDEs...\n"));
447
+ const spinner = ora("Scanning your system...").start();
448
+ const ides = await detectIDEs();
449
+ const installedIDEs = ides.filter((i) => i.installed);
450
+ spinner.stop();
451
+ if (installedIDEs.length === 0) {
452
+ console.log(chalk.yellow("\u26A0 No supported IDEs found on your system.\n"));
453
+ console.log("Supported IDEs:");
454
+ ides.forEach((ide) => {
455
+ console.log(chalk.gray(` ${ide.icon} ${ide.displayName}`));
456
+ });
457
+ console.log(
458
+ "\nPlease install one of the above IDEs and run this wizard again."
459
+ );
460
+ return;
461
+ }
462
+ console.log(chalk.green(`Found ${installedIDEs.length} IDE(s):
463
+ `));
464
+ installedIDEs.forEach((ide) => {
465
+ const version = ide.version ? chalk.gray(` v${ide.version}`) : "";
466
+ console.log(` ${ide.icon} ${chalk.bold(ide.displayName)}${version}`);
467
+ if (ide.path) console.log(chalk.gray(` ${ide.path}`));
468
+ });
469
+ const notInstalled = ides.filter((i) => !i.installed);
470
+ if (notInstalled.length > 0) {
471
+ console.log(chalk.gray("\n Not installed:"));
472
+ notInstalled.forEach((ide) => {
473
+ console.log(chalk.gray(` ${ide.icon} ${ide.displayName} \u2014 not found`));
474
+ });
475
+ }
476
+ console.log();
477
+ console.log(DIVIDER);
478
+ console.log(chalk.bold("\n\u{1F4CD} Step 2/4 \u2014 Select your primary IDE\n"));
479
+ const { selectedIdeId } = await inquirer.prompt([
480
+ {
481
+ type: "list",
482
+ name: "selectedIdeId",
483
+ message: "Which IDE do you want to set up with ADHDev?",
484
+ choices: installedIDEs.map((ide) => ({
485
+ name: `${ide.icon} ${ide.displayName}${ide.version ? chalk.gray(` v${ide.version}`) : ""}`,
486
+ value: ide.id
487
+ }))
488
+ }
489
+ ]);
490
+ const selectedIDE = installedIDEs.find((i) => i.id === selectedIdeId);
491
+ if (!selectedIDE.cliCommand) {
492
+ console.log(
493
+ chalk.yellow(
494
+ `
495
+ \u26A0 CLI command for ${selectedIDE.displayName} not found in PATH.`
496
+ )
497
+ );
498
+ console.log(
499
+ chalk.gray(
500
+ "Extensions will need to be installed manually from the Marketplace."
501
+ )
502
+ );
503
+ }
504
+ console.log(DIVIDER);
505
+ console.log(chalk.bold("\n\u{1F4CD} Step 3/4 \u2014 Choose AI extensions to install\n"));
506
+ const aiExtensions = getAIExtensions();
507
+ const { selectedExtIds } = await inquirer.prompt([
508
+ {
509
+ type: "checkbox",
510
+ name: "selectedExtIds",
511
+ message: "Select AI extensions to install:",
512
+ choices: aiExtensions.map((ext) => ({
513
+ name: `${ext.icon} ${ext.displayName} \u2014 ${chalk.gray(ext.description)}${ext.requiresApiKey ? chalk.yellow(` (requires ${ext.apiKeyName})`) : ""}`,
514
+ value: ext.id,
515
+ checked: ext.recommended
516
+ })),
517
+ validate: (input) => {
518
+ return true;
519
+ }
520
+ }
521
+ ]);
522
+ const bridgeExt = EXTENSION_CATALOG.find((e) => e.category === "bridge");
523
+ const selectedAIExts = aiExtensions.filter(
524
+ (e) => selectedExtIds.includes(e.id)
525
+ );
526
+ const allExtensions = [bridgeExt, ...selectedAIExts];
527
+ console.log(
528
+ chalk.cyan(
529
+ `
530
+ \u{1F4E6} Will install ${allExtensions.length} extension(s):`
531
+ )
532
+ );
533
+ allExtensions.forEach((ext) => {
534
+ console.log(` ${ext.icon} ${ext.displayName}`);
535
+ });
536
+ console.log();
537
+ console.log(DIVIDER);
538
+ console.log(chalk.bold("\n\u{1F4CD} Step 4/4 \u2014 Installing extensions\n"));
539
+ if (selectedIDE.cliCommand) {
540
+ const results = await installExtensions(
541
+ selectedIDE,
542
+ allExtensions,
543
+ (current, total, ext, result) => {
544
+ const status = result.alreadyInstalled ? chalk.blue("already installed") : result.success ? chalk.green("installed \u2713") : chalk.red(`failed \u2717 ${result.error || ""}`);
545
+ console.log(
546
+ ` [${current}/${total}] ${ext.icon} ${ext.displayName} \u2014 ${status}`
547
+ );
548
+ }
549
+ );
550
+ const succeeded = results.filter((r) => r.success).length;
551
+ const failed = results.filter((r) => !r.success).length;
552
+ console.log();
553
+ if (failed > 0) {
554
+ console.log(
555
+ chalk.yellow(
556
+ `\u26A0 ${failed} extension(s) failed to install. You can install them manually from the Marketplace.`
557
+ )
558
+ );
559
+ }
560
+ console.log(
561
+ chalk.green(`\u2713 ${succeeded}/${results.length} extensions ready.`)
562
+ );
563
+ } else {
564
+ console.log(
565
+ chalk.yellow(
566
+ "\u26A0 Automatic installation not available (CLI not found)."
567
+ )
568
+ );
569
+ console.log("Please install these extensions manually:");
570
+ allExtensions.forEach((ext) => {
571
+ console.log(
572
+ chalk.gray(` ${ext.icon} ${ext.displayName}: ${ext.marketplaceId}`)
573
+ );
574
+ });
575
+ }
576
+ console.log(DIVIDER);
577
+ console.log(chalk.bold("\n\u{1F517} Setting up server connection...\n"));
578
+ const token = generateConnectionToken();
579
+ updateConfig({ apiToken: token });
580
+ console.log(chalk.green("\u2713 Connection token generated."));
581
+ console.log(
582
+ chalk.gray(
583
+ " The bridge extension will use this token to connect to ADHDev.\n"
584
+ )
585
+ );
586
+ markSetupComplete(
587
+ selectedIdeId,
588
+ allExtensions.map((e) => e.id)
589
+ );
590
+ console.log(DIVIDER);
591
+ console.log(chalk.bold("\n\u{1F389} Setup Complete!\n"));
592
+ console.log(` ${chalk.bold("IDE:")} ${selectedIDE.icon} ${selectedIDE.displayName}`);
593
+ console.log(` ${chalk.bold("Extensions:")} ${allExtensions.length} installed`);
594
+ console.log(` ${chalk.bold("Status:")} ${chalk.green("Ready to connect")}`);
595
+ console.log();
596
+ console.log(chalk.cyan("Next steps:"));
597
+ console.log(" 1. Open your IDE \u2014 the ADHDev extension will auto-activate");
598
+ console.log(" 2. Sign in at " + chalk.underline("https://app.adhdev.io"));
599
+ console.log(" 3. Your IDE will appear in the dashboard");
600
+ console.log();
601
+ const { shouldLaunch } = await inquirer.prompt([
602
+ {
603
+ type: "confirm",
604
+ name: "shouldLaunch",
605
+ message: `Launch ${selectedIDE.displayName} now?`,
606
+ default: true
607
+ }
608
+ ]);
609
+ if (shouldLaunch) {
610
+ const launched = launchIDE(selectedIDE);
611
+ if (launched) {
612
+ console.log(
613
+ chalk.green(`
614
+ \u2713 ${selectedIDE.displayName} is starting...`)
615
+ );
616
+ } else {
617
+ console.log(
618
+ chalk.yellow(
619
+ `
620
+ \u26A0 Could not launch ${selectedIDE.displayName} automatically. Please open it manually.`
621
+ )
622
+ );
623
+ }
624
+ }
625
+ console.log(chalk.gray("\nThank you for using ADHDev! \u{1F309}\n"));
626
+ }
627
+ async function addExtensionsFlow() {
628
+ const config = loadConfig();
629
+ const ides = await detectIDEs();
630
+ const selectedIDE = ides.find((i) => i.id === config.selectedIde);
631
+ if (!selectedIDE || !selectedIDE.installed) {
632
+ console.log(
633
+ chalk.yellow("\u26A0 Previously selected IDE not found. Please reconfigure.")
634
+ );
635
+ return;
636
+ }
637
+ const aiExtensions = getAIExtensions();
638
+ const notInstalled = aiExtensions.filter(
639
+ (e) => !config.installedExtensions.includes(e.id)
640
+ );
641
+ if (notInstalled.length === 0) {
642
+ console.log(chalk.green("\u2713 All available extensions are already installed!"));
643
+ return;
644
+ }
645
+ const { selectedExtIds } = await inquirer.prompt([
646
+ {
647
+ type: "checkbox",
648
+ name: "selectedExtIds",
649
+ message: "Select additional AI extensions to install:",
650
+ choices: notInstalled.map((ext) => ({
651
+ name: `${ext.icon} ${ext.displayName} \u2014 ${chalk.gray(ext.description)}`,
652
+ value: ext.id
653
+ }))
654
+ }
655
+ ]);
656
+ if (selectedExtIds.length === 0) {
657
+ console.log(chalk.gray("No extensions selected."));
658
+ return;
659
+ }
660
+ const extensions = notInstalled.filter(
661
+ (e) => selectedExtIds.includes(e.id)
662
+ );
663
+ await installExtensions(
664
+ selectedIDE,
665
+ extensions,
666
+ (current, total, ext, result) => {
667
+ const status = result.success ? chalk.green("installed \u2713") : chalk.red(`failed \u2717`);
668
+ console.log(
669
+ ` [${current}/${total}] ${ext.icon} ${ext.displayName} \u2014 ${status}`
670
+ );
671
+ }
672
+ );
673
+ updateConfig({
674
+ installedExtensions: [
675
+ ...config.installedExtensions,
676
+ ...selectedExtIds
677
+ ]
678
+ });
679
+ console.log(chalk.green("\n\u2713 Extensions added successfully!"));
680
+ }
681
+ async function reconnectFlow() {
682
+ const spinner = ora("Reconnecting to ADHDev server...").start();
683
+ await new Promise((resolve) => setTimeout(resolve, 1500));
684
+ const token = generateConnectionToken();
685
+ updateConfig({ apiToken: token });
686
+ spinner.succeed("Reconnected to ADHDev server.");
687
+ console.log(
688
+ chalk.gray(" New connection token has been generated.\n")
689
+ );
690
+ }
691
+
692
+ // src/index.ts
693
+ var program = new Command();
694
+ program.name("adhdev").description("\u{1F309} ADHDev \u2014 Agent Dashboard Hub for your IDE").version("0.1.0");
695
+ program.command("setup", { isDefault: true }).description("Run the interactive setup wizard").option("-f, --force", "Force re-run setup even if already configured").action(async (options) => {
696
+ await runWizard({ force: options.force });
697
+ });
698
+ program.command("status").description("Show current ADHDev setup status").action(() => {
699
+ const config = loadConfig();
700
+ console.log(chalk2.bold("\n\u{1F309} ADHDev Status\n"));
701
+ if (!config.setupCompleted) {
702
+ console.log(chalk2.yellow(" Status: Not configured"));
703
+ console.log(chalk2.gray(" Run `adhdev setup` to get started.\n"));
704
+ return;
705
+ }
706
+ console.log(` ${chalk2.bold("Status:")} ${chalk2.green("\u2713 Configured")}`);
707
+ console.log(` ${chalk2.bold("IDE:")} ${config.selectedIde || "none"}`);
708
+ console.log(` ${chalk2.bold("Extensions:")} ${config.installedExtensions.length} installed`);
709
+ config.installedExtensions.forEach((ext) => {
710
+ console.log(chalk2.gray(` \u2022 ${ext}`));
711
+ });
712
+ console.log(` ${chalk2.bold("Auto-connect:")} ${config.autoConnect ? chalk2.green("enabled") : chalk2.gray("disabled")}`);
713
+ console.log(` ${chalk2.bold("Server:")} ${config.serverUrl}`);
714
+ console.log(` ${chalk2.bold("Setup date:")} ${config.setupDate || "unknown"}`);
715
+ console.log();
716
+ });
717
+ program.command("detect").description("Detect installed IDEs on your system").action(async () => {
718
+ console.log(chalk2.bold("\n\u{1F50D} Detecting installed IDEs...\n"));
719
+ const ides = await detectIDEs();
720
+ ides.forEach((ide) => {
721
+ if (ide.installed) {
722
+ const version = ide.version ? chalk2.gray(` v${ide.version}`) : "";
723
+ console.log(` ${chalk2.green("\u2713")} ${ide.icon} ${chalk2.bold(ide.displayName)}${version}`);
724
+ if (ide.cliCommand) {
725
+ console.log(chalk2.gray(` CLI: ${ide.cliCommand}`));
726
+ }
727
+ if (ide.path) {
728
+ console.log(chalk2.gray(` Path: ${ide.path}`));
729
+ }
730
+ } else {
731
+ console.log(` ${chalk2.gray("\u2717")} ${ide.icon} ${chalk2.gray(ide.displayName)} \u2014 not found`);
732
+ }
733
+ });
734
+ console.log();
735
+ });
736
+ program.command("reset").description("Reset ADHDev configuration").action(async () => {
737
+ const inquirer2 = await import("inquirer");
738
+ const { confirm } = await inquirer2.default.prompt([
739
+ {
740
+ type: "confirm",
741
+ name: "confirm",
742
+ message: "Are you sure you want to reset ADHDev configuration?",
743
+ default: false
744
+ }
745
+ ]);
746
+ if (confirm) {
747
+ resetConfig();
748
+ console.log(chalk2.green("\n\u2713 Configuration reset successfully."));
749
+ console.log(chalk2.gray(" Run `adhdev setup` to reconfigure.\n"));
750
+ }
751
+ });
752
+ program.parse(process.argv);
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "adhdev",
3
+ "version": "0.1.0",
4
+ "description": "ADHDev CLI — Detect, install and configure your IDE + AI agent extensions",
5
+ "type": "module",
6
+ "bin": {
7
+ "adhdev": "./dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "dev": "tsx src/index.ts",
11
+ "build": "tsup",
12
+ "start": "node dist/index.js",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "keywords": [
20
+ "adhdev",
21
+ "ai-agent",
22
+ "ide",
23
+ "cli",
24
+ "setup-wizard",
25
+ "cursor",
26
+ "vscode",
27
+ "antigravity"
28
+ ],
29
+ "author": "vilmire",
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/vilmire/adhdev.git",
34
+ "directory": "packages/launcher"
35
+ },
36
+ "homepage": "https://github.com/vilmire/adhdev#readme",
37
+ "bugs": "https://github.com/vilmire/adhdev/issues",
38
+ "dependencies": {
39
+ "chalk": "^5.3.0",
40
+ "commander": "^12.1.0",
41
+ "inquirer": "^9.3.0",
42
+ "ora": "^8.0.0",
43
+ "conf": "^13.0.0",
44
+ "open": "^10.1.0"
45
+ },
46
+ "devDependencies": {
47
+ "tsx": "^4.19.0",
48
+ "tsup": "^8.2.0",
49
+ "typescript": "^5.5.0",
50
+ "@types/inquirer": "^9.0.0",
51
+ "@types/node": "^22.0.0"
52
+ }
53
+ }