adhdev 0.1.0 → 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/README.md CHANGED
@@ -40,4 +40,4 @@ adhdev setup
40
40
 
41
41
  ## License
42
42
 
43
- MIT
43
+ Proprietary — All rights reserved.
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
- #!/usr/bin/env node
1
+
2
+ export { }
package/dist/index.js CHANGED
@@ -1,19 +1,42 @@
1
1
  #!/usr/bin/env node
2
- #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
3
25
 
4
26
  // src/index.ts
5
- import { Command } from "commander";
6
- import chalk2 from "chalk";
27
+ var import_commander = require("commander");
28
+ var import_chalk2 = __toESM(require("chalk"));
7
29
 
8
30
  // src/wizard.ts
9
- import chalk from "chalk";
10
- import inquirer from "inquirer";
11
- import ora from "ora";
31
+ var import_chalk = __toESM(require("chalk"));
32
+ var import_inquirer = __toESM(require("inquirer"));
33
+ var import_ora = __toESM(require("ora"));
34
+ var import_open = __toESM(require("open"));
12
35
 
13
36
  // src/detector-impl.ts
14
- import { execSync } from "child_process";
15
- import { existsSync } from "fs";
16
- import { platform, homedir } from "os";
37
+ var import_child_process = require("child_process");
38
+ var import_fs = require("fs");
39
+ var import_os = require("os");
17
40
  var IDE_DEFINITIONS = [
18
41
  {
19
42
  id: "vscode",
@@ -105,8 +128,8 @@ var IDE_DEFINITIONS = [
105
128
  ];
106
129
  function findCliCommand(command) {
107
130
  try {
108
- const result = execSync(
109
- platform() === "win32" ? `where ${command}` : `which ${command}`,
131
+ const result = (0, import_child_process.execSync)(
132
+ (0, import_os.platform)() === "win32" ? `where ${command}` : `which ${command}`,
110
133
  { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }
111
134
  ).trim();
112
135
  return result.split("\n")[0] || null;
@@ -116,7 +139,7 @@ function findCliCommand(command) {
116
139
  }
117
140
  function getIdeVersion(cliCommand) {
118
141
  try {
119
- const result = execSync(`"${cliCommand}" --version`, {
142
+ const result = (0, import_child_process.execSync)(`"${cliCommand}" --version`, {
120
143
  encoding: "utf-8",
121
144
  timeout: 1e4,
122
145
  stdio: ["pipe", "pipe", "pipe"]
@@ -127,34 +150,39 @@ function getIdeVersion(cliCommand) {
127
150
  }
128
151
  }
129
152
  function checkPathExists(paths) {
130
- const os = platform();
153
+ const os = (0, import_os.platform)();
131
154
  for (const p of paths) {
132
155
  if (p.includes("*")) {
133
156
  const parts = p.split("*");
134
- const homeDir = homedir();
157
+ const homeDir = (0, import_os.homedir)();
135
158
  const resolved = parts.join(homeDir.split(/[/\\]/).pop() || "");
136
- if (existsSync(resolved)) return resolved;
159
+ if ((0, import_fs.existsSync)(resolved)) return resolved;
137
160
  } else {
138
- if (existsSync(p)) return p;
161
+ if ((0, import_fs.existsSync)(p)) return p;
139
162
  }
140
163
  }
141
164
  return null;
142
165
  }
143
166
  async function detectIDEs() {
144
- const os = platform();
167
+ const os = (0, import_os.platform)();
145
168
  const results = [];
146
169
  for (const def of IDE_DEFINITIONS) {
147
170
  const cliPath = findCliCommand(def.cli);
148
171
  const appPath = checkPathExists(def.paths[os] || []);
149
172
  const installed = !!(cliPath || appPath);
150
- const version = cliPath ? getIdeVersion(cliPath) : null;
173
+ let resolvedCli = cliPath;
174
+ if (!resolvedCli && appPath && os === "darwin") {
175
+ const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
176
+ if ((0, import_fs.existsSync)(bundledCli)) resolvedCli = bundledCli;
177
+ }
178
+ const version = resolvedCli ? getIdeVersion(resolvedCli) : null;
151
179
  results.push({
152
180
  id: def.id,
153
181
  name: def.name,
154
182
  displayName: def.displayName,
155
183
  installed,
156
184
  path: appPath || cliPath,
157
- cliCommand: cliPath ? def.cli : null,
185
+ cliCommand: resolvedCli ? cliPath ? def.cli : resolvedCli : null,
158
186
  version,
159
187
  icon: def.icon,
160
188
  extensionSupport: def.extensionSupport
@@ -164,19 +192,20 @@ async function detectIDEs() {
164
192
  }
165
193
 
166
194
  // src/installer.ts
167
- import { execSync as execSync2, exec } from "child_process";
195
+ var import_child_process2 = require("child_process");
168
196
  var EXTENSION_CATALOG = [
169
- // Bridge extension (always installed)
197
+ // Bridge extension (always installed — from local VSIX)
170
198
  {
171
199
  id: "adhdev",
172
200
  name: "ADHDev",
173
201
  displayName: "ADHDev Bridge",
174
202
  marketplaceId: "adhdev.adhdev-bridge",
175
- // placeholder
176
203
  description: "Connects your IDE to the ADHDev cloud for remote control",
177
204
  category: "bridge",
178
205
  icon: "\u{1F309}",
179
- recommended: true
206
+ recommended: true,
207
+ vsixUrl: "https://api.adhf.dev/api/v1/releases/bridge/latest.vsix"
208
+ // 서버에서 다운로드
180
209
  },
181
210
  // AI Agent extensions
182
211
  {
@@ -253,7 +282,7 @@ var EXTENSION_CATALOG = [
253
282
  function isExtensionInstalled(ide, marketplaceId) {
254
283
  if (!ide.cliCommand) return false;
255
284
  try {
256
- const result = execSync2(`"${ide.cliCommand}" --list-extensions`, {
285
+ const result = (0, import_child_process2.execSync)(`"${ide.cliCommand}" --list-extensions`, {
257
286
  encoding: "utf-8",
258
287
  timeout: 15e3,
259
288
  stdio: ["pipe", "pipe", "pipe"]
@@ -283,9 +312,34 @@ async function installExtension(ide, extension) {
283
312
  alreadyInstalled: true
284
313
  };
285
314
  }
315
+ if (extension.vsixUrl) {
316
+ try {
317
+ const tmpDir = (await import("os")).tmpdir();
318
+ const vsixPath = `${tmpDir}/adhdev-bridge-latest.vsix`;
319
+ const res = await fetch(extension.vsixUrl);
320
+ if (res.ok) {
321
+ const buffer = Buffer.from(await res.arrayBuffer());
322
+ const fs = await import("fs");
323
+ fs.writeFileSync(vsixPath, buffer);
324
+ return new Promise((resolve) => {
325
+ const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
326
+ (0, import_child_process2.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
327
+ resolve({
328
+ extensionId: extension.id,
329
+ marketplaceId: extension.marketplaceId,
330
+ success: !error,
331
+ alreadyInstalled: false,
332
+ error: error ? stderr || error.message : void 0
333
+ });
334
+ });
335
+ });
336
+ }
337
+ } catch {
338
+ }
339
+ }
286
340
  return new Promise((resolve) => {
287
341
  const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
288
- exec(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
342
+ (0, import_child_process2.exec)(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
289
343
  if (error) {
290
344
  resolve({
291
345
  extensionId: extension.id,
@@ -322,7 +376,7 @@ function launchIDE(ide, workspacePath) {
322
376
  if (!ide.cliCommand) return false;
323
377
  try {
324
378
  const args = workspacePath ? `"${workspacePath}"` : "";
325
- exec(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
379
+ (0, import_child_process2.exec)(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
326
380
  return true;
327
381
  } catch {
328
382
  return false;
@@ -330,36 +384,39 @@ function launchIDE(ide, workspacePath) {
330
384
  }
331
385
 
332
386
  // 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";
387
+ var import_os2 = require("os");
388
+ var import_path = require("path");
389
+ var import_fs2 = require("fs");
336
390
  var DEFAULT_CONFIG = {
337
- serverUrl: "https://api.adhdev.io",
391
+ serverUrl: "https://api.adhf.dev",
338
392
  apiToken: null,
393
+ connectionToken: null,
339
394
  selectedIde: null,
340
395
  installedExtensions: [],
341
396
  autoConnect: true,
342
397
  notifications: true,
398
+ userEmail: null,
399
+ userName: null,
343
400
  setupCompleted: false,
344
401
  setupDate: null
345
402
  };
346
403
  function getConfigDir() {
347
- const dir = join(homedir2(), ".adhdev");
348
- if (!existsSync2(dir)) {
349
- mkdirSync(dir, { recursive: true });
404
+ const dir = (0, import_path.join)((0, import_os2.homedir)(), ".adhdev");
405
+ if (!(0, import_fs2.existsSync)(dir)) {
406
+ (0, import_fs2.mkdirSync)(dir, { recursive: true });
350
407
  }
351
408
  return dir;
352
409
  }
353
410
  function getConfigPath() {
354
- return join(getConfigDir(), "config.json");
411
+ return (0, import_path.join)(getConfigDir(), "config.json");
355
412
  }
356
413
  function loadConfig() {
357
414
  const configPath = getConfigPath();
358
- if (!existsSync2(configPath)) {
415
+ if (!(0, import_fs2.existsSync)(configPath)) {
359
416
  return { ...DEFAULT_CONFIG };
360
417
  }
361
418
  try {
362
- const raw = readFileSync(configPath, "utf-8");
419
+ const raw = (0, import_fs2.readFileSync)(configPath, "utf-8");
363
420
  const parsed = JSON.parse(raw);
364
421
  return { ...DEFAULT_CONFIG, ...parsed };
365
422
  } catch {
@@ -369,10 +426,10 @@ function loadConfig() {
369
426
  function saveConfig(config) {
370
427
  const configPath = getConfigPath();
371
428
  const dir = getConfigDir();
372
- if (!existsSync2(dir)) {
373
- mkdirSync(dir, { recursive: true });
429
+ if (!(0, import_fs2.existsSync)(dir)) {
430
+ (0, import_fs2.mkdirSync)(dir, { recursive: true });
374
431
  }
375
- writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
432
+ (0, import_fs2.writeFileSync)(configPath, JSON.stringify(config, null, 2), "utf-8");
376
433
  }
377
434
  function updateConfig(updates) {
378
435
  const config = loadConfig();
@@ -395,32 +452,26 @@ function isSetupComplete() {
395
452
  function resetConfig() {
396
453
  saveConfig({ ...DEFAULT_CONFIG });
397
454
  }
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
455
 
407
456
  // src/wizard.ts
457
+ var SERVER_URL = "https://api.adhf.dev";
408
458
  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")}
459
+ ${import_chalk.default.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")}
460
+ ${import_chalk.default.cyan("\u2551")} ${import_chalk.default.bold.white("\u{1F309} ADHDev Setup Wizard")} ${import_chalk.default.cyan("\u2551")}
461
+ ${import_chalk.default.cyan("\u2551")} ${import_chalk.default.gray("Agent Dashboard Hub for your IDE")} ${import_chalk.default.cyan("\u2551")}
462
+ ${import_chalk.default.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
463
  `;
414
- var DIVIDER = chalk.gray("\u2500".repeat(44));
464
+ var DIVIDER = import_chalk.default.gray("\u2500".repeat(44));
415
465
  async function runWizard(options = {}) {
416
466
  console.log(LOGO);
417
467
  if (isSetupComplete() && !options.force) {
418
468
  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`));
469
+ console.log(import_chalk.default.green("\u2713") + " ADHDev is already set up!");
470
+ console.log(import_chalk.default.gray(` IDE: ${config.selectedIde}`));
471
+ console.log(import_chalk.default.gray(` User: ${config.userEmail || "not logged in"}`));
472
+ console.log(import_chalk.default.gray(` Extensions: ${config.installedExtensions.length} installed`));
422
473
  console.log();
423
- const { action } = await inquirer.prompt([
474
+ const { action } = await import_inquirer.default.prompt([
424
475
  {
425
476
  type: "list",
426
477
  name: "action",
@@ -428,7 +479,7 @@ async function runWizard(options = {}) {
428
479
  choices: [
429
480
  { name: "\u{1F504} Reconfigure (run setup again)", value: "reconfigure" },
430
481
  { name: "\u2795 Add more extensions", value: "add-extensions" },
431
- { name: "\u{1F50C} Reconnect to server", value: "reconnect" },
482
+ { name: "\u{1F510} Re-login", value: "relogin" },
432
483
  { name: "\u274C Exit", value: "exit" }
433
484
  ]
434
485
  }
@@ -438,167 +489,160 @@ async function runWizard(options = {}) {
438
489
  await addExtensionsFlow();
439
490
  return;
440
491
  }
441
- if (action === "reconnect") {
442
- await reconnectFlow();
492
+ if (action === "relogin") {
493
+ await loginFlow();
443
494
  return;
444
495
  }
445
496
  }
446
- console.log(chalk.bold("\n\u{1F4CD} Step 1/4 \u2014 Detecting installed IDEs...\n"));
447
- const spinner = ora("Scanning your system...").start();
497
+ const { mode } = await import_inquirer.default.prompt([
498
+ {
499
+ type: "list",
500
+ name: "mode",
501
+ message: "Setup mode:",
502
+ choices: [
503
+ { name: `\u{1F680} ${import_chalk.default.bold("Quick Setup")} \u2014 Auto-detect IDE, install bridge, login ${import_chalk.default.gray("(recommended)")}`, value: "quick" },
504
+ { name: `\u2699\uFE0F ${import_chalk.default.bold("Custom Setup")} \u2014 Choose IDE, AI extensions, and more`, value: "custom" }
505
+ ]
506
+ }
507
+ ]);
508
+ if (mode === "quick") {
509
+ await quickSetup();
510
+ } else {
511
+ await customSetup();
512
+ }
513
+ }
514
+ async function quickSetup() {
515
+ console.log(import_chalk.default.bold("\n\u{1F680} Quick Setup\n"));
516
+ const spinner = (0, import_ora.default)("Detecting installed IDEs...").start();
448
517
  const ides = await detectIDEs();
449
- const installedIDEs = ides.filter((i) => i.installed);
518
+ const installedIDEs = ides.filter((i) => i.installed && i.cliCommand);
450
519
  spinner.stop();
451
520
  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}`));
521
+ console.log(import_chalk.default.red("\u2717 No supported IDE with CLI found."));
522
+ console.log(import_chalk.default.gray(" Supported: VS Code, Cursor, Antigravity, Windsurf"));
523
+ return;
524
+ }
525
+ const selectedIDE = installedIDEs[0];
526
+ console.log(import_chalk.default.green(`\u2713 Found: ${selectedIDE.icon} ${selectedIDE.displayName} ${selectedIDE.version ? `v${selectedIDE.version}` : ""}`));
527
+ const bridgeExt = EXTENSION_CATALOG.find((e) => e.category === "bridge");
528
+ const installSpinner = (0, import_ora.default)("Installing ADHDev Bridge extension...").start();
529
+ const result = await installExtension(selectedIDE, bridgeExt);
530
+ if (result.success) {
531
+ installSpinner.succeed(result.alreadyInstalled ? "ADHDev Bridge already installed \u2713" : "ADHDev Bridge installed \u2713");
532
+ } else {
533
+ installSpinner.fail(`Installation failed: ${result.error}`);
534
+ return;
535
+ }
536
+ console.log(DIVIDER);
537
+ const loginResult = await loginFlow();
538
+ if (!loginResult) {
539
+ console.log(import_chalk.default.yellow("\u26A0 Setup completed without login. You can login later with `adhdev setup`."));
540
+ }
541
+ if (loginResult?.connectionToken) {
542
+ await injectTokenToIDE(selectedIDE, loginResult.connectionToken);
543
+ }
544
+ markSetupComplete(selectedIDE.id, ["adhdev"]);
545
+ if (loginResult) {
546
+ updateConfig({
547
+ connectionToken: loginResult.connectionToken,
548
+ userEmail: loginResult.email,
549
+ userName: loginResult.name
456
550
  });
457
- console.log(
458
- "\nPlease install one of the above IDEs and run this wizard again."
459
- );
551
+ }
552
+ console.log(DIVIDER);
553
+ console.log(import_chalk.default.bold("\n\u{1F389} Setup Complete!\n"));
554
+ console.log(` ${import_chalk.default.bold("IDE:")} ${selectedIDE.icon} ${selectedIDE.displayName}`);
555
+ console.log(` ${import_chalk.default.bold("User:")} ${loginResult?.email || "not logged in"}`);
556
+ console.log(` ${import_chalk.default.bold("Status:")} ${import_chalk.default.green("Ready to connect")}`);
557
+ console.log();
558
+ }
559
+ async function customSetup() {
560
+ console.log(import_chalk.default.bold("\n\u{1F4CD} Step 1/4 \u2014 Detecting installed IDEs...\n"));
561
+ const spinner = (0, import_ora.default)("Scanning your system...").start();
562
+ const ides = await detectIDEs();
563
+ const installedIDEs = ides.filter((i) => i.installed);
564
+ spinner.stop();
565
+ if (installedIDEs.length === 0) {
566
+ console.log(import_chalk.default.yellow("\u26A0 No supported IDEs found."));
460
567
  return;
461
568
  }
462
- console.log(chalk.green(`Found ${installedIDEs.length} IDE(s):
569
+ console.log(import_chalk.default.green(`Found ${installedIDEs.length} IDE(s):
463
570
  `));
464
571
  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}`));
572
+ const version = ide.version ? import_chalk.default.gray(` v${ide.version}`) : "";
573
+ const cli = ide.cliCommand ? import_chalk.default.gray(` (CLI: \u2713)`) : import_chalk.default.yellow(` (CLI: \u2717 manual install)`);
574
+ console.log(` ${ide.icon} ${import_chalk.default.bold(ide.displayName)}${version}${cli}`);
468
575
  });
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
576
  console.log();
477
577
  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([
578
+ console.log(import_chalk.default.bold("\n\u{1F4CD} Step 2/4 \u2014 Select your primary IDE\n"));
579
+ const { selectedIdeId } = await import_inquirer.default.prompt([
480
580
  {
481
581
  type: "list",
482
582
  name: "selectedIdeId",
483
- message: "Which IDE do you want to set up with ADHDev?",
583
+ message: "Which IDE?",
484
584
  choices: installedIDEs.map((ide) => ({
485
- name: `${ide.icon} ${ide.displayName}${ide.version ? chalk.gray(` v${ide.version}`) : ""}`,
585
+ name: `${ide.icon} ${ide.displayName}${ide.version ? import_chalk.default.gray(` v${ide.version}`) : ""}`,
486
586
  value: ide.id
487
587
  }))
488
588
  }
489
589
  ]);
490
590
  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
591
  console.log(DIVIDER);
505
- console.log(chalk.bold("\n\u{1F4CD} Step 3/4 \u2014 Choose AI extensions to install\n"));
592
+ console.log(import_chalk.default.bold("\n\u{1F4CD} Step 3/4 \u2014 Choose AI extensions\n"));
506
593
  const aiExtensions = getAIExtensions();
507
- const { selectedExtIds } = await inquirer.prompt([
594
+ const { selectedExtIds } = await import_inquirer.default.prompt([
508
595
  {
509
596
  type: "checkbox",
510
597
  name: "selectedExtIds",
511
- message: "Select AI extensions to install:",
598
+ message: "Select AI extensions:",
512
599
  choices: aiExtensions.map((ext) => ({
513
- name: `${ext.icon} ${ext.displayName} \u2014 ${chalk.gray(ext.description)}${ext.requiresApiKey ? chalk.yellow(` (requires ${ext.apiKeyName})`) : ""}`,
600
+ name: `${ext.icon} ${ext.displayName} \u2014 ${import_chalk.default.gray(ext.description)}`,
514
601
  value: ext.id,
515
602
  checked: ext.recommended
516
- })),
517
- validate: (input) => {
518
- return true;
519
- }
603
+ }))
520
604
  }
521
605
  ]);
522
606
  const bridgeExt = EXTENSION_CATALOG.find((e) => e.category === "bridge");
523
- const selectedAIExts = aiExtensions.filter(
524
- (e) => selectedExtIds.includes(e.id)
525
- );
607
+ const selectedAIExts = aiExtensions.filter((e) => selectedExtIds.includes(e.id));
526
608
  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"));
609
+ console.log(import_chalk.default.bold("\n\u{1F4CD} Step 4/4 \u2014 Installing extensions\n"));
539
610
  if (selectedIDE.cliCommand) {
540
- const results = await installExtensions(
611
+ await installExtensions(
541
612
  selectedIDE,
542
613
  allExtensions,
543
614
  (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
- );
615
+ const status = result.alreadyInstalled ? import_chalk.default.blue("already installed") : result.success ? import_chalk.default.green("installed \u2713") : import_chalk.default.red(`failed \u2717`);
616
+ console.log(` [${current}/${total}] ${ext.icon} ${ext.displayName} \u2014 ${status}`);
548
617
  }
549
618
  );
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
619
  } 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:");
620
+ console.log(import_chalk.default.yellow("\u26A0 No CLI \u2014 install manually:"));
570
621
  allExtensions.forEach((ext) => {
571
- console.log(
572
- chalk.gray(` ${ext.icon} ${ext.displayName}: ${ext.marketplaceId}`)
573
- );
622
+ console.log(import_chalk.default.gray(` ${ext.icon} ${ext.displayName}: ${ext.marketplaceId}`));
574
623
  });
575
624
  }
576
625
  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
- );
626
+ const loginResult = await loginFlow();
627
+ if (loginResult?.connectionToken) {
628
+ await injectTokenToIDE(selectedIDE, loginResult.connectionToken);
629
+ }
630
+ markSetupComplete(selectedIdeId, allExtensions.map((e) => e.id));
631
+ if (loginResult) {
632
+ updateConfig({
633
+ connectionToken: loginResult.connectionToken,
634
+ userEmail: loginResult.email,
635
+ userName: loginResult.name
636
+ });
637
+ }
590
638
  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")}`);
639
+ console.log(import_chalk.default.bold("\n\u{1F389} Setup Complete!\n"));
640
+ console.log(` ${import_chalk.default.bold("IDE:")} ${selectedIDE.icon} ${selectedIDE.displayName}`);
641
+ console.log(` ${import_chalk.default.bold("Extensions:")} ${allExtensions.length} installed`);
642
+ console.log(` ${import_chalk.default.bold("User:")} ${loginResult?.email || "not logged in"}`);
643
+ console.log(` ${import_chalk.default.bold("Status:")} ${import_chalk.default.green("Ready to connect")}`);
595
644
  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([
645
+ const { shouldLaunch } = await import_inquirer.default.prompt([
602
646
  {
603
647
  type: "confirm",
604
648
  name: "shouldLaunch",
@@ -609,126 +653,198 @@ async function runWizard(options = {}) {
609
653
  if (shouldLaunch) {
610
654
  const launched = launchIDE(selectedIDE);
611
655
  if (launched) {
612
- console.log(
613
- chalk.green(`
614
- \u2713 ${selectedIDE.displayName} is starting...`)
615
- );
656
+ console.log(import_chalk.default.green(`
657
+ \u2713 ${selectedIDE.displayName} is starting...`));
658
+ } else {
659
+ console.log(import_chalk.default.yellow(`
660
+ \u26A0 Could not launch automatically.`));
661
+ }
662
+ }
663
+ console.log(import_chalk.default.gray("\nThank you for using ADHDev! \u{1F309}\n"));
664
+ }
665
+ async function loginFlow() {
666
+ console.log(import_chalk.default.bold("\n\u{1F510} Login to ADHDev\n"));
667
+ const { wantLogin } = await import_inquirer.default.prompt([
668
+ {
669
+ type: "confirm",
670
+ name: "wantLogin",
671
+ message: "Sign in to connect IDE to your ADHDev account?",
672
+ default: true
673
+ }
674
+ ]);
675
+ if (!wantLogin) return null;
676
+ const spinner = (0, import_ora.default)("Generating authentication code...").start();
677
+ let deviceCode;
678
+ let userCode;
679
+ let verificationUrl;
680
+ try {
681
+ const res = await fetch(`${SERVER_URL}/auth/cli/init`, { method: "POST" });
682
+ if (!res.ok) {
683
+ spinner.fail("Failed to connect to server");
684
+ return null;
685
+ }
686
+ const data = await res.json();
687
+ deviceCode = data.deviceCode;
688
+ userCode = data.userCode;
689
+ verificationUrl = data.verificationUrl;
690
+ spinner.stop();
691
+ } catch (e) {
692
+ spinner.fail(`Server error: ${e.message}`);
693
+ return null;
694
+ }
695
+ console.log();
696
+ console.log(import_chalk.default.cyan(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
697
+ console.log(import_chalk.default.cyan(" \u2502") + ` Your code: ${import_chalk.default.bold.white(userCode)} ` + import_chalk.default.cyan("\u2502"));
698
+ console.log(import_chalk.default.cyan(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));
699
+ console.log();
700
+ console.log(import_chalk.default.gray(` Opening: ${verificationUrl}`));
701
+ console.log();
702
+ try {
703
+ await (0, import_open.default)(verificationUrl);
704
+ console.log(import_chalk.default.green(" \u2713 Browser opened \u2014 please sign in and approve"));
705
+ } catch {
706
+ console.log(import_chalk.default.yellow(` \u26A0 Could not open browser. Visit: ${verificationUrl}`));
707
+ }
708
+ const pollSpinner = (0, import_ora.default)("Waiting for authentication...").start();
709
+ const startTime = Date.now();
710
+ const timeout = 3e5;
711
+ while (Date.now() - startTime < timeout) {
712
+ await new Promise((r) => setTimeout(r, 3e3));
713
+ try {
714
+ const res = await fetch(`${SERVER_URL}/auth/cli/poll`, {
715
+ method: "POST",
716
+ headers: { "Content-Type": "application/json" },
717
+ body: JSON.stringify({ deviceCode })
718
+ });
719
+ if (res.status === 410) {
720
+ pollSpinner.fail("Authentication code expired. Please try again.");
721
+ return null;
722
+ }
723
+ const data = await res.json();
724
+ if (data.status === "completed" && data.connectionToken) {
725
+ pollSpinner.succeed(`Authenticated as ${import_chalk.default.bold(data.user?.email || "user")}`);
726
+ return {
727
+ connectionToken: data.connectionToken,
728
+ email: data.user?.email,
729
+ name: data.user?.name
730
+ };
731
+ }
732
+ } catch {
733
+ }
734
+ }
735
+ pollSpinner.fail("Authentication timed out");
736
+ return null;
737
+ }
738
+ async function injectTokenToIDE(ide, connectionToken) {
739
+ if (!ide.cliCommand) return;
740
+ const { execSync: execSync3 } = await import("child_process");
741
+ try {
742
+ const settingsMap = {
743
+ vscode: `${(await import("os")).homedir()}/Library/Application Support/Code/User/settings.json`,
744
+ cursor: `${(await import("os")).homedir()}/Library/Application Support/Cursor/User/settings.json`,
745
+ antigravity: `${(await import("os")).homedir()}/Library/Application Support/Antigravity/User/settings.json`,
746
+ windsurf: `${(await import("os")).homedir()}/Library/Application Support/Windsurf/User/settings.json`
747
+ };
748
+ const settingsPath = settingsMap[ide.id];
749
+ if (!settingsPath) return;
750
+ const fs = await import("fs");
751
+ const path = await import("path");
752
+ let settings = {};
753
+ if (fs.existsSync(settingsPath)) {
754
+ try {
755
+ settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
756
+ } catch {
757
+ settings = {};
758
+ }
616
759
  } else {
617
- console.log(
618
- chalk.yellow(
619
- `
620
- \u26A0 Could not launch ${selectedIDE.displayName} automatically. Please open it manually.`
621
- )
622
- );
760
+ fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
623
761
  }
762
+ settings["adhdev.connectionToken"] = connectionToken;
763
+ settings["adhdev.autoConnect"] = true;
764
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 4), "utf-8");
765
+ console.log(import_chalk.default.green(" \u2713 Connection token saved to IDE settings"));
766
+ } catch (e) {
767
+ console.log(import_chalk.default.yellow(` \u26A0 Could not inject token: ${e.message}`));
768
+ console.log(import_chalk.default.gray(` You can set it manually: adhdev.connectionToken = ${connectionToken}`));
624
769
  }
625
- console.log(chalk.gray("\nThank you for using ADHDev! \u{1F309}\n"));
626
770
  }
627
771
  async function addExtensionsFlow() {
628
772
  const config = loadConfig();
629
773
  const ides = await detectIDEs();
630
774
  const selectedIDE = ides.find((i) => i.id === config.selectedIde);
631
775
  if (!selectedIDE || !selectedIDE.installed) {
632
- console.log(
633
- chalk.yellow("\u26A0 Previously selected IDE not found. Please reconfigure.")
634
- );
776
+ console.log(import_chalk.default.yellow("\u26A0 Previously selected IDE not found."));
635
777
  return;
636
778
  }
637
779
  const aiExtensions = getAIExtensions();
638
- const notInstalled = aiExtensions.filter(
639
- (e) => !config.installedExtensions.includes(e.id)
640
- );
780
+ const notInstalled = aiExtensions.filter((e) => !config.installedExtensions.includes(e.id));
641
781
  if (notInstalled.length === 0) {
642
- console.log(chalk.green("\u2713 All available extensions are already installed!"));
782
+ console.log(import_chalk.default.green("\u2713 All extensions already installed!"));
643
783
  return;
644
784
  }
645
- const { selectedExtIds } = await inquirer.prompt([
785
+ const { selectedExtIds } = await import_inquirer.default.prompt([
646
786
  {
647
787
  type: "checkbox",
648
788
  name: "selectedExtIds",
649
- message: "Select additional AI extensions to install:",
789
+ message: "Select extensions to install:",
650
790
  choices: notInstalled.map((ext) => ({
651
- name: `${ext.icon} ${ext.displayName} \u2014 ${chalk.gray(ext.description)}`,
791
+ name: `${ext.icon} ${ext.displayName}`,
652
792
  value: ext.id
653
793
  }))
654
794
  }
655
795
  ]);
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
- );
796
+ if (selectedExtIds.length === 0) return;
797
+ const extensions = notInstalled.filter((e) => selectedExtIds.includes(e.id));
798
+ await installExtensions(selectedIDE, extensions, (current, total, ext, result) => {
799
+ const status = result.success ? import_chalk.default.green("installed \u2713") : import_chalk.default.red("failed \u2717");
800
+ console.log(` [${current}/${total}] ${ext.icon} ${ext.displayName} \u2014 ${status}`);
801
+ });
673
802
  updateConfig({
674
- installedExtensions: [
675
- ...config.installedExtensions,
676
- ...selectedExtIds
677
- ]
803
+ installedExtensions: [...config.installedExtensions, ...selectedExtIds]
678
804
  });
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
- );
805
+ console.log(import_chalk.default.green("\n\u2713 Extensions added!"));
690
806
  }
691
807
 
692
808
  // src/index.ts
693
- var program = new Command();
809
+ var program = new import_commander.Command();
694
810
  program.name("adhdev").description("\u{1F309} ADHDev \u2014 Agent Dashboard Hub for your IDE").version("0.1.0");
695
811
  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
812
  await runWizard({ force: options.force });
697
813
  });
698
814
  program.command("status").description("Show current ADHDev setup status").action(() => {
699
815
  const config = loadConfig();
700
- console.log(chalk2.bold("\n\u{1F309} ADHDev Status\n"));
816
+ console.log(import_chalk2.default.bold("\n\u{1F309} ADHDev Status\n"));
701
817
  if (!config.setupCompleted) {
702
- console.log(chalk2.yellow(" Status: Not configured"));
703
- console.log(chalk2.gray(" Run `adhdev setup` to get started.\n"));
818
+ console.log(import_chalk2.default.yellow(" Status: Not configured"));
819
+ console.log(import_chalk2.default.gray(" Run `adhdev setup` to get started.\n"));
704
820
  return;
705
821
  }
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`);
822
+ console.log(` ${import_chalk2.default.bold("Status:")} ${import_chalk2.default.green("\u2713 Configured")}`);
823
+ console.log(` ${import_chalk2.default.bold("IDE:")} ${config.selectedIde || "none"}`);
824
+ console.log(` ${import_chalk2.default.bold("Extensions:")} ${config.installedExtensions.length} installed`);
709
825
  config.installedExtensions.forEach((ext) => {
710
- console.log(chalk2.gray(` \u2022 ${ext}`));
826
+ console.log(import_chalk2.default.gray(` \u2022 ${ext}`));
711
827
  });
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"}`);
828
+ console.log(` ${import_chalk2.default.bold("Auto-connect:")} ${config.autoConnect ? import_chalk2.default.green("enabled") : import_chalk2.default.gray("disabled")}`);
829
+ console.log(` ${import_chalk2.default.bold("Server:")} ${config.serverUrl}`);
830
+ console.log(` ${import_chalk2.default.bold("Setup date:")} ${config.setupDate || "unknown"}`);
715
831
  console.log();
716
832
  });
717
833
  program.command("detect").description("Detect installed IDEs on your system").action(async () => {
718
- console.log(chalk2.bold("\n\u{1F50D} Detecting installed IDEs...\n"));
834
+ console.log(import_chalk2.default.bold("\n\u{1F50D} Detecting installed IDEs...\n"));
719
835
  const ides = await detectIDEs();
720
836
  ides.forEach((ide) => {
721
837
  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}`);
838
+ const version = ide.version ? import_chalk2.default.gray(` v${ide.version}`) : "";
839
+ console.log(` ${import_chalk2.default.green("\u2713")} ${ide.icon} ${import_chalk2.default.bold(ide.displayName)}${version}`);
724
840
  if (ide.cliCommand) {
725
- console.log(chalk2.gray(` CLI: ${ide.cliCommand}`));
841
+ console.log(import_chalk2.default.gray(` CLI: ${ide.cliCommand}`));
726
842
  }
727
843
  if (ide.path) {
728
- console.log(chalk2.gray(` Path: ${ide.path}`));
844
+ console.log(import_chalk2.default.gray(` Path: ${ide.path}`));
729
845
  }
730
846
  } else {
731
- console.log(` ${chalk2.gray("\u2717")} ${ide.icon} ${chalk2.gray(ide.displayName)} \u2014 not found`);
847
+ console.log(` ${import_chalk2.default.gray("\u2717")} ${ide.icon} ${import_chalk2.default.gray(ide.displayName)} \u2014 not found`);
732
848
  }
733
849
  });
734
850
  console.log();
@@ -745,8 +861,8 @@ program.command("reset").description("Reset ADHDev configuration").action(async
745
861
  ]);
746
862
  if (confirm) {
747
863
  resetConfig();
748
- console.log(chalk2.green("\n\u2713 Configuration reset successfully."));
749
- console.log(chalk2.gray(" Run `adhdev setup` to reconfigure.\n"));
864
+ console.log(import_chalk2.default.green("\n\u2713 Configuration reset successfully."));
865
+ console.log(import_chalk2.default.gray(" Run `adhdev setup` to reconfigure.\n"));
750
866
  }
751
867
  });
752
868
  program.parse(process.argv);
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "adhdev",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "ADHDev CLI — Detect, install and configure your IDE + AI agent extensions",
5
- "type": "module",
5
+ "main": "dist/index.js",
6
6
  "bin": {
7
7
  "adhdev": "./dist/index.js"
8
8
  },
@@ -27,7 +27,7 @@
27
27
  "antigravity"
28
28
  ],
29
29
  "author": "vilmire",
30
- "license": "MIT",
30
+ "license": "UNLICENSED",
31
31
  "repository": {
32
32
  "type": "git",
33
33
  "url": "https://github.com/vilmire/adhdev.git",
@@ -50,4 +50,4 @@
50
50
  "@types/inquirer": "^9.0.0",
51
51
  "@types/node": "^22.0.0"
52
52
  }
53
- }
53
+ }