@hasna/connectors 1.4.0 → 1.4.1

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
@@ -1909,7 +1909,7 @@ var package_default;
1909
1909
  var init_package = __esm(() => {
1910
1910
  package_default = {
1911
1911
  name: "@hasna/connectors",
1912
- version: "1.4.0",
1912
+ version: "1.4.1",
1913
1913
  description: "Open source connector library - Install API connectors with a single command",
1914
1914
  type: "module",
1915
1915
  bin: {
@@ -1922,7 +1922,15 @@ var init_package = __esm(() => {
1922
1922
  "dist/",
1923
1923
  "dashboard/dist/",
1924
1924
  "connectors/",
1925
- "README.md"
1925
+ "README.md",
1926
+ "!connectors/**/.test-home/**",
1927
+ "!connectors/**/node_modules/**",
1928
+ "!connectors/**/bun.lock",
1929
+ "!connectors/**/package-lock.json",
1930
+ "!connectors/**/yarn.lock",
1931
+ "!connectors/**/pnpm-lock.yaml",
1932
+ "!connectors/**/.env",
1933
+ "!connectors/**/.env.local"
1926
1934
  ],
1927
1935
  exports: {
1928
1936
  ".": {
@@ -1937,7 +1945,7 @@ var init_package = __esm(() => {
1937
1945
  main: "./dist/index.js",
1938
1946
  types: "./dist/index.d.ts",
1939
1947
  scripts: {
1940
- build: "cd dashboard && bun run build && cd .. && bun build ./src/cli/index.tsx --outdir ./bin --target bun --external ink --external react --external chalk --external conf && bun build ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build ./src/server/index.ts --outfile ./bin/serve.js --target bun && bun build ./src/index.ts --outdir ./dist --target bun && bun build ./src/social/index.ts --outfile ./dist/social/index.js --target bun && tsc --emitDeclarationOnly --outDir ./dist && tsc -p tsconfig.social.json",
1948
+ build: "cd dashboard && bun run build && cd .. && bun build ./src/cli/index.tsx --outdir ./bin --target bun --external ink --external react --external chalk --external conf --external @hasna/events && bun build ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build ./src/server/index.ts --outfile ./bin/serve.js --target bun && bun build ./src/index.ts --outdir ./dist --target bun && bun build ./src/social/index.ts --outfile ./dist/social/index.js --target bun && tsc --emitDeclarationOnly --outDir ./dist && tsc -p tsconfig.social.json",
1941
1949
  "build:dashboard": "cd dashboard && bun run build",
1942
1950
  postinstall: 'mkdir -p $HOME/.hasna/connectors 2>/dev/null || true; [ "$SKIP_DASHBOARD" = "1" ] || [ ! -f dashboard/package.json ] || [ -d dashboard/node_modules ] || (cd dashboard && bun install)',
1943
1951
  dev: "bun run ./src/cli/index.tsx",
@@ -6091,28 +6099,28 @@ var init_zod = __esm(() => {
6091
6099
 
6092
6100
  // src/core/connectors/github.ts
6093
6101
  import { Buffer as Buffer2 } from "buffer";
6094
- import { existsSync as existsSync2 } from "fs";
6095
- import { dirname, join as join2 } from "path";
6102
+ import { existsSync } from "fs";
6103
+ import { dirname, join } from "path";
6096
6104
  import { fileURLToPath, pathToFileURL } from "url";
6097
6105
  function resolveGithubConnectorDir() {
6098
6106
  const candidates = [
6099
- join2(__dirname2, "..", "..", "..", "connectors", "github"),
6100
- join2(__dirname2, "..", "..", "connectors", "github"),
6101
- join2(__dirname2, "..", "connectors", "github"),
6102
- join2(process.cwd(), "connectors", "github")
6107
+ join(__dirname2, "..", "..", "..", "connectors", "github"),
6108
+ join(__dirname2, "..", "..", "connectors", "github"),
6109
+ join(__dirname2, "..", "connectors", "github"),
6110
+ join(process.cwd(), "connectors", "github")
6103
6111
  ];
6104
6112
  for (const candidate of candidates) {
6105
- if (existsSync2(candidate)) {
6113
+ if (existsSync(candidate)) {
6106
6114
  return candidate;
6107
6115
  }
6108
6116
  }
6109
6117
  return candidates[0];
6110
6118
  }
6111
6119
  async function loadGitHubApiModule() {
6112
- return await import(pathToFileURL(join2(CONNECTOR_DIR, "src", "api", "index.ts")).href);
6120
+ return await import(pathToFileURL(join(CONNECTOR_DIR, "src", "api", "index.ts")).href);
6113
6121
  }
6114
6122
  async function loadGitHubConfigModule() {
6115
- return await import(pathToFileURL(join2(CONNECTOR_DIR, "src", "utils", "config.ts")).href);
6123
+ return await import(pathToFileURL(join(CONNECTOR_DIR, "src", "utils", "config.ts")).href);
6116
6124
  }
6117
6125
  function extractGlobalArgs(args) {
6118
6126
  const remaining = [];
@@ -6956,9 +6964,9 @@ Commands:
6956
6964
  });
6957
6965
 
6958
6966
  // src/core/connectors/gmail.ts
6959
- import { existsSync as existsSync3, mkdirSync, readFileSync, readdirSync, writeFileSync } from "fs";
6960
- import { homedir as homedir2 } from "os";
6961
- import { basename, join as join3 } from "path";
6967
+ import { existsSync as existsSync2, mkdirSync, readFileSync, readdirSync, writeFileSync } from "fs";
6968
+ import { homedir } from "os";
6969
+ import { basename, join as join2 } from "path";
6962
6970
  async function modifyMessage(profile, messageId, addLabelIds, removeLabelIds) {
6963
6971
  return requestJson(profile, `/users/me/messages/${encodeURIComponent(messageId)}/modify`, {}, {
6964
6972
  method: "POST",
@@ -6995,7 +7003,7 @@ async function replyToMessage(profile, messageId, input) {
6995
7003
  }
6996
7004
  async function downloadAttachments(profile, input) {
6997
7005
  const messageId = getMessageId(input);
6998
- const outputDir = input.dir ?? input.outputDir ?? join3(configDirs()[0], "attachments", messageId);
7006
+ const outputDir = input.dir ?? input.outputDir ?? join2(configDirs()[0], "attachments", messageId);
6999
7007
  mkdirSync(outputDir, { recursive: true });
7000
7008
  const attachments = input.attachmentId && input.filename ? [{
7001
7009
  attachmentId: input.attachmentId,
@@ -7007,7 +7015,7 @@ async function downloadAttachments(profile, input) {
7007
7015
  for (const attachment of attachments) {
7008
7016
  const data = await requestJson(profile, `/users/me/messages/${encodeURIComponent(messageId)}/attachments/${encodeURIComponent(attachment.attachmentId)}`, {});
7009
7017
  const filename = safeFilename(attachment.filename);
7010
- const path = join3(outputDir, filename);
7018
+ const path = join2(outputDir, filename);
7011
7019
  const buffer = Buffer.from(data.data, "base64url");
7012
7020
  writeFileSync(path, buffer);
7013
7021
  downloaded.push({
@@ -7124,8 +7132,8 @@ async function refreshAccessToken(profile, currentTokens) {
7124
7132
  function listProfiles() {
7125
7133
  const profiles = new Set;
7126
7134
  for (const baseDir of configDirs()) {
7127
- const profilesDir = join3(baseDir, "profiles");
7128
- if (!existsSync3(profilesDir))
7135
+ const profilesDir = join2(baseDir, "profiles");
7136
+ if (!existsSync2(profilesDir))
7129
7137
  continue;
7130
7138
  for (const entry of readdirSync(profilesDir, { withFileTypes: true })) {
7131
7139
  if (entry.isDirectory())
@@ -7143,8 +7151,8 @@ function loadCredentials(profile) {
7143
7151
  return { clientId: envClientId, clientSecret: envClientSecret };
7144
7152
  for (const baseDir of configDirs()) {
7145
7153
  const credentials = {
7146
- ...readJson(join3(baseDir, "credentials.json")),
7147
- ...readJson(join3(baseDir, "profiles", profile, "config.json"))
7154
+ ...readJson(join2(baseDir, "credentials.json")),
7155
+ ...readJson(join2(baseDir, "profiles", profile, "config.json"))
7148
7156
  };
7149
7157
  if (credentials.clientId || credentials.clientSecret)
7150
7158
  return credentials;
@@ -7153,30 +7161,30 @@ function loadCredentials(profile) {
7153
7161
  }
7154
7162
  function loadTokens(profile) {
7155
7163
  for (const baseDir of configDirs()) {
7156
- const fromProfile = readJson(join3(baseDir, "profiles", profile, "tokens.json"));
7164
+ const fromProfile = readJson(join2(baseDir, "profiles", profile, "tokens.json"));
7157
7165
  if (fromProfile)
7158
7166
  return fromProfile;
7159
- const flat = readJson(join3(baseDir, "profiles", `${profile}.json`));
7167
+ const flat = readJson(join2(baseDir, "profiles", `${profile}.json`));
7160
7168
  if (flat)
7161
7169
  return flat.tokens ?? (flat.accessToken || flat.refreshToken ? flat : null);
7162
7170
  }
7163
7171
  return null;
7164
7172
  }
7165
7173
  function saveTokens(profile, tokens) {
7166
- const baseDir = configDirs().find((dir) => existsSync3(dir)) ?? configDirs()[0];
7167
- const profileDir = join3(baseDir, "profiles", profile);
7174
+ const baseDir = configDirs().find((dir) => existsSync2(dir)) ?? configDirs()[0];
7175
+ const profileDir = join2(baseDir, "profiles", profile);
7168
7176
  mkdirSync(profileDir, { recursive: true });
7169
- writeFileSync(join3(profileDir, "tokens.json"), JSON.stringify(tokens, null, 2), { mode: 384 });
7177
+ writeFileSync(join2(profileDir, "tokens.json"), JSON.stringify(tokens, null, 2), { mode: 384 });
7170
7178
  }
7171
7179
  function configDirs() {
7172
7180
  const explicit = process.env.HASNA_GMAIL_CONNECTOR_DIR ?? process.env.GMAIL_CONNECTOR_DIR;
7173
7181
  if (explicit)
7174
7182
  return [explicit];
7175
- const baseDir = process.env.HASNA_CONNECTORS_DIR ?? join3(homedir2(), ".hasna", "connectors");
7176
- return [join3(baseDir, "gmail"), join3(baseDir, "connect-gmail")];
7183
+ const baseDir = process.env.HASNA_CONNECTORS_DIR ?? join2(homedir(), ".hasna", "connectors");
7184
+ return [join2(baseDir, "gmail"), join2(baseDir, "connect-gmail")];
7177
7185
  }
7178
7186
  function readJson(path) {
7179
- if (!existsSync3(path))
7187
+ if (!existsSync2(path))
7180
7188
  return null;
7181
7189
  try {
7182
7190
  return JSON.parse(readFileSync(path, "utf8"));
@@ -7426,9 +7434,9 @@ var init_gmail = __esm(() => {
7426
7434
  });
7427
7435
 
7428
7436
  // src/core/connectors/googledrive.ts
7429
- import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync2, readdirSync as readdirSync2, writeFileSync as writeFileSync2 } from "fs";
7430
- import { homedir as homedir3 } from "os";
7431
- import { basename as basename2, join as join4 } from "path";
7437
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, readdirSync as readdirSync2, writeFileSync as writeFileSync2 } from "fs";
7438
+ import { homedir as homedir2 } from "os";
7439
+ import { basename as basename2, join as join3 } from "path";
7432
7440
  async function requestJson2(profile, path, params) {
7433
7441
  const response = await request(profile, path, params);
7434
7442
  const text = await response.text();
@@ -7496,8 +7504,8 @@ async function refreshAccessToken2(profile, currentTokens) {
7496
7504
  function listProfiles2() {
7497
7505
  const profiles = new Set;
7498
7506
  for (const baseDir of configDirs2()) {
7499
- const profilesDir = join4(baseDir, "profiles");
7500
- if (!existsSync4(profilesDir))
7507
+ const profilesDir = join3(baseDir, "profiles");
7508
+ if (!existsSync3(profilesDir))
7501
7509
  continue;
7502
7510
  for (const entry of readdirSync2(profilesDir, { withFileTypes: true })) {
7503
7511
  if (entry.isDirectory())
@@ -7511,7 +7519,7 @@ function listProfiles2() {
7511
7519
  function listProfileStatuses(profile) {
7512
7520
  const profiles = profile ? [profile] : listProfiles2();
7513
7521
  const uniqueProfiles = profiles.length ? profiles : ["default"];
7514
- const now2 = Date.now();
7522
+ const now = Date.now();
7515
7523
  return uniqueProfiles.map((name) => {
7516
7524
  const tokens = loadTokens2(name);
7517
7525
  const credentials = loadCredentials2(name);
@@ -7519,7 +7527,7 @@ function listProfileStatuses(profile) {
7519
7527
  const hasRefreshToken = Boolean(tokens?.refreshToken);
7520
7528
  const hasOAuthCredentials = Boolean(credentials.clientId && credentials.clientSecret);
7521
7529
  const expiresAt = tokens?.expiresAt ?? null;
7522
- const expired = Boolean(expiresAt && now2 >= expiresAt - REFRESH_BUFFER_MS2);
7530
+ const expired = Boolean(expiresAt && now >= expiresAt - REFRESH_BUFFER_MS2);
7523
7531
  const authenticated = Boolean(process.env.GOOGLE_ACCESS_TOKEN || hasRefreshToken || hasAccessToken && !expired);
7524
7532
  const configured = authenticated || hasOAuthCredentials;
7525
7533
  const authRequired = !authenticated || expired && !hasRefreshToken;
@@ -7544,8 +7552,8 @@ function loadCredentials2(profile) {
7544
7552
  return { clientId: envClientId, clientSecret: envClientSecret };
7545
7553
  for (const baseDir of configDirs2()) {
7546
7554
  const credentials = {
7547
- ...readJson2(join4(baseDir, "credentials.json")),
7548
- ...readJson2(join4(baseDir, "profiles", profile, "config.json"))
7555
+ ...readJson2(join3(baseDir, "credentials.json")),
7556
+ ...readJson2(join3(baseDir, "profiles", profile, "config.json"))
7549
7557
  };
7550
7558
  if (credentials.clientId || credentials.clientSecret)
7551
7559
  return credentials;
@@ -7554,30 +7562,30 @@ function loadCredentials2(profile) {
7554
7562
  }
7555
7563
  function loadTokens2(profile) {
7556
7564
  for (const baseDir of configDirs2()) {
7557
- const fromProfile = readJson2(join4(baseDir, "profiles", profile, "tokens.json"));
7565
+ const fromProfile = readJson2(join3(baseDir, "profiles", profile, "tokens.json"));
7558
7566
  if (fromProfile)
7559
7567
  return fromProfile;
7560
- const flat = readJson2(join4(baseDir, "profiles", `${profile}.json`));
7568
+ const flat = readJson2(join3(baseDir, "profiles", `${profile}.json`));
7561
7569
  if (flat)
7562
7570
  return flat.tokens ?? (flat.accessToken || flat.refreshToken ? flat : null);
7563
7571
  }
7564
7572
  return null;
7565
7573
  }
7566
7574
  function saveTokens2(profile, tokens) {
7567
- const baseDir = configDirs2().find((dir) => existsSync4(dir)) ?? configDirs2()[0];
7568
- const profileDir = join4(baseDir, "profiles", profile);
7575
+ const baseDir = configDirs2().find((dir) => existsSync3(dir)) ?? configDirs2()[0];
7576
+ const profileDir = join3(baseDir, "profiles", profile);
7569
7577
  mkdirSync2(profileDir, { recursive: true });
7570
- writeFileSync2(join4(profileDir, "tokens.json"), JSON.stringify(tokens, null, 2), { mode: 384 });
7578
+ writeFileSync2(join3(profileDir, "tokens.json"), JSON.stringify(tokens, null, 2), { mode: 384 });
7571
7579
  }
7572
7580
  function configDirs2() {
7573
7581
  const explicit = process.env.HASNA_GOOGLE_DRIVE_CONNECTOR_DIR ?? process.env.GOOGLE_DRIVE_CONNECTOR_DIR;
7574
7582
  if (explicit)
7575
7583
  return [explicit];
7576
- const baseDir = process.env.HASNA_CONNECTORS_DIR ?? join4(homedir3(), ".hasna", "connectors");
7577
- return [join4(baseDir, "googledrive"), join4(baseDir, "connect-googledrive")];
7584
+ const baseDir = process.env.HASNA_CONNECTORS_DIR ?? join3(homedir2(), ".hasna", "connectors");
7585
+ return [join3(baseDir, "googledrive"), join3(baseDir, "connect-googledrive")];
7578
7586
  }
7579
7587
  function readJson2(path) {
7580
- if (!existsSync4(path))
7588
+ if (!existsSync3(path))
7581
7589
  return null;
7582
7590
  try {
7583
7591
  return JSON.parse(readFileSync2(path, "utf8"));
@@ -7818,39 +7826,39 @@ var init_sqlite_adapter = () => {};
7818
7826
  var exports_database = {};
7819
7827
  __export(exports_database, {
7820
7828
  shortUuid: () => shortUuid,
7821
- now: () => now2,
7829
+ now: () => now,
7822
7830
  getDatabase: () => getDatabase,
7823
7831
  getConnectorsHome: () => getConnectorsHome,
7824
7832
  closeDatabase: () => closeDatabase,
7825
7833
  SqliteAdapter: () => SqliteAdapter
7826
7834
  });
7827
- import { dirname as dirname2, join as join5 } from "path";
7828
- import { homedir as homedir4 } from "os";
7829
- import { mkdirSync as mkdirSync3, existsSync as existsSync5, readdirSync as readdirSync3, copyFileSync, statSync } from "fs";
7835
+ import { dirname as dirname2, join as join4 } from "path";
7836
+ import { homedir as homedir3 } from "os";
7837
+ import { mkdirSync as mkdirSync3, existsSync as existsSync4, readdirSync as readdirSync3, copyFileSync, statSync } from "fs";
7830
7838
  function mergeDirectoryContents(sourceDir, targetDir) {
7831
- if (!existsSync5(sourceDir)) {
7839
+ if (!existsSync4(sourceDir)) {
7832
7840
  return;
7833
7841
  }
7834
7842
  mkdirSync3(targetDir, { recursive: true });
7835
7843
  for (const entry of readdirSync3(sourceDir)) {
7836
- const sourcePath = join5(sourceDir, entry);
7837
- const targetPath = join5(targetDir, entry);
7844
+ const sourcePath = join4(sourceDir, entry);
7845
+ const targetPath = join4(targetDir, entry);
7838
7846
  try {
7839
7847
  const sourceStat = statSync(sourcePath);
7840
7848
  if (sourceStat.isDirectory()) {
7841
7849
  mergeDirectoryContents(sourcePath, targetPath);
7842
7850
  continue;
7843
7851
  }
7844
- if (!existsSync5(targetPath)) {
7852
+ if (!existsSync4(targetPath)) {
7845
7853
  copyFileSync(sourcePath, targetPath);
7846
7854
  }
7847
7855
  } catch {}
7848
7856
  }
7849
7857
  }
7850
7858
  function getConnectorsHome() {
7851
- const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir4();
7852
- const newDir = join5(home, ".hasna", "connectors");
7853
- const legacyDirs = [join5(home, ".connectors"), join5(home, ".connect")];
7859
+ const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir3();
7860
+ const newDir = join4(home, ".hasna", "connectors");
7861
+ const legacyDirs = [join4(home, ".connectors"), join4(home, ".connect")];
7854
7862
  mkdirSync3(newDir, { recursive: true });
7855
7863
  for (const legacyDir of legacyDirs) {
7856
7864
  try {
@@ -7882,7 +7890,7 @@ function closeDatabase() {
7882
7890
  _db = null;
7883
7891
  _dbPath = null;
7884
7892
  }
7885
- function now2() {
7893
+ function now() {
7886
7894
  return new Date().toISOString();
7887
7895
  }
7888
7896
  function shortUuid() {
@@ -7999,12 +8007,12 @@ var init_database = __esm(() => {
7999
8007
  init_sqlite_adapter();
8000
8008
  init_sqlite_adapter();
8001
8009
  DB_DIR = getConnectorsHome();
8002
- DB_PATH = join5(DB_DIR, "connectors.db");
8010
+ DB_PATH = join4(DB_DIR, "connectors.db");
8003
8011
  });
8004
8012
 
8005
8013
  // src/lib/connector-resolver.ts
8006
- import { existsSync as existsSync6, readdirSync as readdirSync4, statSync as statSync2 } from "fs";
8007
- import { join as join6 } from "path";
8014
+ import { existsSync as existsSync5, readdirSync as readdirSync4, statSync as statSync2 } from "fs";
8015
+ import { join as join5 } from "path";
8008
8016
  function stripLegacyPrefix(name) {
8009
8017
  return name.startsWith(LEGACY_CONNECTOR_PREFIX) ? name.slice(LEGACY_CONNECTOR_PREFIX.length) : name;
8010
8018
  }
@@ -8047,8 +8055,8 @@ function connectorPackageDirNames(name) {
8047
8055
  function resolveConnectorPackagePath(connectorsDir, name) {
8048
8056
  const resolution = resolveConnectorName(name);
8049
8057
  const dirNames = connectorPackageDirNames(name);
8050
- const checkedPaths = dirNames.map((dirName) => join6(connectorsDir, dirName));
8051
- const existingPath = checkedPaths.find((path) => existsSync6(path)) ?? null;
8058
+ const checkedPaths = dirNames.map((dirName) => join5(connectorsDir, dirName));
8059
+ const existingPath = checkedPaths.find((path) => existsSync5(path)) ?? null;
8052
8060
  const existingDirName = existingPath ? dirNames[checkedPaths.indexOf(existingPath)] : null;
8053
8061
  return {
8054
8062
  ...resolution,
@@ -8067,10 +8075,10 @@ function getConnectorPackagePath(connectorsDir, name) {
8067
8075
  function resolveConnectorConfigPaths(name, connectorsHome = getConnectorsHome()) {
8068
8076
  const resolution = resolveConnectorName(name);
8069
8077
  const preferredDirName = resolution.canonicalName || resolution.legacyName;
8070
- const preferredPath = join6(connectorsHome, preferredDirName);
8071
- const legacyPath = join6(connectorsHome, resolution.legacyName);
8078
+ const preferredPath = join5(connectorsHome, preferredDirName);
8079
+ const legacyPath = join5(connectorsHome, resolution.legacyName);
8072
8080
  const paths = preferredPath === legacyPath ? [preferredPath] : [preferredPath, legacyPath];
8073
- const existingPaths = paths.filter((path) => existsSync6(path));
8081
+ const existingPaths = paths.filter((path) => existsSync5(path));
8074
8082
  return {
8075
8083
  ...resolution,
8076
8084
  connectorsHome,
@@ -8088,11 +8096,11 @@ function getConnectorConfigReadDirs(name, connectorsHome = getConnectorsHome())
8088
8096
  return resolveConnectorConfigPaths(name, connectorsHome).readPaths;
8089
8097
  }
8090
8098
  function listConfiguredConnectorNames(connectorsHome = getConnectorsHome()) {
8091
- if (!existsSync6(connectorsHome))
8099
+ if (!existsSync5(connectorsHome))
8092
8100
  return [];
8093
8101
  const names = new Set;
8094
8102
  for (const entry of readdirSync4(connectorsHome)) {
8095
- const fullPath = join6(connectorsHome, entry);
8103
+ const fullPath = join5(connectorsHome, entry);
8096
8104
  try {
8097
8105
  if (!statSync2(fullPath).isDirectory())
8098
8106
  continue;
@@ -8115,7 +8123,7 @@ var init_connector_resolver = __esm(() => {
8115
8123
 
8116
8124
  // src/core/connectors/imessage.ts
8117
8125
  import {
8118
- existsSync as existsSync7,
8126
+ existsSync as existsSync6,
8119
8127
  mkdirSync as mkdirSync4,
8120
8128
  readFileSync as readFileSync3,
8121
8129
  readdirSync as readdirSync5,
@@ -8123,7 +8131,7 @@ import {
8123
8131
  statSync as statSync3,
8124
8132
  writeFileSync as writeFileSync3
8125
8133
  } from "fs";
8126
- import { join as join7 } from "path";
8134
+ import { join as join6 } from "path";
8127
8135
  function buildRootHelp(specs) {
8128
8136
  const lines = [
8129
8137
  "Usage: connect-imessage [options] [command]",
@@ -8174,12 +8182,12 @@ function getConfigReadDirs() {
8174
8182
  return getConnectorConfigReadDirs(CONNECTOR_NAME);
8175
8183
  }
8176
8184
  function getProfilesDir() {
8177
- return join7(getConfigDir(), "profiles");
8185
+ return join6(getConfigDir(), "profiles");
8178
8186
  }
8179
8187
  function getCurrentProfile() {
8180
8188
  for (const configDir of getConfigReadDirs()) {
8181
- const currentProfileFile = join7(configDir, "current_profile");
8182
- if (!existsSync7(currentProfileFile))
8189
+ const currentProfileFile = join6(configDir, "current_profile");
8190
+ if (!existsSync6(currentProfileFile))
8183
8191
  continue;
8184
8192
  try {
8185
8193
  return readFileSync3(currentProfileFile, "utf-8").trim() || "default";
@@ -8192,16 +8200,16 @@ function getCurrentProfile() {
8192
8200
  function setCurrentProfile(profile) {
8193
8201
  const configDir = getConfigDir();
8194
8202
  mkdirSync4(configDir, { recursive: true });
8195
- writeFileSync3(join7(configDir, "current_profile"), profile);
8203
+ writeFileSync3(join6(configDir, "current_profile"), profile);
8196
8204
  }
8197
8205
  function getFlatProfilePath(profile) {
8198
- return join7(getProfilesDir(), `${profile}.json`);
8206
+ return join6(getProfilesDir(), `${profile}.json`);
8199
8207
  }
8200
8208
  function getFlatProfileReadPaths(profile) {
8201
- return getConfigReadDirs().map((dir) => join7(dir, "profiles", `${profile}.json`));
8209
+ return getConfigReadDirs().map((dir) => join6(dir, "profiles", `${profile}.json`));
8202
8210
  }
8203
8211
  function getDirectoryProfileReadPaths(profile) {
8204
- return getConfigReadDirs().map((dir) => join7(dir, "profiles", profile, "config.json"));
8212
+ return getConfigReadDirs().map((dir) => join6(dir, "profiles", profile, "config.json"));
8205
8213
  }
8206
8214
  function loadJsonFile(path) {
8207
8215
  try {
@@ -8221,8 +8229,8 @@ function sanitizeProfileConfig(config) {
8221
8229
  };
8222
8230
  }
8223
8231
  function loadProfile(profile = getCurrentProfile()) {
8224
- const flatConfig = getFlatProfileReadPaths(profile).reverse().reduce((config, path) => ({ ...config, ...existsSync7(path) ? loadJsonFile(path) : {} }), {});
8225
- const directoryConfig = getDirectoryProfileReadPaths(profile).reverse().reduce((config, path) => ({ ...config, ...existsSync7(path) ? loadJsonFile(path) : {} }), {});
8232
+ const flatConfig = getFlatProfileReadPaths(profile).reverse().reduce((config, path) => ({ ...config, ...existsSync6(path) ? loadJsonFile(path) : {} }), {});
8233
+ const directoryConfig = getDirectoryProfileReadPaths(profile).reverse().reduce((config, path) => ({ ...config, ...existsSync6(path) ? loadJsonFile(path) : {} }), {});
8226
8234
  return sanitizeProfileConfig({
8227
8235
  ...flatConfig,
8228
8236
  ...directoryConfig
@@ -8238,17 +8246,17 @@ function profileExists(profile) {
8238
8246
  if (profile === "default") {
8239
8247
  return true;
8240
8248
  }
8241
- return getFlatProfileReadPaths(profile).some((path) => existsSync7(path)) || getConfigReadDirs().some((dir) => existsSync7(join7(dir, "profiles", profile)));
8249
+ return getFlatProfileReadPaths(profile).some((path) => existsSync6(path)) || getConfigReadDirs().some((dir) => existsSync6(join6(dir, "profiles", profile)));
8242
8250
  }
8243
8251
  function listProfiles3() {
8244
8252
  const seen = new Set(["default"]);
8245
8253
  for (const configDir of getConfigReadDirs()) {
8246
- const profilesDir = join7(configDir, "profiles");
8247
- if (!existsSync7(profilesDir))
8254
+ const profilesDir = join6(configDir, "profiles");
8255
+ if (!existsSync6(profilesDir))
8248
8256
  continue;
8249
8257
  try {
8250
8258
  for (const entry of readdirSync5(profilesDir)) {
8251
- const fullPath = join7(profilesDir, entry);
8259
+ const fullPath = join6(profilesDir, entry);
8252
8260
  const stat = statSync3(fullPath);
8253
8261
  if (stat.isDirectory()) {
8254
8262
  seen.add(entry);
@@ -8270,11 +8278,11 @@ function createProfile(profile, config = {}) {
8270
8278
  }
8271
8279
  function clearProfile(profile = getCurrentProfile()) {
8272
8280
  const flatPath = getFlatProfilePath(profile);
8273
- const directoryPath = join7(getProfilesDir(), profile);
8274
- if (existsSync7(flatPath)) {
8281
+ const directoryPath = join6(getProfilesDir(), profile);
8282
+ if (existsSync6(flatPath)) {
8275
8283
  rmSync(flatPath);
8276
8284
  }
8277
- if (existsSync7(directoryPath)) {
8285
+ if (existsSync6(directoryPath)) {
8278
8286
  rmSync(directoryPath, { recursive: true, force: true });
8279
8287
  }
8280
8288
  }
@@ -9200,18 +9208,18 @@ var init_imessage = __esm(() => {
9200
9208
  });
9201
9209
 
9202
9210
  // src/core/connectors/stripe.ts
9203
- import { existsSync as existsSync8 } from "fs";
9204
- import { dirname as dirname3, join as join8 } from "path";
9211
+ import { existsSync as existsSync7 } from "fs";
9212
+ import { dirname as dirname3, join as join7 } from "path";
9205
9213
  import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "url";
9206
9214
  function resolveStripeConnectorDir() {
9207
9215
  const candidates = [
9208
- join8(__dirname3, "..", "..", "..", "connectors", "stripe"),
9209
- join8(__dirname3, "..", "..", "connectors", "stripe"),
9210
- join8(__dirname3, "..", "connectors", "stripe"),
9211
- join8(process.cwd(), "connectors", "stripe")
9216
+ join7(__dirname3, "..", "..", "..", "connectors", "stripe"),
9217
+ join7(__dirname3, "..", "..", "connectors", "stripe"),
9218
+ join7(__dirname3, "..", "connectors", "stripe"),
9219
+ join7(process.cwd(), "connectors", "stripe")
9212
9220
  ];
9213
9221
  for (const candidate of candidates) {
9214
- if (existsSync8(candidate)) {
9222
+ if (existsSync7(candidate)) {
9215
9223
  return candidate;
9216
9224
  }
9217
9225
  }
@@ -9259,10 +9267,10 @@ function buildCommandHelp2(spec) {
9259
9267
  `);
9260
9268
  }
9261
9269
  async function loadStripeApiModule() {
9262
- return await import(pathToFileURL2(join8(CONNECTOR_DIR2, "src", "api", "index.ts")).href);
9270
+ return await import(pathToFileURL2(join7(CONNECTOR_DIR2, "src", "api", "index.ts")).href);
9263
9271
  }
9264
9272
  async function loadStripeConfigModule() {
9265
- return await import(pathToFileURL2(join8(CONNECTOR_DIR2, "src", "utils", "config.ts")).href);
9273
+ return await import(pathToFileURL2(join7(CONNECTOR_DIR2, "src", "utils", "config.ts")).href);
9266
9274
  }
9267
9275
  function extractGlobalArgs3(args) {
9268
9276
  const remaining = [];
@@ -18386,8 +18394,8 @@ __export(exports_registry, {
18386
18394
  CONNECTORS: () => CONNECTORS,
18387
18395
  CATEGORIES: () => CATEGORIES
18388
18396
  });
18389
- import { existsSync as existsSync9, readFileSync as readFileSync4 } from "fs";
18390
- import { join as join9, dirname as dirname4 } from "path";
18397
+ import { existsSync as existsSync8, readFileSync as readFileSync4 } from "fs";
18398
+ import { join as join8, dirname as dirname4 } from "path";
18391
18399
  import { fileURLToPath as fileURLToPath3 } from "url";
18392
18400
  function getConnectorsByCategory(category) {
18393
18401
  return CONNECTORS.filter((c) => c.category === category);
@@ -18551,16 +18559,16 @@ function loadConnectorVersions() {
18551
18559
  versionsLoaded = true;
18552
18560
  const thisDir = dirname4(fileURLToPath3(import.meta.url));
18553
18561
  const candidates = [
18554
- join9(thisDir, "..", "connectors"),
18555
- join9(thisDir, "..", "..", "connectors")
18562
+ join8(thisDir, "..", "connectors"),
18563
+ join8(thisDir, "..", "..", "connectors")
18556
18564
  ];
18557
- const connectorsDir = candidates.find((d) => existsSync9(d));
18565
+ const connectorsDir = candidates.find((d) => existsSync8(d));
18558
18566
  if (!connectorsDir)
18559
18567
  return;
18560
18568
  for (const connector of CONNECTORS) {
18561
18569
  try {
18562
- const pkgPath = join9(getConnectorPackagePath(connectorsDir, connector.name), "package.json");
18563
- if (existsSync9(pkgPath)) {
18570
+ const pkgPath = join8(getConnectorPackagePath(connectorsDir, connector.name), "package.json");
18571
+ if (existsSync8(pkgPath)) {
18564
18572
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
18565
18573
  connector.version = pkg.version || "0.0.0";
18566
18574
  continue;
@@ -20285,30 +20293,30 @@ __export(exports_installer, {
20285
20293
  getConnectorDocs: () => getConnectorDocs,
20286
20294
  connectorExists: () => connectorExists
20287
20295
  });
20288
- import { existsSync as existsSync10, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync4, readdirSync as readdirSync6, statSync as statSync4, rmSync as rmSync2 } from "fs";
20289
- import { join as join10, dirname as dirname5 } from "path";
20296
+ import { existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync4, readdirSync as readdirSync6, statSync as statSync4, rmSync as rmSync2 } from "fs";
20297
+ import { join as join9, dirname as dirname5 } from "path";
20290
20298
  import { fileURLToPath as fileURLToPath4 } from "url";
20291
20299
  function resolveConnectorsDir() {
20292
- const fromBin = join10(__dirname4, "..", "connectors");
20293
- if (existsSync10(fromBin))
20300
+ const fromBin = join9(__dirname4, "..", "connectors");
20301
+ if (existsSync9(fromBin))
20294
20302
  return fromBin;
20295
- const fromSrc = join10(__dirname4, "..", "..", "connectors");
20296
- if (existsSync10(fromSrc))
20303
+ const fromSrc = join9(__dirname4, "..", "..", "connectors");
20304
+ if (existsSync9(fromSrc))
20297
20305
  return fromSrc;
20298
20306
  return fromBin;
20299
20307
  }
20300
20308
  function getProjectConnectorsDir(targetDir) {
20301
- return join10(targetDir, PROJECT_CONNECTORS_DIRNAME);
20309
+ return join9(targetDir, PROJECT_CONNECTORS_DIRNAME);
20302
20310
  }
20303
20311
  function getEnablementManifestPath(targetDir) {
20304
- return join10(getProjectConnectorsDir(targetDir), ENABLEMENT_MANIFEST_FILENAME);
20312
+ return join9(getProjectConnectorsDir(targetDir), ENABLEMENT_MANIFEST_FILENAME);
20305
20313
  }
20306
20314
  function getLegacyInstallPath(targetDir, name) {
20307
- return join10(getProjectConnectorsDir(targetDir), legacyConnectorName(name));
20315
+ return join9(getProjectConnectorsDir(targetDir), legacyConnectorName(name));
20308
20316
  }
20309
20317
  function loadEnablementManifest(targetDir) {
20310
20318
  const manifestPath = getEnablementManifestPath(targetDir);
20311
- if (!existsSync10(manifestPath)) {
20319
+ if (!existsSync9(manifestPath)) {
20312
20320
  return null;
20313
20321
  }
20314
20322
  try {
@@ -20328,11 +20336,11 @@ function loadEnablementManifest(targetDir) {
20328
20336
  }
20329
20337
  function getLegacyInstalledConnectors(targetDir) {
20330
20338
  const connectorsDir = getProjectConnectorsDir(targetDir);
20331
- if (!existsSync10(connectorsDir)) {
20339
+ if (!existsSync9(connectorsDir)) {
20332
20340
  return [];
20333
20341
  }
20334
20342
  return readdirSync6(connectorsDir).filter((entry) => {
20335
- const fullPath = join10(connectorsDir, entry);
20343
+ const fullPath = join9(connectorsDir, entry);
20336
20344
  return entry.startsWith("connect-") && statSync4(fullPath).isDirectory();
20337
20345
  }).map((entry) => entry.replace("connect-", "")).sort();
20338
20346
  }
@@ -20341,7 +20349,7 @@ function getEnabledConnectors(targetDir) {
20341
20349
  return [...new Set([...manifestConnectors, ...getLegacyInstalledConnectors(targetDir)])].sort();
20342
20350
  }
20343
20351
  function updateConnectorsIndex(connectorsDir, connectors18) {
20344
- const indexPath = join10(connectorsDir, ENABLEMENT_INDEX_FILENAME);
20352
+ const indexPath = join9(connectorsDir, ENABLEMENT_INDEX_FILENAME);
20345
20353
  const connectorList = connectors18.map((connector) => ` "${connector}",`).join(`
20346
20354
  `);
20347
20355
  const content = `/**
@@ -20377,7 +20385,7 @@ function getConnectorPath(name) {
20377
20385
  }
20378
20386
  function connectorExists(name) {
20379
20387
  const normalizedName = normalizeConnectorName(name);
20380
- return hasInternalConnectorDefinition(normalizedName) || existsSync10(getConnectorPath(normalizedName));
20388
+ return hasInternalConnectorDefinition(normalizedName) || existsSync9(getConnectorPath(normalizedName));
20381
20389
  }
20382
20390
  function installConnector(name, options = {}) {
20383
20391
  const { targetDir = process.cwd(), overwrite = false } = options;
@@ -20410,7 +20418,7 @@ function installConnector(name, options = {}) {
20410
20418
  try {
20411
20419
  const nextEnabled = [...new Set([...installed, normalizedName])].sort();
20412
20420
  writeEnablementManifest(targetDir, nextEnabled);
20413
- if (overwrite && existsSync10(legacyInstallPath)) {
20421
+ if (overwrite && existsSync9(legacyInstallPath)) {
20414
20422
  rmSync2(legacyInstallPath, { recursive: true });
20415
20423
  }
20416
20424
  return {
@@ -20445,8 +20453,8 @@ function parseConnectorDocs(raw) {
20445
20453
  function getConnectorDocs(name) {
20446
20454
  const normalizedName = normalizeConnectorName(name);
20447
20455
  const connectorPath = getConnectorPath(normalizedName);
20448
- const claudeMdPath = join10(connectorPath, "CLAUDE.md");
20449
- if (existsSync10(claudeMdPath)) {
20456
+ const claudeMdPath = join9(connectorPath, "CLAUDE.md");
20457
+ if (existsSync9(claudeMdPath)) {
20450
20458
  return parseConnectorDocs(readFileSync5(claudeMdPath, "utf-8"));
20451
20459
  }
20452
20460
  const internalDocs = getInternalConnectorDefinition(normalizedName)?.docsMarkdown;
@@ -20491,7 +20499,7 @@ function removeConnector(name, targetDir = process.cwd()) {
20491
20499
  const nextEnabled = installed.filter((connector) => connector !== normalizedName);
20492
20500
  writeEnablementManifest(targetDir, nextEnabled);
20493
20501
  const legacyInstallPath = getLegacyInstallPath(targetDir, normalizedName);
20494
- if (existsSync10(legacyInstallPath)) {
20502
+ if (existsSync9(legacyInstallPath)) {
20495
20503
  rmSync2(legacyInstallPath, { recursive: true });
20496
20504
  }
20497
20505
  return true;
@@ -20578,7 +20586,7 @@ function maybeTruncateOutput(text, options = {}) {
20578
20586
  var DEFAULT_COMPACT_LIMIT = 20, DEFAULT_MCP_LIMIT = 20, MAX_COMPACT_LIMIT = 100, DEFAULT_TEXT_WIDTH = 96, DEFAULT_OUTPUT_CHARS = 6000;
20579
20587
 
20580
20588
  // src/lib/lock.ts
20581
- import { openSync, closeSync, unlinkSync, existsSync as existsSync11, statSync as statSync6 } from "fs";
20589
+ import { openSync, closeSync, unlinkSync, existsSync as existsSync10, statSync as statSync6 } from "fs";
20582
20590
  import { mkdirSync as mkdirSync6 } from "fs";
20583
20591
  function lockPath(connector) {
20584
20592
  const dir = getConnectorConfigDir(connector);
@@ -20594,7 +20602,7 @@ function isStale(path) {
20594
20602
  }
20595
20603
  }
20596
20604
  function tryAcquire(path) {
20597
- if (existsSync11(path) && isStale(path)) {
20605
+ if (existsSync10(path) && isStale(path)) {
20598
20606
  try {
20599
20607
  unlinkSync(path);
20600
20608
  } catch {}
@@ -20644,9 +20652,9 @@ var init_lock = __esm(() => {
20644
20652
  });
20645
20653
 
20646
20654
  // src/server/auth.ts
20647
- import { chmodSync, existsSync as existsSync12, readFileSync as readFileSync6, writeFileSync as writeFileSync5, mkdirSync as mkdirSync7, readdirSync as readdirSync8, rmSync as rmSync3, statSync as statSync7 } from "fs";
20655
+ import { chmodSync, existsSync as existsSync11, readFileSync as readFileSync6, writeFileSync as writeFileSync5, mkdirSync as mkdirSync7, readdirSync as readdirSync8, rmSync as rmSync3, statSync as statSync7 } from "fs";
20648
20656
  import { randomBytes } from "crypto";
20649
- import { join as join12 } from "path";
20657
+ import { join as join11 } from "path";
20650
20658
  function getAuthType(name) {
20651
20659
  name = normalizeConnectorName(name);
20652
20660
  const docs = getConnectorDocs(name);
@@ -20687,8 +20695,8 @@ function writePrivateText(path, data) {
20687
20695
  function getCurrentProfile2(name) {
20688
20696
  name = normalizeConnectorName(name);
20689
20697
  for (const configDir of getConnectorConfigReadDirs2(name)) {
20690
- const currentProfileFile = join12(configDir, "current_profile");
20691
- if (existsSync12(currentProfileFile)) {
20698
+ const currentProfileFile = join11(configDir, "current_profile");
20699
+ if (existsSync11(currentProfileFile)) {
20692
20700
  try {
20693
20701
  return readFileSync6(currentProfileFile, "utf-8").trim() || "default";
20694
20702
  } catch {
@@ -20701,14 +20709,14 @@ function getCurrentProfile2(name) {
20701
20709
  function loadProfileConfigFromDir(configDir, profile) {
20702
20710
  let flatConfig = {};
20703
20711
  let dirConfig = {};
20704
- const profileFile = join12(configDir, "profiles", `${profile}.json`);
20705
- if (existsSync12(profileFile)) {
20712
+ const profileFile = join11(configDir, "profiles", `${profile}.json`);
20713
+ if (existsSync11(profileFile)) {
20706
20714
  try {
20707
20715
  flatConfig = JSON.parse(readFileSync6(profileFile, "utf-8"));
20708
20716
  } catch {}
20709
20717
  }
20710
- const profileDirConfig = join12(configDir, "profiles", profile, "config.json");
20711
- if (existsSync12(profileDirConfig)) {
20718
+ const profileDirConfig = join11(configDir, "profiles", profile, "config.json");
20719
+ if (existsSync11(profileDirConfig)) {
20712
20720
  try {
20713
20721
  dirConfig = JSON.parse(readFileSync6(profileDirConfig, "utf-8"));
20714
20722
  } catch {}
@@ -20728,8 +20736,8 @@ function loadTokens3(name) {
20728
20736
  name = normalizeConnectorName(name);
20729
20737
  const profile = getCurrentProfile2(name);
20730
20738
  for (const configDir of getConnectorConfigReadDirs2(name)) {
20731
- const tokensFile = join12(configDir, "profiles", profile, "tokens.json");
20732
- if (existsSync12(tokensFile)) {
20739
+ const tokensFile = join11(configDir, "profiles", profile, "tokens.json");
20740
+ if (existsSync11(tokensFile)) {
20733
20741
  try {
20734
20742
  return JSON.parse(readFileSync6(tokensFile, "utf-8"));
20735
20743
  } catch {
@@ -20862,10 +20870,10 @@ function _saveApiKey(name, key, field) {
20862
20870
  const profile = getCurrentProfile2(name);
20863
20871
  const keyField = field || guessKeyField(name);
20864
20872
  if (keyField === "clientId" || keyField === "clientSecret") {
20865
- const credentialsFile = join12(configDir, "credentials.json");
20873
+ const credentialsFile = join11(configDir, "credentials.json");
20866
20874
  ensurePrivateDir(configDir);
20867
20875
  let creds = {};
20868
- if (existsSync12(credentialsFile)) {
20876
+ if (existsSync11(credentialsFile)) {
20869
20877
  try {
20870
20878
  creds = JSON.parse(readFileSync6(credentialsFile, "utf-8"));
20871
20879
  } catch {}
@@ -20874,10 +20882,10 @@ function _saveApiKey(name, key, field) {
20874
20882
  writePrivateJson(credentialsFile, creds);
20875
20883
  return;
20876
20884
  }
20877
- const profilesDir = join12(configDir, "profiles");
20878
- const profileFile = join12(profilesDir, `${profile}.json`);
20879
- const profileDir = join12(profilesDir, profile);
20880
- if (existsSync12(profileFile)) {
20885
+ const profilesDir = join11(configDir, "profiles");
20886
+ const profileFile = join11(profilesDir, `${profile}.json`);
20887
+ const profileDir = join11(profilesDir, profile);
20888
+ if (existsSync11(profileFile)) {
20881
20889
  let config = {};
20882
20890
  try {
20883
20891
  config = JSON.parse(readFileSync6(profileFile, "utf-8"));
@@ -20888,10 +20896,10 @@ function _saveApiKey(name, key, field) {
20888
20896
  writePrivateJson(profileFile, config);
20889
20897
  return;
20890
20898
  }
20891
- if (existsSync12(profileDir)) {
20892
- const configFile = join12(profileDir, "config.json");
20899
+ if (existsSync11(profileDir)) {
20900
+ const configFile = join11(profileDir, "config.json");
20893
20901
  let config = {};
20894
- if (existsSync12(configFile)) {
20902
+ if (existsSync11(configFile)) {
20895
20903
  try {
20896
20904
  config = JSON.parse(readFileSync6(configFile, "utf-8"));
20897
20905
  } catch {}
@@ -20906,7 +20914,7 @@ function _saveApiKey(name, key, field) {
20906
20914
  ensurePrivateDir(configDir);
20907
20915
  ensurePrivateDir(profilesDir);
20908
20916
  ensurePrivateDir(profileDir);
20909
- writePrivateJson(join12(profileDir, "config.json"), { [keyField]: key });
20917
+ writePrivateJson(join11(profileDir, "config.json"), { [keyField]: key });
20910
20918
  }
20911
20919
  function guessKeyField(name) {
20912
20920
  name = normalizeConnectorName(name);
@@ -20926,8 +20934,8 @@ function guessKeyField(name) {
20926
20934
  function getOAuthConfig(name) {
20927
20935
  name = normalizeConnectorName(name);
20928
20936
  for (const configDir of getConnectorConfigReadDirs2(name)) {
20929
- const credentialsFile = join12(configDir, "credentials.json");
20930
- if (existsSync12(credentialsFile)) {
20937
+ const credentialsFile = join11(configDir, "credentials.json");
20938
+ if (existsSync11(credentialsFile)) {
20931
20939
  try {
20932
20940
  const creds = JSON.parse(readFileSync6(credentialsFile, "utf-8"));
20933
20941
  return { clientId: creds.clientId, clientSecret: creds.clientSecret };
@@ -21013,12 +21021,12 @@ function saveOAuthTokens(name, tokens) {
21013
21021
  name = normalizeConnectorName(name);
21014
21022
  const configDir = getConnectorConfigDir2(name);
21015
21023
  const profile = getCurrentProfile2(name);
21016
- const profilesDir = join12(configDir, "profiles");
21017
- const profileDir = join12(profilesDir, profile);
21024
+ const profilesDir = join11(configDir, "profiles");
21025
+ const profileDir = join11(profilesDir, profile);
21018
21026
  ensurePrivateDir(configDir);
21019
21027
  ensurePrivateDir(profilesDir);
21020
21028
  ensurePrivateDir(profileDir);
21021
- const tokensFile = join12(profileDir, "tokens.json");
21029
+ const tokensFile = join11(profileDir, "tokens.json");
21022
21030
  writePrivateJson(tokensFile, tokens);
21023
21031
  }
21024
21032
  async function refreshOAuthToken(name) {
@@ -21065,13 +21073,13 @@ function listProfiles4(name) {
21065
21073
  name = normalizeConnectorName(name);
21066
21074
  const seen = new Set;
21067
21075
  for (const configDir of getConnectorConfigReadDirs2(name)) {
21068
- const profilesDir = join12(configDir, "profiles");
21069
- if (!existsSync12(profilesDir))
21076
+ const profilesDir = join11(configDir, "profiles");
21077
+ if (!existsSync11(profilesDir))
21070
21078
  continue;
21071
21079
  try {
21072
21080
  const entries = readdirSync8(profilesDir);
21073
21081
  for (const entry of entries) {
21074
- const fullPath = join12(profilesDir, entry);
21082
+ const fullPath = join11(profilesDir, entry);
21075
21083
  const stat = statSync7(fullPath);
21076
21084
  if (stat.isDirectory()) {
21077
21085
  seen.add(entry);
@@ -21088,24 +21096,24 @@ function switchProfile(name, profile) {
21088
21096
  name = normalizeConnectorName(name);
21089
21097
  const configDir = getConnectorConfigDir2(name);
21090
21098
  ensurePrivateDir(configDir);
21091
- writePrivateText(join12(configDir, "current_profile"), profile);
21099
+ writePrivateText(join11(configDir, "current_profile"), profile);
21092
21100
  }
21093
21101
  function deleteProfile2(name, profile) {
21094
21102
  name = normalizeConnectorName(name);
21095
21103
  if (profile === "default")
21096
21104
  return false;
21097
21105
  const configDir = getConnectorConfigDir2(name);
21098
- const profilesDir = join12(configDir, "profiles");
21099
- const profileFile = join12(profilesDir, `${profile}.json`);
21100
- if (existsSync12(profileFile)) {
21106
+ const profilesDir = join11(configDir, "profiles");
21107
+ const profileFile = join11(profilesDir, `${profile}.json`);
21108
+ if (existsSync11(profileFile)) {
21101
21109
  rmSync3(profileFile);
21102
21110
  if (getCurrentProfile2(name) === profile) {
21103
21111
  switchProfile(name, "default");
21104
21112
  }
21105
21113
  return true;
21106
21114
  }
21107
- const profileDir = join12(profilesDir, profile);
21108
- if (existsSync12(profileDir)) {
21115
+ const profileDir = join11(profilesDir, profile);
21116
+ if (existsSync11(profileDir)) {
21109
21117
  rmSync3(profileDir, { recursive: true });
21110
21118
  if (getCurrentProfile2(name) === profile) {
21111
21119
  switchProfile(name, "default");
@@ -21175,7 +21183,7 @@ __export(exports_promotions, {
21175
21183
  });
21176
21184
  function promoteConnector(name, db) {
21177
21185
  const d = db ?? getDatabase();
21178
- d.run("INSERT OR REPLACE INTO connector_promotions (connector, promoted_at) VALUES (?, ?)", [name, now2()]);
21186
+ d.run("INSERT OR REPLACE INTO connector_promotions (connector, promoted_at) VALUES (?, ?)", [name, now()]);
21179
21187
  }
21180
21188
  function demoteConnector(name, db) {
21181
21189
  const d = db ?? getDatabase();
@@ -21205,7 +21213,7 @@ __export(exports_usage, {
21205
21213
  });
21206
21214
  function logUsage(connector, action, agentId, db) {
21207
21215
  const d = db ?? getDatabase();
21208
- d.run("INSERT INTO connector_usage (id, connector, action, agent_id, timestamp) VALUES (?, ?, ?, ?, ?)", [shortUuid(), connector, action, agentId ?? null, now2()]);
21216
+ d.run("INSERT INTO connector_usage (id, connector, action, agent_id, timestamp) VALUES (?, ?, ?, ?, ?)", [shortUuid(), connector, action, agentId ?? null, now()]);
21209
21217
  }
21210
21218
  function getUsageStats(connector, db) {
21211
21219
  const d = db ?? getDatabase();
@@ -21263,7 +21271,7 @@ function registerAgent(input, db) {
21263
21271
  };
21264
21272
  }
21265
21273
  const updates = ["last_seen_at = ?"];
21266
- const params = [now2()];
21274
+ const params = [now()];
21267
21275
  if (input.session_id && !sameSession) {
21268
21276
  updates.push("session_id = ?");
21269
21277
  params.push(input.session_id);
@@ -21273,7 +21281,7 @@ function registerAgent(input, db) {
21273
21281
  return getAgent(existing.id, d);
21274
21282
  }
21275
21283
  const id = shortUuid2();
21276
- const ts = now2();
21284
+ const ts = now();
21277
21285
  d.run(`INSERT INTO agents (id, name, session_id, role, last_seen_at, created_at)
21278
21286
  VALUES (?, ?, ?, ?, ?, ?)`, [id, normalizedName, input.session_id ?? null, input.role ?? "agent", ts, ts]);
21279
21287
  return getAgent(id, d);
@@ -21292,12 +21300,12 @@ function listAgents(db) {
21292
21300
  }
21293
21301
  function heartbeat(id, db) {
21294
21302
  const d = db ?? getDatabase();
21295
- d.run("UPDATE agents SET last_seen_at = ? WHERE id = ?", [now2(), id]);
21303
+ d.run("UPDATE agents SET last_seen_at = ? WHERE id = ?", [now(), id]);
21296
21304
  return getAgent(id, d);
21297
21305
  }
21298
21306
  function setFocus(id, projectId, db) {
21299
21307
  const d = db ?? getDatabase();
21300
- d.run("UPDATE agents SET project_id = ?, last_seen_at = ? WHERE id = ?", [projectId, now2(), id]);
21308
+ d.run("UPDATE agents SET project_id = ?, last_seen_at = ? WHERE id = ?", [projectId, now(), id]);
21301
21309
  return getAgent(id, d);
21302
21310
  }
21303
21311
  function deleteAgent(id, db) {
@@ -21329,9 +21337,9 @@ function countActiveAgents(db) {
21329
21337
  return Math.max(1, row?.count ?? 1);
21330
21338
  }
21331
21339
  function currentWindowStart() {
21332
- const now4 = Date.now();
21340
+ const now3 = Date.now();
21333
21341
  const windowMs = WINDOW_SECONDS * 1000;
21334
- return new Date(Math.floor(now4 / windowMs) * windowMs).toISOString();
21342
+ return new Date(Math.floor(now3 / windowMs) * windowMs).toISOString();
21335
21343
  }
21336
21344
  function checkRateBudget(agentId, connector, connectorLimit, consume = true, db) {
21337
21345
  const d = db ?? getDatabase();
@@ -21393,14 +21401,14 @@ __export(exports_llm, {
21393
21401
  PROVIDER_DEFAULTS: () => PROVIDER_DEFAULTS,
21394
21402
  LLMClient: () => LLMClient
21395
21403
  });
21396
- import { existsSync as existsSync13, readFileSync as readFileSync7, writeFileSync as writeFileSync6, mkdirSync as mkdirSync8 } from "fs";
21397
- import { join as join13 } from "path";
21404
+ import { existsSync as existsSync12, readFileSync as readFileSync7, writeFileSync as writeFileSync6, mkdirSync as mkdirSync8 } from "fs";
21405
+ import { join as join12 } from "path";
21398
21406
  function getLlmConfigPath() {
21399
- return join13(getConnectorsHome(), "llm.json");
21407
+ return join12(getConnectorsHome(), "llm.json");
21400
21408
  }
21401
21409
  function getLlmConfig() {
21402
21410
  const path = getLlmConfigPath();
21403
- if (!existsSync13(path))
21411
+ if (!existsSync12(path))
21404
21412
  return null;
21405
21413
  try {
21406
21414
  return JSON.parse(readFileSync7(path, "utf-8"));
@@ -21561,7 +21569,7 @@ function rowToJob(row) {
21561
21569
  function createJob(input, db) {
21562
21570
  const d = db ?? getDatabase();
21563
21571
  const id = shortUuid();
21564
- const ts = now2();
21572
+ const ts = now();
21565
21573
  d.run("INSERT INTO connector_jobs (id, name, connector, command, args, cron, enabled, strip, created_at) VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?)", [id, input.name, input.connector, input.command, JSON.stringify(input.args ?? []), input.cron, input.strip ? 1 : 0, ts]);
21566
21574
  return getJob(id, d);
21567
21575
  }
@@ -21627,18 +21635,18 @@ function deleteJob(id, db) {
21627
21635
  }
21628
21636
  function touchJobLastRun(id, db) {
21629
21637
  const d = db ?? getDatabase();
21630
- d.run("UPDATE connector_jobs SET last_run_at = ? WHERE id = ?", [now2(), id]);
21638
+ d.run("UPDATE connector_jobs SET last_run_at = ? WHERE id = ?", [now(), id]);
21631
21639
  }
21632
21640
  function createJobRun(jobId, db) {
21633
21641
  const d = db ?? getDatabase();
21634
21642
  const id = shortUuid();
21635
- const ts = now2();
21643
+ const ts = now();
21636
21644
  d.run("INSERT INTO connector_job_runs (id, job_id, started_at) VALUES (?, ?, ?)", [id, jobId, ts]);
21637
21645
  return { id, job_id: jobId, started_at: ts, finished_at: null, exit_code: null, raw_output: null, stripped_output: null };
21638
21646
  }
21639
21647
  function finishJobRun(id, result, db) {
21640
21648
  const d = db ?? getDatabase();
21641
- d.run("UPDATE connector_job_runs SET finished_at = ?, exit_code = ?, raw_output = ?, stripped_output = ? WHERE id = ?", [now2(), result.exit_code, result.raw_output, result.stripped_output ?? null, id]);
21649
+ d.run("UPDATE connector_job_runs SET finished_at = ?, exit_code = ?, raw_output = ?, stripped_output = ? WHERE id = ?", [now(), result.exit_code, result.raw_output, result.stripped_output ?? null, id]);
21642
21650
  }
21643
21651
  function getLatestRun(jobId, db) {
21644
21652
  const d = db ?? getDatabase();
@@ -21663,7 +21671,7 @@ function rowToWorkflow(row) {
21663
21671
  function createWorkflow(input, db) {
21664
21672
  const d = db ?? getDatabase();
21665
21673
  const id = shortUuid();
21666
- d.run("INSERT INTO connector_workflows (id, name, steps, enabled, created_at) VALUES (?, ?, ?, 1, ?)", [id, input.name, JSON.stringify(input.steps), now2()]);
21674
+ d.run("INSERT INTO connector_workflows (id, name, steps, enabled, created_at) VALUES (?, ?, ?, 1, ?)", [id, input.name, JSON.stringify(input.steps), now()]);
21667
21675
  return getWorkflow(id, d);
21668
21676
  }
21669
21677
  function getWorkflow(id, db) {
@@ -21696,7 +21704,7 @@ __export(exports_scheduler, {
21696
21704
  startScheduler: () => startScheduler,
21697
21705
  cronMatches: () => cronMatches
21698
21706
  });
21699
- import { spawn as spawn2 } from "child_process";
21707
+ import { spawn } from "child_process";
21700
21708
  function cronMatches(cron, d) {
21701
21709
  const parts = cron.trim().split(/\s+/);
21702
21710
  if (parts.length !== 5)
@@ -21723,7 +21731,7 @@ function cronMatches(cron, d) {
21723
21731
  async function runConnectorCommand(connector, command, args) {
21724
21732
  return new Promise((resolve) => {
21725
21733
  const cmdArgs = [connector, command, ...args, "--format", "json"];
21726
- const proc = spawn2("connectors", ["run", ...cmdArgs], { shell: false });
21734
+ const proc = spawn("connectors", ["run", ...cmdArgs], { shell: false });
21727
21735
  let output = "";
21728
21736
  proc.stdout.on("data", (d) => {
21729
21737
  output += d.toString();
@@ -21760,14 +21768,14 @@ function startScheduler(db) {
21760
21768
  _interval = setInterval(() => {
21761
21769
  (async () => {
21762
21770
  try {
21763
- const now4 = new Date;
21764
- const currentMinute = now4.getMinutes() + now4.getHours() * 60;
21771
+ const now3 = new Date;
21772
+ const currentMinute = now3.getMinutes() + now3.getHours() * 60;
21765
21773
  if (currentMinute === _lastCheckedMinute)
21766
21774
  return;
21767
21775
  _lastCheckedMinute = currentMinute;
21768
21776
  const jobs = listEnabledJobs(db);
21769
21777
  for (const job of jobs) {
21770
- if (cronMatches(job.cron, now4)) {
21778
+ if (cronMatches(job.cron, now3)) {
21771
21779
  executeJob(job, db).catch(() => {});
21772
21780
  }
21773
21781
  }
@@ -21869,16 +21877,16 @@ __export(exports_runner, {
21869
21877
  buildEnvWithCredentials: () => buildEnvWithCredentials,
21870
21878
  buildConnectorOperationArgs: () => buildConnectorOperationArgs
21871
21879
  });
21872
- import { existsSync as existsSync14, readdirSync as readdirSync9 } from "fs";
21873
- import { join as join14, dirname as dirname6 } from "path";
21880
+ import { existsSync as existsSync13, readdirSync as readdirSync9 } from "fs";
21881
+ import { join as join13, dirname as dirname6 } from "path";
21874
21882
  import { fileURLToPath as fileURLToPath5 } from "url";
21875
- import { spawn as spawn3 } from "child_process";
21883
+ import { spawn as spawn2 } from "child_process";
21876
21884
  function resolveConnectorsDir2() {
21877
- const fromBin = join14(__dirname5, "..", "connectors");
21878
- if (existsSync14(fromBin))
21885
+ const fromBin = join13(__dirname5, "..", "connectors");
21886
+ if (existsSync13(fromBin))
21879
21887
  return fromBin;
21880
- const fromSrc = join14(__dirname5, "..", "..", "connectors");
21881
- if (existsSync14(fromSrc))
21888
+ const fromSrc = join13(__dirname5, "..", "..", "connectors");
21889
+ if (existsSync13(fromSrc))
21882
21890
  return fromSrc;
21883
21891
  return fromBin;
21884
21892
  }
@@ -21946,8 +21954,8 @@ function buildEnvWithCredentials(connectorName, baseEnv) {
21946
21954
  function getConnectorCliPath(name) {
21947
21955
  const safeName = normalizeConnectorName(name).replace(/[^a-z0-9-]/g, "");
21948
21956
  const connectorDir = getConnectorPackagePath(CONNECTORS_DIR2, safeName);
21949
- const cliPath = join14(connectorDir, "src", "cli", "index.ts");
21950
- if (existsSync14(cliPath))
21957
+ const cliPath = join13(connectorDir, "src", "cli", "index.ts");
21958
+ if (existsSync13(cliPath))
21951
21959
  return cliPath;
21952
21960
  return null;
21953
21961
  }
@@ -22142,7 +22150,7 @@ function runLegacyConnectorCommand(name, args, timeoutMs = 30000) {
22142
22150
  });
22143
22151
  }
22144
22152
  return new Promise((resolve) => {
22145
- const proc = spawn3("bun", ["run", cliPath, ...args], {
22153
+ const proc = spawn2("bun", ["run", cliPath, ...args], {
22146
22154
  timeout: timeoutMs,
22147
22155
  env: buildEnvWithCredentials(connectorName, process.env),
22148
22156
  stdio: ["pipe", "pipe", "pipe"]
@@ -39054,9 +39062,9 @@ var init_management = __esm(() => {
39054
39062
  });
39055
39063
 
39056
39064
  // src/mcp/tools/auth.ts
39057
- import { existsSync as existsSync15, readFileSync as readFileSync8 } from "fs";
39058
- import { join as join15 } from "path";
39059
- import { spawn as spawn4 } from "child_process";
39065
+ import { existsSync as existsSync14, readFileSync as readFileSync8 } from "fs";
39066
+ import { join as join14 } from "path";
39067
+ import { spawn as spawn3 } from "child_process";
39060
39068
  function registerAuthTools(server, stripped) {
39061
39069
  server.registerTool("connector_auth_status", {
39062
39070
  title: "Connector Auth Status",
@@ -39191,7 +39199,7 @@ function registerAuthTools(server, stripped) {
39191
39199
  const oauthUrl = `http://localhost:${serverPort}/oauth/${name}/start`;
39192
39200
  if (noBrowser) {
39193
39201
  const connectorsHome = getConnectorsHome();
39194
- const tokenPaths = getConnectorConfigReadDirs(name, connectorsHome).map((dir) => join15(dir, "profiles", "default", "tokens.json"));
39202
+ const tokenPaths = getConnectorConfigReadDirs(name, connectorsHome).map((dir) => join14(dir, "profiles", "default", "tokens.json"));
39195
39203
  let serverRunning = false;
39196
39204
  try {
39197
39205
  await fetch(`http://localhost:${serverPort}/api/connectors`);
@@ -39199,7 +39207,7 @@ function registerAuthTools(server, stripped) {
39199
39207
  } catch {}
39200
39208
  if (!serverRunning) {
39201
39209
  const scriptPath = process.argv[1];
39202
- const serverProc = spawn4("node", [scriptPath, "serve", "--port", String(serverPort)], {
39210
+ const serverProc = spawn3("node", [scriptPath, "serve", "--port", String(serverPort)], {
39203
39211
  detached: true,
39204
39212
  stdio: "ignore"
39205
39213
  });
@@ -39210,7 +39218,7 @@ function registerAuthTools(server, stripped) {
39210
39218
  const maxAttempts = 120;
39211
39219
  while (attempts < maxAttempts) {
39212
39220
  await new Promise((resolve) => setTimeout(resolve, 500));
39213
- if (tokenPaths.some((tokensPath) => existsSync15(tokensPath))) {
39221
+ if (tokenPaths.some((tokensPath) => existsSync14(tokensPath))) {
39214
39222
  break;
39215
39223
  }
39216
39224
  attempts++;
@@ -39229,7 +39237,7 @@ function registerAuthTools(server, stripped) {
39229
39237
  };
39230
39238
  }
39231
39239
  try {
39232
- const tokensPath = tokenPaths.find((path) => existsSync15(path)) ?? tokenPaths[0];
39240
+ const tokensPath = tokenPaths.find((path) => existsSync14(path)) ?? tokenPaths[0];
39233
39241
  const tokenData = JSON.parse(readFileSync8(tokensPath, "utf-8"));
39234
39242
  return {
39235
39243
  content: [{
@@ -40021,8 +40029,8 @@ var exports_serve = {};
40021
40029
  __export(exports_serve, {
40022
40030
  startServer: () => startServer
40023
40031
  });
40024
- import { existsSync as existsSync16, readdirSync as readdirSync10, readFileSync as readFileSync9, writeFileSync as writeFileSync7, mkdirSync as mkdirSync9 } from "fs";
40025
- import { join as join16, dirname as dirname7, extname, basename as basename3 } from "path";
40032
+ import { existsSync as existsSync15, readdirSync as readdirSync10, readFileSync as readFileSync9, writeFileSync as writeFileSync7, mkdirSync as mkdirSync9 } from "fs";
40033
+ import { join as join15, dirname as dirname7, extname, basename as basename3 } from "path";
40026
40034
  import { fileURLToPath as fileURLToPath6 } from "url";
40027
40035
  function logActivity(action, connector, detail) {
40028
40036
  activityLog.unshift({ action, connector, timestamp: Date.now(), detail });
@@ -40034,20 +40042,20 @@ function resolveDashboardDir() {
40034
40042
  const candidates = [];
40035
40043
  try {
40036
40044
  const scriptDir = dirname7(fileURLToPath6(import.meta.url));
40037
- candidates.push(join16(scriptDir, "..", "dashboard", "dist"));
40038
- candidates.push(join16(scriptDir, "..", "..", "dashboard", "dist"));
40045
+ candidates.push(join15(scriptDir, "..", "dashboard", "dist"));
40046
+ candidates.push(join15(scriptDir, "..", "..", "dashboard", "dist"));
40039
40047
  } catch {}
40040
40048
  if (process.argv[1]) {
40041
40049
  const mainDir = dirname7(process.argv[1]);
40042
- candidates.push(join16(mainDir, "..", "dashboard", "dist"));
40043
- candidates.push(join16(mainDir, "..", "..", "dashboard", "dist"));
40050
+ candidates.push(join15(mainDir, "..", "dashboard", "dist"));
40051
+ candidates.push(join15(mainDir, "..", "..", "dashboard", "dist"));
40044
40052
  }
40045
- candidates.push(join16(process.cwd(), "dashboard", "dist"));
40053
+ candidates.push(join15(process.cwd(), "dashboard", "dist"));
40046
40054
  for (const candidate of candidates) {
40047
- if (existsSync16(candidate))
40055
+ if (existsSync15(candidate))
40048
40056
  return candidate;
40049
40057
  }
40050
- return join16(process.cwd(), "dashboard", "dist");
40058
+ return join15(process.cwd(), "dashboard", "dist");
40051
40059
  }
40052
40060
  function json(data, status = 200, port) {
40053
40061
  return new Response(JSON.stringify(data), {
@@ -40129,7 +40137,7 @@ function oauthPage(type, title, message, hint, extra) {
40129
40137
  </body></html>`;
40130
40138
  }
40131
40139
  function serveStaticFile(filePath) {
40132
- if (!existsSync16(filePath))
40140
+ if (!existsSync15(filePath))
40133
40141
  return null;
40134
40142
  const ext = extname(filePath);
40135
40143
  const contentType = MIME_TYPES[ext] || "application/octet-stream";
@@ -40166,7 +40174,7 @@ async function startServer(requestedPort, options) {
40166
40174
  const strict = options?.strict ?? false;
40167
40175
  loadConnectorVersions();
40168
40176
  const dashboardDir = resolveDashboardDir();
40169
- const dashboardExists = existsSync16(dashboardDir);
40177
+ const dashboardExists = existsSync15(dashboardDir);
40170
40178
  if (!dashboardExists) {
40171
40179
  console.error(`
40172
40180
  Dashboard not found at: ${dashboardDir}`);
@@ -40597,8 +40605,8 @@ ${result.stderr}`;
40597
40605
  const profiles = listProfiles4(name);
40598
40606
  let current = "default";
40599
40607
  for (const configDir of getConnectorConfigReadDirs(name)) {
40600
- const currentProfileFile = join16(configDir, "current_profile");
40601
- if (existsSync16(currentProfileFile)) {
40608
+ const currentProfileFile = join15(configDir, "current_profile");
40609
+ if (existsSync15(currentProfileFile)) {
40602
40610
  try {
40603
40611
  current = readFileSync9(currentProfileFile, "utf-8").trim() || "default";
40604
40612
  } catch {}
@@ -40651,25 +40659,25 @@ ${result.stderr}`;
40651
40659
  try {
40652
40660
  const connectDir = getConnectorsHome();
40653
40661
  const result = {};
40654
- if (existsSync16(connectDir)) {
40662
+ if (existsSync15(connectDir)) {
40655
40663
  for (const connectorName of listConfiguredConnectorNames(connectDir)) {
40656
40664
  const profiles = {};
40657
40665
  for (const configDir of [...getConnectorConfigReadDirs(connectorName, connectDir)].reverse()) {
40658
- const profilesDir = join16(configDir, "profiles");
40659
- if (!existsSync16(profilesDir))
40666
+ const profilesDir = join15(configDir, "profiles");
40667
+ if (!existsSync15(profilesDir))
40660
40668
  continue;
40661
40669
  const profileEntries = readdirSync10(profilesDir, { withFileTypes: true });
40662
40670
  for (const pEntry of profileEntries) {
40663
40671
  if (pEntry.isFile() && pEntry.name.endsWith(".json")) {
40664
40672
  const profileName = basename3(pEntry.name, ".json");
40665
40673
  try {
40666
- const config2 = JSON.parse(readFileSync9(join16(profilesDir, pEntry.name), "utf-8"));
40674
+ const config2 = JSON.parse(readFileSync9(join15(profilesDir, pEntry.name), "utf-8"));
40667
40675
  profiles[profileName] = config2;
40668
40676
  } catch {}
40669
40677
  }
40670
40678
  if (pEntry.isDirectory()) {
40671
- const configPath = join16(profilesDir, pEntry.name, "config.json");
40672
- if (existsSync16(configPath)) {
40679
+ const configPath = join15(profilesDir, pEntry.name, "config.json");
40680
+ if (existsSync15(configPath)) {
40673
40681
  try {
40674
40682
  const config2 = JSON.parse(readFileSync9(configPath, "utf-8"));
40675
40683
  profiles[pEntry.name] = config2;
@@ -40714,12 +40722,12 @@ ${result.stderr}`;
40714
40722
  if (!data.profiles || typeof data.profiles !== "object")
40715
40723
  continue;
40716
40724
  const connectorDir = getConnectorConfigDir(connectorName, connectDir);
40717
- const profilesDir = join16(connectorDir, "profiles");
40725
+ const profilesDir = join15(connectorDir, "profiles");
40718
40726
  for (const [profileName, config2] of Object.entries(data.profiles)) {
40719
40727
  if (!config2 || typeof config2 !== "object")
40720
40728
  continue;
40721
40729
  mkdirSync9(profilesDir, { recursive: true });
40722
- const profileFile = join16(profilesDir, `${profileName}.json`);
40730
+ const profileFile = join15(profilesDir, `${profileName}.json`);
40723
40731
  writeFileSync7(profileFile, JSON.stringify(config2, null, 2));
40724
40732
  imported++;
40725
40733
  }
@@ -40775,12 +40783,12 @@ ${result.stderr}`;
40775
40783
  }
40776
40784
  if (dashboardExists && (method === "GET" || method === "HEAD")) {
40777
40785
  if (path !== "/") {
40778
- const filePath = join16(dashboardDir, path);
40786
+ const filePath = join15(dashboardDir, path);
40779
40787
  const res2 = serveStaticFile(filePath);
40780
40788
  if (res2)
40781
40789
  return res2;
40782
40790
  }
40783
- const indexPath = join16(dashboardDir, "index.html");
40791
+ const indexPath = join15(dashboardDir, "index.html");
40784
40792
  const res = serveStaticFile(indexPath);
40785
40793
  if (res)
40786
40794
  return res;
@@ -40865,692 +40873,10 @@ var {
40865
40873
  Help
40866
40874
  } = import__.default;
40867
40875
 
40868
- // node_modules/@hasna/events/dist/commander.js
40869
- import { chmod, mkdir, readFile, rename, writeFile } from "fs/promises";
40870
- import { existsSync } from "fs";
40871
- import { homedir } from "os";
40872
- import { join } from "path";
40873
- import { createHmac, timingSafeEqual } from "crypto";
40874
- import { randomUUID } from "crypto";
40875
- import { spawn } from "child_process";
40876
- import { randomUUID as randomUUID2 } from "crypto";
40877
- function getPathValue(input, path) {
40878
- return path.split(".").reduce((value, part) => {
40879
- if (value && typeof value === "object" && part in value) {
40880
- return value[part];
40881
- }
40882
- return;
40883
- }, input);
40884
- }
40885
- function wildcardToRegExp(pattern) {
40886
- const escaped = pattern.replace(/[|\\{}()[\]^$+?.]/g, "\\$&").replace(/\*/g, ".*");
40887
- return new RegExp(`^${escaped}$`);
40888
- }
40889
- function matchString(value, matcher) {
40890
- if (matcher === undefined)
40891
- return true;
40892
- if (value === undefined)
40893
- return false;
40894
- const matchers = Array.isArray(matcher) ? matcher : [matcher];
40895
- return matchers.some((item) => wildcardToRegExp(item).test(value));
40896
- }
40897
- function matchRecord(input, matcher) {
40898
- if (!matcher)
40899
- return true;
40900
- return Object.entries(matcher).every(([path, expected]) => {
40901
- const actual = getPathValue(input, path);
40902
- if (typeof expected === "string" || Array.isArray(expected)) {
40903
- return matchString(actual === undefined ? undefined : String(actual), expected);
40904
- }
40905
- return actual === expected;
40906
- });
40907
- }
40908
- function eventMatchesFilter(event, filter) {
40909
- return matchString(event.source, filter.source) && matchString(event.type, filter.type) && matchString(event.subject, filter.subject) && matchString(event.severity, filter.severity) && matchRecord(event.data, filter.data) && matchRecord(event.metadata, filter.metadata);
40910
- }
40911
- function channelMatchesEvent(channel, event) {
40912
- if (!channel.enabled)
40913
- return false;
40914
- if (!channel.filters || channel.filters.length === 0)
40915
- return true;
40916
- return channel.filters.some((filter) => eventMatchesFilter(event, filter));
40917
- }
40918
- var HASNA_EVENTS_DIR_ENV = "HASNA_EVENTS_DIR";
40919
- var HASNA_EVENTS_HOME_ENV = "HASNA_EVENTS_HOME";
40920
- function getEventsDataDir(override) {
40921
- return override || process.env[HASNA_EVENTS_DIR_ENV] || process.env[HASNA_EVENTS_HOME_ENV] || join(homedir(), ".hasna", "events");
40922
- }
40923
- class JsonEventsStore {
40924
- dataDir;
40925
- channelsPath;
40926
- eventsPath;
40927
- deliveriesPath;
40928
- constructor(dataDir = getEventsDataDir()) {
40929
- this.dataDir = dataDir;
40930
- this.channelsPath = join(dataDir, "channels.json");
40931
- this.eventsPath = join(dataDir, "events.json");
40932
- this.deliveriesPath = join(dataDir, "deliveries.json");
40933
- }
40934
- async init() {
40935
- await mkdir(this.dataDir, { recursive: true, mode: 448 });
40936
- await chmod(this.dataDir, 448).catch(() => {
40937
- return;
40938
- });
40939
- await this.ensureArrayFile(this.channelsPath);
40940
- await this.ensureArrayFile(this.eventsPath);
40941
- await this.ensureArrayFile(this.deliveriesPath);
40942
- }
40943
- async addChannel(channel) {
40944
- await this.init();
40945
- const channels = await this.readJson(this.channelsPath, []);
40946
- const index = channels.findIndex((item) => item.id === channel.id);
40947
- if (index >= 0) {
40948
- channels[index] = { ...channel, createdAt: channels[index].createdAt, updatedAt: new Date().toISOString() };
40949
- } else {
40950
- channels.push(channel);
40951
- }
40952
- await this.writeJson(this.channelsPath, channels);
40953
- return index >= 0 ? channels[index] : channel;
40954
- }
40955
- async listChannels() {
40956
- await this.init();
40957
- return this.readJson(this.channelsPath, []);
40958
- }
40959
- async getChannel(id) {
40960
- const channels = await this.listChannels();
40961
- return channels.find((channel) => channel.id === id);
40962
- }
40963
- async removeChannel(id) {
40964
- await this.init();
40965
- const channels = await this.readJson(this.channelsPath, []);
40966
- const next = channels.filter((channel) => channel.id !== id);
40967
- await this.writeJson(this.channelsPath, next);
40968
- return next.length !== channels.length;
40969
- }
40970
- async appendEvent(event) {
40971
- await this.init();
40972
- const events = await this.readJson(this.eventsPath, []);
40973
- events.push(event);
40974
- await this.writeJson(this.eventsPath, events);
40975
- return event;
40976
- }
40977
- async listEvents() {
40978
- await this.init();
40979
- return this.readJson(this.eventsPath, []);
40980
- }
40981
- async findEventByIdentity(identity) {
40982
- const events = await this.listEvents();
40983
- return events.find((event) => identity.id !== undefined && event.id === identity.id || identity.dedupeKey !== undefined && event.dedupeKey === identity.dedupeKey);
40984
- }
40985
- async appendDelivery(result) {
40986
- await this.init();
40987
- const deliveries = await this.readJson(this.deliveriesPath, []);
40988
- deliveries.push(result);
40989
- await this.writeJson(this.deliveriesPath, deliveries);
40990
- return result;
40991
- }
40992
- async listDeliveries() {
40993
- await this.init();
40994
- return this.readJson(this.deliveriesPath, []);
40995
- }
40996
- async exportData() {
40997
- return {
40998
- channels: await this.listChannels(),
40999
- events: await this.listEvents(),
41000
- deliveries: await this.listDeliveries()
41001
- };
41002
- }
41003
- async ensureArrayFile(path) {
41004
- if (!existsSync(path)) {
41005
- await writeFile(path, `[]
41006
- `, { encoding: "utf-8", mode: 384 });
41007
- }
41008
- await chmod(path, 384).catch(() => {
41009
- return;
41010
- });
41011
- }
41012
- async readJson(path, fallback) {
41013
- try {
41014
- const raw = await readFile(path, "utf-8");
41015
- if (!raw.trim())
41016
- return fallback;
41017
- return JSON.parse(raw);
41018
- } catch (error) {
41019
- if (error.code === "ENOENT")
41020
- return fallback;
41021
- throw error;
41022
- }
41023
- }
41024
- async writeJson(path, value) {
41025
- const tempPath = `${path}.${process.pid}.${Date.now()}.tmp`;
41026
- await writeFile(tempPath, `${JSON.stringify(value, null, 2)}
41027
- `, { encoding: "utf-8", mode: 384 });
41028
- await rename(tempPath, path);
41029
- await chmod(path, 384).catch(() => {
41030
- return;
41031
- });
41032
- }
41033
- }
41034
- var DEFAULT_SIGNATURE_TOLERANCE_MS = 5 * 60 * 1000;
41035
- function buildSignatureBase(timestamp, body) {
41036
- return `${timestamp}.${body}`;
41037
- }
41038
- function signPayload(secret, timestamp, body) {
41039
- const digest = createHmac("sha256", secret).update(buildSignatureBase(timestamp, body)).digest("hex");
41040
- return `sha256=${digest}`;
41041
- }
41042
- function now() {
41043
- return new Date().toISOString();
41044
- }
41045
- function truncate(value, max = 4096) {
41046
- return value.length > max ? `${value.slice(0, max)}...` : value;
41047
- }
41048
- function buildWebhookRequest(event, channel) {
41049
- if (!channel.webhook)
41050
- throw new Error(`Channel ${channel.id} has no webhook config`);
41051
- const body = JSON.stringify(event);
41052
- const timestamp = event.time;
41053
- const headers = {
41054
- "Content-Type": "application/json",
41055
- "User-Agent": "@hasna/events",
41056
- "X-Hasna-Event-Id": event.id,
41057
- "X-Hasna-Event-Type": event.type,
41058
- "X-Hasna-Timestamp": timestamp,
41059
- ...channel.webhook.headers
41060
- };
41061
- if (channel.webhook.secret) {
41062
- headers["X-Hasna-Signature"] = signPayload(channel.webhook.secret, timestamp, body);
41063
- }
41064
- return { body, headers };
41065
- }
41066
- async function dispatchWebhook(event, channel, options = {}) {
41067
- if (!channel.webhook)
41068
- throw new Error(`Channel ${channel.id} has no webhook config`);
41069
- const startedAt = now();
41070
- const { body, headers } = buildWebhookRequest(event, channel);
41071
- const controller = new AbortController;
41072
- const timeout = setTimeout(() => controller.abort(), channel.webhook.timeoutMs ?? 15000);
41073
- try {
41074
- const response = await (options.fetchImpl ?? fetch)(channel.webhook.url, {
41075
- method: "POST",
41076
- headers,
41077
- body,
41078
- signal: controller.signal
41079
- });
41080
- const responseBody = truncate(await response.text());
41081
- return {
41082
- attempt: 1,
41083
- status: response.ok ? "success" : "failed",
41084
- startedAt,
41085
- completedAt: now(),
41086
- responseStatus: response.status,
41087
- responseBody,
41088
- error: response.ok ? undefined : `Webhook returned HTTP ${response.status}`
41089
- };
41090
- } catch (error) {
41091
- return {
41092
- attempt: 1,
41093
- status: "failed",
41094
- startedAt,
41095
- completedAt: now(),
41096
- error: error instanceof Error ? error.message : String(error)
41097
- };
41098
- } finally {
41099
- clearTimeout(timeout);
41100
- }
41101
- }
41102
- async function dispatchCommand(event, channel) {
41103
- if (!channel.command)
41104
- throw new Error(`Channel ${channel.id} has no command config`);
41105
- const startedAt = now();
41106
- const eventJson = JSON.stringify(event);
41107
- const env = {
41108
- ...process.env,
41109
- ...channel.command.env,
41110
- HASNA_CHANNEL_ID: channel.id,
41111
- HASNA_EVENT_ID: event.id,
41112
- HASNA_EVENT_TYPE: event.type,
41113
- HASNA_EVENT_SOURCE: event.source,
41114
- HASNA_EVENT_SUBJECT: event.subject ?? "",
41115
- HASNA_EVENT_SEVERITY: event.severity,
41116
- HASNA_EVENT_TIME: event.time,
41117
- HASNA_EVENT_DEDUPE_KEY: event.dedupeKey ?? "",
41118
- HASNA_EVENT_SCHEMA_VERSION: event.schemaVersion,
41119
- HASNA_EVENT_JSON: eventJson
41120
- };
41121
- return new Promise((resolve) => {
41122
- const child = spawn(channel.command.command, channel.command.args ?? [], {
41123
- cwd: channel.command.cwd,
41124
- env,
41125
- stdio: ["pipe", "pipe", "pipe"]
41126
- });
41127
- let stdout = "";
41128
- let stderr = "";
41129
- const timeout = setTimeout(() => child.kill("SIGTERM"), channel.command.timeoutMs ?? 15000);
41130
- child.stdin.end(eventJson);
41131
- child.stdout.on("data", (chunk) => {
41132
- stdout += chunk.toString();
41133
- });
41134
- child.stderr.on("data", (chunk) => {
41135
- stderr += chunk.toString();
41136
- });
41137
- child.on("error", (error) => {
41138
- clearTimeout(timeout);
41139
- resolve({
41140
- attempt: 1,
41141
- status: "failed",
41142
- startedAt,
41143
- completedAt: now(),
41144
- stdout: truncate(stdout),
41145
- stderr: truncate(stderr),
41146
- error: error.message
41147
- });
41148
- });
41149
- child.on("close", (code, signal) => {
41150
- clearTimeout(timeout);
41151
- const success = code === 0;
41152
- resolve({
41153
- attempt: 1,
41154
- status: success ? "success" : "failed",
41155
- startedAt,
41156
- completedAt: now(),
41157
- stdout: truncate(stdout),
41158
- stderr: truncate(stderr),
41159
- error: success ? undefined : `Command exited with ${signal ? `signal ${signal}` : `code ${code}`}`
41160
- });
41161
- });
41162
- });
41163
- }
41164
- async function dispatchChannel(event, channel, options = {}) {
41165
- if (channel.transport === "webhook")
41166
- return dispatchWebhook(event, channel, options);
41167
- if (channel.transport === "command")
41168
- return dispatchCommand(event, channel);
41169
- return {
41170
- attempt: 1,
41171
- status: "skipped",
41172
- startedAt: now(),
41173
- completedAt: now(),
41174
- error: `Unsupported transport: ${channel.transport}`
41175
- };
41176
- }
41177
- function createDeliveryResult(event, channel, attempts) {
41178
- const status = attempts.some((attempt) => attempt.status === "success") ? "success" : attempts.every((attempt) => attempt.status === "skipped") ? "skipped" : "failed";
41179
- return {
41180
- id: randomUUID(),
41181
- eventId: event.id,
41182
- channelId: channel.id,
41183
- transport: channel.transport,
41184
- status,
41185
- attempts,
41186
- createdAt: attempts[0]?.startedAt ?? now(),
41187
- completedAt: attempts.at(-1)?.completedAt ?? now()
41188
- };
41189
- }
41190
- function createEvent(input) {
41191
- return {
41192
- id: input.id ?? randomUUID2(),
41193
- source: input.source,
41194
- type: input.type,
41195
- time: normalizeTime(input.time),
41196
- subject: input.subject,
41197
- severity: input.severity ?? "info",
41198
- data: input.data ?? {},
41199
- message: input.message,
41200
- dedupeKey: input.dedupeKey,
41201
- schemaVersion: input.schemaVersion ?? "1.0",
41202
- metadata: input.metadata ?? {}
41203
- };
41204
- }
41205
-
41206
- class EventsClient {
41207
- store;
41208
- redactors;
41209
- transportOptions;
41210
- constructor(options = {}) {
41211
- this.store = options.store ?? new JsonEventsStore(options.dataDir);
41212
- this.redactors = options.redactors ?? [];
41213
- this.transportOptions = { fetchImpl: options.fetchImpl };
41214
- }
41215
- async addChannel(input) {
41216
- const timestamp = new Date().toISOString();
41217
- return this.store.addChannel({
41218
- ...input,
41219
- createdAt: input.createdAt ?? timestamp,
41220
- updatedAt: input.updatedAt ?? timestamp
41221
- });
41222
- }
41223
- async listChannels() {
41224
- return this.store.listChannels();
41225
- }
41226
- async removeChannel(id) {
41227
- return this.store.removeChannel(id);
41228
- }
41229
- async emit(input, options = {}) {
41230
- const event = options.redactSensitiveData === false ? createEvent(input) : redactSensitiveKeys(createEvent(input));
41231
- if (options.dedupe !== false) {
41232
- const existing = await this.store.findEventByIdentity({ id: input.id, dedupeKey: event.dedupeKey });
41233
- if (existing) {
41234
- return { event: existing, deliveries: [], deduped: true };
41235
- }
41236
- }
41237
- await this.store.appendEvent(event);
41238
- const deliveries = options.deliver === false ? [] : await this.deliver(event);
41239
- return { event, deliveries, deduped: false };
41240
- }
41241
- async listEvents() {
41242
- return this.store.listEvents();
41243
- }
41244
- async listDeliveries() {
41245
- return this.store.listDeliveries();
41246
- }
41247
- async deliver(event) {
41248
- const channels = await this.store.listChannels();
41249
- const selected = channels.filter((channel) => channelMatchesEvent(channel, event));
41250
- const deliveries = [];
41251
- for (const channel of selected) {
41252
- const eventForChannel = await this.applyRedaction(event, channel);
41253
- const result = await this.deliverWithRetry(eventForChannel, channel);
41254
- await this.store.appendDelivery(result);
41255
- deliveries.push(result);
41256
- }
41257
- return deliveries;
41258
- }
41259
- async testChannel(id, input = {}) {
41260
- const channel = await this.store.getChannel(id);
41261
- if (!channel)
41262
- throw new Error(`Channel not found: ${id}`);
41263
- const event = createEvent({
41264
- source: input.source ?? "hasna.events",
41265
- type: input.type ?? "events.test",
41266
- subject: input.subject ?? id,
41267
- severity: input.severity ?? "info",
41268
- data: input.data ?? { test: true },
41269
- message: input.message ?? "Hasna events test delivery",
41270
- dedupeKey: input.dedupeKey,
41271
- schemaVersion: input.schemaVersion,
41272
- metadata: input.metadata,
41273
- time: input.time,
41274
- id: input.id
41275
- });
41276
- const eventForChannel = await this.applyRedaction(event, channel);
41277
- const result = await this.deliverWithRetry(eventForChannel, channel);
41278
- await this.store.appendDelivery(result);
41279
- return result;
41280
- }
41281
- async replay(options = {}) {
41282
- const events = (await this.store.listEvents()).filter((event) => {
41283
- if (options.eventId && event.id !== options.eventId)
41284
- return false;
41285
- if (options.source && event.source !== options.source)
41286
- return false;
41287
- if (options.type && event.type !== options.type)
41288
- return false;
41289
- return true;
41290
- });
41291
- if (options.dryRun)
41292
- return { events, deliveries: [] };
41293
- const deliveries = [];
41294
- for (const event of events) {
41295
- deliveries.push(...await this.deliver(event));
41296
- }
41297
- return { events, deliveries };
41298
- }
41299
- async applyRedaction(event, channel) {
41300
- let next = redactPaths(event, channel.redact?.paths ?? [], channel.redact?.replacement ?? "[REDACTED]");
41301
- for (const redactor of this.redactors) {
41302
- next = await redactor(next, channel);
41303
- }
41304
- return next;
41305
- }
41306
- async deliverWithRetry(event, channel) {
41307
- const policy = normalizeRetryPolicy(channel.retry);
41308
- const attempts = [];
41309
- for (let index = 0;index < policy.maxAttempts; index += 1) {
41310
- const attempt = await dispatchChannel(event, channel, this.transportOptions);
41311
- attempt.attempt = index + 1;
41312
- if (attempt.status === "failed" && index + 1 < policy.maxAttempts) {
41313
- attempt.nextBackoffMs = Math.round(policy.backoffMs * policy.multiplier ** index);
41314
- }
41315
- attempts.push(attempt);
41316
- if (attempt.status !== "failed")
41317
- break;
41318
- if (attempt.nextBackoffMs)
41319
- await Bun.sleep(attempt.nextBackoffMs);
41320
- }
41321
- return createDeliveryResult(event, channel, attempts);
41322
- }
41323
- }
41324
- function redactPaths(event, paths, replacement = "[REDACTED]") {
41325
- if (paths.length === 0)
41326
- return event;
41327
- const copy = structuredClone(event);
41328
- for (const path of paths) {
41329
- setPath(copy, path, replacement);
41330
- }
41331
- return copy;
41332
- }
41333
- function sanitizeChannelForOutput(channel) {
41334
- const copy = structuredClone(channel);
41335
- if (copy.webhook?.secret)
41336
- copy.webhook.secret = "[REDACTED]";
41337
- if (copy.command?.env) {
41338
- copy.command.env = Object.fromEntries(Object.entries(copy.command.env).map(([key, value]) => [key, shouldRedactKey(key) ? "[REDACTED]" : value]));
41339
- }
41340
- return copy;
41341
- }
41342
- function sanitizeChannelsForOutput(channels) {
41343
- return channels.map(sanitizeChannelForOutput);
41344
- }
41345
- function redactSensitiveKeys(event, replacement = "[REDACTED]") {
41346
- return redactValue(event, replacement);
41347
- }
41348
- function shouldRedactKey(key) {
41349
- return /secret|token|password|api[_-]?key|authorization/i.test(key);
41350
- }
41351
- function redactValue(value, replacement) {
41352
- if (Array.isArray(value))
41353
- return value.map((item) => redactValue(item, replacement));
41354
- if (!value || typeof value !== "object")
41355
- return value;
41356
- return Object.fromEntries(Object.entries(value).map(([key, item]) => [
41357
- key,
41358
- shouldRedactKey(key) ? replacement : redactValue(item, replacement)
41359
- ]));
41360
- }
41361
- function setPath(input, path, replacement) {
41362
- const parts = path.split(".");
41363
- let cursor = input;
41364
- for (const part of parts.slice(0, -1)) {
41365
- const next = cursor[part];
41366
- if (!next || typeof next !== "object")
41367
- return;
41368
- cursor = next;
41369
- }
41370
- const last = parts.at(-1);
41371
- if (last && last in cursor)
41372
- cursor[last] = replacement;
41373
- }
41374
- function normalizeTime(value) {
41375
- if (!value)
41376
- return new Date().toISOString();
41377
- return value instanceof Date ? value.toISOString() : value;
41378
- }
41379
- function normalizeRetryPolicy(policy) {
41380
- return {
41381
- maxAttempts: Math.max(1, policy?.maxAttempts ?? 1),
41382
- backoffMs: Math.max(0, policy?.backoffMs ?? 250),
41383
- multiplier: Math.max(1, policy?.multiplier ?? 2)
41384
- };
41385
- }
41386
- function parseJsonObject(value, fallback) {
41387
- if (!value)
41388
- return fallback;
41389
- const parsed = JSON.parse(value);
41390
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
41391
- throw new Error("Expected a JSON object");
41392
- }
41393
- return parsed;
41394
- }
41395
- function parseHeaders(values) {
41396
- if (!values?.length)
41397
- return;
41398
- const headers = {};
41399
- for (const value of values) {
41400
- const separator = value.indexOf("=");
41401
- if (separator === -1)
41402
- throw new Error(`Invalid header, expected name=value: ${value}`);
41403
- headers[value.slice(0, separator)] = value.slice(separator + 1);
41404
- }
41405
- return headers;
41406
- }
41407
- function parseFilter(options) {
41408
- const filter2 = {};
41409
- if (options.source)
41410
- filter2.source = options.source;
41411
- if (options.type)
41412
- filter2.type = options.type;
41413
- if (options.subject)
41414
- filter2.subject = options.subject;
41415
- if (options.severity)
41416
- filter2.severity = options.severity;
41417
- return Object.keys(filter2).length > 0 ? [filter2] : undefined;
41418
- }
41419
- function createClient(options) {
41420
- if (options.createClient)
41421
- return options.createClient();
41422
- return new EventsClient({ store: new JsonEventsStore(options.dataDir) });
41423
- }
41424
- function print(value, json, text) {
41425
- if (json)
41426
- console.log(JSON.stringify(value, null, 2));
41427
- else
41428
- console.log(text);
41429
- }
41430
- function hasJsonOption(options) {
41431
- return Boolean(options?.json || options?.opts?.().json || options?.optsWithGlobals?.().json || options?.parent?.opts?.().json || options?.parent?.optsWithGlobals?.().json);
41432
- }
41433
- function wantsJson(actionOptions, command) {
41434
- return hasJsonOption(actionOptions) || hasJsonOption(command);
41435
- }
41436
- function registerWebhookCommands(program2, options) {
41437
- const webhooks = program2.command(options.webhooksCommandName ?? "webhooks").description("Manage Hasna event webhook subscriptions");
41438
- webhooks.command("add").description("Add or replace a webhook or command subscription").argument("<target>", "Webhook URL or command binary").requiredOption("--id <id>", "Subscription/channel identifier").option("--transport <kind>", "Transport kind: webhook or command", "webhook").option("--name <name>", "Display name").option("--type <pattern>", "Event type filter, e.g. todos.task.*").option("--source <pattern>", "Event source filter").option("--subject <pattern>", "Event subject filter").option("--severity <pattern>", "Event severity filter").option("--secret <secret>", "Webhook HMAC secret").option("--header <name=value...>", "Webhook header", collectValues, []).option("--arg <arg...>", "Command argument", collectValues, []).option("--timeout-ms <ms>", "Transport timeout in milliseconds", parseNumber).option("--retry-attempts <n>", "Maximum delivery attempts", parseNumber).option("--retry-backoff-ms <ms>", "Initial retry backoff in milliseconds", parseNumber).option("--redact <path...>", "Event field path to redact before delivery", collectValues, []).option("--disabled", "Create channel disabled", false).option("-j, --json", "Print JSON output", false).action(async (target, actionOptions, command) => {
41439
- const timestamp = new Date().toISOString();
41440
- const channel = {
41441
- id: actionOptions.id,
41442
- name: actionOptions.name,
41443
- enabled: !actionOptions.disabled,
41444
- transport: actionOptions.transport,
41445
- filters: parseFilter(actionOptions),
41446
- retry: actionOptions.retryAttempts || actionOptions.retryBackoffMs ? { maxAttempts: actionOptions.retryAttempts, backoffMs: actionOptions.retryBackoffMs } : undefined,
41447
- redact: actionOptions.redact?.length ? { paths: actionOptions.redact } : undefined,
41448
- createdAt: timestamp,
41449
- updatedAt: timestamp
41450
- };
41451
- if (actionOptions.transport === "webhook") {
41452
- channel.webhook = { url: target, secret: actionOptions.secret, headers: parseHeaders(actionOptions.header), timeoutMs: actionOptions.timeoutMs };
41453
- } else if (actionOptions.transport === "command") {
41454
- channel.command = { command: target, args: actionOptions.arg ?? [], timeoutMs: actionOptions.timeoutMs };
41455
- } else {
41456
- throw new Error(`Transport ${actionOptions.transport} is reserved for future use and cannot be added yet`);
41457
- }
41458
- const saved = await createClient(options).addChannel(channel);
41459
- print(sanitizeChannelForOutput(saved), wantsJson(actionOptions, command), `Added ${saved.transport} channel ${saved.id}`);
41460
- });
41461
- webhooks.command("list").description("List configured subscriptions").option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
41462
- const channels = await createClient(options).listChannels();
41463
- if (wantsJson(actionOptions, command)) {
41464
- console.log(JSON.stringify(sanitizeChannelsForOutput(channels), null, 2));
41465
- return;
41466
- }
41467
- if (!channels.length) {
41468
- console.log("No channels configured.");
41469
- return;
41470
- }
41471
- for (const channel of channels) {
41472
- console.log(`${channel.id} ${channel.enabled ? "enabled" : "disabled"} ${channel.transport} ${channel.webhook?.url ?? channel.command?.command ?? channel.transport}`);
41473
- }
41474
- });
41475
- webhooks.command("remove").description("Remove a subscription").argument("<id>", "Subscription/channel identifier").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
41476
- const removed = await createClient(options).removeChannel(id);
41477
- print({ removed }, wantsJson(actionOptions, command), removed ? `Removed ${id}` : `Channel not found: ${id}`);
41478
- });
41479
- webhooks.command("test").description("Send a test event to one subscription").argument("<id>", "Subscription/channel identifier").option("--type <type>", "Event type", "events.test").option("--subject <subject>", "Event subject").option("--message <message>", "Event message", "Hasna events test delivery").option("--data <json>", "Event data JSON object").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
41480
- const result = await createClient(options).testChannel(id, {
41481
- source: options.source,
41482
- type: actionOptions.type,
41483
- subject: actionOptions.subject ?? id,
41484
- message: actionOptions.message,
41485
- data: parseJsonObject(actionOptions.data, { test: true })
41486
- });
41487
- print(result, wantsJson(actionOptions, command), `${result.status}: ${result.channelId}`);
41488
- });
41489
- return webhooks;
41490
- }
41491
- function registerEventCommands(program2, options) {
41492
- const events = program2.command(options.eventsCommandName ?? "events").description("Emit, list, and replay Hasna events");
41493
- events.command("emit").description("Emit an event from this app").argument("<type>", "Event type").option("--source <source>", "Event source override").option("--subject <subject>", "Event subject").option("--severity <severity>", "Event severity", "info").option("--message <message>", "Event message").option("--dedupe-key <key>", "Dedupe key").option("--data <json>", "Event data JSON object").option("--metadata <json>", "Event metadata JSON object").option("--no-deliver", "Record without delivering").option("--no-dedupe", "Allow duplicate id/dedupeKey events").option("-j, --json", "Print JSON output", false).action(async (type, actionOptions, command) => {
41494
- const result = await createClient(options).emit({
41495
- source: actionOptions.source ?? options.source,
41496
- type,
41497
- subject: actionOptions.subject,
41498
- severity: actionOptions.severity,
41499
- message: actionOptions.message,
41500
- dedupeKey: actionOptions.dedupeKey,
41501
- data: parseJsonObject(actionOptions.data, {}),
41502
- metadata: parseJsonObject(actionOptions.metadata, {})
41503
- }, { deliver: actionOptions.deliver, dedupe: actionOptions.dedupe });
41504
- print(result, wantsJson(actionOptions, command), `${result.deduped ? "Deduped" : "Emitted"} ${result.event.id} to ${result.deliveries.length} channel(s)`);
41505
- });
41506
- events.command("list").description("List recorded events").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--limit <n>", "Limit results", parseNumber).option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
41507
- let rows = await createClient(options).listEvents();
41508
- if (actionOptions.source)
41509
- rows = rows.filter((event) => event.source === actionOptions.source);
41510
- if (actionOptions.type)
41511
- rows = rows.filter((event) => event.type === actionOptions.type);
41512
- if (actionOptions.limit)
41513
- rows = rows.slice(-actionOptions.limit);
41514
- if (wantsJson(actionOptions, command)) {
41515
- console.log(JSON.stringify(rows, null, 2));
41516
- return;
41517
- }
41518
- if (!rows.length) {
41519
- console.log("No events recorded.");
41520
- return;
41521
- }
41522
- for (const event of rows)
41523
- console.log(`${event.time} ${event.id} ${event.source} ${event.type} ${event.severity}`);
41524
- });
41525
- events.command("replay").description("Replay recorded events").option("--id <id>", "Replay one event id").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--dry-run", "Preview without delivery", false).option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
41526
- const result = await createClient(options).replay({
41527
- eventId: actionOptions.id,
41528
- source: actionOptions.source,
41529
- type: actionOptions.type,
41530
- dryRun: actionOptions.dryRun
41531
- });
41532
- print(result, wantsJson(actionOptions, command), `Replayed ${result.events.length} event(s), ${result.deliveries.length} delivery result(s)`);
41533
- });
41534
- return events;
41535
- }
41536
- function registerEventsCommands(program2, options) {
41537
- registerWebhookCommands(program2, options);
41538
- registerEventCommands(program2, options);
41539
- }
41540
- function parseNumber(value) {
41541
- const parsed = Number(value);
41542
- if (!Number.isFinite(parsed))
41543
- throw new Error(`Expected a number, got ${value}`);
41544
- return parsed;
41545
- }
41546
- function collectValues(value, previous) {
41547
- previous.push(value);
41548
- return previous;
41549
- }
41550
-
41551
40876
  // src/cli/index.tsx
41552
40877
  init_package();
41553
40878
  init_registry2();
40879
+ import { registerEventsCommands } from "@hasna/events/commander";
41554
40880
 
41555
40881
  // src/cli/components/App.tsx
41556
40882
  import { useState as useState7 } from "react";
@@ -43028,7 +42354,7 @@ init_installer();
43028
42354
  import { render } from "ink";
43029
42355
  import chalk2 from "chalk";
43030
42356
  import { readdirSync as readdirSync7, statSync as statSync5 } from "fs";
43031
- import { join as join11, relative } from "path";
42357
+ import { join as join10, relative } from "path";
43032
42358
  import { createInterface } from "readline";
43033
42359
  import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
43034
42360
  var isTTY = process.stdout.isTTY ?? false;
@@ -43043,7 +42369,7 @@ var PRESETS = {
43043
42369
  function listFilesRecursive(dir, base = dir) {
43044
42370
  const files = [];
43045
42371
  for (const entry of readdirSync7(dir)) {
43046
- const fullPath = join11(dir, entry);
42372
+ const fullPath = join10(dir, entry);
43047
42373
  if (statSync5(fullPath).isDirectory()) {
43048
42374
  files.push(...listFilesRecursive(fullPath, base));
43049
42375
  } else {
@@ -43093,9 +42419,9 @@ function registerCommands(program2) {
43093
42419
  }
43094
42420
  if (options.dryRun) {
43095
42421
  const installed = getInstalledConnectors();
43096
- const connectorsDir = join11(process.cwd(), ".connectors");
43097
- const manifestPath = join11(connectorsDir, "manifest.json");
43098
- const indexPath = join11(connectorsDir, "index.ts");
42422
+ const connectorsDir = join10(process.cwd(), ".connectors");
42423
+ const manifestPath = join10(connectorsDir, "manifest.json");
42424
+ const indexPath = join10(connectorsDir, "index.ts");
43099
42425
  const actions = [];
43100
42426
  for (const name of connectors18) {
43101
42427
  if (!/^[a-z0-9-]+$/.test(name)) {
@@ -43805,8 +43131,8 @@ init_auth();
43805
43131
  init_database();
43806
43132
  init_connector_resolver();
43807
43133
  import chalk4 from "chalk";
43808
- import { existsSync as existsSync17, readFileSync as readFileSync10 } from "fs";
43809
- import { join as join17 } from "path";
43134
+ import { existsSync as existsSync16, readFileSync as readFileSync10 } from "fs";
43135
+ import { join as join16 } from "path";
43810
43136
  function registerCommands3(program2) {
43811
43137
  program2.command("status").option("--json", "Output as JSON", false).option("--limit <n>", "Limit rows per section in human output").option("--offset <n>", "Skip first N rows per section in human output").option("-v, --verbose", "Show all human rows", false).description("Show auth status of all configured connectors (project + global)").action((options) => {
43812
43138
  const parsedLimit = parseNonNegativeInt(options.limit, "--limit");
@@ -43828,8 +43154,8 @@ function registerCommands3(program2) {
43828
43154
  const auth = getAuthStatus(name);
43829
43155
  let profile = "default";
43830
43156
  for (const connectorConfigDir of getConnectorConfigReadDirs(name, configDir)) {
43831
- const currentProfileFile = join17(connectorConfigDir, "current_profile");
43832
- if (existsSync17(currentProfileFile)) {
43157
+ const currentProfileFile = join16(connectorConfigDir, "current_profile");
43158
+ if (existsSync16(currentProfileFile)) {
43833
43159
  try {
43834
43160
  profile = readFileSync10(currentProfileFile, "utf-8").trim() || "default";
43835
43161
  } catch {}
@@ -43869,7 +43195,7 @@ function registerCommands3(program2) {
43869
43195
  seen.add(name);
43870
43196
  allStatuses.push(buildStatusEntry(name, "project"));
43871
43197
  }
43872
- if (existsSync17(configDir)) {
43198
+ if (existsSync16(configDir)) {
43873
43199
  try {
43874
43200
  for (const name of listConfiguredConnectorNames(configDir)) {
43875
43201
  if (name.startsWith("zzztest"))
@@ -44116,9 +43442,9 @@ init_registry2();
44116
43442
  init_auth();
44117
43443
  init_database();
44118
43444
  import chalk5 from "chalk";
44119
- import { existsSync as existsSync18, readdirSync as readdirSync11, statSync as statSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync10 } from "fs";
44120
- import { join as join18 } from "path";
44121
- import { homedir as homedir5 } from "os";
43445
+ import { existsSync as existsSync17, readdirSync as readdirSync11, statSync as statSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync10 } from "fs";
43446
+ import { join as join17 } from "path";
43447
+ import { homedir as homedir4 } from "os";
44122
43448
  import { createInterface as createInterface2 } from "readline";
44123
43449
  init_connector_resolver();
44124
43450
  var SENSITIVE_FIELDS = new Set([
@@ -44143,7 +43469,7 @@ var SENSITIVE_FIELDS = new Set([
44143
43469
  "private_key",
44144
43470
  "privatekey"
44145
43471
  ]);
44146
- function redactValue2(value) {
43472
+ function redactValue(value) {
44147
43473
  if (value.length <= 8)
44148
43474
  return "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
44149
43475
  return value.slice(0, 4) + "\u2022\u2022\u2022\u2022" + value.slice(-4);
@@ -44159,7 +43485,7 @@ function redactSecrets(obj) {
44159
43485
  const result = {};
44160
43486
  for (const [key, value] of Object.entries(obj)) {
44161
43487
  if (SENSITIVE_FIELDS.has(key.toLowerCase()) && typeof value === "string") {
44162
- result[key] = redactValue2(value);
43488
+ result[key] = redactValue(value);
44163
43489
  } else if (typeof value === "object" && value !== null) {
44164
43490
  result[key] = redactSecrets(value);
44165
43491
  } else {
@@ -44178,10 +43504,10 @@ function getOAuthTokenState(name) {
44178
43504
  if (!tokens.expiresAt) {
44179
43505
  return { hasTokens: true, expired: false };
44180
43506
  }
44181
- const now4 = Date.now();
44182
- const isExpired = now4 >= tokens.expiresAt - 60000;
43507
+ const now3 = Date.now();
43508
+ const isExpired = now3 >= tokens.expiresAt - 60000;
44183
43509
  const expiresIn = isExpired ? undefined : (() => {
44184
- const ms = tokens.expiresAt - now4;
43510
+ const ms = tokens.expiresAt - now3;
44185
43511
  const mins = Math.floor(ms / 60000);
44186
43512
  if (mins < 1)
44187
43513
  return "less than a minute";
@@ -44193,8 +43519,8 @@ function getOAuthTokenState(name) {
44193
43519
  }
44194
43520
  function getCurrentOAuthProfile(name, connectorsHome = getConnectorsHome()) {
44195
43521
  for (const dir of getConnectorConfigReadDirs(name, connectorsHome)) {
44196
- const currentProfilePath = join18(dir, "current_profile");
44197
- if (!existsSync18(currentProfilePath))
43522
+ const currentProfilePath = join17(dir, "current_profile");
43523
+ if (!existsSync17(currentProfilePath))
44198
43524
  continue;
44199
43525
  const profile = readFileSync11(currentProfilePath, "utf8").trim();
44200
43526
  if (profile)
@@ -44203,11 +43529,11 @@ function getCurrentOAuthProfile(name, connectorsHome = getConnectorsHome()) {
44203
43529
  return "default";
44204
43530
  }
44205
43531
  function getOAuthTokenPathsForProfile(name, connectorsHome = getConnectorsHome(), profile = getCurrentOAuthProfile(name, connectorsHome)) {
44206
- return getConnectorConfigReadDirs(name, connectorsHome).map((dir) => join18(dir, "profiles", profile, "tokens.json"));
43532
+ return getConnectorConfigReadDirs(name, connectorsHome).map((dir) => join17(dir, "profiles", profile, "tokens.json"));
44207
43533
  }
44208
43534
  function hasOAuthTokenFileUpdatedSince(tokenPaths, sinceMs) {
44209
43535
  return tokenPaths.some((tokensPath) => {
44210
- if (!existsSync18(tokensPath))
43536
+ if (!existsSync17(tokensPath))
44211
43537
  return false;
44212
43538
  return statSync8(tokensPath).mtimeMs >= sinceMs;
44213
43539
  });
@@ -44335,9 +43661,9 @@ ${meta.displayName} \u2014 Auth Configuration
44335
43661
  try {
44336
43662
  if (!options.browser) {
44337
43663
  console.log(chalk5.dim(`Starting OAuth server on port ${port}...`));
44338
- const { spawn: spawn5 } = await import("child_process");
43664
+ const { spawn: spawn4 } = await import("child_process");
44339
43665
  const scriptPath = process.argv[1];
44340
- const serverProc = spawn5(process.execPath, [scriptPath, "serve", "--port", String(port)], {
43666
+ const serverProc = spawn4(process.execPath, [scriptPath, "serve", "--port", String(port)], {
44341
43667
  detached: true,
44342
43668
  stdio: "ignore"
44343
43669
  });
@@ -44511,9 +43837,9 @@ Open this URL to authenticate:
44511
43837
  let configuredCount = 0;
44512
43838
  const configuredNames = [];
44513
43839
  try {
44514
- if (existsSync18(connectorsHome)) {
43840
+ if (existsSync17(connectorsHome)) {
44515
43841
  for (const name of listConfiguredConnectorNames(connectorsHome)) {
44516
- const hasProfiles = getConnectorConfigReadDirs(name, connectorsHome).some((dir) => existsSync18(join18(dir, "profiles")));
43842
+ const hasProfiles = getConnectorConfigReadDirs(name, connectorsHome).some((dir) => existsSync17(join17(dir, "profiles")));
44517
43843
  if (hasProfiles) {
44518
43844
  configuredCount++;
44519
43845
  configuredNames.push(name);
@@ -44565,13 +43891,13 @@ Open this URL to authenticate:
44565
43891
  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) => {
44566
43892
  const connectDir = getConnectorsHome();
44567
43893
  const result = {};
44568
- if (existsSync18(connectDir)) {
43894
+ if (existsSync17(connectDir)) {
44569
43895
  for (const connectorName of listConfiguredConnectorNames(connectDir)) {
44570
43896
  const connectorDirs = [...getConnectorConfigReadDirs(connectorName, connectDir)].reverse();
44571
43897
  let credentials = undefined;
44572
43898
  for (const connectorDir of connectorDirs) {
44573
- const credentialsPath = join18(connectorDir, "credentials.json");
44574
- if (existsSync18(credentialsPath)) {
43899
+ const credentialsPath = join17(connectorDir, "credentials.json");
43900
+ if (existsSync17(credentialsPath)) {
44575
43901
  try {
44576
43902
  credentials = JSON.parse(readFileSync11(credentialsPath, "utf-8"));
44577
43903
  } catch {}
@@ -44579,24 +43905,24 @@ Open this URL to authenticate:
44579
43905
  }
44580
43906
  const profiles = {};
44581
43907
  for (const connectorDir of connectorDirs) {
44582
- const profilesDir = join18(connectorDir, "profiles");
44583
- if (existsSync18(profilesDir)) {
43908
+ const profilesDir = join17(connectorDir, "profiles");
43909
+ if (existsSync17(profilesDir)) {
44584
43910
  for (const pEntry of readdirSync11(profilesDir)) {
44585
- const pPath = join18(profilesDir, pEntry);
43911
+ const pPath = join17(profilesDir, pEntry);
44586
43912
  if (statSync8(pPath).isFile() && pEntry.endsWith(".json")) {
44587
43913
  try {
44588
43914
  profiles[pEntry.replace(/\.json$/, "")] = JSON.parse(readFileSync11(pPath, "utf-8"));
44589
43915
  } catch {}
44590
43916
  } else if (statSync8(pPath).isDirectory()) {
44591
- const configPath = join18(pPath, "config.json");
44592
- const tokensPath = join18(pPath, "tokens.json");
43917
+ const configPath = join17(pPath, "config.json");
43918
+ const tokensPath = join17(pPath, "tokens.json");
44593
43919
  let merged = {};
44594
- if (existsSync18(configPath)) {
43920
+ if (existsSync17(configPath)) {
44595
43921
  try {
44596
43922
  merged = { ...merged, ...JSON.parse(readFileSync11(configPath, "utf-8")) };
44597
43923
  } catch {}
44598
43924
  }
44599
- if (existsSync18(tokensPath)) {
43925
+ if (existsSync17(tokensPath)) {
44600
43926
  try {
44601
43927
  merged = { ...merged, ...JSON.parse(readFileSync11(tokensPath, "utf-8")) };
44602
43928
  } catch {}
@@ -44634,7 +43960,7 @@ Open this URL to authenticate:
44634
43960
  chunks.push(chunk.toString());
44635
43961
  raw = chunks.join("");
44636
43962
  } else {
44637
- if (!existsSync18(file)) {
43963
+ if (!existsSync17(file)) {
44638
43964
  if (options.json) {
44639
43965
  console.log(JSON.stringify({ error: `File not found: ${file}` }));
44640
43966
  } else {
@@ -44674,17 +44000,17 @@ Open this URL to authenticate:
44674
44000
  const connectorDir = getConnectorConfigDir(connectorName, connectDir);
44675
44001
  if (connData.credentials && typeof connData.credentials === "object") {
44676
44002
  mkdirSync10(connectorDir, { recursive: true });
44677
- writeFileSync8(join18(connectorDir, "credentials.json"), JSON.stringify(connData.credentials, null, 2));
44003
+ writeFileSync8(join17(connectorDir, "credentials.json"), JSON.stringify(connData.credentials, null, 2));
44678
44004
  imported++;
44679
44005
  }
44680
44006
  if (!connData.profiles || typeof connData.profiles !== "object")
44681
44007
  continue;
44682
- const profilesDir = join18(connectorDir, "profiles");
44008
+ const profilesDir = join17(connectorDir, "profiles");
44683
44009
  for (const [profileName, config2] of Object.entries(connData.profiles)) {
44684
44010
  if (!config2 || typeof config2 !== "object")
44685
44011
  continue;
44686
44012
  mkdirSync10(profilesDir, { recursive: true });
44687
- writeFileSync8(join18(profilesDir, `${profileName}.json`), JSON.stringify(config2, null, 2));
44013
+ writeFileSync8(join17(profilesDir, `${profileName}.json`), JSON.stringify(config2, null, 2));
44688
44014
  imported++;
44689
44015
  }
44690
44016
  }
@@ -44695,9 +44021,9 @@ Open this URL to authenticate:
44695
44021
  }
44696
44022
  });
44697
44023
  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 ~/.hasna/connectors/", false).description("Migrate auth tokens from ~/.connect/ to ~/.hasna/connectors/").action((options) => {
44698
- const oldBase = join18(homedir5(), ".connect");
44024
+ const oldBase = join17(homedir4(), ".connect");
44699
44025
  const newBase = getConnectorsHome();
44700
- if (!existsSync18(oldBase)) {
44026
+ if (!existsSync17(oldBase)) {
44701
44027
  if (options.json) {
44702
44028
  console.log(JSON.stringify({ imported: [], skipped: [], error: null, message: "No ~/.connect/ directory found" }));
44703
44029
  } else {
@@ -44709,7 +44035,7 @@ Open this URL to authenticate:
44709
44035
  if (!name.startsWith("connect-"))
44710
44036
  return false;
44711
44037
  try {
44712
- return statSync8(join18(oldBase, name)).isDirectory();
44038
+ return statSync8(join17(oldBase, name)).isDirectory();
44713
44039
  } catch {
44714
44040
  return false;
44715
44041
  }
@@ -44725,7 +44051,7 @@ Open this URL to authenticate:
44725
44051
  const imported = [];
44726
44052
  const skipped = [];
44727
44053
  for (const dirName of entries) {
44728
- const oldDir = join18(oldBase, dirName);
44054
+ const oldDir = join17(oldBase, dirName);
44729
44055
  const connectorName = dirName.replace(/^connect-/, "");
44730
44056
  const newDir = getConnectorConfigDir(connectorName, newBase);
44731
44057
  const allFiles = listFilesRecursive(oldDir);
@@ -44737,14 +44063,14 @@ Open this URL to authenticate:
44737
44063
  const copiedFiles = [];
44738
44064
  const skippedFiles = [];
44739
44065
  for (const relFile of authFiles) {
44740
- const srcPath = join18(oldDir, relFile);
44741
- const destPath = join18(newDir, relFile);
44742
- if (existsSync18(destPath) && !options.force) {
44066
+ const srcPath = join17(oldDir, relFile);
44067
+ const destPath = join17(newDir, relFile);
44068
+ if (existsSync17(destPath) && !options.force) {
44743
44069
  skippedFiles.push(relFile);
44744
44070
  continue;
44745
44071
  }
44746
44072
  if (!options.dryRun) {
44747
- const parentDir = join18(destPath, "..");
44073
+ const parentDir = join17(destPath, "..");
44748
44074
  mkdirSync10(parentDir, { recursive: true });
44749
44075
  const content = readFileSync11(srcPath);
44750
44076
  writeFileSync8(destPath, content);
@@ -44813,8 +44139,8 @@ init_installer();
44813
44139
  init_auth();
44814
44140
  init_database();
44815
44141
  import chalk6 from "chalk";
44816
- import { existsSync as existsSync19, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "fs";
44817
- import { join as join19 } from "path";
44142
+ import { existsSync as existsSync18, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "fs";
44143
+ import { join as join18 } from "path";
44818
44144
 
44819
44145
  // src/lib/test-endpoints.ts
44820
44146
  var TEST_ENDPOINTS = {
@@ -45299,8 +44625,8 @@ Available presets:
45299
44625
  unconfigured++;
45300
44626
  let profile = "default";
45301
44627
  for (const connectorConfigDir of getConnectorConfigReadDirs(name, configDir)) {
45302
- const currentProfileFile = join19(connectorConfigDir, "current_profile");
45303
- if (existsSync19(currentProfileFile)) {
44628
+ const currentProfileFile = join18(connectorConfigDir, "current_profile");
44629
+ if (existsSync18(currentProfileFile)) {
45304
44630
  try {
45305
44631
  profile = readFileSync12(currentProfileFile, "utf-8").trim() || "default";
45306
44632
  } catch {}
@@ -45309,7 +44635,7 @@ Available presets:
45309
44635
  }
45310
44636
  connectorDetails.push({ name, configured: auth.configured, authType: auth.type, profile, source: "project" });
45311
44637
  }
45312
- if (existsSync19(configDir)) {
44638
+ if (existsSync18(configDir)) {
45313
44639
  try {
45314
44640
  for (const name of listConfiguredConnectorNames(configDir)) {
45315
44641
  if (seen.has(name))
@@ -45321,8 +44647,8 @@ Available presets:
45321
44647
  configured++;
45322
44648
  let profile = "default";
45323
44649
  for (const connectorConfigDir of getConnectorConfigReadDirs(name, configDir)) {
45324
- const currentProfileFile = join19(connectorConfigDir, "current_profile");
45325
- if (existsSync19(currentProfileFile)) {
44650
+ const currentProfileFile = join18(connectorConfigDir, "current_profile");
44651
+ if (existsSync18(currentProfileFile)) {
45326
44652
  try {
45327
44653
  profile = readFileSync12(currentProfileFile, "utf-8").trim() || "default";
45328
44654
  } catch {}
@@ -45337,7 +44663,7 @@ Available presets:
45337
44663
  console.log(JSON.stringify({
45338
44664
  version: version2,
45339
44665
  configDir,
45340
- configDirExists: existsSync19(configDir),
44666
+ configDirExists: existsSync18(configDir),
45341
44667
  installed: installed.length,
45342
44668
  configured,
45343
44669
  unconfigured,
@@ -45349,7 +44675,7 @@ Available presets:
45349
44675
  Connectors Setup
45350
44676
  `));
45351
44677
  console.log(` Version: ${chalk6.cyan(version2)}`);
45352
- console.log(` Config: ${configDir}${existsSync19(configDir) ? "" : chalk6.dim(" (not created yet)")}`);
44678
+ console.log(` Config: ${configDir}${existsSync18(configDir) ? "" : chalk6.dim(" (not created yet)")}`);
45353
44679
  console.log(` Installed: ${installed.length} connector${installed.length !== 1 ? "s" : ""}`);
45354
44680
  console.log(` Configured: ${chalk6.green(String(configured))} ready, ${unconfigured > 0 ? chalk6.red(String(unconfigured)) : chalk6.dim("0")} need auth`);
45355
44681
  const projectConnectors = connectorDetails.filter((c) => c.source === "project");
@@ -45457,15 +44783,15 @@ Testing connector credentials...
45457
44783
  const connectorConfigDirs = getConnectorConfigReadDirs(name);
45458
44784
  let currentProfile = "default";
45459
44785
  for (const connectorConfigDir of connectorConfigDirs) {
45460
- const currentProfileFile = join19(connectorConfigDir, "current_profile");
45461
- if (existsSync19(currentProfileFile)) {
44786
+ const currentProfileFile = join18(connectorConfigDir, "current_profile");
44787
+ if (existsSync18(currentProfileFile)) {
45462
44788
  try {
45463
44789
  currentProfile = readFileSync12(currentProfileFile, "utf-8").trim() || "default";
45464
44790
  } catch {}
45465
44791
  break;
45466
44792
  }
45467
44793
  }
45468
- const tokensFile = connectorConfigDirs.map((dir) => join19(dir, "profiles", currentProfile, "tokens.json")).find((path) => existsSync19(path));
44794
+ const tokensFile = connectorConfigDirs.map((dir) => join18(dir, "profiles", currentProfile, "tokens.json")).find((path) => existsSync18(path));
45469
44795
  if (tokensFile) {
45470
44796
  try {
45471
44797
  const tokens = JSON.parse(readFileSync12(tokensFile, "utf-8"));
@@ -45487,8 +44813,8 @@ Testing connector credentials...
45487
44813
  }
45488
44814
  if (!apiKey) {
45489
44815
  for (const connectorConfigDir of connectorConfigDirs) {
45490
- const profileFile = join19(connectorConfigDir, "profiles", `${currentProfile}.json`);
45491
- if (existsSync19(profileFile)) {
44816
+ const profileFile = join18(connectorConfigDir, "profiles", `${currentProfile}.json`);
44817
+ if (existsSync18(profileFile)) {
45492
44818
  try {
45493
44819
  const config2 = JSON.parse(readFileSync12(profileFile, "utf-8"));
45494
44820
  apiKey = Object.values(config2).find((v) => typeof v === "string" && v.length > 0);
@@ -45500,8 +44826,8 @@ Testing connector credentials...
45500
44826
  }
45501
44827
  if (!apiKey) {
45502
44828
  for (const connectorConfigDir of connectorConfigDirs) {
45503
- const profileDirConfig = join19(connectorConfigDir, "profiles", currentProfile, "config.json");
45504
- if (existsSync19(profileDirConfig)) {
44829
+ const profileDirConfig = join18(connectorConfigDir, "profiles", currentProfile, "config.json");
44830
+ if (existsSync18(profileDirConfig)) {
45505
44831
  try {
45506
44832
  const config2 = JSON.parse(readFileSync12(profileDirConfig, "utf-8"));
45507
44833
  apiKey = Object.values(config2).find((v) => typeof v === "string" && v.length > 0);
@@ -45764,10 +45090,10 @@ Setting up ${meta.displayName}...
45764
45090
  ${chalk7.bold("Open this URL to authenticate:")}`);
45765
45091
  console.log(` ${chalk7.cyan(oauthUrl)}
45766
45092
  `);
45767
- const { spawn: spawn5 } = await import("child_process");
45093
+ const { spawn: spawn4 } = await import("child_process");
45768
45094
  const { getConnectorsHome: getConnectorsHome2 } = await Promise.resolve().then(() => (init_database(), exports_database));
45769
45095
  const scriptPath = process.argv[1];
45770
- const serverProc = spawn5(process.execPath, [scriptPath, "serve", "--port", String(port)], {
45096
+ const serverProc = spawn4(process.execPath, [scriptPath, "serve", "--port", String(port)], {
45771
45097
  detached: true,
45772
45098
  stdio: "ignore"
45773
45099
  });