@hasna/connectors 1.3.25 → 1.3.26

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/serve.js CHANGED
@@ -10009,7 +10009,7 @@ var init_promotions = __esm(() => {
10009
10009
  });
10010
10010
 
10011
10011
  // src/server/serve.ts
10012
- import { existsSync as existsSync16, readdirSync as readdirSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync7, mkdirSync as mkdirSync11 } from "fs";
10012
+ import { existsSync as existsSync17, readdirSync as readdirSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync8, mkdirSync as mkdirSync12 } from "fs";
10013
10013
 
10014
10014
  // src/db/agents.ts
10015
10015
  init_database();
@@ -10240,12 +10240,12 @@ async function runWorkflow(workflow) {
10240
10240
 
10241
10241
  // src/server/serve.ts
10242
10242
  init_database();
10243
- import { join as join17, dirname as dirname8, extname, basename as basename2 } from "path";
10243
+ import { join as join18, dirname as dirname8, extname, basename as basename3 } from "path";
10244
10244
  import { fileURLToPath as fileURLToPath6 } from "url";
10245
10245
 
10246
10246
  // src/lib/registry.ts
10247
- import { existsSync as existsSync11, readFileSync as readFileSync5 } from "fs";
10248
- import { join as join12, dirname as dirname5 } from "path";
10247
+ import { existsSync as existsSync12, readFileSync as readFileSync6 } from "fs";
10248
+ import { join as join13, dirname as dirname5 } from "path";
10249
10249
  import { fileURLToPath as fileURLToPath3 } from "url";
10250
10250
 
10251
10251
  // src/core/errors.ts
@@ -10260,7 +10260,7 @@ class ConnectorDefinitionError extends Error {
10260
10260
 
10261
10261
  // src/core/connector.ts
10262
10262
  var CONNECTOR_NAME_RE = /^[a-z0-9-]+$/;
10263
- var OPERATION_NAME_RE = /^[a-z0-9:._-]+$/;
10263
+ var OPERATION_NAME_RE = /^[A-Za-z0-9:._-]+$/;
10264
10264
  function defineConnector(definition) {
10265
10265
  const { meta, auth, operations } = definition;
10266
10266
  if (!CONNECTOR_NAME_RE.test(meta.name)) {
@@ -15159,13 +15159,444 @@ var githubConnector = defineConnector({
15159
15159
  }
15160
15160
  });
15161
15161
 
15162
- // src/core/connectors/googledrive.ts
15162
+ // src/core/connectors/gmail.ts
15163
15163
  import { existsSync as existsSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync3, readdirSync as readdirSync5, writeFileSync as writeFileSync3 } from "fs";
15164
15164
  import { homedir as homedir8 } from "os";
15165
15165
  import { basename, join as join9 } from "path";
15166
- var DRIVE_API_BASE = "https://www.googleapis.com/drive/v3";
15166
+ var GMAIL_API_BASE = "https://gmail.googleapis.com/gmail/v1";
15167
15167
  var TOKEN_URL = "https://oauth2.googleapis.com/token";
15168
15168
  var REFRESH_BUFFER_MS = 5 * 60 * 1000;
15169
+ var listMessagesSchema = exports_external2.object({
15170
+ max: exports_external2.coerce.number().int().positive().max(500).optional(),
15171
+ maxResults: exports_external2.coerce.number().int().positive().max(500).optional(),
15172
+ pageToken: exports_external2.string().optional(),
15173
+ query: exports_external2.string().optional(),
15174
+ q: exports_external2.string().optional(),
15175
+ label: exports_external2.string().optional(),
15176
+ labelIds: exports_external2.union([exports_external2.string(), exports_external2.array(exports_external2.string())]).optional(),
15177
+ includeSpamTrash: exports_external2.boolean().optional()
15178
+ });
15179
+ var messageIdSchema = exports_external2.object({
15180
+ args: exports_external2.array(exports_external2.union([exports_external2.string(), exports_external2.number(), exports_external2.boolean()])).optional(),
15181
+ messageId: exports_external2.string().optional()
15182
+ });
15183
+ var readMessageSchema = messageIdSchema.extend({
15184
+ body: exports_external2.boolean().optional(),
15185
+ html: exports_external2.boolean().optional(),
15186
+ format: exports_external2.enum(["full", "metadata", "minimal", "raw"]).optional()
15187
+ });
15188
+ var attachmentListSchema = messageIdSchema;
15189
+ var attachmentDownloadSchema = messageIdSchema.extend({
15190
+ attachmentId: exports_external2.string().optional(),
15191
+ filename: exports_external2.string().optional(),
15192
+ mimeType: exports_external2.string().optional(),
15193
+ dir: exports_external2.string().optional(),
15194
+ outputDir: exports_external2.string().optional()
15195
+ });
15196
+ var historyListSchema = exports_external2.object({
15197
+ startHistoryId: exports_external2.string(),
15198
+ historyTypes: exports_external2.union([exports_external2.string(), exports_external2.array(exports_external2.string())]).optional(),
15199
+ labelId: exports_external2.string().optional(),
15200
+ maxResults: exports_external2.coerce.number().int().positive().max(500).optional(),
15201
+ pageToken: exports_external2.string().optional()
15202
+ });
15203
+ var replySchema = messageIdSchema.extend({
15204
+ body: exports_external2.string(),
15205
+ html: exports_external2.boolean().optional(),
15206
+ isHtml: exports_external2.boolean().optional(),
15207
+ cc: exports_external2.union([exports_external2.string(), exports_external2.array(exports_external2.string())]).optional(),
15208
+ bcc: exports_external2.union([exports_external2.string(), exports_external2.array(exports_external2.string())]).optional()
15209
+ });
15210
+ var gmailConnector = defineConnector({
15211
+ meta: {
15212
+ name: "gmail",
15213
+ displayName: "Gmail",
15214
+ description: "Profile-aware Gmail mailbox operations for sync, labels, attachments, history, and replies.",
15215
+ category: "communication",
15216
+ tags: ["google", "gmail", "email", "mailbox"]
15217
+ },
15218
+ auth: {
15219
+ type: "oauth2",
15220
+ supportsProfiles: true,
15221
+ fields: [
15222
+ { key: "clientId", env: "GMAIL_CLIENT_ID", label: "OAuth client ID" },
15223
+ { key: "clientSecret", env: "GMAIL_CLIENT_SECRET", label: "OAuth client secret", secret: true }
15224
+ ]
15225
+ },
15226
+ createContext: ({ profile }) => ({ profile: profile || "default" }),
15227
+ operations: {
15228
+ "profiles.list": {
15229
+ summary: "List configured Gmail profiles.",
15230
+ execute: () => ({ profiles: listProfiles() })
15231
+ },
15232
+ "profile.get": {
15233
+ summary: "Get the authenticated Gmail profile.",
15234
+ execute: async ({ context }) => requestJson(context.profile, "/users/me/profile", {})
15235
+ },
15236
+ "messages.list": {
15237
+ summary: "List Gmail messages.",
15238
+ inputSchema: listMessagesSchema,
15239
+ execute: async ({ context }, input) => {
15240
+ const labelIds = normalizeStringArray(input.labelIds ?? input.label);
15241
+ return requestJson(context.profile, "/users/me/messages", {
15242
+ maxResults: input.maxResults ?? input.max ?? 50,
15243
+ pageToken: input.pageToken,
15244
+ q: input.q ?? input.query,
15245
+ labelIds: labelIds.length > 0 ? labelIds.join(",") : undefined,
15246
+ includeSpamTrash: input.includeSpamTrash
15247
+ });
15248
+ }
15249
+ },
15250
+ "messages.read": {
15251
+ summary: "Read a Gmail message with optional extracted body.",
15252
+ inputSchema: readMessageSchema,
15253
+ execute: async ({ context }, input) => {
15254
+ const messageId = getMessageId(input);
15255
+ const message = await requestJson(context.profile, `/users/me/messages/${encodeURIComponent(messageId)}`, { format: input.format ?? "full" });
15256
+ const headers = headersToObject(message.payload?.headers ?? []);
15257
+ return {
15258
+ ...message,
15259
+ from: headers.From ?? headers.from ?? "",
15260
+ to: headers.To ?? headers.to ?? "",
15261
+ cc: headers.Cc ?? headers.cc ?? "",
15262
+ subject: headers.Subject ?? headers.subject ?? "",
15263
+ date: headers.Date ?? headers.date ?? "",
15264
+ body: input.body ? extractBody(message, Boolean(input.html)) : undefined,
15265
+ size: message.sizeEstimate
15266
+ };
15267
+ }
15268
+ },
15269
+ "messages.getRaw": {
15270
+ summary: "Read raw base64url Gmail message content.",
15271
+ inputSchema: messageIdSchema,
15272
+ execute: async ({ context }, input) => {
15273
+ const messageId = getMessageId(input);
15274
+ return requestJson(context.profile, `/users/me/messages/${encodeURIComponent(messageId)}`, { format: "raw" });
15275
+ }
15276
+ },
15277
+ "messages.mark-read": {
15278
+ summary: "Mark a message as read.",
15279
+ inputSchema: messageIdSchema,
15280
+ execute: async ({ context }, input) => modifyMessage(context.profile, getMessageId(input), undefined, ["UNREAD"])
15281
+ },
15282
+ "messages.mark-unread": {
15283
+ summary: "Mark a message as unread.",
15284
+ inputSchema: messageIdSchema,
15285
+ execute: async ({ context }, input) => modifyMessage(context.profile, getMessageId(input), ["UNREAD"], undefined)
15286
+ },
15287
+ "messages.archive": {
15288
+ summary: "Archive a message by removing the INBOX label.",
15289
+ inputSchema: messageIdSchema,
15290
+ execute: async ({ context }, input) => modifyMessage(context.profile, getMessageId(input), undefined, ["INBOX"])
15291
+ },
15292
+ "messages.star": {
15293
+ summary: "Star a message.",
15294
+ inputSchema: messageIdSchema,
15295
+ execute: async ({ context }, input) => modifyMessage(context.profile, getMessageId(input), ["STARRED"], undefined)
15296
+ },
15297
+ "messages.reply": {
15298
+ summary: "Reply to a Gmail message in the same thread.",
15299
+ inputSchema: replySchema,
15300
+ execute: async ({ context }, input) => replyToMessage(context.profile, getMessageId(input), input)
15301
+ },
15302
+ "attachments.list": {
15303
+ summary: "List Gmail message attachments.",
15304
+ inputSchema: attachmentListSchema,
15305
+ execute: async ({ context }, input) => {
15306
+ const message = await requestJson(context.profile, `/users/me/messages/${encodeURIComponent(getMessageId(input))}`, { format: "full" });
15307
+ return collectAttachments(message.payload);
15308
+ }
15309
+ },
15310
+ "attachments.download": {
15311
+ summary: "Download one or all Gmail message attachments to disk.",
15312
+ inputSchema: attachmentDownloadSchema,
15313
+ execute: async ({ context }, input) => downloadAttachments(context.profile, input)
15314
+ },
15315
+ "labels.list": {
15316
+ summary: "List Gmail labels.",
15317
+ execute: async ({ context }) => requestJson(context.profile, "/users/me/labels", {})
15318
+ },
15319
+ "history.list": {
15320
+ summary: "List Gmail mailbox history from a history id.",
15321
+ inputSchema: historyListSchema,
15322
+ execute: async ({ context }, input) => requestJson(context.profile, "/users/me/history", {
15323
+ startHistoryId: input.startHistoryId,
15324
+ historyTypes: normalizeStringArray(input.historyTypes).join(",") || undefined,
15325
+ labelId: input.labelId,
15326
+ maxResults: input.maxResults,
15327
+ pageToken: input.pageToken
15328
+ })
15329
+ }
15330
+ }
15331
+ });
15332
+ async function modifyMessage(profile, messageId, addLabelIds, removeLabelIds) {
15333
+ return requestJson(profile, `/users/me/messages/${encodeURIComponent(messageId)}/modify`, {}, {
15334
+ method: "POST",
15335
+ body: {
15336
+ addLabelIds: addLabelIds ?? [],
15337
+ removeLabelIds: removeLabelIds ?? []
15338
+ }
15339
+ });
15340
+ }
15341
+ async function replyToMessage(profile, messageId, input) {
15342
+ const original = await requestJson(profile, `/users/me/messages/${encodeURIComponent(messageId)}`, { format: "full" });
15343
+ const headers = headersToObject(original.payload?.headers ?? []);
15344
+ const subject = normalizeReplySubject(headers.Subject ?? headers.subject ?? "");
15345
+ const to = headers.From ?? headers.from ?? "";
15346
+ const messageIdHeader = headers["Message-ID"] ?? headers["Message-Id"] ?? headers["message-id"] ?? "";
15347
+ const references = [headers.References ?? headers.references, messageIdHeader].filter(Boolean).join(" ");
15348
+ const raw = buildRawEmail({
15349
+ to,
15350
+ cc: normalizeStringArray(input.cc),
15351
+ bcc: normalizeStringArray(input.bcc),
15352
+ subject,
15353
+ body: input.body,
15354
+ isHtml: Boolean(input.html ?? input.isHtml),
15355
+ inReplyTo: messageIdHeader,
15356
+ references
15357
+ });
15358
+ return requestJson(profile, "/users/me/messages/send", {}, {
15359
+ method: "POST",
15360
+ body: {
15361
+ raw: Buffer.from(raw).toString("base64url"),
15362
+ threadId: original.threadId
15363
+ }
15364
+ });
15365
+ }
15366
+ async function downloadAttachments(profile, input) {
15367
+ const messageId = getMessageId(input);
15368
+ const outputDir = input.dir ?? input.outputDir ?? join9(configDirs()[0], "attachments", messageId);
15369
+ mkdirSync6(outputDir, { recursive: true });
15370
+ const attachments = input.attachmentId && input.filename ? [{
15371
+ attachmentId: input.attachmentId,
15372
+ filename: input.filename,
15373
+ mimeType: input.mimeType ?? "application/octet-stream",
15374
+ size: 0
15375
+ }] : collectAttachments((await requestJson(profile, `/users/me/messages/${encodeURIComponent(messageId)}`, { format: "full" })).payload);
15376
+ const downloaded = [];
15377
+ for (const attachment of attachments) {
15378
+ const data = await requestJson(profile, `/users/me/messages/${encodeURIComponent(messageId)}/attachments/${encodeURIComponent(attachment.attachmentId)}`, {});
15379
+ const filename = safeFilename(attachment.filename);
15380
+ const path = join9(outputDir, filename);
15381
+ const buffer = Buffer.from(data.data, "base64url");
15382
+ writeFileSync3(path, buffer);
15383
+ downloaded.push({
15384
+ filename,
15385
+ path,
15386
+ size: buffer.length,
15387
+ mimeType: attachment.mimeType
15388
+ });
15389
+ }
15390
+ return downloaded;
15391
+ }
15392
+ async function requestJson(profile, path, params, options = {}) {
15393
+ const token = await getValidAccessToken(profile);
15394
+ const url = new URL(`${GMAIL_API_BASE}${path}`);
15395
+ for (const [key, value] of Object.entries(params)) {
15396
+ if (value !== undefined && value !== null && value !== "")
15397
+ url.searchParams.append(key, String(value));
15398
+ }
15399
+ const response = await fetch(url, {
15400
+ method: options.method ?? "GET",
15401
+ headers: {
15402
+ Authorization: `Bearer ${token}`,
15403
+ Accept: "application/json",
15404
+ ...options.body ? { "Content-Type": "application/json" } : {}
15405
+ },
15406
+ body: options.body ? JSON.stringify(options.body) : undefined
15407
+ });
15408
+ const text = await response.text();
15409
+ const data = text ? JSON.parse(text) : {};
15410
+ if (!response.ok) {
15411
+ const error = data;
15412
+ throw new Error(`Gmail request failed (${response.status}): ${error.error?.message ?? response.statusText}`);
15413
+ }
15414
+ return data;
15415
+ }
15416
+ async function getValidAccessToken(profile) {
15417
+ if (process.env.GMAIL_ACCESS_TOKEN)
15418
+ return process.env.GMAIL_ACCESS_TOKEN;
15419
+ const tokens = loadTokens(profile);
15420
+ if (!tokens?.accessToken && !tokens?.refreshToken) {
15421
+ throw new Error(`Gmail profile "${profile}" is not authenticated. Run: connectors auth gmail`);
15422
+ }
15423
+ if (tokens.accessToken && (!tokens.expiresAt || Date.now() < tokens.expiresAt - REFRESH_BUFFER_MS))
15424
+ return tokens.accessToken;
15425
+ if (!tokens.refreshToken)
15426
+ return tokens.accessToken ?? "";
15427
+ return (await refreshAccessToken(profile, tokens)).accessToken ?? "";
15428
+ }
15429
+ async function refreshAccessToken(profile, currentTokens) {
15430
+ const credentials = loadCredentials(profile);
15431
+ if (!credentials.clientId || !credentials.clientSecret)
15432
+ throw new Error("Gmail OAuth credentials are not configured. Run: connectors auth gmail");
15433
+ if (!currentTokens.refreshToken)
15434
+ throw new Error(`Gmail profile "${profile}" has no refresh token. Run: connectors auth gmail`);
15435
+ const response = await fetch(TOKEN_URL, {
15436
+ method: "POST",
15437
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
15438
+ body: new URLSearchParams({
15439
+ client_id: credentials.clientId,
15440
+ client_secret: credentials.clientSecret,
15441
+ refresh_token: currentTokens.refreshToken,
15442
+ grant_type: "refresh_token"
15443
+ })
15444
+ });
15445
+ const data = await response.json().catch(() => ({}));
15446
+ if (!response.ok || !data.access_token)
15447
+ throw new Error(`Gmail token refresh failed: ${data.error_description || data.error || response.statusText}`);
15448
+ const tokens = {
15449
+ accessToken: data.access_token,
15450
+ refreshToken: currentTokens.refreshToken,
15451
+ expiresAt: Date.now() + (data.expires_in ?? 3600) * 1000,
15452
+ tokenType: data.token_type ?? currentTokens.tokenType,
15453
+ scope: data.scope ?? currentTokens.scope
15454
+ };
15455
+ saveTokens(profile, tokens);
15456
+ return tokens;
15457
+ }
15458
+ function listProfiles() {
15459
+ const profiles = new Set;
15460
+ for (const baseDir of configDirs()) {
15461
+ const profilesDir = join9(baseDir, "profiles");
15462
+ if (!existsSync8(profilesDir))
15463
+ continue;
15464
+ for (const entry of readdirSync5(profilesDir, { withFileTypes: true })) {
15465
+ if (entry.isDirectory())
15466
+ profiles.add(entry.name);
15467
+ if (entry.isFile() && entry.name.endsWith(".json"))
15468
+ profiles.add(basename(entry.name, ".json"));
15469
+ }
15470
+ }
15471
+ return Array.from(profiles).sort((a, b) => a.localeCompare(b));
15472
+ }
15473
+ function loadCredentials(profile) {
15474
+ const envClientId = process.env.GMAIL_CLIENT_ID ?? process.env.GOOGLE_CLIENT_ID;
15475
+ const envClientSecret = process.env.GMAIL_CLIENT_SECRET ?? process.env.GOOGLE_CLIENT_SECRET;
15476
+ if (envClientId && envClientSecret)
15477
+ return { clientId: envClientId, clientSecret: envClientSecret };
15478
+ for (const baseDir of configDirs()) {
15479
+ const credentials = {
15480
+ ...readJson(join9(baseDir, "credentials.json")),
15481
+ ...readJson(join9(baseDir, "profiles", profile, "config.json"))
15482
+ };
15483
+ if (credentials.clientId || credentials.clientSecret)
15484
+ return credentials;
15485
+ }
15486
+ return {};
15487
+ }
15488
+ function loadTokens(profile) {
15489
+ for (const baseDir of configDirs()) {
15490
+ const fromProfile = readJson(join9(baseDir, "profiles", profile, "tokens.json"));
15491
+ if (fromProfile)
15492
+ return fromProfile;
15493
+ const flat = readJson(join9(baseDir, "profiles", `${profile}.json`));
15494
+ if (flat)
15495
+ return flat.tokens ?? (flat.accessToken || flat.refreshToken ? flat : null);
15496
+ }
15497
+ return null;
15498
+ }
15499
+ function saveTokens(profile, tokens) {
15500
+ const baseDir = configDirs().find((dir) => existsSync8(dir)) ?? configDirs()[0];
15501
+ const profileDir = join9(baseDir, "profiles", profile);
15502
+ mkdirSync6(profileDir, { recursive: true });
15503
+ writeFileSync3(join9(profileDir, "tokens.json"), JSON.stringify(tokens, null, 2), { mode: 384 });
15504
+ }
15505
+ function configDirs() {
15506
+ const explicit = process.env.HASNA_GMAIL_CONNECTOR_DIR ?? process.env.GMAIL_CONNECTOR_DIR;
15507
+ if (explicit)
15508
+ return [explicit];
15509
+ const baseDir = process.env.HASNA_CONNECTORS_DIR ?? join9(homedir8(), ".hasna", "connectors");
15510
+ return [join9(baseDir, "connect-gmail"), join9(baseDir, "gmail")];
15511
+ }
15512
+ function readJson(path) {
15513
+ if (!existsSync8(path))
15514
+ return null;
15515
+ try {
15516
+ return JSON.parse(readFileSync3(path, "utf8"));
15517
+ } catch {
15518
+ return null;
15519
+ }
15520
+ }
15521
+ function getMessageId(input) {
15522
+ const id = input.messageId ?? (input.args?.[0] != null ? String(input.args[0]) : undefined);
15523
+ if (!id)
15524
+ throw new Error("Gmail messageId is required");
15525
+ return id;
15526
+ }
15527
+ function headersToObject(headers) {
15528
+ const out = {};
15529
+ for (const header of headers)
15530
+ out[header.name] = header.value;
15531
+ return out;
15532
+ }
15533
+ function extractBody(message, preferHtml = false) {
15534
+ if (!message.payload)
15535
+ return "";
15536
+ const targetType = preferHtml ? "text/html" : "text/plain";
15537
+ const parts = [];
15538
+ collectTextParts(message.payload, parts);
15539
+ return parts.find((part) => part.mimeType === targetType)?.data ?? parts.find((part) => part.mimeType.startsWith("text/"))?.data ?? "";
15540
+ }
15541
+ function collectTextParts(part, results) {
15542
+ const mimeType = (part.mimeType ?? "").split(";")[0].trim().toLowerCase();
15543
+ if (part.body?.data && mimeType.startsWith("text/")) {
15544
+ results.push({ mimeType, data: Buffer.from(part.body.data, "base64url").toString("utf8") });
15545
+ }
15546
+ for (const child of part.parts ?? [])
15547
+ collectTextParts(child, results);
15548
+ }
15549
+ function collectAttachments(part, attachments = []) {
15550
+ if (!part)
15551
+ return attachments;
15552
+ if (part.body?.attachmentId && part.filename) {
15553
+ attachments.push({
15554
+ attachmentId: part.body.attachmentId,
15555
+ filename: part.filename,
15556
+ mimeType: part.mimeType ?? "application/octet-stream",
15557
+ size: part.body.size ?? 0,
15558
+ partId: part.partId
15559
+ });
15560
+ }
15561
+ for (const child of part.parts ?? [])
15562
+ collectAttachments(child, attachments);
15563
+ return attachments;
15564
+ }
15565
+ function normalizeStringArray(value) {
15566
+ if (!value)
15567
+ return [];
15568
+ return Array.isArray(value) ? value : value.split(",").map((item) => item.trim()).filter(Boolean);
15569
+ }
15570
+ function normalizeReplySubject(subject) {
15571
+ return subject.toLowerCase().startsWith("re:") ? subject : `Re: ${subject}`;
15572
+ }
15573
+ function buildRawEmail(input) {
15574
+ const headers = [
15575
+ `To: ${input.to}`,
15576
+ input.cc.length ? `Cc: ${input.cc.join(", ")}` : "",
15577
+ input.bcc.length ? `Bcc: ${input.bcc.join(", ")}` : "",
15578
+ `Subject: ${input.subject}`,
15579
+ input.inReplyTo ? `In-Reply-To: ${input.inReplyTo}` : "",
15580
+ input.references ? `References: ${input.references}` : "",
15581
+ "MIME-Version: 1.0",
15582
+ `Content-Type: ${input.isHtml ? "text/html" : "text/plain"}; charset=UTF-8`
15583
+ ].filter(Boolean);
15584
+ return `${headers.join(`\r
15585
+ `)}\r
15586
+ \r
15587
+ ${input.body}`;
15588
+ }
15589
+ function safeFilename(filename) {
15590
+ return basename(filename.replace(/[\u00A0\u2000-\u200B\u202F\u205F\u3000]/g, " ")).replace(/[\/\\]/g, "_");
15591
+ }
15592
+
15593
+ // src/core/connectors/googledrive.ts
15594
+ import { existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync4, readdirSync as readdirSync6, writeFileSync as writeFileSync4 } from "fs";
15595
+ import { homedir as homedir9 } from "os";
15596
+ import { basename as basename2, join as join10 } from "path";
15597
+ var DRIVE_API_BASE = "https://www.googleapis.com/drive/v3";
15598
+ var TOKEN_URL2 = "https://oauth2.googleapis.com/token";
15599
+ var REFRESH_BUFFER_MS2 = 5 * 60 * 1000;
15169
15600
  var DEFAULT_FILE_FIELDS = [
15170
15601
  "id",
15171
15602
  "name",
@@ -15246,12 +15677,12 @@ var googleDriveConnector = defineConnector({
15246
15677
  operations: {
15247
15678
  "profiles.list": {
15248
15679
  summary: "List configured Google Drive profiles.",
15249
- execute: () => ({ profiles: listProfiles() })
15680
+ execute: () => ({ profiles: listProfiles2() })
15250
15681
  },
15251
15682
  "files.list": {
15252
15683
  summary: "List Google Drive files.",
15253
15684
  inputSchema: listFilesSchema,
15254
- execute: async ({ context }, input) => requestJson(context.profile, "/files", {
15685
+ execute: async ({ context }, input) => requestJson2(context.profile, "/files", {
15255
15686
  pageSize: input.pageSize ?? 1000,
15256
15687
  pageToken: input.pageToken,
15257
15688
  q: input.q,
@@ -15266,7 +15697,7 @@ var googleDriveConnector = defineConnector({
15266
15697
  "files.get": {
15267
15698
  summary: "Get Google Drive file metadata.",
15268
15699
  inputSchema: fileIdSchema,
15269
- execute: async ({ context }, input) => requestJson(context.profile, `/files/${encodeURIComponent(input.fileId)}`, {
15700
+ execute: async ({ context }, input) => requestJson2(context.profile, `/files/${encodeURIComponent(input.fileId)}`, {
15270
15701
  fields: input.fields ?? DEFAULT_FILE_FIELDS,
15271
15702
  supportsAllDrives: true
15272
15703
  })
@@ -15275,7 +15706,7 @@ var googleDriveConnector = defineConnector({
15275
15706
  summary: "Download or export a Google Drive file as base64 content.",
15276
15707
  inputSchema: downloadSchema,
15277
15708
  execute: async ({ context }, input) => {
15278
- const file = input.file ?? await requestJson(context.profile, `/files/${encodeURIComponent(input.fileId)}`, { fields: DEFAULT_FILE_FIELDS, supportsAllDrives: true });
15709
+ const file = input.file ?? await requestJson2(context.profile, `/files/${encodeURIComponent(input.fileId)}`, { fields: DEFAULT_FILE_FIELDS, supportsAllDrives: true });
15279
15710
  const exportMimeType = file.mimeType.startsWith("application/vnd.google-apps.") ? input.exportMimeType ?? defaultExportMimeType(file.mimeType) : undefined;
15280
15711
  const data = await requestBinary(context.profile, exportMimeType ? `/files/${encodeURIComponent(file.id)}/export` : `/files/${encodeURIComponent(file.id)}`, exportMimeType ? { mimeType: exportMimeType, supportsAllDrives: true } : { alt: "media", supportsAllDrives: true });
15281
15712
  const mimeType = exportMimeType ?? file.mimeType ?? "application/octet-stream";
@@ -15289,7 +15720,7 @@ var googleDriveConnector = defineConnector({
15289
15720
  "drives.list": {
15290
15721
  summary: "List Google shared drives.",
15291
15722
  inputSchema: listDrivesSchema,
15292
- execute: async ({ context }, input) => requestJson(context.profile, "/drives", {
15723
+ execute: async ({ context }, input) => requestJson2(context.profile, "/drives", {
15293
15724
  pageSize: input.pageSize ?? 100,
15294
15725
  pageToken: input.pageToken,
15295
15726
  q: input.q
@@ -15297,7 +15728,7 @@ var googleDriveConnector = defineConnector({
15297
15728
  }
15298
15729
  }
15299
15730
  });
15300
- async function requestJson(profile, path, params) {
15731
+ async function requestJson2(profile, path, params) {
15301
15732
  const response = await request(profile, path, params);
15302
15733
  const text = await response.text();
15303
15734
  return text ? JSON.parse(text) : {};
@@ -15306,7 +15737,7 @@ async function requestBinary(profile, path, params) {
15306
15737
  return (await request(profile, path, params)).arrayBuffer();
15307
15738
  }
15308
15739
  async function request(profile, path, params) {
15309
- const token = await getValidAccessToken(profile);
15740
+ const token = await getValidAccessToken2(profile);
15310
15741
  const url = new URL(`${DRIVE_API_BASE}${path}`);
15311
15742
  for (const [key, value] of Object.entries(params)) {
15312
15743
  if (value !== undefined && value !== null && value !== "")
@@ -15319,26 +15750,26 @@ async function request(profile, path, params) {
15319
15750
  }
15320
15751
  return response;
15321
15752
  }
15322
- async function getValidAccessToken(profile) {
15753
+ async function getValidAccessToken2(profile) {
15323
15754
  if (process.env.GOOGLE_ACCESS_TOKEN)
15324
15755
  return process.env.GOOGLE_ACCESS_TOKEN;
15325
- const tokens = loadTokens(profile);
15756
+ const tokens = loadTokens2(profile);
15326
15757
  if (!tokens?.accessToken && !tokens?.refreshToken) {
15327
15758
  throw new Error(`Google Drive profile "${profile}" is not authenticated. Run: connectors auth googledrive`);
15328
15759
  }
15329
- if (tokens.accessToken && (!tokens.expiresAt || Date.now() < tokens.expiresAt - REFRESH_BUFFER_MS))
15760
+ if (tokens.accessToken && (!tokens.expiresAt || Date.now() < tokens.expiresAt - REFRESH_BUFFER_MS2))
15330
15761
  return tokens.accessToken;
15331
15762
  if (!tokens.refreshToken)
15332
15763
  return tokens.accessToken ?? "";
15333
- return (await refreshAccessToken(profile, tokens)).accessToken ?? "";
15764
+ return (await refreshAccessToken2(profile, tokens)).accessToken ?? "";
15334
15765
  }
15335
- async function refreshAccessToken(profile, currentTokens) {
15336
- const credentials = loadCredentials(profile);
15766
+ async function refreshAccessToken2(profile, currentTokens) {
15767
+ const credentials = loadCredentials2(profile);
15337
15768
  if (!credentials.clientId || !credentials.clientSecret)
15338
15769
  throw new Error("Google Drive OAuth credentials are not configured. Run: connectors auth googledrive");
15339
15770
  if (!currentTokens.refreshToken)
15340
15771
  throw new Error(`Google Drive profile "${profile}" has no refresh token. Run: connectors auth googledrive`);
15341
- const response = await fetch(TOKEN_URL, {
15772
+ const response = await fetch(TOKEN_URL2, {
15342
15773
  method: "POST",
15343
15774
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
15344
15775
  body: new URLSearchParams({
@@ -15358,68 +15789,68 @@ async function refreshAccessToken(profile, currentTokens) {
15358
15789
  tokenType: data.token_type ?? currentTokens.tokenType,
15359
15790
  scope: data.scope ?? currentTokens.scope
15360
15791
  };
15361
- saveTokens(profile, tokens);
15792
+ saveTokens2(profile, tokens);
15362
15793
  return tokens;
15363
15794
  }
15364
- function listProfiles() {
15795
+ function listProfiles2() {
15365
15796
  const profiles = new Set;
15366
- for (const baseDir of configDirs()) {
15367
- const profilesDir = join9(baseDir, "profiles");
15368
- if (!existsSync8(profilesDir))
15797
+ for (const baseDir of configDirs2()) {
15798
+ const profilesDir = join10(baseDir, "profiles");
15799
+ if (!existsSync9(profilesDir))
15369
15800
  continue;
15370
- for (const entry of readdirSync5(profilesDir, { withFileTypes: true })) {
15801
+ for (const entry of readdirSync6(profilesDir, { withFileTypes: true })) {
15371
15802
  if (entry.isDirectory())
15372
15803
  profiles.add(entry.name);
15373
15804
  if (entry.isFile() && entry.name.endsWith(".json"))
15374
- profiles.add(basename(entry.name, ".json"));
15805
+ profiles.add(basename2(entry.name, ".json"));
15375
15806
  }
15376
15807
  }
15377
15808
  return Array.from(profiles).sort((a, b) => a.localeCompare(b));
15378
15809
  }
15379
- function loadCredentials(profile) {
15810
+ function loadCredentials2(profile) {
15380
15811
  const envClientId = process.env.GOOGLE_CLIENT_ID;
15381
15812
  const envClientSecret = process.env.GOOGLE_CLIENT_SECRET;
15382
15813
  if (envClientId && envClientSecret)
15383
15814
  return { clientId: envClientId, clientSecret: envClientSecret };
15384
- for (const baseDir of configDirs()) {
15815
+ for (const baseDir of configDirs2()) {
15385
15816
  const credentials = {
15386
- ...readJson(join9(baseDir, "credentials.json")),
15387
- ...readJson(join9(baseDir, "profiles", profile, "config.json"))
15817
+ ...readJson2(join10(baseDir, "credentials.json")),
15818
+ ...readJson2(join10(baseDir, "profiles", profile, "config.json"))
15388
15819
  };
15389
15820
  if (credentials.clientId || credentials.clientSecret)
15390
15821
  return credentials;
15391
15822
  }
15392
15823
  return {};
15393
15824
  }
15394
- function loadTokens(profile) {
15395
- for (const baseDir of configDirs()) {
15396
- const fromProfile = readJson(join9(baseDir, "profiles", profile, "tokens.json"));
15825
+ function loadTokens2(profile) {
15826
+ for (const baseDir of configDirs2()) {
15827
+ const fromProfile = readJson2(join10(baseDir, "profiles", profile, "tokens.json"));
15397
15828
  if (fromProfile)
15398
15829
  return fromProfile;
15399
- const flat = readJson(join9(baseDir, "profiles", `${profile}.json`));
15830
+ const flat = readJson2(join10(baseDir, "profiles", `${profile}.json`));
15400
15831
  if (flat)
15401
15832
  return flat.tokens ?? (flat.accessToken || flat.refreshToken ? flat : null);
15402
15833
  }
15403
15834
  return null;
15404
15835
  }
15405
- function saveTokens(profile, tokens) {
15406
- const baseDir = configDirs().find((dir) => existsSync8(dir)) ?? configDirs()[0];
15407
- const profileDir = join9(baseDir, "profiles", profile);
15408
- mkdirSync6(profileDir, { recursive: true });
15409
- writeFileSync3(join9(profileDir, "tokens.json"), JSON.stringify(tokens, null, 2), { mode: 384 });
15836
+ function saveTokens2(profile, tokens) {
15837
+ const baseDir = configDirs2().find((dir) => existsSync9(dir)) ?? configDirs2()[0];
15838
+ const profileDir = join10(baseDir, "profiles", profile);
15839
+ mkdirSync7(profileDir, { recursive: true });
15840
+ writeFileSync4(join10(profileDir, "tokens.json"), JSON.stringify(tokens, null, 2), { mode: 384 });
15410
15841
  }
15411
- function configDirs() {
15842
+ function configDirs2() {
15412
15843
  const explicit = process.env.HASNA_GOOGLE_DRIVE_CONNECTOR_DIR ?? process.env.GOOGLE_DRIVE_CONNECTOR_DIR;
15413
15844
  if (explicit)
15414
15845
  return [explicit];
15415
- const baseDir = process.env.HASNA_CONNECTORS_DIR ?? join9(homedir8(), ".hasna", "connectors");
15416
- return [join9(baseDir, "connect-googledrive"), join9(baseDir, "googledrive")];
15846
+ const baseDir = process.env.HASNA_CONNECTORS_DIR ?? join10(homedir9(), ".hasna", "connectors");
15847
+ return [join10(baseDir, "connect-googledrive"), join10(baseDir, "googledrive")];
15417
15848
  }
15418
- function readJson(path) {
15419
- if (!existsSync8(path))
15849
+ function readJson2(path) {
15850
+ if (!existsSync9(path))
15420
15851
  return null;
15421
15852
  try {
15422
- return JSON.parse(readFileSync3(path, "utf8"));
15853
+ return JSON.parse(readFileSync4(path, "utf8"));
15423
15854
  } catch {
15424
15855
  return null;
15425
15856
  }
@@ -15451,7 +15882,7 @@ function extractGoogleError(body) {
15451
15882
  // package.json
15452
15883
  var package_default = {
15453
15884
  name: "@hasna/connectors",
15454
- version: "1.3.25",
15885
+ version: "1.3.26",
15455
15886
  description: "Open source connector library - Install API connectors with a single command",
15456
15887
  type: "module",
15457
15888
  bin: {
@@ -15539,15 +15970,15 @@ var package_default = {
15539
15970
 
15540
15971
  // src/core/connectors/imessage.ts
15541
15972
  import {
15542
- existsSync as existsSync9,
15543
- mkdirSync as mkdirSync7,
15544
- readFileSync as readFileSync4,
15545
- readdirSync as readdirSync6,
15973
+ existsSync as existsSync10,
15974
+ mkdirSync as mkdirSync8,
15975
+ readFileSync as readFileSync5,
15976
+ readdirSync as readdirSync7,
15546
15977
  rmSync,
15547
15978
  statSync as statSync2,
15548
- writeFileSync as writeFileSync4
15979
+ writeFileSync as writeFileSync5
15549
15980
  } from "fs";
15550
- import { join as join10 } from "path";
15981
+ import { join as join11 } from "path";
15551
15982
  init_database();
15552
15983
  var CONNECTOR_DIRNAME = "connect-imessage";
15553
15984
  var COMMAND_SPECS = [
@@ -15709,36 +16140,36 @@ var messageReplyInputSchema = exports_external2.object({
15709
16140
  deviceId: exports_external2.string().optional()
15710
16141
  });
15711
16142
  function getConfigDir2() {
15712
- return join10(getConnectorsHome(), CONNECTOR_DIRNAME);
16143
+ return join11(getConnectorsHome(), CONNECTOR_DIRNAME);
15713
16144
  }
15714
16145
  function getProfilesDir() {
15715
- return join10(getConfigDir2(), "profiles");
16146
+ return join11(getConfigDir2(), "profiles");
15716
16147
  }
15717
16148
  function getCurrentProfile() {
15718
- const currentProfileFile = join10(getConfigDir2(), "current_profile");
15719
- if (!existsSync9(currentProfileFile)) {
16149
+ const currentProfileFile = join11(getConfigDir2(), "current_profile");
16150
+ if (!existsSync10(currentProfileFile)) {
15720
16151
  return "default";
15721
16152
  }
15722
16153
  try {
15723
- return readFileSync4(currentProfileFile, "utf-8").trim() || "default";
16154
+ return readFileSync5(currentProfileFile, "utf-8").trim() || "default";
15724
16155
  } catch {
15725
16156
  return "default";
15726
16157
  }
15727
16158
  }
15728
16159
  function setCurrentProfile(profile) {
15729
16160
  const configDir = getConfigDir2();
15730
- mkdirSync7(configDir, { recursive: true });
15731
- writeFileSync4(join10(configDir, "current_profile"), profile);
16161
+ mkdirSync8(configDir, { recursive: true });
16162
+ writeFileSync5(join11(configDir, "current_profile"), profile);
15732
16163
  }
15733
16164
  function getFlatProfilePath(profile) {
15734
- return join10(getProfilesDir(), `${profile}.json`);
16165
+ return join11(getProfilesDir(), `${profile}.json`);
15735
16166
  }
15736
16167
  function getDirectoryProfilePath(profile) {
15737
- return join10(getProfilesDir(), profile, "config.json");
16168
+ return join11(getProfilesDir(), profile, "config.json");
15738
16169
  }
15739
16170
  function loadJsonFile(path) {
15740
16171
  try {
15741
- return JSON.parse(readFileSync4(path, "utf-8"));
16172
+ return JSON.parse(readFileSync5(path, "utf-8"));
15742
16173
  } catch {
15743
16174
  return {};
15744
16175
  }
@@ -15754,8 +16185,8 @@ function sanitizeProfileConfig(config) {
15754
16185
  };
15755
16186
  }
15756
16187
  function loadProfile(profile = getCurrentProfile()) {
15757
- const flatConfig = existsSync9(getFlatProfilePath(profile)) ? loadJsonFile(getFlatProfilePath(profile)) : {};
15758
- const directoryConfig = existsSync9(getDirectoryProfilePath(profile)) ? loadJsonFile(getDirectoryProfilePath(profile)) : {};
16188
+ const flatConfig = existsSync10(getFlatProfilePath(profile)) ? loadJsonFile(getFlatProfilePath(profile)) : {};
16189
+ const directoryConfig = existsSync10(getDirectoryProfilePath(profile)) ? loadJsonFile(getDirectoryProfilePath(profile)) : {};
15759
16190
  return sanitizeProfileConfig({
15760
16191
  ...flatConfig,
15761
16192
  ...directoryConfig
@@ -15763,25 +16194,25 @@ function loadProfile(profile = getCurrentProfile()) {
15763
16194
  }
15764
16195
  function writeProfile(profile, config) {
15765
16196
  const profilesDir = getProfilesDir();
15766
- mkdirSync7(profilesDir, { recursive: true });
15767
- writeFileSync4(getFlatProfilePath(profile), JSON.stringify(config, null, 2) + `
16197
+ mkdirSync8(profilesDir, { recursive: true });
16198
+ writeFileSync5(getFlatProfilePath(profile), JSON.stringify(config, null, 2) + `
15768
16199
  `);
15769
16200
  }
15770
16201
  function profileExists(profile) {
15771
16202
  if (profile === "default") {
15772
16203
  return true;
15773
16204
  }
15774
- return existsSync9(getFlatProfilePath(profile)) || existsSync9(join10(getProfilesDir(), profile));
16205
+ return existsSync10(getFlatProfilePath(profile)) || existsSync10(join11(getProfilesDir(), profile));
15775
16206
  }
15776
- function listProfiles2() {
16207
+ function listProfiles3() {
15777
16208
  const profilesDir = getProfilesDir();
15778
16209
  const seen = new Set(["default"]);
15779
- if (!existsSync9(profilesDir)) {
16210
+ if (!existsSync10(profilesDir)) {
15780
16211
  return [...seen];
15781
16212
  }
15782
16213
  try {
15783
- for (const entry of readdirSync6(profilesDir)) {
15784
- const fullPath = join10(profilesDir, entry);
16214
+ for (const entry of readdirSync7(profilesDir)) {
16215
+ const fullPath = join11(profilesDir, entry);
15785
16216
  const stat = statSync2(fullPath);
15786
16217
  if (stat.isDirectory()) {
15787
16218
  seen.add(entry);
@@ -15802,11 +16233,11 @@ function createProfile(profile, config = {}) {
15802
16233
  }
15803
16234
  function clearProfile(profile = getCurrentProfile()) {
15804
16235
  const flatPath = getFlatProfilePath(profile);
15805
- const directoryPath = join10(getProfilesDir(), profile);
15806
- if (existsSync9(flatPath)) {
16236
+ const directoryPath = join11(getProfilesDir(), profile);
16237
+ if (existsSync10(flatPath)) {
15807
16238
  rmSync(flatPath);
15808
16239
  }
15809
- if (existsSync9(directoryPath)) {
16240
+ if (existsSync10(directoryPath)) {
15810
16241
  rmSync(directoryPath, { recursive: true, force: true });
15811
16242
  }
15812
16243
  }
@@ -16102,7 +16533,7 @@ async function sendMessage(context, input) {
16102
16533
  direction: "outbound"
16103
16534
  });
16104
16535
  }
16105
- async function replyToMessage(context, input) {
16536
+ async function replyToMessage2(context, input) {
16106
16537
  const payload = await bridgeRequest(context, "/messages/reply", {
16107
16538
  method: "POST",
16108
16539
  body: {
@@ -16216,7 +16647,7 @@ async function runProfileCommand2(args, context) {
16216
16647
  switch (subcommand) {
16217
16648
  case "list": {
16218
16649
  const current = getCurrentProfile();
16219
- const profiles = listProfiles2();
16650
+ const profiles = listProfiles3();
16220
16651
  return successOutput({ current, profiles }, context.format, () => profiles.map((profile) => `${profile}${profile === current ? " (active)" : ""}`).join(`
16221
16652
  `));
16222
16653
  }
@@ -16390,7 +16821,7 @@ async function runMessageCommand(args, context) {
16390
16821
  if (!conversationId || !text) {
16391
16822
  return failure2("Usage: connect-imessage message reply --conversation <id> --text <text>");
16392
16823
  }
16393
- return successOutput(await replyToMessage(resolved, {
16824
+ return successOutput(await replyToMessage2(resolved, {
16394
16825
  conversationId,
16395
16826
  text,
16396
16827
  replyToMessageId: asString2(options.replyTo),
@@ -16548,7 +16979,7 @@ var imessageConnector = defineConnector({
16548
16979
  summary: "Reply to an existing conversation through the bridge",
16549
16980
  inputSchema: messageReplyInputSchema,
16550
16981
  async execute({ context }, input) {
16551
- return replyToMessage(context, input);
16982
+ return replyToMessage2(context, input);
16552
16983
  }
16553
16984
  }
16554
16985
  },
@@ -16611,19 +17042,19 @@ var imessageConnector = defineConnector({
16611
17042
  });
16612
17043
 
16613
17044
  // src/core/connectors/stripe.ts
16614
- import { existsSync as existsSync10 } from "fs";
16615
- import { dirname as dirname4, join as join11 } from "path";
17045
+ import { existsSync as existsSync11 } from "fs";
17046
+ import { dirname as dirname4, join as join12 } from "path";
16616
17047
  import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "url";
16617
17048
  var __dirname3 = dirname4(fileURLToPath2(import.meta.url));
16618
17049
  function resolveStripeConnectorDir() {
16619
17050
  const candidates = [
16620
- join11(__dirname3, "..", "..", "..", "connectors", "connect-stripe"),
16621
- join11(__dirname3, "..", "..", "connectors", "connect-stripe"),
16622
- join11(__dirname3, "..", "connectors", "connect-stripe"),
16623
- join11(process.cwd(), "connectors", "connect-stripe")
17051
+ join12(__dirname3, "..", "..", "..", "connectors", "connect-stripe"),
17052
+ join12(__dirname3, "..", "..", "connectors", "connect-stripe"),
17053
+ join12(__dirname3, "..", "connectors", "connect-stripe"),
17054
+ join12(process.cwd(), "connectors", "connect-stripe")
16624
17055
  ];
16625
17056
  for (const candidate of candidates) {
16626
- if (existsSync10(candidate)) {
17057
+ if (existsSync11(candidate)) {
16627
17058
  return candidate;
16628
17059
  }
16629
17060
  }
@@ -16862,10 +17293,10 @@ function buildCommandHelp2(spec) {
16862
17293
  var ROOT_HELP3 = buildRootHelp2(COMMAND_SPECS2);
16863
17294
  var COMMAND_HELP3 = Object.fromEntries(COMMAND_SPECS2.map((spec) => [spec.name, buildCommandHelp2(spec)]));
16864
17295
  async function loadStripeApiModule() {
16865
- return await import(pathToFileURL2(join11(CONNECTOR_DIR2, "src", "api", "index.ts")).href);
17296
+ return await import(pathToFileURL2(join12(CONNECTOR_DIR2, "src", "api", "index.ts")).href);
16866
17297
  }
16867
17298
  async function loadStripeConfigModule() {
16868
- return await import(pathToFileURL2(join11(CONNECTOR_DIR2, "src", "utils", "config.ts")).href);
17299
+ return await import(pathToFileURL2(join12(CONNECTOR_DIR2, "src", "utils", "config.ts")).href);
16869
17300
  }
16870
17301
  function extractGlobalArgs3(args) {
16871
17302
  const remaining = [];
@@ -17477,6 +17908,7 @@ var stripeConnector = defineConnector({
17477
17908
 
17478
17909
  // src/core/builtins.ts
17479
17910
  var INTERNAL_CONNECTOR_DEFINITIONS = [
17911
+ gmailConnector,
17480
17912
  githubConnector,
17481
17913
  googleDriveConnector,
17482
17914
  imessageConnector,
@@ -23503,17 +23935,17 @@ function loadConnectorVersions() {
23503
23935
  versionsLoaded = true;
23504
23936
  const thisDir = dirname5(fileURLToPath3(import.meta.url));
23505
23937
  const candidates = [
23506
- join12(thisDir, "..", "connectors"),
23507
- join12(thisDir, "..", "..", "connectors")
23938
+ join13(thisDir, "..", "connectors"),
23939
+ join13(thisDir, "..", "..", "connectors")
23508
23940
  ];
23509
- const connectorsDir = candidates.find((d) => existsSync11(d));
23941
+ const connectorsDir = candidates.find((d) => existsSync12(d));
23510
23942
  if (!connectorsDir)
23511
23943
  return;
23512
23944
  for (const connector of CONNECTORS) {
23513
23945
  try {
23514
- const pkgPath = join12(connectorsDir, `connect-${connector.name}`, "package.json");
23515
- if (existsSync11(pkgPath)) {
23516
- const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
23946
+ const pkgPath = join13(connectorsDir, `connect-${connector.name}`, "package.json");
23947
+ if (existsSync12(pkgPath)) {
23948
+ const pkg = JSON.parse(readFileSync6(pkgPath, "utf-8"));
23517
23949
  connector.version = pkg.version || "0.0.0";
23518
23950
  continue;
23519
23951
  }
@@ -23526,16 +23958,16 @@ function loadConnectorVersions() {
23526
23958
  }
23527
23959
 
23528
23960
  // src/lib/installer.ts
23529
- import { existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync5, readdirSync as readdirSync7, statSync as statSync3, rmSync as rmSync2 } from "fs";
23530
- import { join as join13, dirname as dirname6 } from "path";
23961
+ import { existsSync as existsSync13, mkdirSync as mkdirSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync6, readdirSync as readdirSync8, statSync as statSync3, rmSync as rmSync2 } from "fs";
23962
+ import { join as join14, dirname as dirname6 } from "path";
23531
23963
  import { fileURLToPath as fileURLToPath4 } from "url";
23532
23964
  var __dirname4 = dirname6(fileURLToPath4(import.meta.url));
23533
23965
  function resolveConnectorsDir() {
23534
- const fromBin = join13(__dirname4, "..", "connectors");
23535
- if (existsSync12(fromBin))
23966
+ const fromBin = join14(__dirname4, "..", "connectors");
23967
+ if (existsSync13(fromBin))
23536
23968
  return fromBin;
23537
- const fromSrc = join13(__dirname4, "..", "..", "connectors");
23538
- if (existsSync12(fromSrc))
23969
+ const fromSrc = join14(__dirname4, "..", "..", "connectors");
23970
+ if (existsSync13(fromSrc))
23539
23971
  return fromSrc;
23540
23972
  return fromBin;
23541
23973
  }
@@ -23547,21 +23979,21 @@ function normalizeConnectorName(name) {
23547
23979
  return name.startsWith("connect-") ? name.slice("connect-".length) : name;
23548
23980
  }
23549
23981
  function getProjectConnectorsDir(targetDir) {
23550
- return join13(targetDir, PROJECT_CONNECTORS_DIRNAME);
23982
+ return join14(targetDir, PROJECT_CONNECTORS_DIRNAME);
23551
23983
  }
23552
23984
  function getEnablementManifestPath(targetDir) {
23553
- return join13(getProjectConnectorsDir(targetDir), ENABLEMENT_MANIFEST_FILENAME);
23985
+ return join14(getProjectConnectorsDir(targetDir), ENABLEMENT_MANIFEST_FILENAME);
23554
23986
  }
23555
23987
  function getLegacyInstallPath(targetDir, name) {
23556
- return join13(getProjectConnectorsDir(targetDir), `connect-${normalizeConnectorName(name)}`);
23988
+ return join14(getProjectConnectorsDir(targetDir), `connect-${normalizeConnectorName(name)}`);
23557
23989
  }
23558
23990
  function loadEnablementManifest(targetDir) {
23559
23991
  const manifestPath = getEnablementManifestPath(targetDir);
23560
- if (!existsSync12(manifestPath)) {
23992
+ if (!existsSync13(manifestPath)) {
23561
23993
  return null;
23562
23994
  }
23563
23995
  try {
23564
- const raw = JSON.parse(readFileSync6(manifestPath, "utf-8"));
23996
+ const raw = JSON.parse(readFileSync7(manifestPath, "utf-8"));
23565
23997
  if (!Array.isArray(raw.connectors)) {
23566
23998
  return null;
23567
23999
  }
@@ -23577,11 +24009,11 @@ function loadEnablementManifest(targetDir) {
23577
24009
  }
23578
24010
  function getLegacyInstalledConnectors(targetDir) {
23579
24011
  const connectorsDir = getProjectConnectorsDir(targetDir);
23580
- if (!existsSync12(connectorsDir)) {
24012
+ if (!existsSync13(connectorsDir)) {
23581
24013
  return [];
23582
24014
  }
23583
- return readdirSync7(connectorsDir).filter((entry) => {
23584
- const fullPath = join13(connectorsDir, entry);
24015
+ return readdirSync8(connectorsDir).filter((entry) => {
24016
+ const fullPath = join14(connectorsDir, entry);
23585
24017
  return entry.startsWith("connect-") && statSync3(fullPath).isDirectory();
23586
24018
  }).map((entry) => entry.replace("connect-", "")).sort();
23587
24019
  }
@@ -23590,7 +24022,7 @@ function getEnabledConnectors(targetDir) {
23590
24022
  return [...new Set([...manifestConnectors, ...getLegacyInstalledConnectors(targetDir)])].sort();
23591
24023
  }
23592
24024
  function updateConnectorsIndex(connectorsDir, connectors18) {
23593
- const indexPath = join13(connectorsDir, ENABLEMENT_INDEX_FILENAME);
24025
+ const indexPath = join14(connectorsDir, ENABLEMENT_INDEX_FILENAME);
23594
24026
  const connectorList = connectors18.map((connector) => ` "${connector}",`).join(`
23595
24027
  `);
23596
24028
  const content = `/**
@@ -23606,28 +24038,28 @@ ${connectorList}
23606
24038
 
23607
24039
  export type EnabledConnectorName = typeof enabledConnectors[number];
23608
24040
  `;
23609
- writeFileSync5(indexPath, content);
24041
+ writeFileSync6(indexPath, content);
23610
24042
  }
23611
24043
  function writeEnablementManifest(targetDir, connectors18) {
23612
24044
  const connectorsDir = getProjectConnectorsDir(targetDir);
23613
- mkdirSync8(connectorsDir, { recursive: true });
24045
+ mkdirSync9(connectorsDir, { recursive: true });
23614
24046
  const manifest = {
23615
24047
  version: 1,
23616
24048
  mode: "internal",
23617
24049
  updatedAt: new Date().toISOString(),
23618
24050
  connectors: [...new Set(connectors18.map((value) => normalizeConnectorName(value)))].sort()
23619
24051
  };
23620
- writeFileSync5(getEnablementManifestPath(targetDir), JSON.stringify(manifest, null, 2) + `
24052
+ writeFileSync6(getEnablementManifestPath(targetDir), JSON.stringify(manifest, null, 2) + `
23621
24053
  `);
23622
24054
  updateConnectorsIndex(connectorsDir, manifest.connectors);
23623
24055
  }
23624
24056
  function getConnectorPath(name) {
23625
24057
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
23626
- return join13(CONNECTORS_DIR, connectorName);
24058
+ return join14(CONNECTORS_DIR, connectorName);
23627
24059
  }
23628
24060
  function connectorExists(name) {
23629
24061
  const normalizedName = normalizeConnectorName(name);
23630
- return hasInternalConnectorDefinition(normalizedName) || existsSync12(getConnectorPath(normalizedName));
24062
+ return hasInternalConnectorDefinition(normalizedName) || existsSync13(getConnectorPath(normalizedName));
23631
24063
  }
23632
24064
  function installConnector(name, options = {}) {
23633
24065
  const { targetDir = process.cwd(), overwrite = false } = options;
@@ -23660,7 +24092,7 @@ function installConnector(name, options = {}) {
23660
24092
  try {
23661
24093
  const nextEnabled = [...new Set([...installed, normalizedName])].sort();
23662
24094
  writeEnablementManifest(targetDir, nextEnabled);
23663
- if (overwrite && existsSync12(legacyInstallPath)) {
24095
+ if (overwrite && existsSync13(legacyInstallPath)) {
23664
24096
  rmSync2(legacyInstallPath, { recursive: true });
23665
24097
  }
23666
24098
  return {
@@ -23692,9 +24124,9 @@ function parseConnectorDocs(raw) {
23692
24124
  function getConnectorDocs(name) {
23693
24125
  const normalizedName = normalizeConnectorName(name);
23694
24126
  const connectorPath = getConnectorPath(normalizedName);
23695
- const claudeMdPath = join13(connectorPath, "CLAUDE.md");
23696
- if (existsSync12(claudeMdPath)) {
23697
- return parseConnectorDocs(readFileSync6(claudeMdPath, "utf-8"));
24127
+ const claudeMdPath = join14(connectorPath, "CLAUDE.md");
24128
+ if (existsSync13(claudeMdPath)) {
24129
+ return parseConnectorDocs(readFileSync7(claudeMdPath, "utf-8"));
23698
24130
  }
23699
24131
  const internalDocs = getInternalConnectorDefinition(normalizedName)?.docsMarkdown;
23700
24132
  if (internalDocs) {
@@ -23738,29 +24170,29 @@ function removeConnector(name, targetDir = process.cwd()) {
23738
24170
  const nextEnabled = installed.filter((connector) => connector !== normalizedName);
23739
24171
  writeEnablementManifest(targetDir, nextEnabled);
23740
24172
  const legacyInstallPath = getLegacyInstallPath(targetDir, normalizedName);
23741
- if (existsSync12(legacyInstallPath)) {
24173
+ if (existsSync13(legacyInstallPath)) {
23742
24174
  rmSync2(legacyInstallPath, { recursive: true });
23743
24175
  }
23744
24176
  return true;
23745
24177
  }
23746
24178
 
23747
24179
  // src/lib/runner.ts
23748
- import { existsSync as existsSync15, readdirSync as readdirSync9 } from "fs";
23749
- import { join as join16, dirname as dirname7 } from "path";
24180
+ import { existsSync as existsSync16, readdirSync as readdirSync10 } from "fs";
24181
+ import { join as join17, dirname as dirname7 } from "path";
23750
24182
  import { fileURLToPath as fileURLToPath5 } from "url";
23751
24183
  import { spawn as spawn2 } from "child_process";
23752
24184
  init_database();
23753
24185
 
23754
24186
  // src/server/auth.ts
23755
- import { existsSync as existsSync14, readFileSync as readFileSync7, writeFileSync as writeFileSync6, mkdirSync as mkdirSync10, readdirSync as readdirSync8, rmSync as rmSync3, statSync as statSync5 } from "fs";
24187
+ import { existsSync as existsSync15, readFileSync as readFileSync8, writeFileSync as writeFileSync7, mkdirSync as mkdirSync11, readdirSync as readdirSync9, rmSync as rmSync3, statSync as statSync5 } from "fs";
23756
24188
  import { randomBytes } from "crypto";
23757
- import { join as join15 } from "path";
24189
+ import { join as join16 } from "path";
23758
24190
 
23759
24191
  // src/lib/lock.ts
23760
24192
  init_database();
23761
- import { openSync, closeSync, unlinkSync, existsSync as existsSync13, statSync as statSync4 } from "fs";
23762
- import { join as join14 } from "path";
23763
- import { mkdirSync as mkdirSync9 } from "fs";
24193
+ import { openSync, closeSync, unlinkSync, existsSync as existsSync14, statSync as statSync4 } from "fs";
24194
+ import { join as join15 } from "path";
24195
+ import { mkdirSync as mkdirSync10 } from "fs";
23764
24196
  var LOCK_TIMEOUT_MS = 5000;
23765
24197
  var LOCK_RETRY_MS = 100;
23766
24198
  var STALE_LOCK_MS = 30000;
@@ -23774,9 +24206,9 @@ class LockTimeoutError extends Error {
23774
24206
  }
23775
24207
  }
23776
24208
  function lockPath(connector) {
23777
- const dir = join14(getConnectorsHome(), `connect-${connector}`);
23778
- mkdirSync9(dir, { recursive: true });
23779
- return join14(dir, ".write.lock");
24209
+ const dir = join15(getConnectorsHome(), `connect-${connector}`);
24210
+ mkdirSync10(dir, { recursive: true });
24211
+ return join15(dir, ".write.lock");
23780
24212
  }
23781
24213
  function isStale(path) {
23782
24214
  try {
@@ -23787,7 +24219,7 @@ function isStale(path) {
23787
24219
  }
23788
24220
  }
23789
24221
  function tryAcquire(path) {
23790
- if (existsSync13(path) && isStale(path)) {
24222
+ if (existsSync14(path) && isStale(path)) {
23791
24223
  try {
23792
24224
  unlinkSync(path);
23793
24225
  } catch {}
@@ -23880,14 +24312,14 @@ function getAuthType(name) {
23880
24312
  }
23881
24313
  function getConnectorConfigDir(name) {
23882
24314
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
23883
- return join15(getConnectorsHome(), connectorName);
24315
+ return join16(getConnectorsHome(), connectorName);
23884
24316
  }
23885
24317
  function getCurrentProfile2(name) {
23886
24318
  const configDir = getConnectorConfigDir(name);
23887
- const currentProfileFile = join15(configDir, "current_profile");
23888
- if (existsSync14(currentProfileFile)) {
24319
+ const currentProfileFile = join16(configDir, "current_profile");
24320
+ if (existsSync15(currentProfileFile)) {
23889
24321
  try {
23890
- return readFileSync7(currentProfileFile, "utf-8").trim() || "default";
24322
+ return readFileSync8(currentProfileFile, "utf-8").trim() || "default";
23891
24323
  } catch {
23892
24324
  return "default";
23893
24325
  }
@@ -23899,16 +24331,16 @@ function loadProfileConfig(name) {
23899
24331
  const profile = getCurrentProfile2(name);
23900
24332
  let flatConfig = {};
23901
24333
  let dirConfig = {};
23902
- const profileFile = join15(configDir, "profiles", `${profile}.json`);
23903
- if (existsSync14(profileFile)) {
24334
+ const profileFile = join16(configDir, "profiles", `${profile}.json`);
24335
+ if (existsSync15(profileFile)) {
23904
24336
  try {
23905
- flatConfig = JSON.parse(readFileSync7(profileFile, "utf-8"));
24337
+ flatConfig = JSON.parse(readFileSync8(profileFile, "utf-8"));
23906
24338
  } catch {}
23907
24339
  }
23908
- const profileDirConfig = join15(configDir, "profiles", profile, "config.json");
23909
- if (existsSync14(profileDirConfig)) {
24340
+ const profileDirConfig = join16(configDir, "profiles", profile, "config.json");
24341
+ if (existsSync15(profileDirConfig)) {
23910
24342
  try {
23911
- dirConfig = JSON.parse(readFileSync7(profileDirConfig, "utf-8"));
24343
+ dirConfig = JSON.parse(readFileSync8(profileDirConfig, "utf-8"));
23912
24344
  } catch {}
23913
24345
  }
23914
24346
  if (Object.keys(flatConfig).length === 0 && Object.keys(dirConfig).length === 0) {
@@ -23916,13 +24348,13 @@ function loadProfileConfig(name) {
23916
24348
  }
23917
24349
  return { ...flatConfig, ...dirConfig };
23918
24350
  }
23919
- function loadTokens2(name) {
24351
+ function loadTokens3(name) {
23920
24352
  const configDir = getConnectorConfigDir(name);
23921
24353
  const profile = getCurrentProfile2(name);
23922
- const tokensFile = join15(configDir, "profiles", profile, "tokens.json");
23923
- if (existsSync14(tokensFile)) {
24354
+ const tokensFile = join16(configDir, "profiles", profile, "tokens.json");
24355
+ if (existsSync15(tokensFile)) {
23924
24356
  try {
23925
- return JSON.parse(readFileSync7(tokensFile, "utf-8"));
24357
+ return JSON.parse(readFileSync8(tokensFile, "utf-8"));
23926
24358
  } catch {
23927
24359
  return null;
23928
24360
  }
@@ -23961,7 +24393,7 @@ function getAuthStatus(name) {
23961
24393
  const authType = getAuthType(name);
23962
24394
  const docs = getConnectorDocs(name);
23963
24395
  const oauthConfig = authType === "oauth" ? getOAuthConfig(name) : {};
23964
- const tokens = authType === "oauth" ? loadTokens2(name) : null;
24396
+ const tokens = authType === "oauth" ? loadTokens3(name) : null;
23965
24397
  const profileConfig = authType === "oauth" ? loadProfileConfig(name) : {};
23966
24398
  const envVars = (docs?.envVars || []).map((v) => ({
23967
24399
  variable: v.variable,
@@ -24010,43 +24442,43 @@ function _saveApiKey(name, key, field) {
24010
24442
  const profile = getCurrentProfile2(name);
24011
24443
  const keyField = field || guessKeyField(name);
24012
24444
  if (keyField === "clientId" || keyField === "clientSecret") {
24013
- const credentialsFile = join15(configDir, "credentials.json");
24014
- mkdirSync10(configDir, { recursive: true });
24445
+ const credentialsFile = join16(configDir, "credentials.json");
24446
+ mkdirSync11(configDir, { recursive: true });
24015
24447
  let creds = {};
24016
- if (existsSync14(credentialsFile)) {
24448
+ if (existsSync15(credentialsFile)) {
24017
24449
  try {
24018
- creds = JSON.parse(readFileSync7(credentialsFile, "utf-8"));
24450
+ creds = JSON.parse(readFileSync8(credentialsFile, "utf-8"));
24019
24451
  } catch {}
24020
24452
  }
24021
24453
  creds[keyField] = key;
24022
- writeFileSync6(credentialsFile, JSON.stringify(creds, null, 2));
24454
+ writeFileSync7(credentialsFile, JSON.stringify(creds, null, 2));
24023
24455
  return;
24024
24456
  }
24025
- const profileFile = join15(configDir, "profiles", `${profile}.json`);
24026
- const profileDir = join15(configDir, "profiles", profile);
24027
- if (existsSync14(profileFile)) {
24457
+ const profileFile = join16(configDir, "profiles", `${profile}.json`);
24458
+ const profileDir = join16(configDir, "profiles", profile);
24459
+ if (existsSync15(profileFile)) {
24028
24460
  let config = {};
24029
24461
  try {
24030
- config = JSON.parse(readFileSync7(profileFile, "utf-8"));
24462
+ config = JSON.parse(readFileSync8(profileFile, "utf-8"));
24031
24463
  } catch {}
24032
24464
  config[keyField] = key;
24033
- writeFileSync6(profileFile, JSON.stringify(config, null, 2));
24465
+ writeFileSync7(profileFile, JSON.stringify(config, null, 2));
24034
24466
  return;
24035
24467
  }
24036
- if (existsSync14(profileDir)) {
24037
- const configFile = join15(profileDir, "config.json");
24468
+ if (existsSync15(profileDir)) {
24469
+ const configFile = join16(profileDir, "config.json");
24038
24470
  let config = {};
24039
- if (existsSync14(configFile)) {
24471
+ if (existsSync15(configFile)) {
24040
24472
  try {
24041
- config = JSON.parse(readFileSync7(configFile, "utf-8"));
24473
+ config = JSON.parse(readFileSync8(configFile, "utf-8"));
24042
24474
  } catch {}
24043
24475
  }
24044
24476
  config[keyField] = key;
24045
- writeFileSync6(configFile, JSON.stringify(config, null, 2));
24477
+ writeFileSync7(configFile, JSON.stringify(config, null, 2));
24046
24478
  return;
24047
24479
  }
24048
- mkdirSync10(profileDir, { recursive: true });
24049
- writeFileSync6(join15(profileDir, "config.json"), JSON.stringify({ [keyField]: key }, null, 2));
24480
+ mkdirSync11(profileDir, { recursive: true });
24481
+ writeFileSync7(join16(profileDir, "config.json"), JSON.stringify({ [keyField]: key }, null, 2));
24050
24482
  }
24051
24483
  function guessKeyField(name) {
24052
24484
  const docs = getConnectorDocs(name);
@@ -24064,10 +24496,10 @@ function guessKeyField(name) {
24064
24496
  }
24065
24497
  function getOAuthConfig(name) {
24066
24498
  const configDir = getConnectorConfigDir(name);
24067
- const credentialsFile = join15(configDir, "credentials.json");
24068
- if (existsSync14(credentialsFile)) {
24499
+ const credentialsFile = join16(configDir, "credentials.json");
24500
+ if (existsSync15(credentialsFile)) {
24069
24501
  try {
24070
- const creds = JSON.parse(readFileSync7(credentialsFile, "utf-8"));
24502
+ const creds = JSON.parse(readFileSync8(credentialsFile, "utf-8"));
24071
24503
  return { clientId: creds.clientId, clientSecret: creds.clientSecret };
24072
24504
  } catch {}
24073
24505
  }
@@ -24146,17 +24578,17 @@ async function exchangeOAuthCode(name, code, redirectUri) {
24146
24578
  function saveOAuthTokens(name, tokens) {
24147
24579
  const configDir = getConnectorConfigDir(name);
24148
24580
  const profile = getCurrentProfile2(name);
24149
- const profileDir = join15(configDir, "profiles", profile);
24150
- mkdirSync10(profileDir, { recursive: true });
24151
- const tokensFile = join15(profileDir, "tokens.json");
24152
- writeFileSync6(tokensFile, JSON.stringify(tokens, null, 2), { mode: 384 });
24581
+ const profileDir = join16(configDir, "profiles", profile);
24582
+ mkdirSync11(profileDir, { recursive: true });
24583
+ const tokensFile = join16(profileDir, "tokens.json");
24584
+ writeFileSync7(tokensFile, JSON.stringify(tokens, null, 2), { mode: 384 });
24153
24585
  }
24154
24586
  async function refreshOAuthToken(name) {
24155
24587
  return withWriteLock(name, () => _refreshOAuthToken(name));
24156
24588
  }
24157
24589
  async function _refreshOAuthToken(name) {
24158
24590
  const oauthConfig = getOAuthConfig(name);
24159
- const currentTokens = loadTokens2(name);
24591
+ const currentTokens = loadTokens3(name);
24160
24592
  if (!oauthConfig.clientId || !oauthConfig.clientSecret) {
24161
24593
  throw new Error("OAuth credentials not configured for " + name);
24162
24594
  }
@@ -24189,16 +24621,16 @@ async function _refreshOAuthToken(name) {
24189
24621
  saveOAuthTokens(name, tokens);
24190
24622
  return tokens;
24191
24623
  }
24192
- function listProfiles3(name) {
24624
+ function listProfiles4(name) {
24193
24625
  const configDir = getConnectorConfigDir(name);
24194
- const profilesDir = join15(configDir, "profiles");
24195
- if (!existsSync14(profilesDir))
24626
+ const profilesDir = join16(configDir, "profiles");
24627
+ if (!existsSync15(profilesDir))
24196
24628
  return ["default"];
24197
24629
  const seen = new Set;
24198
24630
  try {
24199
- const entries = readdirSync8(profilesDir);
24631
+ const entries = readdirSync9(profilesDir);
24200
24632
  for (const entry of entries) {
24201
- const fullPath = join15(profilesDir, entry);
24633
+ const fullPath = join16(profilesDir, entry);
24202
24634
  const stat = statSync5(fullPath);
24203
24635
  if (stat.isDirectory()) {
24204
24636
  seen.add(entry);
@@ -24212,24 +24644,24 @@ function listProfiles3(name) {
24212
24644
  }
24213
24645
  function switchProfile(name, profile) {
24214
24646
  const configDir = getConnectorConfigDir(name);
24215
- mkdirSync10(configDir, { recursive: true });
24216
- writeFileSync6(join15(configDir, "current_profile"), profile);
24647
+ mkdirSync11(configDir, { recursive: true });
24648
+ writeFileSync7(join16(configDir, "current_profile"), profile);
24217
24649
  }
24218
24650
  function deleteProfile2(name, profile) {
24219
24651
  if (profile === "default")
24220
24652
  return false;
24221
24653
  const configDir = getConnectorConfigDir(name);
24222
- const profilesDir = join15(configDir, "profiles");
24223
- const profileFile = join15(profilesDir, `${profile}.json`);
24224
- if (existsSync14(profileFile)) {
24654
+ const profilesDir = join16(configDir, "profiles");
24655
+ const profileFile = join16(profilesDir, `${profile}.json`);
24656
+ if (existsSync15(profileFile)) {
24225
24657
  rmSync3(profileFile);
24226
24658
  if (getCurrentProfile2(name) === profile) {
24227
24659
  switchProfile(name, "default");
24228
24660
  }
24229
24661
  return true;
24230
24662
  }
24231
- const profileDir = join15(profilesDir, profile);
24232
- if (existsSync14(profileDir)) {
24663
+ const profileDir = join16(profilesDir, profile);
24664
+ if (existsSync15(profileDir)) {
24233
24665
  rmSync3(profileDir, { recursive: true });
24234
24666
  if (getCurrentProfile2(name) === profile) {
24235
24667
  switchProfile(name, "default");
@@ -24242,11 +24674,11 @@ function deleteProfile2(name, profile) {
24242
24674
  // src/lib/runner.ts
24243
24675
  var __dirname5 = dirname7(fileURLToPath5(import.meta.url));
24244
24676
  function resolveConnectorsDir2() {
24245
- const fromBin = join16(__dirname5, "..", "connectors");
24246
- if (existsSync15(fromBin))
24677
+ const fromBin = join17(__dirname5, "..", "connectors");
24678
+ if (existsSync16(fromBin))
24247
24679
  return fromBin;
24248
- const fromSrc = join16(__dirname5, "..", "..", "connectors");
24249
- if (existsSync15(fromSrc))
24680
+ const fromSrc = join17(__dirname5, "..", "..", "connectors");
24681
+ if (existsSync16(fromSrc))
24250
24682
  return fromSrc;
24251
24683
  return fromBin;
24252
24684
  }
@@ -24299,7 +24731,7 @@ function buildEnvWithCredentials(connectorName, baseEnv) {
24299
24731
  }
24300
24732
  if (getAuthType(connectorName) === "oauth") {
24301
24733
  const oauthConfig = getOAuthConfig(connectorName);
24302
- const tokens = loadTokens2(connectorName);
24734
+ const tokens = loadTokens3(connectorName);
24303
24735
  for (const { variable } of getEnvVars(connectorName)) {
24304
24736
  if (env[variable])
24305
24737
  continue;
@@ -24320,9 +24752,9 @@ function buildEnvWithCredentials(connectorName, baseEnv) {
24320
24752
  }
24321
24753
  function getConnectorCliPath(name) {
24322
24754
  const safeName = name.replace(/[^a-z0-9-]/g, "");
24323
- const connectorDir = join16(CONNECTORS_DIR2, `connect-${safeName}`);
24324
- const cliPath = join16(connectorDir, "src", "cli", "index.ts");
24325
- if (existsSync15(cliPath))
24755
+ const connectorDir = join17(CONNECTORS_DIR2, `connect-${safeName}`);
24756
+ const cliPath = join17(connectorDir, "src", "cli", "index.ts");
24757
+ if (existsSync16(cliPath))
24326
24758
  return cliPath;
24327
24759
  return null;
24328
24760
  }
@@ -24499,20 +24931,20 @@ function resolveDashboardDir() {
24499
24931
  const candidates = [];
24500
24932
  try {
24501
24933
  const scriptDir = dirname8(fileURLToPath6(import.meta.url));
24502
- candidates.push(join17(scriptDir, "..", "dashboard", "dist"));
24503
- candidates.push(join17(scriptDir, "..", "..", "dashboard", "dist"));
24934
+ candidates.push(join18(scriptDir, "..", "dashboard", "dist"));
24935
+ candidates.push(join18(scriptDir, "..", "..", "dashboard", "dist"));
24504
24936
  } catch {}
24505
24937
  if (process.argv[1]) {
24506
24938
  const mainDir = dirname8(process.argv[1]);
24507
- candidates.push(join17(mainDir, "..", "dashboard", "dist"));
24508
- candidates.push(join17(mainDir, "..", "..", "dashboard", "dist"));
24939
+ candidates.push(join18(mainDir, "..", "dashboard", "dist"));
24940
+ candidates.push(join18(mainDir, "..", "..", "dashboard", "dist"));
24509
24941
  }
24510
- candidates.push(join17(process.cwd(), "dashboard", "dist"));
24942
+ candidates.push(join18(process.cwd(), "dashboard", "dist"));
24511
24943
  for (const candidate of candidates) {
24512
- if (existsSync16(candidate))
24944
+ if (existsSync17(candidate))
24513
24945
  return candidate;
24514
24946
  }
24515
- return join17(process.cwd(), "dashboard", "dist");
24947
+ return join18(process.cwd(), "dashboard", "dist");
24516
24948
  }
24517
24949
  var MIME_TYPES = {
24518
24950
  ".html": "text/html; charset=utf-8",
@@ -24614,7 +25046,7 @@ function oauthPage(type, title, message, hint, extra) {
24614
25046
  </body></html>`;
24615
25047
  }
24616
25048
  function serveStaticFile(filePath) {
24617
- if (!existsSync16(filePath))
25049
+ if (!existsSync17(filePath))
24618
25050
  return null;
24619
25051
  const ext = extname(filePath);
24620
25052
  const contentType = MIME_TYPES[ext] || "application/octet-stream";
@@ -24651,7 +25083,7 @@ async function startServer(requestedPort, options) {
24651
25083
  const strict = options?.strict ?? false;
24652
25084
  loadConnectorVersions();
24653
25085
  const dashboardDir = resolveDashboardDir();
24654
- const dashboardExists = existsSync16(dashboardDir);
25086
+ const dashboardExists = existsSync17(dashboardDir);
24655
25087
  if (!dashboardExists) {
24656
25088
  console.error(`
24657
25089
  Dashboard not found at: ${dashboardDir}`);
@@ -25053,13 +25485,13 @@ ${result.stderr}`;
25053
25485
  if (!isValidConnectorName(name))
25054
25486
  return json({ error: "Invalid connector name" }, 400, port);
25055
25487
  try {
25056
- const profiles = listProfiles3(name);
25057
- const configDir = join17(getConnectorsHome(), name.startsWith("connect-") ? name : `connect-${name}`);
25058
- const currentProfileFile = join17(configDir, "current_profile");
25488
+ const profiles = listProfiles4(name);
25489
+ const configDir = join18(getConnectorsHome(), name.startsWith("connect-") ? name : `connect-${name}`);
25490
+ const currentProfileFile = join18(configDir, "current_profile");
25059
25491
  let current = "default";
25060
- if (existsSync16(currentProfileFile)) {
25492
+ if (existsSync17(currentProfileFile)) {
25061
25493
  try {
25062
- current = readFileSync8(currentProfileFile, "utf-8").trim() || "default";
25494
+ current = readFileSync9(currentProfileFile, "utf-8").trim() || "default";
25063
25495
  } catch {}
25064
25496
  }
25065
25497
  return json({ current, profiles }, 200, port);
@@ -25108,30 +25540,30 @@ ${result.stderr}`;
25108
25540
  try {
25109
25541
  const connectDir = getConnectorsHome();
25110
25542
  const result = {};
25111
- if (existsSync16(connectDir)) {
25112
- const entries = readdirSync10(connectDir, { withFileTypes: true });
25543
+ if (existsSync17(connectDir)) {
25544
+ const entries = readdirSync11(connectDir, { withFileTypes: true });
25113
25545
  for (const entry of entries) {
25114
25546
  if (!entry.isDirectory() || !entry.name.startsWith("connect-"))
25115
25547
  continue;
25116
25548
  const connectorName = entry.name.replace(/^connect-/, "");
25117
- const profilesDir = join17(connectDir, entry.name, "profiles");
25118
- if (!existsSync16(profilesDir))
25549
+ const profilesDir = join18(connectDir, entry.name, "profiles");
25550
+ if (!existsSync17(profilesDir))
25119
25551
  continue;
25120
25552
  const profiles = {};
25121
- const profileEntries = readdirSync10(profilesDir, { withFileTypes: true });
25553
+ const profileEntries = readdirSync11(profilesDir, { withFileTypes: true });
25122
25554
  for (const pEntry of profileEntries) {
25123
25555
  if (pEntry.isFile() && pEntry.name.endsWith(".json")) {
25124
- const profileName = basename2(pEntry.name, ".json");
25556
+ const profileName = basename3(pEntry.name, ".json");
25125
25557
  try {
25126
- const config = JSON.parse(readFileSync8(join17(profilesDir, pEntry.name), "utf-8"));
25558
+ const config = JSON.parse(readFileSync9(join18(profilesDir, pEntry.name), "utf-8"));
25127
25559
  profiles[profileName] = config;
25128
25560
  } catch {}
25129
25561
  }
25130
25562
  if (pEntry.isDirectory()) {
25131
- const configPath = join17(profilesDir, pEntry.name, "config.json");
25132
- if (existsSync16(configPath)) {
25563
+ const configPath = join18(profilesDir, pEntry.name, "config.json");
25564
+ if (existsSync17(configPath)) {
25133
25565
  try {
25134
- const config = JSON.parse(readFileSync8(configPath, "utf-8"));
25566
+ const config = JSON.parse(readFileSync9(configPath, "utf-8"));
25135
25567
  profiles[pEntry.name] = config;
25136
25568
  } catch {}
25137
25569
  }
@@ -25172,14 +25604,14 @@ ${result.stderr}`;
25172
25604
  continue;
25173
25605
  if (!data.profiles || typeof data.profiles !== "object")
25174
25606
  continue;
25175
- const connectorDir = join17(connectDir, `connect-${connectorName}`);
25176
- const profilesDir = join17(connectorDir, "profiles");
25607
+ const connectorDir = join18(connectDir, `connect-${connectorName}`);
25608
+ const profilesDir = join18(connectorDir, "profiles");
25177
25609
  for (const [profileName, config] of Object.entries(data.profiles)) {
25178
25610
  if (!config || typeof config !== "object")
25179
25611
  continue;
25180
- mkdirSync11(profilesDir, { recursive: true });
25181
- const profileFile = join17(profilesDir, `${profileName}.json`);
25182
- writeFileSync7(profileFile, JSON.stringify(config, null, 2));
25612
+ mkdirSync12(profilesDir, { recursive: true });
25613
+ const profileFile = join18(profilesDir, `${profileName}.json`);
25614
+ writeFileSync8(profileFile, JSON.stringify(config, null, 2));
25183
25615
  imported++;
25184
25616
  }
25185
25617
  }
@@ -25234,12 +25666,12 @@ ${result.stderr}`;
25234
25666
  }
25235
25667
  if (dashboardExists && (method === "GET" || method === "HEAD")) {
25236
25668
  if (path !== "/") {
25237
- const filePath = join17(dashboardDir, path);
25669
+ const filePath = join18(dashboardDir, path);
25238
25670
  const res2 = serveStaticFile(filePath);
25239
25671
  if (res2)
25240
25672
  return res2;
25241
25673
  }
25242
- const indexPath = join17(dashboardDir, "index.html");
25674
+ const indexPath = join18(dashboardDir, "index.html");
25243
25675
  const res = serveStaticFile(indexPath);
25244
25676
  if (res)
25245
25677
  return res;