@hasna/connectors 1.1.8 → 1.1.9

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/index.js CHANGED
@@ -9471,8 +9471,7 @@ var require_cli_spinners = __commonJS((exports, module) => {
9471
9471
  });
9472
9472
 
9473
9473
  // src/lib/installer.ts
9474
- import { existsSync as existsSync2, cpSync, mkdirSync, readFileSync as readFileSync2, writeFileSync, readdirSync, statSync, rmSync } from "fs";
9475
- import { homedir } from "os";
9474
+ import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync, statSync } from "fs";
9476
9475
  import { join as join2, dirname as dirname2 } from "path";
9477
9476
  import { fileURLToPath as fileURLToPath2 } from "url";
9478
9477
  function resolveConnectorsDir() {
@@ -9488,11 +9487,7 @@ function getConnectorPath(name) {
9488
9487
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
9489
9488
  return join2(CONNECTORS_DIR, connectorName);
9490
9489
  }
9491
- function connectorExists(name) {
9492
- return existsSync2(getConnectorPath(name));
9493
- }
9494
9490
  function installConnector(name, options = {}) {
9495
- const { targetDir = process.cwd(), overwrite = false } = options;
9496
9491
  if (!/^[a-z0-9-]+$/.test(name)) {
9497
9492
  return {
9498
9493
  connector: name,
@@ -9500,10 +9495,7 @@ function installConnector(name, options = {}) {
9500
9495
  error: `Invalid connector name '${name}'`
9501
9496
  };
9502
9497
  }
9503
- const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
9504
9498
  const sourcePath = getConnectorPath(name);
9505
- const destDir = join2(targetDir, ".connectors");
9506
- const destPath = join2(destDir, connectorName);
9507
9499
  if (!existsSync2(sourcePath)) {
9508
9500
  return {
9509
9501
  connector: name,
@@ -9511,71 +9503,18 @@ function installConnector(name, options = {}) {
9511
9503
  error: `Connector '${name}' not found`
9512
9504
  };
9513
9505
  }
9514
- if (existsSync2(destPath) && !overwrite) {
9515
- return {
9516
- connector: name,
9517
- success: false,
9518
- error: `Already installed. Use --overwrite to replace.`,
9519
- path: destPath
9520
- };
9521
- }
9522
- try {
9523
- if (!existsSync2(destDir)) {
9524
- mkdirSync(destDir, { recursive: true });
9525
- }
9526
- cpSync(sourcePath, destPath, { recursive: true });
9527
- const homeCredDir = join2(homedir(), ".connectors", connectorName);
9528
- if (existsSync2(homeCredDir)) {
9529
- const filesToCopy = ["credentials.json", "current_profile"];
9530
- for (const file of filesToCopy) {
9531
- const src = join2(homeCredDir, file);
9532
- if (existsSync2(src)) {
9533
- cpSync(src, join2(destPath, file));
9534
- }
9535
- }
9536
- const profilesDir = join2(homeCredDir, "profiles");
9537
- if (existsSync2(profilesDir)) {
9538
- cpSync(profilesDir, join2(destPath, "profiles"), { recursive: true });
9539
- }
9540
- }
9541
- updateConnectorsIndex(destDir);
9542
- return {
9543
- connector: name,
9544
- success: true,
9545
- path: destPath
9546
- };
9547
- } catch (error) {
9548
- return {
9549
- connector: name,
9550
- success: false,
9551
- error: error instanceof Error ? error.message : "Unknown error"
9552
- };
9553
- }
9554
- }
9555
- function updateConnectorsIndex(connectorsDir) {
9556
- const indexPath = join2(connectorsDir, "index.ts");
9557
- const connectors = readdirSync(connectorsDir).filter((f) => f.startsWith("connect-") && !f.includes("."));
9558
- const exports = connectors.map((c) => {
9559
- const name = c.replace("connect-", "");
9560
- return `export * as ${name} from './${c}/src/index.js';`;
9561
- }).join(`
9562
- `);
9563
- const content = `/**
9564
- * Auto-generated index of installed connectors
9565
- * Do not edit manually - run 'connectors install' to update
9566
- */
9567
-
9568
- ${exports}
9569
- `;
9570
- writeFileSync(indexPath, content);
9506
+ return {
9507
+ connector: name,
9508
+ success: true,
9509
+ path: sourcePath
9510
+ };
9571
9511
  }
9572
- function getInstalledConnectors(targetDir = process.cwd()) {
9573
- const connectorsDir = join2(targetDir, ".connectors");
9574
- if (!existsSync2(connectorsDir)) {
9512
+ function getInstalledConnectors() {
9513
+ if (!existsSync2(CONNECTORS_DIR)) {
9575
9514
  return [];
9576
9515
  }
9577
- return readdirSync(connectorsDir).filter((f) => {
9578
- const fullPath = join2(connectorsDir, f);
9516
+ return readdirSync(CONNECTORS_DIR).filter((f) => {
9517
+ const fullPath = join2(CONNECTORS_DIR, f);
9579
9518
  return f.startsWith("connect-") && statSync(fullPath).isDirectory();
9580
9519
  }).map((f) => f.replace("connect-", ""));
9581
9520
  }
@@ -9621,16 +9560,8 @@ function parseEnvVarsTable(section) {
9621
9560
  }
9622
9561
  return vars;
9623
9562
  }
9624
- function removeConnector(name, targetDir = process.cwd()) {
9625
- const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
9626
- const connectorsDir = join2(targetDir, ".connectors");
9627
- const connectorPath = join2(connectorsDir, connectorName);
9628
- if (!existsSync2(connectorPath)) {
9629
- return false;
9630
- }
9631
- rmSync(connectorPath, { recursive: true });
9632
- updateConnectorsIndex(connectorsDir);
9633
- return true;
9563
+ function removeConnector(name) {
9564
+ return false;
9634
9565
  }
9635
9566
  var __dirname2, CONNECTORS_DIR;
9636
9567
  var init_installer = __esm(() => {
@@ -9639,9 +9570,9 @@ var init_installer = __esm(() => {
9639
9570
  });
9640
9571
 
9641
9572
  // src/server/auth.ts
9642
- import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2 } from "fs";
9573
+ import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync, mkdirSync, readdirSync as readdirSync2, rmSync, statSync as statSync2 } from "fs";
9643
9574
  import { randomBytes } from "crypto";
9644
- import { homedir as homedir2 } from "os";
9575
+ import { homedir } from "os";
9645
9576
  import { join as join3 } from "path";
9646
9577
  function getAuthType(name) {
9647
9578
  const docs = getConnectorDocs(name);
@@ -9656,7 +9587,7 @@ function getAuthType(name) {
9656
9587
  }
9657
9588
  function getConnectorConfigDir(name) {
9658
9589
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
9659
- return join3(homedir2(), ".connectors", connectorName);
9590
+ return join3(homedir(), ".connectors", connectorName);
9660
9591
  }
9661
9592
  function getCurrentProfile(name) {
9662
9593
  const configDir = getConnectorConfigDir(name);
@@ -9753,7 +9684,7 @@ function saveApiKey(name, key, field) {
9753
9684
  const keyField = field || guessKeyField(name);
9754
9685
  if (keyField === "clientId" || keyField === "clientSecret") {
9755
9686
  const credentialsFile = join3(configDir, "credentials.json");
9756
- mkdirSync2(configDir, { recursive: true });
9687
+ mkdirSync(configDir, { recursive: true });
9757
9688
  let creds = {};
9758
9689
  if (existsSync3(credentialsFile)) {
9759
9690
  try {
@@ -9761,7 +9692,7 @@ function saveApiKey(name, key, field) {
9761
9692
  } catch {}
9762
9693
  }
9763
9694
  creds[keyField] = key;
9764
- writeFileSync2(credentialsFile, JSON.stringify(creds, null, 2));
9695
+ writeFileSync(credentialsFile, JSON.stringify(creds, null, 2));
9765
9696
  return;
9766
9697
  }
9767
9698
  const profileFile = join3(configDir, "profiles", `${profile}.json`);
@@ -9772,7 +9703,7 @@ function saveApiKey(name, key, field) {
9772
9703
  config = JSON.parse(readFileSync3(profileFile, "utf-8"));
9773
9704
  } catch {}
9774
9705
  config[keyField] = key;
9775
- writeFileSync2(profileFile, JSON.stringify(config, null, 2));
9706
+ writeFileSync(profileFile, JSON.stringify(config, null, 2));
9776
9707
  return;
9777
9708
  }
9778
9709
  if (existsSync3(profileDir)) {
@@ -9784,11 +9715,11 @@ function saveApiKey(name, key, field) {
9784
9715
  } catch {}
9785
9716
  }
9786
9717
  config[keyField] = key;
9787
- writeFileSync2(configFile, JSON.stringify(config, null, 2));
9718
+ writeFileSync(configFile, JSON.stringify(config, null, 2));
9788
9719
  return;
9789
9720
  }
9790
- mkdirSync2(profileDir, { recursive: true });
9791
- writeFileSync2(join3(profileDir, "config.json"), JSON.stringify({ [keyField]: key }, null, 2));
9721
+ mkdirSync(profileDir, { recursive: true });
9722
+ writeFileSync(join3(profileDir, "config.json"), JSON.stringify({ [keyField]: key }, null, 2));
9792
9723
  }
9793
9724
  function guessKeyField(name) {
9794
9725
  const docs = getConnectorDocs(name);
@@ -9889,9 +9820,9 @@ function saveOAuthTokens(name, tokens) {
9889
9820
  const configDir = getConnectorConfigDir(name);
9890
9821
  const profile = getCurrentProfile(name);
9891
9822
  const profileDir = join3(configDir, "profiles", profile);
9892
- mkdirSync2(profileDir, { recursive: true });
9823
+ mkdirSync(profileDir, { recursive: true });
9893
9824
  const tokensFile = join3(profileDir, "tokens.json");
9894
- writeFileSync2(tokensFile, JSON.stringify(tokens, null, 2), { mode: 384 });
9825
+ writeFileSync(tokensFile, JSON.stringify(tokens, null, 2), { mode: 384 });
9895
9826
  }
9896
9827
  async function refreshOAuthToken(name) {
9897
9828
  const oauthConfig = getOAuthConfig(name);
@@ -9951,8 +9882,8 @@ function listProfiles(name) {
9951
9882
  }
9952
9883
  function switchProfile(name, profile) {
9953
9884
  const configDir = getConnectorConfigDir(name);
9954
- mkdirSync2(configDir, { recursive: true });
9955
- writeFileSync2(join3(configDir, "current_profile"), profile);
9885
+ mkdirSync(configDir, { recursive: true });
9886
+ writeFileSync(join3(configDir, "current_profile"), profile);
9956
9887
  }
9957
9888
  function deleteProfile(name, profile) {
9958
9889
  if (profile === "default")
@@ -9961,7 +9892,7 @@ function deleteProfile(name, profile) {
9961
9892
  const profilesDir = join3(configDir, "profiles");
9962
9893
  const profileFile = join3(profilesDir, `${profile}.json`);
9963
9894
  if (existsSync3(profileFile)) {
9964
- rmSync2(profileFile);
9895
+ rmSync(profileFile);
9965
9896
  if (getCurrentProfile(name) === profile) {
9966
9897
  switchProfile(name, "default");
9967
9898
  }
@@ -9969,7 +9900,7 @@ function deleteProfile(name, profile) {
9969
9900
  }
9970
9901
  const profileDir = join3(profilesDir, profile);
9971
9902
  if (existsSync3(profileDir)) {
9972
- rmSync2(profileDir, { recursive: true });
9903
+ rmSync(profileDir, { recursive: true });
9973
9904
  if (getCurrentProfile(name) === profile) {
9974
9905
  switchProfile(name, "default");
9975
9906
  }
@@ -10026,10 +9957,10 @@ var exports_serve = {};
10026
9957
  __export(exports_serve, {
10027
9958
  startServer: () => startServer
10028
9959
  });
10029
- import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
9960
+ import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
10030
9961
  import { join as join5, dirname as dirname4, extname, basename } from "path";
10031
9962
  import { fileURLToPath as fileURLToPath4 } from "url";
10032
- import { homedir as homedir3 } from "os";
9963
+ import { homedir as homedir2 } from "os";
10033
9964
  function logActivity(action, connector, detail) {
10034
9965
  activityLog.unshift({ action, connector, timestamp: Date.now(), detail });
10035
9966
  if (activityLog.length > MAX_ACTIVITY_LOG) {
@@ -10270,10 +10201,7 @@ Dashboard not found at: ${dashboardDir}`);
10270
10201
  if (!isValidConnectorName(name))
10271
10202
  return json({ error: "Invalid connector name" }, 400, port);
10272
10203
  try {
10273
- const removed = removeConnector(name);
10274
- if (!removed) {
10275
- return json({ error: `Connector '${name}' is not installed` }, 404, port);
10276
- }
10204
+ removeConnector(name);
10277
10205
  logActivity("uninstalled", name);
10278
10206
  return json({ success: true, name }, 200, port);
10279
10207
  } catch (e) {
@@ -10306,7 +10234,7 @@ Dashboard not found at: ${dashboardDir}`);
10306
10234
  return json({ error: "Invalid connector name" }, 400, port);
10307
10235
  try {
10308
10236
  const profiles = listProfiles(name);
10309
- const configDir = join5(homedir3(), ".connectors", name.startsWith("connect-") ? name : `connect-${name}`);
10237
+ const configDir = join5(homedir2(), ".connectors", name.startsWith("connect-") ? name : `connect-${name}`);
10310
10238
  const currentProfileFile = join5(configDir, "current_profile");
10311
10239
  let current = "default";
10312
10240
  if (existsSync5(currentProfileFile)) {
@@ -10358,7 +10286,7 @@ Dashboard not found at: ${dashboardDir}`);
10358
10286
  }
10359
10287
  if (path === "/api/export" && method === "GET") {
10360
10288
  try {
10361
- const connectDir = join5(homedir3(), ".connectors");
10289
+ const connectDir = join5(homedir2(), ".connectors");
10362
10290
  const result = {};
10363
10291
  if (existsSync5(connectDir)) {
10364
10292
  const entries = readdirSync3(connectDir, { withFileTypes: true });
@@ -10418,7 +10346,7 @@ Dashboard not found at: ${dashboardDir}`);
10418
10346
  return json({ error: "Invalid import format: missing 'connectors' object" }, 400, port);
10419
10347
  }
10420
10348
  let imported = 0;
10421
- const connectDir = join5(homedir3(), ".connectors");
10349
+ const connectDir = join5(homedir2(), ".connectors");
10422
10350
  for (const [connectorName, data] of Object.entries(body.connectors)) {
10423
10351
  if (!isValidConnectorName(connectorName))
10424
10352
  continue;
@@ -10429,9 +10357,9 @@ Dashboard not found at: ${dashboardDir}`);
10429
10357
  for (const [profileName, config] of Object.entries(data.profiles)) {
10430
10358
  if (!config || typeof config !== "object")
10431
10359
  continue;
10432
- mkdirSync3(profilesDir, { recursive: true });
10360
+ mkdirSync2(profilesDir, { recursive: true });
10433
10361
  const profileFile = join5(profilesDir, `${profileName}.json`);
10434
- writeFileSync3(profileFile, JSON.stringify(config, null, 2));
10362
+ writeFileSync2(profileFile, JSON.stringify(config, null, 2));
10435
10363
  imported++;
10436
10364
  }
10437
10365
  }
@@ -12034,8 +11962,8 @@ function App({ initialConnectors, overwrite = false }) {
12034
11962
  init_registry();
12035
11963
  init_installer();
12036
11964
  init_auth();
12037
- import { readdirSync as readdirSync4, existsSync as existsSync6, statSync as statSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4 } from "fs";
12038
- import { homedir as homedir4 } from "os";
11965
+ import { readdirSync as readdirSync4, existsSync as existsSync6, statSync as statSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
11966
+ import { homedir as homedir3 } from "os";
12039
11967
  import { join as join6, relative } from "path";
12040
11968
 
12041
11969
  // src/lib/test-endpoints.ts
@@ -12381,7 +12309,7 @@ var PRESETS = {
12381
12309
  commerce: { description: "Commerce and finance", connectors: ["stripe", "shopify", "revolut", "mercury", "pandadoc"] }
12382
12310
  };
12383
12311
  var program2 = new Command;
12384
- program2.name("connectors").description("Install API connectors for your project").version("1.1.8").enablePositionalOptions();
12312
+ program2.name("connectors").description("Install API connectors for your project").version("1.1.9").enablePositionalOptions();
12385
12313
  program2.command("interactive", { isDefault: true }).alias("i").description("Interactive connector browser").action(() => {
12386
12314
  if (!isTTY) {
12387
12315
  console.log(`Non-interactive environment detected. Use a subcommand:
@@ -12411,7 +12339,7 @@ function listFilesRecursive(dir, base = dir) {
12411
12339
  }
12412
12340
  return files;
12413
12341
  }
12414
- program2.command("install").alias("add").argument("[connectors...]", "Connectors to install").option("-o, --overwrite", "Overwrite existing connectors", false).option("-d, --dry-run", "Preview what would be installed without making changes", false).option("-c, --category <category>", "Install all connectors in a category").option("--preset <preset>", "Install a preset bundle (e.g. ai, fullstack, google)").option("--json", "Output results as JSON", false).description("Install one or more connectors").action((connectors, options) => {
12342
+ program2.command("install").alias("add").argument("[connectors...]", "Connectors to verify").option("-c, --category <category>", "Verify all connectors in a category").option("--preset <preset>", "Verify a preset bundle (e.g. ai, fullstack, google)").option("--json", "Output results as JSON", false).description("Verify connectors are available in the global package").action((connectors, options) => {
12415
12343
  if (options.category) {
12416
12344
  const category = CATEGORIES.find((c) => c.toLowerCase() === options.category.toLowerCase());
12417
12345
  if (!category) {
@@ -12424,8 +12352,7 @@ program2.command("install").alias("add").argument("[connectors...]", "Connectors
12424
12352
  process.exit(1);
12425
12353
  return;
12426
12354
  }
12427
- const categoryConnectors = getConnectorsByCategory(category).map((c) => c.name);
12428
- connectors.push(...categoryConnectors);
12355
+ connectors.push(...getConnectorsByCategory(category).map((c) => c.name));
12429
12356
  }
12430
12357
  if (options.preset) {
12431
12358
  const preset = PRESETS[options.preset.toLowerCase()];
@@ -12443,133 +12370,25 @@ program2.command("install").alias("add").argument("[connectors...]", "Connectors
12443
12370
  }
12444
12371
  if (connectors.length === 0) {
12445
12372
  if (!isTTY) {
12446
- console.error("Error: specify connectors to install. Example: connectors install figma stripe");
12373
+ console.error("Error: specify connectors to verify. Example: connectors install figma stripe");
12447
12374
  process.exit(1);
12448
12375
  }
12449
12376
  render(/* @__PURE__ */ jsxDEV7(App, {}, undefined, false, undefined, this));
12450
12377
  return;
12451
12378
  }
12452
- if (options.dryRun) {
12453
- const installed = getInstalledConnectors();
12454
- const destDir = join6(process.cwd(), ".connectors");
12455
- const actions = [];
12456
- for (const name of connectors) {
12457
- if (!/^[a-z0-9-]+$/.test(name)) {
12458
- actions.push({ connector: name, action: "error", reason: `Invalid connector name '${name}'` });
12459
- continue;
12460
- }
12461
- const meta = getConnector(name);
12462
- if (!meta) {
12463
- actions.push({ connector: name, action: "error", reason: `Connector '${name}' not found in registry` });
12464
- continue;
12465
- }
12466
- if (!connectorExists(name)) {
12467
- actions.push({ connector: name, action: "error", reason: `Connector '${name}' source files not found` });
12468
- continue;
12469
- }
12470
- const connectorDirName = name.startsWith("connect-") ? name : `connect-${name}`;
12471
- const sourcePath = getConnectorPath(name);
12472
- const destPath = join6(destDir, connectorDirName);
12473
- const alreadyInstalled = installed.includes(name);
12474
- const files = listFilesRecursive(sourcePath);
12475
- const importLine = `export * as ${name} from './${connectorDirName}/src/index.js';`;
12476
- if (alreadyInstalled && !options.overwrite) {
12477
- actions.push({
12478
- connector: name,
12479
- action: "skip",
12480
- reason: "Already installed. Use --overwrite to replace.",
12481
- sourcePath,
12482
- destPath
12483
- });
12484
- } else {
12485
- actions.push({
12486
- connector: name,
12487
- action: alreadyInstalled ? "overwrite" : "install",
12488
- sourcePath,
12489
- destPath,
12490
- files,
12491
- importLine
12492
- });
12493
- }
12494
- }
12495
- if (options.json) {
12496
- console.log(JSON.stringify({ dryRun: true, actions }, null, 2));
12497
- process.exit(actions.every((a) => a.action !== "error") ? 0 : 1);
12498
- return;
12499
- }
12500
- console.log(chalk2.bold(`
12501
- Dry run \u2014 no changes will be made
12502
- `));
12503
- for (const a of actions) {
12504
- if (a.action === "error") {
12505
- console.log(chalk2.red(` \u2717 ${a.connector}: ${a.reason}`));
12506
- continue;
12507
- }
12508
- if (a.action === "skip") {
12509
- console.log(chalk2.yellow(` \u2298 ${a.connector}: ${a.reason}`));
12510
- continue;
12511
- }
12512
- const actionLabel = a.action === "overwrite" ? chalk2.yellow("overwrite") : chalk2.green("install");
12513
- console.log(` ${actionLabel} ${chalk2.cyan(a.connector)}`);
12514
- console.log(chalk2.dim(` source: ${a.sourcePath}`));
12515
- console.log(chalk2.dim(` dest: ${a.destPath}`));
12516
- if (a.files && a.files.length > 0) {
12517
- console.log(chalk2.dim(` files (${a.files.length}):`));
12518
- for (const f of a.files) {
12519
- console.log(chalk2.dim(` ${f}`));
12520
- }
12521
- }
12522
- if (a.importLine) {
12523
- console.log(` ${chalk2.dim("index.ts:")} ${a.importLine}`);
12524
- }
12525
- console.log();
12526
- }
12527
- const installCount = actions.filter((a) => a.action === "install").length;
12528
- const overwriteCount = actions.filter((a) => a.action === "overwrite").length;
12529
- const skipCount = actions.filter((a) => a.action === "skip").length;
12530
- const errorCount = actions.filter((a) => a.action === "error").length;
12531
- const parts = [];
12532
- if (installCount)
12533
- parts.push(chalk2.green(`${installCount} to install`));
12534
- if (overwriteCount)
12535
- parts.push(chalk2.yellow(`${overwriteCount} to overwrite`));
12536
- if (skipCount)
12537
- parts.push(chalk2.yellow(`${skipCount} skipped`));
12538
- if (errorCount)
12539
- parts.push(chalk2.red(`${errorCount} failed`));
12540
- console.log(` ${chalk2.bold("Summary:")} ${parts.join(", ")}`);
12541
- console.log(chalk2.dim(`
12542
- Run without --dry-run to apply.
12543
- `));
12544
- process.exit(errorCount > 0 ? 1 : 0);
12545
- return;
12546
- }
12547
- const results = connectors.map((name) => installConnector(name, { overwrite: options.overwrite }));
12379
+ const results = connectors.map((name) => installConnector(name));
12548
12380
  if (options.json) {
12549
12381
  console.log(JSON.stringify(results, null, 2));
12550
12382
  process.exit(results.every((r) => r.success) ? 0 : 1);
12551
12383
  return;
12552
12384
  }
12553
- console.log(chalk2.bold(`
12554
- Installing connectors...
12555
- `));
12556
- const succeeded = [];
12557
12385
  for (const result of results) {
12558
12386
  if (result.success) {
12559
- console.log(chalk2.green(`\u2713 ${result.connector}`));
12560
- succeeded.push(result.connector);
12387
+ console.log(chalk2.green(`\u2713 ${result.connector}`) + chalk2.dim(` \u2014 available at ${result.path}`));
12561
12388
  } else {
12562
12389
  console.log(chalk2.red(`\u2717 ${result.connector}: ${result.error}`));
12563
12390
  }
12564
12391
  }
12565
- if (succeeded.length > 0) {
12566
- console.log(chalk2.bold(`
12567
- Next steps:`));
12568
- const importNames = succeeded.join(", ");
12569
- console.log(chalk2.dim(` 1. Import: `) + `import { ${importNames} } from './.connectors'`);
12570
- console.log(chalk2.dim(` 2. Set key: `) + `connectors docs ${succeeded[0]}` + chalk2.dim(` (see env vars)`));
12571
- console.log(chalk2.dim(` 3. Explore: `) + `connectors serve` + chalk2.dim(` (dashboard for auth management)`));
12572
- }
12573
12392
  process.exit(results.every((r) => r.success) ? 0 : 1);
12574
12393
  });
12575
12394
  program2.command("list").alias("ls").option("-c, --category <category>", "Filter by category").option("-a, --all", "Show all available connectors", false).option("-i, --installed", "Show only installed connectors", false).option("-b, --brief", "Output only connector names", false).option("--json", "Output as JSON", false).description("List available or installed connectors").action((options) => {
@@ -12973,7 +12792,7 @@ Updating ${toUpdate.length} connector(s)...
12973
12792
  });
12974
12793
  program2.command("status").option("--json", "Output as JSON", false).description("Show auth status of all configured connectors (project + global)").action((options) => {
12975
12794
  const installed = getInstalledConnectors();
12976
- const configDir = join6(homedir4(), ".connectors");
12795
+ const configDir = join6(homedir3(), ".connectors");
12977
12796
  const seen = new Set;
12978
12797
  const allStatuses = [];
12979
12798
  function buildStatusEntry(name, source) {
@@ -13390,7 +13209,7 @@ program2.command("init").option("--json", "Output presets and suggestions as JSO
13390
13209
  { key: "commerce", emoji: "\uD83D\uDCB3", label: "Commerce", connectors: ["stripe", "shopify", "paypal", "revolut", "mercury"], description: "Commerce and finance" },
13391
13210
  { key: "google", emoji: "\uD83D\uDCC1", label: "Google Workspace", connectors: ["gmail", "googledrive", "googlecalendar", "googledocs", "googlesheets"], description: "Google Workspace suite" }
13392
13211
  ];
13393
- const connectorsHome = join6(homedir4(), ".connectors");
13212
+ const connectorsHome = join6(homedir3(), ".connectors");
13394
13213
  let configuredCount = 0;
13395
13214
  const configuredNames = [];
13396
13215
  try {
@@ -13496,7 +13315,7 @@ function redactSecrets(obj) {
13496
13315
  return obj;
13497
13316
  }
13498
13317
  program2.command("export").option("-o, --output <file>", "Write to file instead of stdout").option("--include-secrets", "Include secrets in plaintext (dangerous \u2014 use only for backup/restore)").description("Export all connector credentials as JSON backup").action((options) => {
13499
- const connectDir = join6(homedir4(), ".connectors");
13318
+ const connectDir = join6(homedir3(), ".connectors");
13500
13319
  const result = {};
13501
13320
  if (existsSync6(connectDir)) {
13502
13321
  for (const entry of readdirSync4(connectDir)) {
@@ -13554,7 +13373,7 @@ program2.command("export").option("-o, --output <file>", "Write to file instead
13554
13373
  }
13555
13374
  const exportData = JSON.stringify(exportPayload, null, 2);
13556
13375
  if (options.output) {
13557
- writeFileSync4(options.output, exportData);
13376
+ writeFileSync3(options.output, exportData);
13558
13377
  console.log(chalk2.green(`\u2713 Exported to ${options.output}`));
13559
13378
  } else {
13560
13379
  console.log(exportData);
@@ -13600,15 +13419,15 @@ program2.command("import").argument("<file>", "JSON backup file to import (use -
13600
13419
  process.exit(1);
13601
13420
  return;
13602
13421
  }
13603
- const connectDir = join6(homedir4(), ".connectors");
13422
+ const connectDir = join6(homedir3(), ".connectors");
13604
13423
  let imported = 0;
13605
13424
  for (const [connectorName, connData] of Object.entries(data.connectors)) {
13606
13425
  if (!/^[a-z0-9-]+$/.test(connectorName))
13607
13426
  continue;
13608
13427
  const connectorDir = join6(connectDir, `connect-${connectorName}`);
13609
13428
  if (connData.credentials && typeof connData.credentials === "object") {
13610
- mkdirSync4(connectorDir, { recursive: true });
13611
- writeFileSync4(join6(connectorDir, "credentials.json"), JSON.stringify(connData.credentials, null, 2));
13429
+ mkdirSync3(connectorDir, { recursive: true });
13430
+ writeFileSync3(join6(connectorDir, "credentials.json"), JSON.stringify(connData.credentials, null, 2));
13612
13431
  imported++;
13613
13432
  }
13614
13433
  if (!connData.profiles || typeof connData.profiles !== "object")
@@ -13617,8 +13436,8 @@ program2.command("import").argument("<file>", "JSON backup file to import (use -
13617
13436
  for (const [profileName, config] of Object.entries(connData.profiles)) {
13618
13437
  if (!config || typeof config !== "object")
13619
13438
  continue;
13620
- mkdirSync4(profilesDir, { recursive: true });
13621
- writeFileSync4(join6(profilesDir, `${profileName}.json`), JSON.stringify(config, null, 2));
13439
+ mkdirSync3(profilesDir, { recursive: true });
13440
+ writeFileSync3(join6(profilesDir, `${profileName}.json`), JSON.stringify(config, null, 2));
13622
13441
  imported++;
13623
13442
  }
13624
13443
  }
@@ -13629,8 +13448,8 @@ program2.command("import").argument("<file>", "JSON backup file to import (use -
13629
13448
  }
13630
13449
  });
13631
13450
  program2.command("auth-import").option("--json", "Output as JSON", false).option("-d, --dry-run", "Preview what would be imported without copying", false).option("--force", "Overwrite existing files in ~/.connectors/", false).description("Migrate auth tokens from ~/.connect/ to ~/.connectors/").action((options) => {
13632
- const oldBase = join6(homedir4(), ".connect");
13633
- const newBase = join6(homedir4(), ".connectors");
13451
+ const oldBase = join6(homedir3(), ".connect");
13452
+ const newBase = join6(homedir3(), ".connectors");
13634
13453
  if (!existsSync6(oldBase)) {
13635
13454
  if (options.json) {
13636
13455
  console.log(JSON.stringify({ imported: [], skipped: [], error: null, message: "No ~/.connect/ directory found" }));
@@ -13679,9 +13498,9 @@ program2.command("auth-import").option("--json", "Output as JSON", false).option
13679
13498
  }
13680
13499
  if (!options.dryRun) {
13681
13500
  const parentDir = join6(destPath, "..");
13682
- mkdirSync4(parentDir, { recursive: true });
13501
+ mkdirSync3(parentDir, { recursive: true });
13683
13502
  const content = readFileSync5(srcPath);
13684
- writeFileSync4(destPath, content);
13503
+ writeFileSync3(destPath, content);
13685
13504
  }
13686
13505
  copiedFiles.push(relFile);
13687
13506
  }
@@ -13926,7 +13745,7 @@ program2.command("env").option("-o, --output <file>", "Write to file instead of
13926
13745
  `) + `
13927
13746
  `;
13928
13747
  if (options.output) {
13929
- writeFileSync4(options.output, output);
13748
+ writeFileSync3(options.output, output);
13930
13749
  console.log(chalk2.green(`\u2713 Written to ${options.output} (${vars.length} variables)`));
13931
13750
  } else {
13932
13751
  console.log(output);
@@ -13954,7 +13773,7 @@ Available presets:
13954
13773
  `));
13955
13774
  });
13956
13775
  program2.command("whoami").option("--json", "Output as JSON", false).description("Show current setup: config dir, installed connectors, auth status").action((options) => {
13957
- const configDir = join6(homedir4(), ".connectors");
13776
+ const configDir = join6(homedir3(), ".connectors");
13958
13777
  const installed = getInstalledConnectors();
13959
13778
  const version = "0.3.1";
13960
13779
  let configured = 0;
@@ -14115,7 +13934,7 @@ Testing connector credentials...
14115
13934
  }
14116
13935
  }
14117
13936
  if (!apiKey) {
14118
- const connectorConfigDir = join6(homedir4(), ".connectors", name.startsWith("connect-") ? name : `connect-${name}`);
13937
+ const connectorConfigDir = join6(homedir3(), ".connectors", name.startsWith("connect-") ? name : `connect-${name}`);
14119
13938
  let currentProfile = "default";
14120
13939
  const currentProfileFile = join6(connectorConfigDir, "current_profile");
14121
13940
  if (existsSync6(currentProfileFile)) {
package/bin/mcp.js CHANGED
@@ -25351,8 +25351,7 @@ function loadConnectorVersions() {
25351
25351
  }
25352
25352
 
25353
25353
  // src/lib/installer.ts
25354
- import { existsSync as existsSync2, cpSync, mkdirSync, readFileSync as readFileSync2, writeFileSync, readdirSync, statSync, rmSync } from "fs";
25355
- import { homedir } from "os";
25354
+ import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync, statSync } from "fs";
25356
25355
  import { join as join2, dirname as dirname2 } from "path";
25357
25356
  import { fileURLToPath as fileURLToPath2 } from "url";
25358
25357
  var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
@@ -25371,7 +25370,6 @@ function getConnectorPath(name) {
25371
25370
  return join2(CONNECTORS_DIR, connectorName);
25372
25371
  }
25373
25372
  function installConnector(name, options = {}) {
25374
- const { targetDir = process.cwd(), overwrite = false } = options;
25375
25373
  if (!/^[a-z0-9-]+$/.test(name)) {
25376
25374
  return {
25377
25375
  connector: name,
@@ -25379,10 +25377,7 @@ function installConnector(name, options = {}) {
25379
25377
  error: `Invalid connector name '${name}'`
25380
25378
  };
25381
25379
  }
25382
- const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
25383
25380
  const sourcePath = getConnectorPath(name);
25384
- const destDir = join2(targetDir, ".connectors");
25385
- const destPath = join2(destDir, connectorName);
25386
25381
  if (!existsSync2(sourcePath)) {
25387
25382
  return {
25388
25383
  connector: name,
@@ -25390,71 +25385,18 @@ function installConnector(name, options = {}) {
25390
25385
  error: `Connector '${name}' not found`
25391
25386
  };
25392
25387
  }
25393
- if (existsSync2(destPath) && !overwrite) {
25394
- return {
25395
- connector: name,
25396
- success: false,
25397
- error: `Already installed. Use --overwrite to replace.`,
25398
- path: destPath
25399
- };
25400
- }
25401
- try {
25402
- if (!existsSync2(destDir)) {
25403
- mkdirSync(destDir, { recursive: true });
25404
- }
25405
- cpSync(sourcePath, destPath, { recursive: true });
25406
- const homeCredDir = join2(homedir(), ".connectors", connectorName);
25407
- if (existsSync2(homeCredDir)) {
25408
- const filesToCopy = ["credentials.json", "current_profile"];
25409
- for (const file of filesToCopy) {
25410
- const src = join2(homeCredDir, file);
25411
- if (existsSync2(src)) {
25412
- cpSync(src, join2(destPath, file));
25413
- }
25414
- }
25415
- const profilesDir = join2(homeCredDir, "profiles");
25416
- if (existsSync2(profilesDir)) {
25417
- cpSync(profilesDir, join2(destPath, "profiles"), { recursive: true });
25418
- }
25419
- }
25420
- updateConnectorsIndex(destDir);
25421
- return {
25422
- connector: name,
25423
- success: true,
25424
- path: destPath
25425
- };
25426
- } catch (error2) {
25427
- return {
25428
- connector: name,
25429
- success: false,
25430
- error: error2 instanceof Error ? error2.message : "Unknown error"
25431
- };
25432
- }
25433
- }
25434
- function updateConnectorsIndex(connectorsDir) {
25435
- const indexPath = join2(connectorsDir, "index.ts");
25436
- const connectors = readdirSync(connectorsDir).filter((f) => f.startsWith("connect-") && !f.includes("."));
25437
- const exports = connectors.map((c) => {
25438
- const name = c.replace("connect-", "");
25439
- return `export * as ${name} from './${c}/src/index.js';`;
25440
- }).join(`
25441
- `);
25442
- const content = `/**
25443
- * Auto-generated index of installed connectors
25444
- * Do not edit manually - run 'connectors install' to update
25445
- */
25446
-
25447
- ${exports}
25448
- `;
25449
- writeFileSync(indexPath, content);
25388
+ return {
25389
+ connector: name,
25390
+ success: true,
25391
+ path: sourcePath
25392
+ };
25450
25393
  }
25451
- function getInstalledConnectors(targetDir = process.cwd()) {
25452
- const connectorsDir = join2(targetDir, ".connectors");
25453
- if (!existsSync2(connectorsDir)) {
25394
+ function getInstalledConnectors() {
25395
+ if (!existsSync2(CONNECTORS_DIR)) {
25454
25396
  return [];
25455
25397
  }
25456
- return readdirSync(connectorsDir).filter((f) => {
25457
- const fullPath = join2(connectorsDir, f);
25398
+ return readdirSync(CONNECTORS_DIR).filter((f) => {
25399
+ const fullPath = join2(CONNECTORS_DIR, f);
25458
25400
  return f.startsWith("connect-") && statSync(fullPath).isDirectory();
25459
25401
  }).map((f) => f.replace("connect-", ""));
25460
25402
  }
@@ -25500,21 +25442,13 @@ function parseEnvVarsTable(section) {
25500
25442
  }
25501
25443
  return vars;
25502
25444
  }
25503
- function removeConnector(name, targetDir = process.cwd()) {
25504
- const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
25505
- const connectorsDir = join2(targetDir, ".connectors");
25506
- const connectorPath = join2(connectorsDir, connectorName);
25507
- if (!existsSync2(connectorPath)) {
25508
- return false;
25509
- }
25510
- rmSync(connectorPath, { recursive: true });
25511
- updateConnectorsIndex(connectorsDir);
25512
- return true;
25445
+ function removeConnector(name) {
25446
+ return false;
25513
25447
  }
25514
25448
 
25515
25449
  // src/server/auth.ts
25516
- import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2 } from "fs";
25517
- import { homedir as homedir2 } from "os";
25450
+ import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync, mkdirSync, readdirSync as readdirSync2, rmSync, statSync as statSync2 } from "fs";
25451
+ import { homedir } from "os";
25518
25452
  import { join as join3 } from "path";
25519
25453
  var oauthStateStore = new Map;
25520
25454
  var GOOGLE_SCOPES = {
@@ -25568,7 +25502,7 @@ function getAuthType(name) {
25568
25502
  }
25569
25503
  function getConnectorConfigDir(name) {
25570
25504
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
25571
- return join3(homedir2(), ".connectors", connectorName);
25505
+ return join3(homedir(), ".connectors", connectorName);
25572
25506
  }
25573
25507
  function getCurrentProfile(name) {
25574
25508
  const configDir = getConnectorConfigDir(name);
@@ -25661,7 +25595,7 @@ function saveApiKey(name, key, field) {
25661
25595
  const keyField = field || guessKeyField(name);
25662
25596
  if (keyField === "clientId" || keyField === "clientSecret") {
25663
25597
  const credentialsFile = join3(configDir, "credentials.json");
25664
- mkdirSync2(configDir, { recursive: true });
25598
+ mkdirSync(configDir, { recursive: true });
25665
25599
  let creds = {};
25666
25600
  if (existsSync3(credentialsFile)) {
25667
25601
  try {
@@ -25669,7 +25603,7 @@ function saveApiKey(name, key, field) {
25669
25603
  } catch {}
25670
25604
  }
25671
25605
  creds[keyField] = key;
25672
- writeFileSync2(credentialsFile, JSON.stringify(creds, null, 2));
25606
+ writeFileSync(credentialsFile, JSON.stringify(creds, null, 2));
25673
25607
  return;
25674
25608
  }
25675
25609
  const profileFile = join3(configDir, "profiles", `${profile}.json`);
@@ -25680,7 +25614,7 @@ function saveApiKey(name, key, field) {
25680
25614
  config2 = JSON.parse(readFileSync3(profileFile, "utf-8"));
25681
25615
  } catch {}
25682
25616
  config2[keyField] = key;
25683
- writeFileSync2(profileFile, JSON.stringify(config2, null, 2));
25617
+ writeFileSync(profileFile, JSON.stringify(config2, null, 2));
25684
25618
  return;
25685
25619
  }
25686
25620
  if (existsSync3(profileDir)) {
@@ -25692,11 +25626,11 @@ function saveApiKey(name, key, field) {
25692
25626
  } catch {}
25693
25627
  }
25694
25628
  config2[keyField] = key;
25695
- writeFileSync2(configFile, JSON.stringify(config2, null, 2));
25629
+ writeFileSync(configFile, JSON.stringify(config2, null, 2));
25696
25630
  return;
25697
25631
  }
25698
- mkdirSync2(profileDir, { recursive: true });
25699
- writeFileSync2(join3(profileDir, "config.json"), JSON.stringify({ [keyField]: key }, null, 2));
25632
+ mkdirSync(profileDir, { recursive: true });
25633
+ writeFileSync(join3(profileDir, "config.json"), JSON.stringify({ [keyField]: key }, null, 2));
25700
25634
  }
25701
25635
  function guessKeyField(name) {
25702
25636
  const docs = getConnectorDocs(name);
@@ -25849,7 +25783,7 @@ async function getConnectorCommandHelp(name, command) {
25849
25783
  loadConnectorVersions();
25850
25784
  var server = new McpServer({
25851
25785
  name: "connectors",
25852
- version: "1.1.8"
25786
+ version: "1.1.9"
25853
25787
  });
25854
25788
  server.registerTool("search_connectors", {
25855
25789
  title: "Search Connectors",
@@ -25947,14 +25881,14 @@ server.registerTool("connector_docs", {
25947
25881
  });
25948
25882
  server.registerTool("install_connector", {
25949
25883
  title: "Install Connector",
25950
- description: "Install connectors into .connectors/.",
25884
+ description: "Verify connectors are available in the global package.",
25951
25885
  inputSchema: {
25952
25886
  names: exports_external.array(exports_external.string()),
25953
25887
  overwrite: exports_external.boolean().optional()
25954
25888
  }
25955
- }, async ({ names, overwrite }) => {
25956
- const results = names.map((name) => installConnector(name, { overwrite: overwrite ?? false }));
25957
- const summary = results.map((r) => r.success ? `\u2713 ${r.connector} \u2192 ${r.path}` : `\u2717 ${r.connector}: ${r.error}`);
25889
+ }, async ({ names }) => {
25890
+ const results = names.map((name) => installConnector(name));
25891
+ const summary = results.map((r) => r.success ? `\u2713 ${r.connector} available at ${r.path}` : `\u2717 ${r.connector}: ${r.error}`);
25958
25892
  return {
25959
25893
  content: [
25960
25894
  {
@@ -25962,8 +25896,7 @@ server.registerTool("install_connector", {
25962
25896
  text: JSON.stringify({
25963
25897
  results,
25964
25898
  summary: summary.join(`
25965
- `),
25966
- usage: results.some((r) => r.success) ? "Import from './.connectors': import { " + results.filter((r) => r.success).map((r) => r.connector).join(", ") + " } from './.connectors'" : undefined
25899
+ `)
25967
25900
  }, null, 2)
25968
25901
  }
25969
25902
  ]
@@ -25971,22 +25904,22 @@ server.registerTool("install_connector", {
25971
25904
  });
25972
25905
  server.registerTool("remove_connector", {
25973
25906
  title: "Remove Connector",
25974
- description: "Remove an installed connector.",
25907
+ description: "Remove connector auth/credentials from ~/.connectors/. Does not remove the connector from the global package.",
25975
25908
  inputSchema: { name: exports_external.string() }
25976
25909
  }, async ({ name }) => {
25977
- const removed = removeConnector(name);
25910
+ removeConnector(name);
25978
25911
  return {
25979
25912
  content: [
25980
25913
  {
25981
25914
  type: "text",
25982
- text: JSON.stringify({ name, removed })
25915
+ text: JSON.stringify({ name, message: "Connector auth can be cleared with configure_auth. The connector itself is part of the global package." })
25983
25916
  }
25984
25917
  ]
25985
25918
  };
25986
25919
  });
25987
25920
  server.registerTool("list_installed", {
25988
25921
  title: "List Installed Connectors",
25989
- description: "List connectors installed in .connectors/.",
25922
+ description: "List all connectors available in the global package.",
25990
25923
  inputSchema: {}
25991
25924
  }, async () => {
25992
25925
  const installed = getInstalledConnectors();
package/bin/serve.js CHANGED
@@ -3,10 +3,10 @@
3
3
  var __require = import.meta.require;
4
4
 
5
5
  // src/server/serve.ts
6
- import { existsSync as existsSync4, readdirSync as readdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
6
+ import { existsSync as existsSync4, readdirSync as readdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
7
7
  import { join as join4, dirname as dirname3, extname, basename } from "path";
8
8
  import { fileURLToPath as fileURLToPath3 } from "url";
9
- import { homedir as homedir3 } from "os";
9
+ import { homedir as homedir2 } from "os";
10
10
 
11
11
  // src/lib/registry.ts
12
12
  import { existsSync, readFileSync } from "fs";
@@ -5943,8 +5943,7 @@ function loadConnectorVersions() {
5943
5943
  }
5944
5944
 
5945
5945
  // src/lib/installer.ts
5946
- import { existsSync as existsSync2, cpSync, mkdirSync, readFileSync as readFileSync2, writeFileSync, readdirSync, statSync, rmSync } from "fs";
5947
- import { homedir } from "os";
5946
+ import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync, statSync } from "fs";
5948
5947
  import { join as join2, dirname as dirname2 } from "path";
5949
5948
  import { fileURLToPath as fileURLToPath2 } from "url";
5950
5949
  var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
@@ -5963,7 +5962,6 @@ function getConnectorPath(name) {
5963
5962
  return join2(CONNECTORS_DIR, connectorName);
5964
5963
  }
5965
5964
  function installConnector(name, options = {}) {
5966
- const { targetDir = process.cwd(), overwrite = false } = options;
5967
5965
  if (!/^[a-z0-9-]+$/.test(name)) {
5968
5966
  return {
5969
5967
  connector: name,
@@ -5971,10 +5969,7 @@ function installConnector(name, options = {}) {
5971
5969
  error: `Invalid connector name '${name}'`
5972
5970
  };
5973
5971
  }
5974
- const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
5975
5972
  const sourcePath = getConnectorPath(name);
5976
- const destDir = join2(targetDir, ".connectors");
5977
- const destPath = join2(destDir, connectorName);
5978
5973
  if (!existsSync2(sourcePath)) {
5979
5974
  return {
5980
5975
  connector: name,
@@ -5982,71 +5977,18 @@ function installConnector(name, options = {}) {
5982
5977
  error: `Connector '${name}' not found`
5983
5978
  };
5984
5979
  }
5985
- if (existsSync2(destPath) && !overwrite) {
5986
- return {
5987
- connector: name,
5988
- success: false,
5989
- error: `Already installed. Use --overwrite to replace.`,
5990
- path: destPath
5991
- };
5992
- }
5993
- try {
5994
- if (!existsSync2(destDir)) {
5995
- mkdirSync(destDir, { recursive: true });
5996
- }
5997
- cpSync(sourcePath, destPath, { recursive: true });
5998
- const homeCredDir = join2(homedir(), ".connectors", connectorName);
5999
- if (existsSync2(homeCredDir)) {
6000
- const filesToCopy = ["credentials.json", "current_profile"];
6001
- for (const file of filesToCopy) {
6002
- const src = join2(homeCredDir, file);
6003
- if (existsSync2(src)) {
6004
- cpSync(src, join2(destPath, file));
6005
- }
6006
- }
6007
- const profilesDir = join2(homeCredDir, "profiles");
6008
- if (existsSync2(profilesDir)) {
6009
- cpSync(profilesDir, join2(destPath, "profiles"), { recursive: true });
6010
- }
6011
- }
6012
- updateConnectorsIndex(destDir);
6013
- return {
6014
- connector: name,
6015
- success: true,
6016
- path: destPath
6017
- };
6018
- } catch (error) {
6019
- return {
6020
- connector: name,
6021
- success: false,
6022
- error: error instanceof Error ? error.message : "Unknown error"
6023
- };
6024
- }
6025
- }
6026
- function updateConnectorsIndex(connectorsDir) {
6027
- const indexPath = join2(connectorsDir, "index.ts");
6028
- const connectors = readdirSync(connectorsDir).filter((f) => f.startsWith("connect-") && !f.includes("."));
6029
- const exports = connectors.map((c) => {
6030
- const name = c.replace("connect-", "");
6031
- return `export * as ${name} from './${c}/src/index.js';`;
6032
- }).join(`
6033
- `);
6034
- const content = `/**
6035
- * Auto-generated index of installed connectors
6036
- * Do not edit manually - run 'connectors install' to update
6037
- */
6038
-
6039
- ${exports}
6040
- `;
6041
- writeFileSync(indexPath, content);
5980
+ return {
5981
+ connector: name,
5982
+ success: true,
5983
+ path: sourcePath
5984
+ };
6042
5985
  }
6043
- function getInstalledConnectors(targetDir = process.cwd()) {
6044
- const connectorsDir = join2(targetDir, ".connectors");
6045
- if (!existsSync2(connectorsDir)) {
5986
+ function getInstalledConnectors() {
5987
+ if (!existsSync2(CONNECTORS_DIR)) {
6046
5988
  return [];
6047
5989
  }
6048
- return readdirSync(connectorsDir).filter((f) => {
6049
- const fullPath = join2(connectorsDir, f);
5990
+ return readdirSync(CONNECTORS_DIR).filter((f) => {
5991
+ const fullPath = join2(CONNECTORS_DIR, f);
6050
5992
  return f.startsWith("connect-") && statSync(fullPath).isDirectory();
6051
5993
  }).map((f) => f.replace("connect-", ""));
6052
5994
  }
@@ -6092,22 +6034,14 @@ function parseEnvVarsTable(section) {
6092
6034
  }
6093
6035
  return vars;
6094
6036
  }
6095
- function removeConnector(name, targetDir = process.cwd()) {
6096
- const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
6097
- const connectorsDir = join2(targetDir, ".connectors");
6098
- const connectorPath = join2(connectorsDir, connectorName);
6099
- if (!existsSync2(connectorPath)) {
6100
- return false;
6101
- }
6102
- rmSync(connectorPath, { recursive: true });
6103
- updateConnectorsIndex(connectorsDir);
6104
- return true;
6037
+ function removeConnector(name) {
6038
+ return false;
6105
6039
  }
6106
6040
 
6107
6041
  // src/server/auth.ts
6108
- import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2 } from "fs";
6042
+ import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync, mkdirSync, readdirSync as readdirSync2, rmSync, statSync as statSync2 } from "fs";
6109
6043
  import { randomBytes } from "crypto";
6110
- import { homedir as homedir2 } from "os";
6044
+ import { homedir } from "os";
6111
6045
  import { join as join3 } from "path";
6112
6046
  var FETCH_TIMEOUT = 1e4;
6113
6047
  var oauthStateStore = new Map;
@@ -6164,7 +6098,7 @@ function getAuthType(name) {
6164
6098
  }
6165
6099
  function getConnectorConfigDir(name) {
6166
6100
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
6167
- return join3(homedir2(), ".connectors", connectorName);
6101
+ return join3(homedir(), ".connectors", connectorName);
6168
6102
  }
6169
6103
  function getCurrentProfile(name) {
6170
6104
  const configDir = getConnectorConfigDir(name);
@@ -6257,7 +6191,7 @@ function saveApiKey(name, key, field) {
6257
6191
  const keyField = field || guessKeyField(name);
6258
6192
  if (keyField === "clientId" || keyField === "clientSecret") {
6259
6193
  const credentialsFile = join3(configDir, "credentials.json");
6260
- mkdirSync2(configDir, { recursive: true });
6194
+ mkdirSync(configDir, { recursive: true });
6261
6195
  let creds = {};
6262
6196
  if (existsSync3(credentialsFile)) {
6263
6197
  try {
@@ -6265,7 +6199,7 @@ function saveApiKey(name, key, field) {
6265
6199
  } catch {}
6266
6200
  }
6267
6201
  creds[keyField] = key;
6268
- writeFileSync2(credentialsFile, JSON.stringify(creds, null, 2));
6202
+ writeFileSync(credentialsFile, JSON.stringify(creds, null, 2));
6269
6203
  return;
6270
6204
  }
6271
6205
  const profileFile = join3(configDir, "profiles", `${profile}.json`);
@@ -6276,7 +6210,7 @@ function saveApiKey(name, key, field) {
6276
6210
  config = JSON.parse(readFileSync3(profileFile, "utf-8"));
6277
6211
  } catch {}
6278
6212
  config[keyField] = key;
6279
- writeFileSync2(profileFile, JSON.stringify(config, null, 2));
6213
+ writeFileSync(profileFile, JSON.stringify(config, null, 2));
6280
6214
  return;
6281
6215
  }
6282
6216
  if (existsSync3(profileDir)) {
@@ -6288,11 +6222,11 @@ function saveApiKey(name, key, field) {
6288
6222
  } catch {}
6289
6223
  }
6290
6224
  config[keyField] = key;
6291
- writeFileSync2(configFile, JSON.stringify(config, null, 2));
6225
+ writeFileSync(configFile, JSON.stringify(config, null, 2));
6292
6226
  return;
6293
6227
  }
6294
- mkdirSync2(profileDir, { recursive: true });
6295
- writeFileSync2(join3(profileDir, "config.json"), JSON.stringify({ [keyField]: key }, null, 2));
6228
+ mkdirSync(profileDir, { recursive: true });
6229
+ writeFileSync(join3(profileDir, "config.json"), JSON.stringify({ [keyField]: key }, null, 2));
6296
6230
  }
6297
6231
  function guessKeyField(name) {
6298
6232
  const docs = getConnectorDocs(name);
@@ -6393,9 +6327,9 @@ function saveOAuthTokens(name, tokens) {
6393
6327
  const configDir = getConnectorConfigDir(name);
6394
6328
  const profile = getCurrentProfile(name);
6395
6329
  const profileDir = join3(configDir, "profiles", profile);
6396
- mkdirSync2(profileDir, { recursive: true });
6330
+ mkdirSync(profileDir, { recursive: true });
6397
6331
  const tokensFile = join3(profileDir, "tokens.json");
6398
- writeFileSync2(tokensFile, JSON.stringify(tokens, null, 2), { mode: 384 });
6332
+ writeFileSync(tokensFile, JSON.stringify(tokens, null, 2), { mode: 384 });
6399
6333
  }
6400
6334
  async function refreshOAuthToken(name) {
6401
6335
  const oauthConfig = getOAuthConfig(name);
@@ -6455,8 +6389,8 @@ function listProfiles(name) {
6455
6389
  }
6456
6390
  function switchProfile(name, profile) {
6457
6391
  const configDir = getConnectorConfigDir(name);
6458
- mkdirSync2(configDir, { recursive: true });
6459
- writeFileSync2(join3(configDir, "current_profile"), profile);
6392
+ mkdirSync(configDir, { recursive: true });
6393
+ writeFileSync(join3(configDir, "current_profile"), profile);
6460
6394
  }
6461
6395
  function deleteProfile(name, profile) {
6462
6396
  if (profile === "default")
@@ -6465,7 +6399,7 @@ function deleteProfile(name, profile) {
6465
6399
  const profilesDir = join3(configDir, "profiles");
6466
6400
  const profileFile = join3(profilesDir, `${profile}.json`);
6467
6401
  if (existsSync3(profileFile)) {
6468
- rmSync2(profileFile);
6402
+ rmSync(profileFile);
6469
6403
  if (getCurrentProfile(name) === profile) {
6470
6404
  switchProfile(name, "default");
6471
6405
  }
@@ -6473,7 +6407,7 @@ function deleteProfile(name, profile) {
6473
6407
  }
6474
6408
  const profileDir = join3(profilesDir, profile);
6475
6409
  if (existsSync3(profileDir)) {
6476
- rmSync2(profileDir, { recursive: true });
6410
+ rmSync(profileDir, { recursive: true });
6477
6411
  if (getCurrentProfile(name) === profile) {
6478
6412
  switchProfile(name, "default");
6479
6413
  }
@@ -6742,10 +6676,7 @@ Dashboard not found at: ${dashboardDir}`);
6742
6676
  if (!isValidConnectorName(name))
6743
6677
  return json({ error: "Invalid connector name" }, 400, port);
6744
6678
  try {
6745
- const removed = removeConnector(name);
6746
- if (!removed) {
6747
- return json({ error: `Connector '${name}' is not installed` }, 404, port);
6748
- }
6679
+ removeConnector(name);
6749
6680
  logActivity("uninstalled", name);
6750
6681
  return json({ success: true, name }, 200, port);
6751
6682
  } catch (e) {
@@ -6778,7 +6709,7 @@ Dashboard not found at: ${dashboardDir}`);
6778
6709
  return json({ error: "Invalid connector name" }, 400, port);
6779
6710
  try {
6780
6711
  const profiles = listProfiles(name);
6781
- const configDir = join4(homedir3(), ".connectors", name.startsWith("connect-") ? name : `connect-${name}`);
6712
+ const configDir = join4(homedir2(), ".connectors", name.startsWith("connect-") ? name : `connect-${name}`);
6782
6713
  const currentProfileFile = join4(configDir, "current_profile");
6783
6714
  let current = "default";
6784
6715
  if (existsSync4(currentProfileFile)) {
@@ -6830,7 +6761,7 @@ Dashboard not found at: ${dashboardDir}`);
6830
6761
  }
6831
6762
  if (path === "/api/export" && method === "GET") {
6832
6763
  try {
6833
- const connectDir = join4(homedir3(), ".connectors");
6764
+ const connectDir = join4(homedir2(), ".connectors");
6834
6765
  const result = {};
6835
6766
  if (existsSync4(connectDir)) {
6836
6767
  const entries = readdirSync3(connectDir, { withFileTypes: true });
@@ -6890,7 +6821,7 @@ Dashboard not found at: ${dashboardDir}`);
6890
6821
  return json({ error: "Invalid import format: missing 'connectors' object" }, 400, port);
6891
6822
  }
6892
6823
  let imported = 0;
6893
- const connectDir = join4(homedir3(), ".connectors");
6824
+ const connectDir = join4(homedir2(), ".connectors");
6894
6825
  for (const [connectorName, data] of Object.entries(body.connectors)) {
6895
6826
  if (!isValidConnectorName(connectorName))
6896
6827
  continue;
@@ -6901,9 +6832,9 @@ Dashboard not found at: ${dashboardDir}`);
6901
6832
  for (const [profileName, config] of Object.entries(data.profiles)) {
6902
6833
  if (!config || typeof config !== "object")
6903
6834
  continue;
6904
- mkdirSync3(profilesDir, { recursive: true });
6835
+ mkdirSync2(profilesDir, { recursive: true });
6905
6836
  const profileFile = join4(profilesDir, `${profileName}.json`);
6906
- writeFileSync3(profileFile, JSON.stringify(config, null, 2));
6837
+ writeFileSync2(profileFile, JSON.stringify(config, null, 2));
6907
6838
  imported++;
6908
6839
  }
6909
6840
  }
package/dist/index.js CHANGED
@@ -5961,8 +5961,7 @@ function loadConnectorVersions() {
5961
5961
  }
5962
5962
  }
5963
5963
  // src/lib/installer.ts
5964
- import { existsSync as existsSync2, cpSync, mkdirSync, readFileSync as readFileSync2, writeFileSync, readdirSync, statSync, rmSync } from "fs";
5965
- import { homedir } from "os";
5964
+ import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync, statSync } from "fs";
5966
5965
  import { join as join2, dirname as dirname2 } from "path";
5967
5966
  import { fileURLToPath as fileURLToPath2 } from "url";
5968
5967
  var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
@@ -5984,7 +5983,6 @@ function connectorExists(name) {
5984
5983
  return existsSync2(getConnectorPath(name));
5985
5984
  }
5986
5985
  function installConnector(name, options = {}) {
5987
- const { targetDir = process.cwd(), overwrite = false } = options;
5988
5986
  if (!/^[a-z0-9-]+$/.test(name)) {
5989
5987
  return {
5990
5988
  connector: name,
@@ -5992,10 +5990,7 @@ function installConnector(name, options = {}) {
5992
5990
  error: `Invalid connector name '${name}'`
5993
5991
  };
5994
5992
  }
5995
- const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
5996
5993
  const sourcePath = getConnectorPath(name);
5997
- const destDir = join2(targetDir, ".connectors");
5998
- const destPath = join2(destDir, connectorName);
5999
5994
  if (!existsSync2(sourcePath)) {
6000
5995
  return {
6001
5996
  connector: name,
@@ -6003,74 +5998,21 @@ function installConnector(name, options = {}) {
6003
5998
  error: `Connector '${name}' not found`
6004
5999
  };
6005
6000
  }
6006
- if (existsSync2(destPath) && !overwrite) {
6007
- return {
6008
- connector: name,
6009
- success: false,
6010
- error: `Already installed. Use --overwrite to replace.`,
6011
- path: destPath
6012
- };
6013
- }
6014
- try {
6015
- if (!existsSync2(destDir)) {
6016
- mkdirSync(destDir, { recursive: true });
6017
- }
6018
- cpSync(sourcePath, destPath, { recursive: true });
6019
- const homeCredDir = join2(homedir(), ".connectors", connectorName);
6020
- if (existsSync2(homeCredDir)) {
6021
- const filesToCopy = ["credentials.json", "current_profile"];
6022
- for (const file of filesToCopy) {
6023
- const src = join2(homeCredDir, file);
6024
- if (existsSync2(src)) {
6025
- cpSync(src, join2(destPath, file));
6026
- }
6027
- }
6028
- const profilesDir = join2(homeCredDir, "profiles");
6029
- if (existsSync2(profilesDir)) {
6030
- cpSync(profilesDir, join2(destPath, "profiles"), { recursive: true });
6031
- }
6032
- }
6033
- updateConnectorsIndex(destDir);
6034
- return {
6035
- connector: name,
6036
- success: true,
6037
- path: destPath
6038
- };
6039
- } catch (error) {
6040
- return {
6041
- connector: name,
6042
- success: false,
6043
- error: error instanceof Error ? error.message : "Unknown error"
6044
- };
6045
- }
6001
+ return {
6002
+ connector: name,
6003
+ success: true,
6004
+ path: sourcePath
6005
+ };
6046
6006
  }
6047
6007
  function installConnectors(names, options = {}) {
6048
6008
  return names.map((name) => installConnector(name, options));
6049
6009
  }
6050
- function updateConnectorsIndex(connectorsDir) {
6051
- const indexPath = join2(connectorsDir, "index.ts");
6052
- const connectors = readdirSync(connectorsDir).filter((f) => f.startsWith("connect-") && !f.includes("."));
6053
- const exports = connectors.map((c) => {
6054
- const name = c.replace("connect-", "");
6055
- return `export * as ${name} from './${c}/src/index.js';`;
6056
- }).join(`
6057
- `);
6058
- const content = `/**
6059
- * Auto-generated index of installed connectors
6060
- * Do not edit manually - run 'connectors install' to update
6061
- */
6062
-
6063
- ${exports}
6064
- `;
6065
- writeFileSync(indexPath, content);
6066
- }
6067
- function getInstalledConnectors(targetDir = process.cwd()) {
6068
- const connectorsDir = join2(targetDir, ".connectors");
6069
- if (!existsSync2(connectorsDir)) {
6010
+ function getInstalledConnectors() {
6011
+ if (!existsSync2(CONNECTORS_DIR)) {
6070
6012
  return [];
6071
6013
  }
6072
- return readdirSync(connectorsDir).filter((f) => {
6073
- const fullPath = join2(connectorsDir, f);
6014
+ return readdirSync(CONNECTORS_DIR).filter((f) => {
6015
+ const fullPath = join2(CONNECTORS_DIR, f);
6074
6016
  return f.startsWith("connect-") && statSync(fullPath).isDirectory();
6075
6017
  }).map((f) => f.replace("connect-", ""));
6076
6018
  }
@@ -6116,16 +6058,8 @@ function parseEnvVarsTable(section) {
6116
6058
  }
6117
6059
  return vars;
6118
6060
  }
6119
- function removeConnector(name, targetDir = process.cwd()) {
6120
- const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
6121
- const connectorsDir = join2(targetDir, ".connectors");
6122
- const connectorPath = join2(connectorsDir, connectorName);
6123
- if (!existsSync2(connectorPath)) {
6124
- return false;
6125
- }
6126
- rmSync(connectorPath, { recursive: true });
6127
- updateConnectorsIndex(connectorsDir);
6128
- return true;
6061
+ function removeConnector(name) {
6062
+ return false;
6129
6063
  }
6130
6064
  // src/lib/runner.ts
6131
6065
  import { existsSync as existsSync3 } from "fs";
@@ -8,7 +8,6 @@ export interface InstallResult {
8
8
  path?: string;
9
9
  }
10
10
  export interface InstallOptions {
11
- targetDir?: string;
12
11
  overwrite?: boolean;
13
12
  }
14
13
  /**
@@ -20,7 +19,8 @@ export declare function getConnectorPath(name: string): string;
20
19
  */
21
20
  export declare function connectorExists(name: string): boolean;
22
21
  /**
23
- * Install a single connector to the target directory
22
+ * Install a single connector verifies it exists in the global package.
23
+ * Auth/tokens always live in ~/.connectors/connect-{name}/ and are never touched here.
24
24
  */
25
25
  export declare function installConnector(name: string, options?: InstallOptions): InstallResult;
26
26
  /**
@@ -28,9 +28,9 @@ export declare function installConnector(name: string, options?: InstallOptions)
28
28
  */
29
29
  export declare function installConnectors(names: string[], options?: InstallOptions): InstallResult[];
30
30
  /**
31
- * Get list of installed connectors in a directory
31
+ * Get list of available connectors from the global package
32
32
  */
33
- export declare function getInstalledConnectors(targetDir?: string): string[];
33
+ export declare function getInstalledConnectors(): string[];
34
34
  /**
35
35
  * Parsed documentation from a connector's CLAUDE.md
36
36
  */
@@ -50,6 +50,7 @@ export interface ConnectorDocs {
50
50
  */
51
51
  export declare function getConnectorDocs(name: string): ConnectorDocs | null;
52
52
  /**
53
- * Remove an installed connector
53
+ * Remove a connector — connectors are part of the global package and cannot be
54
+ * individually removed. This always returns false.
54
55
  */
55
- export declare function removeConnector(name: string, targetDir?: string): boolean;
56
+ export declare function removeConnector(name: string): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/connectors",
3
- "version": "1.1.8",
3
+ "version": "1.1.9",
4
4
  "description": "Open source connector library - Install API connectors with a single command",
5
5
  "type": "module",
6
6
  "bin": {