@ha-bits/cortex-core 0.1.0-next.69 → 1.1.16

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/index.js CHANGED
@@ -7,27 +7,13 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
7
7
 
8
8
  // packages/cortex/core/src/WorkflowExecutor.ts
9
9
  import { v4 as uuidv4 } from "uuid";
10
- import { Cron } from "croner";
11
10
 
12
11
  // packages/bindings/src/runtime.ts
13
12
  function isTauri() {
14
- const g = globalThis;
15
- return !!(g.__TAURI__ || g.__TAURI_INTERNALS__);
16
- }
17
- function getTauri() {
18
- if (!isTauri()) return null;
19
- return globalThis.__TAURI__;
20
- }
21
- function getTauriPlugin(pluginName) {
22
- const tauri = getTauri();
23
- if (!tauri) {
24
- throw new Error(`Tauri is not available. Make sure withGlobalTauri is enabled in tauri.conf.json.`);
25
- }
26
- const plugin = tauri[pluginName];
27
- if (!plugin) {
28
- throw new Error(`Tauri plugin '${pluginName}' is not available. Make sure the plugin is installed and enabled.`);
13
+ if (typeof window === "undefined") {
14
+ return false;
29
15
  }
30
- return plugin;
16
+ return !!(window.__TAURI__ || window.__TAURI_INTERNALS__);
31
17
  }
32
18
  function isNode() {
33
19
  return typeof process !== "undefined" && process.versions != null && process.versions.node != null;
@@ -231,12 +217,16 @@ function dirname(p) {
231
217
  // packages/bindings/src/shell.ts
232
218
  var nodeChildProcess = null;
233
219
  var nodeUtil = null;
220
+ var tauriShell = null;
234
221
  if (isNode()) {
235
222
  nodeChildProcess = __require("child_process");
236
223
  nodeUtil = __require("util");
237
224
  }
238
- function getTauriShell() {
239
- return getTauriPlugin("shell");
225
+ async function getTauriShell() {
226
+ if (!tauriShell) {
227
+ tauriShell = await import("@tauri-apps/plugin-shell");
228
+ }
229
+ return tauriShell;
240
230
  }
241
231
  function filterEnv(env) {
242
232
  if (!env) return void 0;
@@ -250,7 +240,7 @@ function filterEnv(env) {
250
240
  }
251
241
  async function exec(command, options = {}) {
252
242
  if (isTauri()) {
253
- const shell = getTauriShell();
243
+ const shell = await getTauriShell();
254
244
  const shellProgram = process.platform === "win32" ? "cmd" : "sh";
255
245
  const shellArgs = process.platform === "win32" ? ["/c", command] : ["-c", command];
256
246
  const cmd = shell.Command.create(shellProgram, shellArgs, {
@@ -291,6 +281,11 @@ async function exec(command, options = {}) {
291
281
  throw new Error("exec is not supported in this environment");
292
282
  }
293
283
 
284
+ // packages/core/src/types.ts
285
+ function isFrontendWorkflow(workflow) {
286
+ return "nodes" in workflow && "edges" in workflow && Array.isArray(workflow.nodes) && Array.isArray(workflow.edges);
287
+ }
288
+
294
289
  // packages/core/src/logger/types.ts
295
290
  var LOG_LEVEL_PRIORITY = {
296
291
  trace: 0,
@@ -608,9 +603,9 @@ var ConfigResolver = class {
608
603
  }
609
604
  const formatEnv = env[LOG_ENV_VARS.FORMAT];
610
605
  if (formatEnv && ["text", "json"].includes(formatEnv.toLowerCase())) {
611
- const format2 = formatEnv.toLowerCase();
606
+ const format = formatEnv.toLowerCase();
612
607
  result.outputs = result.outputs.map(
613
- (o) => o.type === "console" || o.type === "file" ? { ...o, format: format2 } : o
608
+ (o) => o.type === "console" || o.type === "file" ? { ...o, format } : o
614
609
  );
615
610
  }
616
611
  for (const [key, value] of Object.entries(env)) {
@@ -1172,8 +1167,8 @@ var LoggerFactory = class {
1172
1167
  /**
1173
1168
  * Create a formatter based on format type
1174
1169
  */
1175
- static createFormatter(format2) {
1176
- return format2 === "json" ? new JsonFormatter() : new TextFormatter();
1170
+ static createFormatter(format) {
1171
+ return format === "json" ? new JsonFormatter() : new TextFormatter();
1177
1172
  }
1178
1173
  };
1179
1174
 
@@ -2201,17 +2196,6 @@ function getModuleMainFile(moduleDefinition) {
2201
2196
 
2202
2197
  // packages/cortex/core/src/utils/moduleLoader.ts
2203
2198
  var logger2 = LoggerFactory.getRoot();
2204
- var bundledModulesRegistry = /* @__PURE__ */ new Map();
2205
- function registerBundledModule(moduleName, moduleExports) {
2206
- bundledModulesRegistry.set(moduleName, moduleExports);
2207
- console.log(`\u{1F4E6} Registered bundled module: ${moduleName}`);
2208
- }
2209
- function getBundledModule(moduleName) {
2210
- return bundledModulesRegistry.get(moduleName);
2211
- }
2212
- function isBundledModule(moduleName) {
2213
- return bundledModulesRegistry.has(moduleName);
2214
- }
2215
2199
  function getModuleName(moduleDefinition) {
2216
2200
  if (moduleDefinition.source === "github") {
2217
2201
  const url = moduleDefinition.repository;
@@ -2230,20 +2214,6 @@ function getModuleName(moduleDefinition) {
2230
2214
  var MODULES_CONFIG_PATH = join(process.cwd(), "modules.json");
2231
2215
  async function ensureModuleInstalled(moduleDefinition) {
2232
2216
  const moduleName = getModuleName(moduleDefinition);
2233
- if (isBundledModule(moduleDefinition.repository)) {
2234
- console.log(`\u2713 Module ${moduleName} is pre-bundled, skipping installation
2235
- `);
2236
- return moduleDefinition.repository;
2237
- }
2238
- if (typeof __require !== "undefined") {
2239
- try {
2240
- __require(moduleDefinition.repository);
2241
- console.log(`\u2713 Module ${moduleName} already available via require
2242
- `);
2243
- return moduleDefinition.repository;
2244
- } catch {
2245
- }
2246
- }
2247
2217
  console.log(`
2248
2218
  \u{1F50D} ensureModuleInstalled called:`);
2249
2219
  console.log(` Module name: ${moduleName}`);
@@ -2265,157 +2235,75 @@ async function ensureModuleInstalled(moduleDefinition) {
2265
2235
  // packages/cortex/core/src/n8n/executionContext.ts
2266
2236
  import * as path3 from "path";
2267
2237
 
2268
- // packages/bindings/src/fetch.ts
2269
- function getTauriHttp() {
2270
- return getTauriPlugin("http");
2271
- }
2272
- function headersToObject(headers) {
2273
- if (!headers) return void 0;
2274
- if (headers instanceof Headers) {
2275
- const obj = {};
2276
- headers.forEach((value, key) => {
2277
- obj[key] = value;
2278
- });
2279
- return obj;
2280
- }
2281
- if (Array.isArray(headers)) {
2282
- const obj = {};
2283
- for (const [key, value] of headers) {
2284
- obj[key] = value;
2285
- }
2286
- return obj;
2287
- }
2288
- return headers;
2289
- }
2290
- function wrapTauriResponse(response) {
2291
- return {
2292
- ok: response.ok,
2293
- status: response.status,
2294
- statusText: response.statusText || "",
2295
- headers: response.headers,
2296
- url: response.url,
2297
- redirected: response.redirected || false,
2298
- text: () => response.text(),
2299
- json: () => response.json(),
2300
- arrayBuffer: () => response.arrayBuffer(),
2301
- blob: () => response.blob()
2302
- };
2303
- }
2304
- function wrapNativeResponse(response) {
2305
- return {
2306
- ok: response.ok,
2307
- status: response.status,
2308
- statusText: response.statusText,
2309
- headers: response.headers,
2310
- url: response.url,
2311
- redirected: response.redirected,
2312
- text: () => response.text(),
2313
- json: () => response.json(),
2314
- arrayBuffer: () => response.arrayBuffer(),
2315
- blob: () => response.blob()
2238
+ // packages/cortex/core/src/n8n/httpRequest.ts
2239
+ import axios from "axios";
2240
+ import FormData from "form-data";
2241
+ var logger3 = LoggerFactory.getRoot();
2242
+ function convertN8nRequestToAxios(requestOptions) {
2243
+ const { headers, method, timeout, auth, url, body, qs } = requestOptions;
2244
+ const axiosConfig = {
2245
+ headers: headers ?? {},
2246
+ method: method || "GET",
2247
+ timeout: timeout || 3e5,
2248
+ url,
2249
+ maxBodyLength: Infinity,
2250
+ maxContentLength: Infinity
2316
2251
  };
2317
- }
2318
- async function fetch2(url, options = {}) {
2319
- if (isTauri()) {
2320
- return fetchTauri(url, options);
2321
- }
2322
- return fetchNative(url, options);
2323
- }
2324
- async function fetchNative(url, options = {}) {
2325
- const { timeout, maxRedirections, body, ...nativeOptions } = options;
2326
- let processedBody = void 0;
2327
- if (body !== null && body !== void 0) {
2328
- if (typeof body === "object" && !(body instanceof ArrayBuffer) && !(body instanceof Blob) && !(body instanceof FormData) && !(body instanceof URLSearchParams) && !(body instanceof ReadableStream) && !ArrayBuffer.isView(body)) {
2329
- processedBody = JSON.stringify(body);
2330
- } else {
2331
- processedBody = body;
2332
- }
2252
+ if (qs) {
2253
+ axiosConfig.params = qs;
2333
2254
  }
2334
- let controller;
2335
- let timeoutId;
2336
- if (timeout) {
2337
- controller = new AbortController();
2338
- timeoutId = setTimeout(() => controller.abort(), timeout);
2255
+ if (auth) {
2256
+ axiosConfig.auth = {
2257
+ username: auth.username || "",
2258
+ password: auth.password || ""
2259
+ };
2339
2260
  }
2340
- try {
2341
- const response = await globalThis.fetch(url, {
2342
- ...nativeOptions,
2343
- body: processedBody,
2344
- signal: controller?.signal ?? options.signal
2345
- });
2346
- return wrapNativeResponse(response);
2347
- } finally {
2348
- if (timeoutId) {
2349
- clearTimeout(timeoutId);
2350
- }
2261
+ if (requestOptions.baseURL) {
2262
+ axiosConfig.baseURL = requestOptions.baseURL;
2351
2263
  }
2352
- }
2353
- async function fetchTauri(url, options = {}) {
2354
- const http = getTauriHttp();
2355
- const { timeout, maxRedirections, body, headers, ...restOptions } = options;
2356
- let processedBody = void 0;
2357
- if (body !== null && body !== void 0) {
2358
- if (typeof body === "object" && !(body instanceof ArrayBuffer) && !(body instanceof Blob) && !(body instanceof FormData) && !(body instanceof URLSearchParams) && !(body instanceof ReadableStream) && !ArrayBuffer.isView(body)) {
2359
- processedBody = JSON.stringify(body);
2360
- } else {
2361
- processedBody = body;
2362
- }
2264
+ if (requestOptions.disableFollowRedirect) {
2265
+ axiosConfig.maxRedirects = 0;
2363
2266
  }
2364
- const tauriOptions = {
2365
- ...restOptions,
2366
- body: processedBody,
2367
- headers: headersToObject(headers)
2368
- };
2369
- if (timeout !== void 0) {
2370
- tauriOptions.timeout = timeout;
2267
+ if (requestOptions.encoding) {
2268
+ axiosConfig.responseType = requestOptions.encoding;
2371
2269
  }
2372
- if (maxRedirections !== void 0) {
2373
- tauriOptions.maxRedirections = maxRedirections;
2270
+ if (requestOptions.skipSslCertificateValidation) {
2374
2271
  }
2375
- const response = await http.fetch(url.toString(), tauriOptions);
2376
- return wrapTauriResponse(response);
2377
- }
2378
-
2379
- // packages/cortex/core/src/n8n/httpRequest.ts
2380
- import FormData2 from "form-data";
2381
- var logger3 = LoggerFactory.getRoot();
2382
- function buildUrl(url, baseURL, qs) {
2383
- let fullUrl = url;
2384
- if (baseURL && !url.startsWith("http://") && !url.startsWith("https://")) {
2385
- fullUrl = baseURL.replace(/\/$/, "") + "/" + url.replace(/^\//, "");
2386
- }
2387
- if (qs && Object.keys(qs).length > 0) {
2388
- const params = new URLSearchParams();
2389
- for (const [key, value] of Object.entries(qs)) {
2390
- if (value !== void 0 && value !== null) {
2391
- params.append(key, String(value));
2392
- }
2272
+ if (body) {
2273
+ if (body instanceof FormData) {
2274
+ axiosConfig.data = body;
2275
+ axiosConfig.headers = {
2276
+ ...axiosConfig.headers,
2277
+ ...body.getHeaders()
2278
+ };
2279
+ } else if (body instanceof URLSearchParams) {
2280
+ axiosConfig.headers = {
2281
+ ...axiosConfig.headers,
2282
+ "Content-Type": "application/x-www-form-urlencoded"
2283
+ };
2284
+ axiosConfig.data = body;
2285
+ } else if (typeof body === "object" && Object.keys(body).length > 0) {
2286
+ axiosConfig.data = body;
2287
+ } else if (typeof body === "string") {
2288
+ axiosConfig.data = body;
2393
2289
  }
2394
- fullUrl += (fullUrl.includes("?") ? "&" : "?") + params.toString();
2395
2290
  }
2396
- return fullUrl;
2397
- }
2398
- function prepareBody(body, headers) {
2399
- if (!body) return void 0;
2400
- if (body instanceof FormData2) {
2401
- const formHeaders = body.getHeaders();
2402
- Object.assign(headers, formHeaders);
2403
- return body;
2404
- }
2405
- if (body instanceof URLSearchParams) {
2406
- headers["Content-Type"] = "application/x-www-form-urlencoded";
2407
- return body.toString();
2291
+ if (requestOptions.json) {
2292
+ axiosConfig.headers = {
2293
+ ...axiosConfig.headers,
2294
+ Accept: "application/json"
2295
+ };
2408
2296
  }
2409
- if (typeof body === "object" && Object.keys(body).length > 0) {
2410
- if (!headers["Content-Type"]) {
2411
- headers["Content-Type"] = "application/json";
2412
- }
2413
- return JSON.stringify(body);
2297
+ if (!axiosConfig.headers?.["User-Agent"]) {
2298
+ axiosConfig.headers = {
2299
+ ...axiosConfig.headers,
2300
+ "User-Agent": "n8n-habits-executor"
2301
+ };
2414
2302
  }
2415
- if (typeof body === "string") {
2416
- return body;
2303
+ if (requestOptions.ignoreHttpStatusErrors) {
2304
+ axiosConfig.validateStatus = () => true;
2417
2305
  }
2418
- return void 0;
2306
+ return axiosConfig;
2419
2307
  }
2420
2308
  async function httpRequest(requestOptions) {
2421
2309
  const noBodyMethods = ["GET", "HEAD", "OPTIONS"];
@@ -2423,69 +2311,27 @@ async function httpRequest(requestOptions) {
2423
2311
  if (noBodyMethods.includes(method) && requestOptions.body && Object.keys(requestOptions.body).length === 0) {
2424
2312
  delete requestOptions.body;
2425
2313
  }
2426
- const headers = {
2427
- ...requestOptions.headers ?? {}
2428
- };
2429
- if (requestOptions.auth) {
2430
- const credentials = Buffer.from(
2431
- `${requestOptions.auth.username || ""}:${requestOptions.auth.password || ""}`
2432
- ).toString("base64");
2433
- headers["Authorization"] = `Basic ${credentials}`;
2434
- }
2435
- if (requestOptions.json) {
2436
- headers["Accept"] = "application/json";
2437
- }
2438
- if (!headers["User-Agent"]) {
2439
- headers["User-Agent"] = "n8n-habits-executor";
2314
+ const axiosConfig = convertN8nRequestToAxios(requestOptions);
2315
+ if (axiosConfig.data === void 0 || axiosConfig.method?.toUpperCase() === "GET") {
2316
+ delete axiosConfig.data;
2440
2317
  }
2441
- const url = buildUrl(requestOptions.url, requestOptions.baseURL, requestOptions.qs);
2442
- let body;
2443
- if (!noBodyMethods.includes(method)) {
2444
- body = prepareBody(requestOptions.body, headers);
2445
- }
2446
- logger3.log(`\u{1F310} Making HTTP request: ${method} ${url}`);
2318
+ logger3.log(`\u{1F310} Making HTTP request: ${axiosConfig.method} ${axiosConfig.url}`);
2447
2319
  try {
2448
- const response = await fetch2(url, {
2449
- method,
2450
- headers,
2451
- body,
2452
- redirect: requestOptions.disableFollowRedirect ? "manual" : "follow"
2453
- });
2454
- let responseData;
2455
- const contentType = response.headers.get("content-type") || "";
2456
- if (requestOptions.encoding === "arraybuffer" || contentType.includes("application/octet-stream")) {
2457
- responseData = await response.arrayBuffer();
2458
- } else if (contentType.includes("application/json")) {
2459
- responseData = await response.json();
2460
- } else {
2461
- responseData = await response.text();
2462
- try {
2463
- responseData = JSON.parse(responseData);
2464
- } catch {
2465
- }
2466
- }
2467
- if (!response.ok && !requestOptions.ignoreHttpStatusErrors) {
2468
- logger3.error(`HTTP Error (${response.status}): ${JSON.stringify(responseData)}`);
2469
- throw new Error(`HTTP Error (${response.status}): ${JSON.stringify(responseData)}`);
2470
- }
2320
+ const response = await axios(axiosConfig);
2471
2321
  if (requestOptions.returnFullResponse) {
2472
- const responseHeaders = {};
2473
- response.headers.forEach((value, key) => {
2474
- responseHeaders[key] = value;
2475
- });
2476
2322
  return {
2477
- body: responseData,
2478
- headers: responseHeaders,
2323
+ body: response.data,
2324
+ headers: response.headers,
2479
2325
  statusCode: response.status,
2480
2326
  statusMessage: response.statusText
2481
2327
  };
2482
2328
  }
2483
- return responseData;
2329
+ return response.data;
2484
2330
  } catch (error) {
2485
- if (error.message?.startsWith("HTTP Error")) {
2486
- throw error;
2331
+ if (error.response) {
2332
+ logger3.error(`HTTP Error (${error.response.status}): ${JSON.stringify(error.response.data)}`);
2333
+ throw new Error(`HTTP Error (${error.response.status}): ${JSON.stringify(error.response.data)}`);
2487
2334
  }
2488
- logger3.error(`Request failed: ${error.message}`);
2489
2335
  throw error;
2490
2336
  }
2491
2337
  }
@@ -2701,7 +2547,7 @@ function createExecutionContext(node, params, options) {
2701
2547
  },
2702
2548
  // Helpers object with HTTP request and other utilities
2703
2549
  helpers: {
2704
- // HTTP request function
2550
+ // HTTP request function (real implementation)
2705
2551
  httpRequest: async (opts) => {
2706
2552
  return await httpRequest(opts);
2707
2553
  },
@@ -2886,6 +2732,7 @@ function createExecutionContext(node, params, options) {
2886
2732
 
2887
2733
  // packages/cortex/core/src/n8n/nodeExecution.ts
2888
2734
  import * as path4 from "path";
2735
+ import axios2 from "axios";
2889
2736
  var logger6 = LoggerFactory.getRoot();
2890
2737
  async function loadNodeFromModule(moduleDefinition, mainFilePath) {
2891
2738
  const moduleName = getModuleName(moduleDefinition);
@@ -3093,33 +2940,23 @@ async function executeRoutingBasedNode(node, params, context) {
3093
2940
  }
3094
2941
  logger6.log(`\u{1F310} Making routing-based request: ${method} ${url}`);
3095
2942
  logger6.log(`\u{1F4E4} Request body:`, { body });
3096
- let fullUrl = url;
3097
- if (Object.keys(queryParams).length > 0) {
3098
- const params2 = new URLSearchParams();
3099
- for (const [key, value] of Object.entries(queryParams)) {
3100
- if (value !== void 0 && value !== null) {
3101
- params2.append(key, String(value));
3102
- }
3103
- }
3104
- fullUrl += (fullUrl.includes("?") ? "&" : "?") + params2.toString();
3105
- }
3106
- const requestBody = Object.keys(body).length > 0 ? JSON.stringify(body) : void 0;
3107
- if (requestBody && !headers["Content-Type"]) {
3108
- headers["Content-Type"] = "application/json";
2943
+ const axiosConfig = {
2944
+ method,
2945
+ url,
2946
+ headers,
2947
+ params: Object.keys(queryParams).length > 0 ? queryParams : void 0,
2948
+ data: Object.keys(body).length > 0 ? body : void 0
2949
+ };
2950
+ if (requestConfig.encoding === "arraybuffer") {
2951
+ axiosConfig.responseType = "arraybuffer";
3109
2952
  }
3110
2953
  try {
3111
- const response = await fetch2(fullUrl, {
3112
- method,
3113
- headers,
3114
- body: requestBody
3115
- });
2954
+ const response = await axios2(axiosConfig);
3116
2955
  logger6.log(`\u2705 Routing-based request successful: ${response.status}`);
3117
- const contentType = response.headers.get("content-type") || "";
3118
- if (requestConfig.encoding === "arraybuffer" || contentType.includes("audio")) {
3119
- const arrayBuffer = await response.arrayBuffer();
3120
- const binaryData = Buffer.from(arrayBuffer);
2956
+ if (requestConfig.encoding === "arraybuffer" || response.headers["content-type"]?.includes("audio")) {
2957
+ const binaryData = Buffer.from(response.data);
3121
2958
  const base64Data = binaryData.toString("base64");
3122
- const mimeType = contentType || "audio/mpeg";
2959
+ const mimeType = response.headers["content-type"] || "audio/mpeg";
3123
2960
  return [[{
3124
2961
  json: {
3125
2962
  success: true,
@@ -3136,28 +2973,14 @@ async function executeRoutingBasedNode(node, params, context) {
3136
2973
  }
3137
2974
  }]];
3138
2975
  }
3139
- let responseData;
3140
- if (contentType.includes("application/json")) {
3141
- responseData = await response.json();
3142
- } else {
3143
- const text = await response.text();
3144
- try {
3145
- responseData = JSON.parse(text);
3146
- } catch {
3147
- responseData = text;
3148
- }
3149
- }
3150
- if (!response.ok) {
3151
- const errorMessage = typeof responseData === "object" ? JSON.stringify(responseData) : String(responseData);
3152
- logger6.error(`HTTP Error (${response.status}): ${errorMessage}`);
3153
- throw new Error(`HTTP Error (${response.status}): ${errorMessage}`);
3154
- }
3155
- return [[{ json: responseData }]];
2976
+ return [[{ json: response.data }]];
3156
2977
  } catch (error) {
3157
- if (error.message?.startsWith("HTTP Error")) {
3158
- throw error;
2978
+ if (error.response) {
2979
+ const errorData = error.response.data;
2980
+ const errorMessage = Buffer.isBuffer(errorData) ? errorData.toString("utf-8") : JSON.stringify(errorData);
2981
+ logger6.error(`HTTP Error (${error.response.status}): ${errorMessage}`);
2982
+ throw new Error(`HTTP Error (${error.response.status}): ${errorMessage}`);
3159
2983
  }
3160
- logger6.error(`Request failed: ${error.message}`);
3161
2984
  throw error;
3162
2985
  }
3163
2986
  }
@@ -3437,13 +3260,13 @@ async function ensureActivepiecesModulesLoaded2() {
3437
3260
  trimVersionFromAlias2 = shared.trimVersionFromAlias;
3438
3261
  }
3439
3262
  var logger9 = LoggerFactory.getRoot();
3440
- var TriggerHookType = /* @__PURE__ */ ((TriggerHookType4) => {
3441
- TriggerHookType4["ON_ENABLE"] = "ON_ENABLE";
3442
- TriggerHookType4["ON_DISABLE"] = "ON_DISABLE";
3443
- TriggerHookType4["RUN"] = "RUN";
3444
- TriggerHookType4["TEST"] = "TEST";
3445
- TriggerHookType4["HANDSHAKE"] = "HANDSHAKE";
3446
- return TriggerHookType4;
3263
+ var TriggerHookType = /* @__PURE__ */ ((TriggerHookType3) => {
3264
+ TriggerHookType3["ON_ENABLE"] = "ON_ENABLE";
3265
+ TriggerHookType3["ON_DISABLE"] = "ON_DISABLE";
3266
+ TriggerHookType3["RUN"] = "RUN";
3267
+ TriggerHookType3["TEST"] = "TEST";
3268
+ TriggerHookType3["HANDSHAKE"] = "HANDSHAKE";
3269
+ return TriggerHookType3;
3447
3270
  })(TriggerHookType || {});
3448
3271
  function createSimpleStore(prefix = "") {
3449
3272
  const storage = /* @__PURE__ */ new Map();
@@ -3835,6 +3658,7 @@ var triggerHelper = {
3835
3658
  };
3836
3659
 
3837
3660
  // packages/cortex/core/src/bits/declarativeExecutor.ts
3661
+ import axios3 from "axios";
3838
3662
  function resolveExpression(expression, context) {
3839
3663
  if (expression === null || expression === void 0) {
3840
3664
  return expression;
@@ -4172,73 +3996,30 @@ async function executeDeclarativeNode(node, context) {
4172
3996
  throw new Error("No URL specified in request configuration or defaults");
4173
3997
  }
4174
3998
  try {
4175
- let fullUrl = requestConfig.url || "";
4176
- if (requestConfig.baseURL && !fullUrl.startsWith("http://") && !fullUrl.startsWith("https://")) {
4177
- fullUrl = requestConfig.baseURL.replace(/\/$/, "") + "/" + fullUrl.replace(/^\//, "");
4178
- }
4179
- if (requestConfig.params && Object.keys(requestConfig.params).length > 0) {
4180
- const params = new URLSearchParams();
4181
- for (const [key, value] of Object.entries(requestConfig.params)) {
4182
- if (value !== void 0 && value !== null) {
4183
- params.append(key, String(value));
4184
- }
4185
- }
4186
- fullUrl += (fullUrl.includes("?") ? "&" : "?") + params.toString();
4187
- }
4188
- const headers = { ...requestConfig.headers };
4189
- let body;
4190
- if (requestConfig.data) {
4191
- if (!headers["Content-Type"]) {
4192
- headers["Content-Type"] = "application/json";
4193
- }
4194
- body = typeof requestConfig.data === "string" ? requestConfig.data : JSON.stringify(requestConfig.data);
4195
- }
4196
- const response = await fetch2(fullUrl, {
4197
- method: requestConfig.method || "GET",
4198
- headers,
4199
- body
4200
- });
4201
- let responseData;
4202
- const contentType = response.headers.get("content-type") || "";
4203
- if (contentType.includes("application/json")) {
4204
- responseData = await response.json();
4205
- } else {
4206
- const text = await response.text();
4207
- try {
4208
- responseData = JSON.parse(text);
4209
- } catch {
4210
- responseData = text;
4211
- }
4212
- }
4213
- const responseHeaders = {};
4214
- response.headers.forEach((value, key) => {
4215
- responseHeaders[key] = value;
4216
- });
3999
+ const response = await axios3(requestConfig);
4217
4000
  const operationRouting = findOperationRouting(description.properties, context.parameters);
4218
- if (!response.ok) {
4219
- if (operationRouting?.request?.ignoreHttpStatusErrors) {
4220
- return {
4221
- success: true,
4222
- data: responseData,
4223
- status: response.status,
4224
- headers: responseHeaders
4225
- };
4226
- }
4227
- throw new Error(`HTTP Error (${response.status}): ${JSON.stringify(responseData)}`);
4228
- }
4229
4001
  const expressionContext = {
4230
4002
  $parameter: context.parameters,
4231
4003
  $credentials: context.credentials || {},
4232
- $response: responseData
4004
+ $response: response.data
4233
4005
  };
4234
- const processedData = processResponse(responseData, operationRouting, expressionContext);
4006
+ const processedData = processResponse(response.data, operationRouting, expressionContext);
4235
4007
  return {
4236
4008
  success: true,
4237
4009
  data: processedData,
4238
4010
  status: response.status,
4239
- headers: responseHeaders
4011
+ headers: response.headers
4240
4012
  };
4241
4013
  } catch (error) {
4014
+ const operationRouting = findOperationRouting(description.properties, context.parameters);
4015
+ if (operationRouting?.request?.ignoreHttpStatusErrors && error.response) {
4016
+ return {
4017
+ success: true,
4018
+ data: error.response.data,
4019
+ status: error.response.status,
4020
+ headers: error.response.headers
4021
+ };
4022
+ }
4242
4023
  throw new Error(`Request failed: ${error.message}`);
4243
4024
  }
4244
4025
  }
@@ -4317,374 +4098,12 @@ function extractDeclarativeNode(loadedModule) {
4317
4098
  return null;
4318
4099
  }
4319
4100
 
4320
- // packages/cortex/core/src/store.ts
4321
- var logger10 = LoggerFactory.getRoot();
4322
- var driverModule = null;
4323
- var driverLoadAttempted = false;
4324
- var useInMemoryFallback = false;
4325
- var inMemoryStore = /* @__PURE__ */ new Map();
4326
- var inMemoryDriver = {
4327
- async store(params) {
4328
- const key = `${params.collection}:${params.key}`;
4329
- inMemoryStore.set(key, params.value);
4330
- return { success: true };
4331
- },
4332
- async get(params) {
4333
- const key = `${params.collection}:${params.key}`;
4334
- if (inMemoryStore.has(key)) {
4335
- return { found: true, value: inMemoryStore.get(key) };
4336
- }
4337
- return { found: false, value: null };
4338
- },
4339
- async del(params) {
4340
- const key = `${params.collection}:${params.key}`;
4341
- inMemoryStore.delete(key);
4342
- return { success: true };
4343
- },
4344
- async list(params) {
4345
- const prefix = `${params.collection}:${params.prefix || ""}`;
4346
- const keys = [];
4347
- for (const key of inMemoryStore.keys()) {
4348
- if (key.startsWith(prefix)) {
4349
- keys.push(key.replace(`${params.collection}:`, ""));
4350
- }
4351
- }
4352
- return { keys: keys.slice(0, params.limit || 100) };
4353
- }
4354
- };
4355
- async function getDriver() {
4356
- if (useInMemoryFallback) {
4357
- return inMemoryDriver;
4358
- }
4359
- if (!driverModule && !driverLoadAttempted) {
4360
- driverLoadAttempted = true;
4361
- try {
4362
- const modulePath = "@ha-bits/bit-database-sql/driver";
4363
- driverModule = await import(
4364
- /* webpackIgnore: true */
4365
- modulePath
4366
- );
4367
- logger10.log("\u{1F4BE} Polling store: Loaded database driver");
4368
- } catch (err) {
4369
- logger10.warn(`\u{1F4BE} Polling store: Database driver not available, using in-memory fallback: ${err.message}`);
4370
- useInMemoryFallback = true;
4371
- return inMemoryDriver;
4372
- }
4373
- }
4374
- return driverModule || inMemoryDriver;
4375
- }
4376
- var PollingStore = class {
4377
- constructor(options = {}) {
4378
- this.options = {
4379
- database: options.database ?? "habits-polling.db",
4380
- collection: options.collection ?? "polling",
4381
- dedupStrategy: options.dedupStrategy ?? "id",
4382
- ttlDays: options.ttlDays ?? 30
4383
- };
4384
- }
4385
- /**
4386
- * Generate a unique key for a seen item
4387
- */
4388
- getItemKey(ctx, itemId) {
4389
- return `${ctx.workflowId}:${ctx.triggerId}:${itemId}`;
4390
- }
4391
- /**
4392
- * Generate the key for storing last polled date
4393
- */
4394
- getLastPolledKey(ctx) {
4395
- return `${ctx.workflowId}:${ctx.triggerId}:__lastPolled__`;
4396
- }
4397
- /**
4398
- * Check if an item has been seen before
4399
- */
4400
- async hasSeenItem(ctx, itemId, itemDate) {
4401
- const driver = await getDriver();
4402
- const key = this.getItemKey(ctx, itemId);
4403
- const result = await driver.get({
4404
- collection: this.options.collection,
4405
- key,
4406
- database: this.options.database
4407
- });
4408
- if (!result.found) {
4409
- return false;
4410
- }
4411
- if (this.options.dedupStrategy === "date" && itemDate) {
4412
- const record = result.value;
4413
- return new Date(record.sourceDate) >= new Date(itemDate);
4414
- }
4415
- return true;
4416
- }
4417
- /**
4418
- * Mark an item as seen
4419
- */
4420
- async markItemSeen(ctx, itemId, sourceDate, data) {
4421
- const driver = await getDriver();
4422
- const key = this.getItemKey(ctx, itemId);
4423
- const record = {
4424
- id: itemId,
4425
- sourceDate,
4426
- seenAt: (/* @__PURE__ */ new Date()).toISOString(),
4427
- data
4428
- };
4429
- await driver.store({
4430
- collection: this.options.collection,
4431
- key,
4432
- value: record,
4433
- database: this.options.database
4434
- });
4435
- logger10.log(`\u{1F4BE} Polling store: Marked item as seen: ${itemId}`);
4436
- }
4437
- /**
4438
- * Get multiple items' seen status in batch
4439
- * Returns a Set of item IDs that have been seen
4440
- */
4441
- async getSeenItems(ctx, itemIds) {
4442
- const seen = /* @__PURE__ */ new Set();
4443
- for (const itemId of itemIds) {
4444
- if (await this.hasSeenItem(ctx, itemId)) {
4445
- seen.add(itemId);
4446
- }
4447
- }
4448
- return seen;
4449
- }
4450
- /**
4451
- * Mark multiple items as seen in batch
4452
- */
4453
- async markItemsSeen(ctx, items) {
4454
- for (const item of items) {
4455
- await this.markItemSeen(ctx, item.id, item.date, item.data);
4456
- }
4457
- }
4458
- /**
4459
- * Get the last polled timestamp for a trigger
4460
- * Returns null if never polled before
4461
- */
4462
- async getLastPolledDate(ctx) {
4463
- const driver = await getDriver();
4464
- const key = this.getLastPolledKey(ctx);
4465
- const result = await driver.get({
4466
- collection: this.options.collection,
4467
- key,
4468
- database: this.options.database
4469
- });
4470
- if (!result.found) {
4471
- return null;
4472
- }
4473
- return result.value;
4474
- }
4475
- /**
4476
- * Set the last polled timestamp for a trigger
4477
- */
4478
- async setLastPolledDate(ctx, date) {
4479
- const driver = await getDriver();
4480
- const key = this.getLastPolledKey(ctx);
4481
- await driver.store({
4482
- collection: this.options.collection,
4483
- key,
4484
- value: date,
4485
- database: this.options.database
4486
- });
4487
- logger10.log(`\u{1F4BE} Polling store: Updated last polled date: ${date}`);
4488
- }
4489
- /**
4490
- * Get the count of seen items for a trigger
4491
- */
4492
- async getSeenCount(ctx) {
4493
- const driver = await getDriver();
4494
- const prefix = `${ctx.workflowId}:${ctx.triggerId}:`;
4495
- const result = await driver.list({
4496
- collection: this.options.collection,
4497
- prefix,
4498
- limit: 1e4,
4499
- // High limit to count all
4500
- database: this.options.database
4501
- });
4502
- const count = result.keys.filter((k) => !k.endsWith("__lastPolled__")).length;
4503
- return count;
4504
- }
4505
- /**
4506
- * Clear all seen items for a trigger (useful for testing or reset)
4507
- */
4508
- async clearTrigger(ctx) {
4509
- const driver = await getDriver();
4510
- const prefix = `${ctx.workflowId}:${ctx.triggerId}:`;
4511
- const result = await driver.list({
4512
- collection: this.options.collection,
4513
- prefix,
4514
- limit: 1e4,
4515
- database: this.options.database
4516
- });
4517
- let deleted = 0;
4518
- for (const key of result.keys) {
4519
- await driver.del({
4520
- collection: this.options.collection,
4521
- key,
4522
- database: this.options.database
4523
- });
4524
- deleted++;
4525
- }
4526
- logger10.log(`\u{1F4BE} Polling store: Cleared ${deleted} items for trigger ${ctx.triggerId}`);
4527
- return deleted;
4528
- }
4529
- /**
4530
- * TODO: Implement TTL-based cleanup
4531
- * Clean up old records based on ttlDays configuration
4532
- */
4533
- async cleanup() {
4534
- logger10.log(`\u{1F4BE} Polling store: Cleanup not yet implemented (TTL: ${this.options.ttlDays} days)`);
4535
- return 0;
4536
- }
4537
- };
4538
- function createPollingStore(options) {
4539
- return new PollingStore(options);
4540
- }
4541
-
4542
- // packages/cortex/core/src/bits/oauthTokenStore.ts
4543
- var OAuth2TokenStore = class {
4544
- constructor() {
4545
- this.tokens = /* @__PURE__ */ new Map();
4546
- this.logger = LoggerFactory.create(void 0, void 0, { bitName: "OAuth2TokenStore" });
4547
- }
4548
- /**
4549
- * Store tokens for a bit
4550
- * @param bitId - Unique identifier for the bit (e.g., "bit-oauth-mock")
4551
- * @param tokens - Token set from OAuth provider
4552
- * @param config - OAuth config used (for refresh)
4553
- */
4554
- setToken(bitId, tokens, config) {
4555
- this.tokens.set(bitId, {
4556
- tokens,
4557
- config,
4558
- storedAt: Date.now()
4559
- });
4560
- this.logger.info("Token stored", { bitId, expiresAt: tokens.expiresAt });
4561
- }
4562
- /**
4563
- * Get tokens for a bit
4564
- * @param bitId - Unique identifier for the bit
4565
- * @returns Token set or null if not found
4566
- */
4567
- getToken(bitId) {
4568
- const entry = this.tokens.get(bitId);
4569
- if (!entry) {
4570
- return null;
4571
- }
4572
- return entry.tokens;
4573
- }
4574
- /**
4575
- * Get full token entry including config
4576
- * @param bitId - Unique identifier for the bit
4577
- */
4578
- getEntry(bitId) {
4579
- return this.tokens.get(bitId) || null;
4580
- }
4581
- /**
4582
- * Check if a valid (non-expired) token exists for a bit
4583
- * @param bitId - Unique identifier for the bit
4584
- * @returns true if valid token exists
4585
- */
4586
- hasValidToken(bitId) {
4587
- const entry = this.tokens.get(bitId);
4588
- if (!entry) {
4589
- return false;
4590
- }
4591
- return !this.isExpired(bitId);
4592
- }
4593
- /**
4594
- * Check if token is expired
4595
- * @param bitId - Unique identifier for the bit
4596
- * @returns true if token is expired or doesn't exist
4597
- */
4598
- isExpired(bitId) {
4599
- const entry = this.tokens.get(bitId);
4600
- if (!entry) {
4601
- return true;
4602
- }
4603
- if (!entry.tokens.expiresAt) {
4604
- return false;
4605
- }
4606
- return Date.now() > entry.tokens.expiresAt - 6e4;
4607
- }
4608
- /**
4609
- * Remove token for a bit
4610
- * @param bitId - Unique identifier for the bit
4611
- */
4612
- removeToken(bitId) {
4613
- this.tokens.delete(bitId);
4614
- this.logger.info("Token removed", { bitId });
4615
- }
4616
- /**
4617
- * Get all stored bit IDs
4618
- */
4619
- getAllBitIds() {
4620
- return Array.from(this.tokens.keys());
4621
- }
4622
- /**
4623
- * Clear all tokens
4624
- */
4625
- clear() {
4626
- this.tokens.clear();
4627
- this.logger.info("All tokens cleared");
4628
- }
4629
- /**
4630
- * Refresh an expired token using the refresh token
4631
- * @param bitId - Unique identifier for the bit
4632
- * @returns New token set or null if refresh failed
4633
- */
4634
- async refreshToken(bitId) {
4635
- const entry = this.tokens.get(bitId);
4636
- if (!entry || !entry.tokens.refreshToken) {
4637
- this.logger.warn("Cannot refresh token: no refresh token available", { bitId });
4638
- return null;
4639
- }
4640
- const { config, tokens } = entry;
4641
- try {
4642
- const params = new URLSearchParams({
4643
- grant_type: "refresh_token",
4644
- refresh_token: tokens.refreshToken,
4645
- client_id: config.clientId
4646
- });
4647
- if (config.clientSecret) {
4648
- params.set("client_secret", config.clientSecret);
4649
- }
4650
- const response = await fetch(config.tokenUrl, {
4651
- method: "POST",
4652
- headers: {
4653
- "Content-Type": "application/x-www-form-urlencoded"
4654
- },
4655
- body: params.toString()
4656
- });
4657
- if (!response.ok) {
4658
- const errorText = await response.text();
4659
- this.logger.error("Token refresh failed", { bitId, status: response.status, error: errorText });
4660
- return null;
4661
- }
4662
- const data = await response.json();
4663
- const newTokens = {
4664
- accessToken: data.access_token,
4665
- refreshToken: data.refresh_token || tokens.refreshToken,
4666
- // Keep old refresh token if not returned
4667
- tokenType: data.token_type || "Bearer",
4668
- expiresAt: data.expires_in ? Date.now() + data.expires_in * 1e3 : void 0,
4669
- scope: data.scope
4670
- };
4671
- this.setToken(bitId, newTokens, config);
4672
- this.logger.info("Token refreshed successfully", { bitId });
4673
- return newTokens;
4674
- } catch (error) {
4675
- this.logger.error("Token refresh error", { bitId, error: String(error) });
4676
- return null;
4677
- }
4678
- }
4679
- };
4680
- var oauthTokenStore = new OAuth2TokenStore();
4681
-
4682
4101
  // packages/cortex/core/src/bits/bitsDoer.ts
4683
- var logger11 = LoggerFactory.getRoot();
4102
+ var logger10 = LoggerFactory.getRoot();
4684
4103
  function extractBitsPieceFromModule(loadedModule) {
4685
4104
  const declarativeNode = extractDeclarativeNode(loadedModule);
4686
4105
  if (declarativeNode) {
4687
- logger11.log(`\u{1F4CB} Detected declarative node: ${declarativeNode.description.displayName}`);
4106
+ logger10.log(`\u{1F4CB} Detected declarative node: ${declarativeNode.description.displayName}`);
4688
4107
  return convertDeclarativeNodeToBitsPiece(declarativeNode);
4689
4108
  }
4690
4109
  let piece = null;
@@ -4705,8 +4124,6 @@ function extractBitsPieceFromModule(loadedModule) {
4705
4124
  throw new Error("No valid bits piece found in module. Expected export with actions and triggers.");
4706
4125
  }
4707
4126
  return {
4708
- id: piece.id,
4709
- // Webhook routing ID (e.g., 'gohighlevel', 'hubspot')
4710
4127
  displayName: piece.displayName || "Unknown Piece",
4711
4128
  description: piece.description,
4712
4129
  logoUrl: piece.logoUrl,
@@ -4824,20 +4241,11 @@ function createDeclarativeActionRunner(node, operation) {
4824
4241
  }
4825
4242
  async function pieceFromModule2(moduleDefinition) {
4826
4243
  const moduleName = getModuleName(moduleDefinition);
4827
- if (isBundledModule(moduleDefinition.repository)) {
4828
- logger11.log(`\u{1F4E6} Using pre-bundled module: ${moduleName}`);
4829
- const loadedModule = getBundledModule(moduleDefinition.repository);
4830
- if (loadedModule) {
4831
- const piece = extractBitsPieceFromModule(loadedModule);
4832
- return piece;
4833
- }
4834
- throw new Error(`Bundled module ${moduleName} not found in registry`);
4835
- }
4836
4244
  const mainFilePath = getModuleMainFile(moduleDefinition);
4837
4245
  if (!mainFilePath) {
4838
4246
  throw new Error(`Could not locate main file for module: ${moduleName}`);
4839
4247
  }
4840
- logger11.log(`\u{1F4E6} Bits module ready at: ${mainFilePath}`);
4248
+ logger10.log(`\u{1F4E6} Bits module ready at: ${mainFilePath}`);
4841
4249
  const originalCwd = process.cwd();
4842
4250
  const moduleDir = dirname(mainFilePath);
4843
4251
  let nodeModulesDir = moduleDir;
@@ -4852,18 +4260,18 @@ async function pieceFromModule2(moduleDefinition) {
4852
4260
  return piece;
4853
4261
  } catch (error) {
4854
4262
  process.chdir(originalCwd);
4855
- logger11.error(error.stack);
4263
+ logger10.error(error.stack);
4856
4264
  throw error;
4857
4265
  }
4858
4266
  }
4859
4267
  async function executeGenericBitsPiece(params, moduleDefinition) {
4860
4268
  try {
4861
4269
  const piece = await pieceFromModule2(moduleDefinition);
4862
- logger11.log(`\u{1F680} Executing Bits piece: ${piece.displayName}`);
4270
+ logger10.log(`\u{1F680} Executing Bits piece: ${piece.displayName}`);
4863
4271
  const actionName = params.params.operation;
4864
4272
  const pieceActions = piece.actions();
4865
- logger11.log(`Available actions: ${Object.keys(pieceActions).join(", ")}`);
4866
- logger11.log(`Requested action: ${actionName}`);
4273
+ logger10.log(`Available actions: ${Object.keys(pieceActions).join(", ")}`);
4274
+ logger10.log(`Requested action: ${actionName}`);
4867
4275
  const action = pieceActions[actionName];
4868
4276
  if (!action) {
4869
4277
  throw new Error(
@@ -4872,80 +4280,11 @@ async function executeGenericBitsPiece(params, moduleDefinition) {
4872
4280
  }
4873
4281
  let auth = void 0;
4874
4282
  const { credentials, ...actionProps } = params.params;
4875
- if (piece.auth && (piece.auth.type === "OAUTH2" || piece.auth.type === "OAUTH2_PKCE")) {
4876
- const parts = moduleDefinition.repository.split("/");
4877
- const bitId = parts[parts.length - 1];
4878
- const oauthCredKey = Object.keys(credentials || {}).find((key) => {
4879
- const cred = credentials[key];
4880
- return cred && (cred.accessToken || cred.access_token);
4881
- });
4882
- if (oauthCredKey && credentials[oauthCredKey]) {
4883
- const directTokens = credentials[oauthCredKey];
4884
- auth = {
4885
- accessToken: directTokens.accessToken || directTokens.access_token,
4886
- refreshToken: directTokens.refreshToken || directTokens.refresh_token,
4887
- tokenType: directTokens.tokenType || directTokens.token_type || "Bearer",
4888
- expiresAt: directTokens.expiresAt || directTokens.expires_at
4889
- };
4890
- logger11.log(`\u{1F510} Using OAuth2 tokens from credentials for: ${bitId}`);
4891
- if (auth.refreshToken) {
4892
- const pieceAuth = piece.auth;
4893
- oauthTokenStore.setToken(bitId, auth, {
4894
- displayName: pieceAuth.displayName || bitId,
4895
- required: pieceAuth.required || false,
4896
- authorizationUrl: pieceAuth.authorizationUrl || "",
4897
- tokenUrl: pieceAuth.tokenUrl || "",
4898
- clientId: pieceAuth.clientId || "",
4899
- clientSecret: pieceAuth.clientSecret,
4900
- scopes: pieceAuth.scopes || []
4901
- });
4902
- }
4903
- } else if (params.oauthTokens && params.oauthTokens[bitId]) {
4904
- const userToken = params.oauthTokens[bitId];
4905
- auth = {
4906
- accessToken: userToken.accessToken,
4907
- refreshToken: userToken.refreshToken,
4908
- tokenType: userToken.tokenType,
4909
- expiresAt: userToken.expiresAt
4910
- };
4911
- logger11.log(`\u{1F510} Using per-user OAuth2 token from cookies for: ${bitId}`);
4912
- if (userToken.expiresAt && userToken.expiresAt < Date.now()) {
4913
- logger11.warn(`\u26A0\uFE0F Per-user OAuth token expired for ${bitId}. User needs to re-authenticate.`);
4914
- }
4915
- } else {
4916
- const oauthToken = oauthTokenStore.getToken(bitId);
4917
- if (oauthToken) {
4918
- auth = {
4919
- accessToken: oauthToken.accessToken,
4920
- refreshToken: oauthToken.refreshToken,
4921
- tokenType: oauthToken.tokenType,
4922
- expiresAt: oauthToken.expiresAt
4923
- };
4924
- logger11.log(`\u{1F510} Using OAuth2 PKCE token for: ${bitId}`);
4925
- if (oauthTokenStore.isExpired(bitId)) {
4926
- logger11.log(`\u26A0\uFE0F OAuth token expired for ${bitId}, attempting refresh...`);
4927
- const refreshedToken = await oauthTokenStore.refreshToken(bitId);
4928
- if (refreshedToken) {
4929
- auth = {
4930
- accessToken: refreshedToken.accessToken,
4931
- refreshToken: refreshedToken.refreshToken,
4932
- tokenType: refreshedToken.tokenType,
4933
- expiresAt: refreshedToken.expiresAt
4934
- };
4935
- logger11.log(`\u2705 OAuth token refreshed for ${bitId}`);
4936
- } else {
4937
- logger11.warn(`\u274C Failed to refresh OAuth token for ${bitId}`);
4938
- }
4939
- }
4940
- } else {
4941
- logger11.warn(`\u26A0\uFE0F No OAuth token found for ${bitId}. Provide tokens via credentials or complete the OAuth flow.`);
4942
- }
4943
- }
4944
- } else if (credentials) {
4283
+ if (credentials) {
4945
4284
  const credentialKeys = Object.keys(credentials);
4946
4285
  if (credentialKeys.length > 0) {
4947
4286
  auth = credentials[credentialKeys[0]];
4948
- logger11.log(`\u{1F510} Using credentials for: ${credentialKeys[0]}`);
4287
+ logger10.log(`\u{1F510} Using credentials for: ${credentialKeys[0]}`);
4949
4288
  }
4950
4289
  }
4951
4290
  let bitLogger = void 0;
@@ -4963,10 +4302,9 @@ async function executeGenericBitsPiece(params, moduleDefinition) {
4963
4302
  propsValue: {
4964
4303
  ...actionProps
4965
4304
  },
4966
- logger: bitLogger,
4967
- executor: params.executor
4305
+ logger: bitLogger
4968
4306
  });
4969
- logger11.log(`\u2705 Successfully executed Bits piece action: ${actionName}`, result);
4307
+ logger10.log(`\u2705 Successfully executed Bits piece action: ${actionName}`, result);
4970
4308
  return {
4971
4309
  success: true,
4972
4310
  module: moduleDefinition.repository,
@@ -4981,7 +4319,7 @@ async function executeGenericBitsPiece(params, moduleDefinition) {
4981
4319
  }
4982
4320
  };
4983
4321
  } catch (error) {
4984
- logger11.error(error.stack);
4322
+ logger10.error(error.stack);
4985
4323
  throw error;
4986
4324
  }
4987
4325
  }
@@ -4995,7 +4333,7 @@ async function executeBitsModule(params) {
4995
4333
  throw new Error(`Bits module '${params.moduleName}' not found in modules.json`);
4996
4334
  }
4997
4335
  const inferredModuleName = getModuleName(moduleDefinition);
4998
- logger11.log(`
4336
+ logger10.log(`
4999
4337
  \u{1F50D} Ensuring bits module is ready: ${inferredModuleName}`);
5000
4338
  await ensureModuleInstalled(moduleDefinition);
5001
4339
  try {
@@ -5006,7 +4344,7 @@ async function executeBitsModule(params) {
5006
4344
  }
5007
4345
 
5008
4346
  // packages/cortex/core/src/bits/bitsWatcher.ts
5009
- var logger12 = LoggerFactory.getRoot();
4347
+ var logger11 = LoggerFactory.getRoot();
5010
4348
  function createSimpleStore2(prefix = "") {
5011
4349
  const storage = /* @__PURE__ */ new Map();
5012
4350
  return {
@@ -5024,39 +4362,6 @@ function createSimpleStore2(prefix = "") {
5024
4362
  }
5025
4363
  };
5026
4364
  }
5027
- function createBoundPollingStore(workflowId, triggerId, dedupStrategy = "id") {
5028
- const store = createPollingStore({
5029
- collection: "polling_seen_items",
5030
- dedupStrategy
5031
- });
5032
- const ctx = { workflowId, triggerId };
5033
- const baseStore = createSimpleStore2(`polling:${workflowId}:${triggerId}`);
5034
- return {
5035
- // Base store methods
5036
- get: baseStore.get,
5037
- put: baseStore.put,
5038
- delete: baseStore.delete,
5039
- // Polling-specific methods
5040
- async hasSeenItem(itemId, itemDate) {
5041
- return store.hasSeenItem(ctx, itemId, itemDate);
5042
- },
5043
- async markItemSeen(itemId, sourceDate, data) {
5044
- return store.markItemSeen(ctx, itemId, sourceDate, data);
5045
- },
5046
- async getLastPolledDate() {
5047
- return store.getLastPolledDate(ctx);
5048
- },
5049
- async setLastPolledDate(date) {
5050
- return store.setLastPolledDate(ctx, date);
5051
- },
5052
- async getSeenCount() {
5053
- return store.getSeenCount(ctx);
5054
- },
5055
- async clearTrigger() {
5056
- return store.clearTrigger(ctx);
5057
- }
5058
- };
5059
- }
5060
4365
  function isNil2(value) {
5061
4366
  return value === null || value === void 0;
5062
4367
  }
@@ -5101,7 +4406,7 @@ var bitsTriggerHelper = {
5101
4406
  * Execute a trigger based on hook type
5102
4407
  */
5103
4408
  async executeTrigger(params) {
5104
- const { moduleDefinition, triggerName, input, hookType, trigger, payload, webhookUrl, isTest, store, executor, workflowId, nodeId } = params;
4409
+ const { moduleDefinition, triggerName, input, hookType, trigger, payload, webhookUrl, isTest, store } = params;
5105
4410
  if (isNil2(triggerName)) {
5106
4411
  throw new Error("Trigger name is not set");
5107
4412
  }
@@ -5112,19 +4417,11 @@ var bitsTriggerHelper = {
5112
4417
  const { trigger: loadedTrigger } = await this.getTrigger(moduleDefinition, triggerName);
5113
4418
  bitsTrigger = loadedTrigger;
5114
4419
  }
5115
- logger12.log(`\u{1F514} Executing bits trigger: ${triggerName} (${hookType})`);
4420
+ logger11.log(`\u{1F514} Executing bits trigger: ${triggerName} (${hookType})`);
5116
4421
  const appListeners = [];
5117
4422
  let scheduleOptions;
5118
4423
  const storePrefix = isTest ? "test" : triggerName;
5119
4424
  const triggerStore = store || createSimpleStore2(storePrefix);
5120
- const triggerType = mapTriggerType(bitsTrigger.type);
5121
- let pollingStore;
5122
- if (triggerType === "POLLING" /* POLLING */ && workflowId) {
5123
- const dedupStrategy = input.dedupBy || "id";
5124
- const triggerId = `${moduleDefinition.repository}:${triggerName}`;
5125
- pollingStore = createBoundPollingStore(workflowId, triggerId, dedupStrategy);
5126
- logger12.log(`\u{1F4CA} Created polling store for ${triggerId} (dedup: ${dedupStrategy})`);
5127
- }
5128
4425
  let auth = void 0;
5129
4426
  const { credentials, ...triggerProps } = input;
5130
4427
  if (credentials) {
@@ -5135,7 +4432,7 @@ var bitsTriggerHelper = {
5135
4432
  props: credentialData,
5136
4433
  ...credentialData
5137
4434
  };
5138
- logger12.log(`\u{1F510} Using credentials for trigger: ${credentialKeys[0]}`);
4435
+ logger11.log(`\u{1F510} Using credentials for trigger: ${credentialKeys[0]}`);
5139
4436
  }
5140
4437
  }
5141
4438
  const context = {
@@ -5154,11 +4451,7 @@ var bitsTriggerHelper = {
5154
4451
  cronExpression: options.cronExpression,
5155
4452
  timezone: options.timezone ?? "UTC"
5156
4453
  };
5157
- },
5158
- executor,
5159
- workflowId,
5160
- nodeId,
5161
- pollingStore
4454
+ }
5162
4455
  };
5163
4456
  try {
5164
4457
  switch (hookType) {
@@ -5166,11 +4459,11 @@ var bitsTriggerHelper = {
5166
4459
  if (bitsTrigger.onEnable) {
5167
4460
  await bitsTrigger.onEnable(context);
5168
4461
  }
5169
- const triggerTypeForResult = mapTriggerType(bitsTrigger.type);
4462
+ const triggerType = mapTriggerType(bitsTrigger.type);
5170
4463
  return {
5171
4464
  success: true,
5172
4465
  listeners: appListeners,
5173
- scheduleOptions: triggerTypeForResult === "POLLING" /* POLLING */ ? scheduleOptions : void 0
4466
+ scheduleOptions: triggerType === "POLLING" /* POLLING */ ? scheduleOptions : void 0
5174
4467
  };
5175
4468
  }
5176
4469
  case "ON_DISABLE" /* ON_DISABLE */: {
@@ -5227,7 +4520,7 @@ var bitsTriggerHelper = {
5227
4520
  };
5228
4521
  }
5229
4522
  } catch (error) {
5230
- logger12.error(`Error executing trigger ${triggerName}:`, error);
4523
+ logger11.error(`Error executing trigger ${triggerName}:`, error);
5231
4524
  return {
5232
4525
  success: false,
5233
4526
  message: `Error executing trigger: ${error}`,
@@ -5256,13 +4549,13 @@ var bitsTriggerHelper = {
5256
4549
  * For webhooks: calls run directly
5257
4550
  */
5258
4551
  async executeBitsTrigger(params) {
5259
- const { moduleDefinition, triggerName, input, payload, webhookUrl, store, executor, workflowId, nodeId } = params;
4552
+ const { moduleDefinition, triggerName, input, payload, webhookUrl, store } = params;
5260
4553
  const { piece, trigger } = await this.getTrigger(moduleDefinition, triggerName);
5261
4554
  const triggerType = mapTriggerType(trigger.type);
5262
4555
  const triggerStore = store || createSimpleStore2(`trigger:${triggerName}`);
5263
4556
  switch (triggerType) {
5264
4557
  case "POLLING" /* POLLING */: {
5265
- logger12.log(`Polling trigger flow: onEnable \u2192 run`);
4558
+ logger11.log(`Polling trigger flow: onEnable \u2192 run`);
5266
4559
  const onEnableResult = await this.executeTrigger({
5267
4560
  moduleDefinition,
5268
4561
  triggerName,
@@ -5272,22 +4565,19 @@ var bitsTriggerHelper = {
5272
4565
  payload,
5273
4566
  webhookUrl,
5274
4567
  isTest: false,
5275
- store: triggerStore,
5276
- executor,
5277
- workflowId,
5278
- nodeId
4568
+ store: triggerStore
5279
4569
  });
5280
4570
  if (!onEnableResult.success) {
5281
4571
  return onEnableResult;
5282
4572
  }
5283
- logger12.log(` \u2705 onEnable completed`);
4573
+ logger11.log(` \u2705 onEnable completed`);
5284
4574
  if (onEnableResult.scheduleOptions) {
5285
- logger12.log(` \u{1F4C5} Schedule: ${onEnableResult.scheduleOptions.cronExpression} (${onEnableResult.scheduleOptions.timezone})`);
4575
+ logger11.log(` \u{1F4C5} Schedule: ${onEnableResult.scheduleOptions.cronExpression} (${onEnableResult.scheduleOptions.timezone})`);
5286
4576
  }
5287
4577
  if (onEnableResult.listeners && onEnableResult.listeners.length > 0) {
5288
- logger12.log(` \u{1F442} Listeners: ${onEnableResult.listeners.length}`);
4578
+ logger11.log(` \u{1F442} Listeners: ${onEnableResult.listeners.length}`);
5289
4579
  }
5290
- logger12.log(` \u2192 Calling run to fetch items...`);
4580
+ logger11.log(` \u2192 Calling run to fetch items...`);
5291
4581
  const runResult = await this.executeTrigger({
5292
4582
  moduleDefinition,
5293
4583
  triggerName,
@@ -5297,20 +4587,17 @@ var bitsTriggerHelper = {
5297
4587
  payload,
5298
4588
  webhookUrl,
5299
4589
  isTest: false,
5300
- store: triggerStore,
5301
- executor,
5302
- workflowId,
5303
- nodeId
4590
+ store: triggerStore
5304
4591
  });
5305
4592
  if (!runResult.success) {
5306
- logger12.warn(` \u26A0\uFE0F Run failed: ${runResult.message}`);
4593
+ logger11.warn(` \u26A0\uFE0F Run failed: ${runResult.message}`);
5307
4594
  } else {
5308
- logger12.log(` \u2705 Run completed, items found: ${runResult.output?.length || 0}`);
4595
+ logger11.log(` \u2705 Run completed, items found: ${runResult.output?.length || 0}`);
5309
4596
  }
5310
4597
  return runResult;
5311
4598
  }
5312
4599
  case "WEBHOOK" /* WEBHOOK */: {
5313
- logger12.log(`Webhook trigger`);
4600
+ logger11.log(`Webhook trigger`);
5314
4601
  return await this.executeTrigger({
5315
4602
  moduleDefinition,
5316
4603
  triggerName,
@@ -5318,10 +4605,7 @@ var bitsTriggerHelper = {
5318
4605
  hookType: "RUN" /* RUN */,
5319
4606
  payload,
5320
4607
  webhookUrl,
5321
- isTest: false,
5322
- executor,
5323
- workflowId,
5324
- nodeId
4608
+ isTest: false
5325
4609
  });
5326
4610
  }
5327
4611
  default: {
@@ -5341,14 +4625,14 @@ var bitsTriggerHelper = {
5341
4625
  const triggers = piece.triggers();
5342
4626
  for (const [triggerName, trigger] of Object.entries(triggers)) {
5343
4627
  const triggerType = mapTriggerType(trigger.type);
5344
- logger12.log(`\u{1F514} Hooking trigger: ${triggerName} (type: ${triggerType})`);
4628
+ logger11.log(`\u{1F514} Hooking trigger: ${triggerName} (type: ${triggerType})`);
5345
4629
  switch (triggerType) {
5346
4630
  case "POLLING" /* POLLING */:
5347
- logger12.log(` \u2192 Setting up polling trigger`);
4631
+ logger11.log(` \u2192 Setting up polling trigger`);
5348
4632
  if (options?.onPollingTrigger) {
5349
4633
  options.onPollingTrigger(triggerName, trigger);
5350
4634
  }
5351
- logger12.log(` \u{1F680} Running polling trigger immediately...`);
4635
+ logger11.log(` \u{1F680} Running polling trigger immediately...`);
5352
4636
  try {
5353
4637
  const result = await this.executeBitsTrigger({
5354
4638
  moduleDefinition,
@@ -5356,32 +4640,32 @@ var bitsTriggerHelper = {
5356
4640
  input: options?.input || {}
5357
4641
  });
5358
4642
  if (result.success) {
5359
- logger12.log(` \u2705 Trigger ${triggerName} executed successfully`);
5360
- logger12.log(` \u{1F4E6} Output items: ${result.output?.length || 0}`);
4643
+ logger11.log(` \u2705 Trigger ${triggerName} executed successfully`);
4644
+ logger11.log(` \u{1F4E6} Output items: ${result.output?.length || 0}`);
5361
4645
  } else {
5362
- logger12.warn(` \u26A0\uFE0F Trigger ${triggerName} failed: ${result.message}`);
4646
+ logger11.warn(` \u26A0\uFE0F Trigger ${triggerName} failed: ${result.message}`);
5363
4647
  }
5364
4648
  if (options?.onTriggerResult) {
5365
4649
  options.onTriggerResult(triggerName, result);
5366
4650
  }
5367
4651
  } catch (error) {
5368
- logger12.error(` \u274C Error running trigger ${triggerName}:`, error.message);
4652
+ logger11.error(` \u274C Error running trigger ${triggerName}:`, error.message);
5369
4653
  }
5370
4654
  break;
5371
4655
  case "WEBHOOK" /* WEBHOOK */:
5372
- logger12.log(` \u2192 Setting up webhook trigger`);
4656
+ logger11.log(` \u2192 Setting up webhook trigger`);
5373
4657
  if (options?.onWebhookTrigger) {
5374
4658
  options.onWebhookTrigger(triggerName, trigger);
5375
4659
  }
5376
4660
  break;
5377
4661
  case "APP_WEBHOOK" /* APP_WEBHOOK */:
5378
- logger12.log(` \u2192 Setting up app webhook trigger`);
4662
+ logger11.log(` \u2192 Setting up app webhook trigger`);
5379
4663
  if (options?.onAppWebhookTrigger) {
5380
4664
  options.onAppWebhookTrigger(triggerName, trigger);
5381
4665
  }
5382
4666
  break;
5383
4667
  default:
5384
- logger12.warn(` \u26A0\uFE0F Unknown trigger type: ${triggerType}`);
4668
+ logger11.warn(` \u26A0\uFE0F Unknown trigger type: ${triggerType}`);
5385
4669
  }
5386
4670
  }
5387
4671
  },
@@ -5419,7 +4703,7 @@ var bitsTriggerHelper = {
5419
4703
  * Execute a webhook trigger with received payload
5420
4704
  */
5421
4705
  async executeWebhookTrigger(nodeId, payload, headers, query) {
5422
- logger12.log(`\u{1F514} Executing webhook trigger for node: ${nodeId}`);
4706
+ logger11.log(`\u{1F514} Executing webhook trigger for node: ${nodeId}`);
5423
4707
  return {
5424
4708
  success: true,
5425
4709
  output: [
@@ -5440,10 +4724,10 @@ var bitsTriggerHelper = {
5440
4724
  import * as fs3 from "fs";
5441
4725
  import * as path5 from "path";
5442
4726
  import * as vm from "vm";
5443
- import { spawn as spawn2, execSync as execSync2 } from "child_process";
4727
+ import { spawn, execSync } from "child_process";
5444
4728
  import * as os from "os";
5445
4729
  import * as ts from "typescript";
5446
- var logger13 = LoggerFactory.getRoot();
4730
+ var logger12 = LoggerFactory.getRoot();
5447
4731
  function convertDenoImports(code) {
5448
4732
  const npmPackages = [];
5449
4733
  const imports = [];
@@ -5616,7 +4900,7 @@ async function executeJavaScript(code, params, context) {
5616
4900
  });
5617
4901
  return result;
5618
4902
  } catch (error) {
5619
- logger13.error(`JavaScript execution error: ${error.message}`);
4903
+ logger12.error(`JavaScript execution error: ${error.message}`);
5620
4904
  throw error;
5621
4905
  }
5622
4906
  }
@@ -5645,7 +4929,7 @@ if __name__ == "__main__":
5645
4929
  fs3.writeFileSync(scriptPath, wrappedCode);
5646
4930
  return new Promise((resolve4, reject) => {
5647
4931
  const pythonCmd = process.platform === "win32" ? "python" : "python3";
5648
- const proc = spawn2(pythonCmd, [scriptPath], {
4932
+ const proc = spawn(pythonCmd, [scriptPath], {
5649
4933
  env: { ...process.env },
5650
4934
  cwd: tmpDir
5651
4935
  });
@@ -5724,8 +5008,8 @@ func main() {
5724
5008
  fs3.writeFileSync(scriptPath, wrappedCode);
5725
5009
  return new Promise((resolve4, reject) => {
5726
5010
  try {
5727
- execSync2(`go build -o main`, { cwd: scriptDir, stdio: "pipe" });
5728
- const proc = spawn2("./main", [], {
5011
+ execSync(`go build -o main`, { cwd: scriptDir, stdio: "pipe" });
5012
+ const proc = spawn("./main", [], {
5729
5013
  cwd: scriptDir,
5730
5014
  env: { ...process.env }
5731
5015
  });
@@ -5797,7 +5081,7 @@ ${code}
5797
5081
  `;
5798
5082
  fs3.writeFileSync(scriptPath, wrappedCode, { mode: 493 });
5799
5083
  return new Promise((resolve4, reject) => {
5800
- const proc = spawn2("bash", [scriptPath], {
5084
+ const proc = spawn("bash", [scriptPath], {
5801
5085
  env: { ...process.env },
5802
5086
  cwd: tmpDir
5803
5087
  });
@@ -5871,9 +5155,9 @@ async function executeScriptModule(paramsOrModuleName, maybeParams) {
5871
5155
  executionParams = paramsOrModuleName.params;
5872
5156
  inlineScript = paramsOrModuleName.script;
5873
5157
  }
5874
- logger13.log(`
5158
+ logger12.log(`
5875
5159
  \u{1F300} Executing Script module: ${moduleName}`);
5876
- logger13.log(` Source: ${source}`);
5160
+ logger12.log(` Source: ${source}`);
5877
5161
  let script = null;
5878
5162
  if (source === "inline" && inlineScript) {
5879
5163
  script = inlineScript;
@@ -5885,7 +5169,7 @@ async function executeScriptModule(paramsOrModuleName, maybeParams) {
5885
5169
  if (!script || !script.content) {
5886
5170
  throw new Error(`Could not load script: ${moduleName}`);
5887
5171
  }
5888
- logger13.log(` Language: ${script.language}`);
5172
+ logger12.log(` Language: ${script.language}`);
5889
5173
  const context = {
5890
5174
  flow_input: executionParams,
5891
5175
  previous_result: executionParams.previous_result || null,
@@ -5911,7 +5195,7 @@ async function executeScriptModule(paramsOrModuleName, maybeParams) {
5911
5195
  default:
5912
5196
  throw new Error(`Unsupported language: ${script.language}`);
5913
5197
  }
5914
- logger13.log(`\u2705 Script executed successfully`);
5198
+ logger12.log(`\u2705 Script executed successfully`);
5915
5199
  return {
5916
5200
  success: true,
5917
5201
  module: moduleName,
@@ -5925,7 +5209,7 @@ async function executeScriptModule(paramsOrModuleName, maybeParams) {
5925
5209
  }
5926
5210
  };
5927
5211
  } catch (error) {
5928
- logger13.error(`\u274C Script failed: ${error.message}`);
5212
+ logger12.error(`\u274C Script failed: ${error.message}`);
5929
5213
  return {
5930
5214
  success: false,
5931
5215
  module: moduleName,
@@ -5952,7 +5236,7 @@ function getSecurityConfig() {
5952
5236
  const moderationEnabled = process.env.HABITS_MODERATION_ENABLED === "true";
5953
5237
  return { dlpEnabled, dlpIcapUrl, dlpIcapTimeout, piiMode, moderationEnabled };
5954
5238
  }
5955
- async function scanInputForSecurity(data, config, logger15) {
5239
+ async function scanInputForSecurity(data, config, logger13) {
5956
5240
  let processedData = data;
5957
5241
  if (!config.dlpEnabled && !config.piiMode && !config.moderationEnabled) {
5958
5242
  return processedData;
@@ -5960,50 +5244,50 @@ async function scanInputForSecurity(data, config, logger15) {
5960
5244
  try {
5961
5245
  const intersect = await import("@codenteam/intersect");
5962
5246
  if (config.dlpEnabled) {
5963
- logger15.log("\u{1F510} [Security] Running DLP scan on input data...");
5247
+ logger13.log("\u{1F510} [Security] Running DLP scan on input data...");
5964
5248
  try {
5965
5249
  const dlpOptions = {};
5966
5250
  if (config.dlpIcapUrl) {
5967
5251
  dlpOptions.icapUrl = config.dlpIcapUrl;
5968
5252
  dlpOptions.timeout = config.dlpIcapTimeout;
5969
- logger15.log(`\u{1F510} [DLP] Using ICAP server: ${config.dlpIcapUrl}`);
5253
+ logger13.log(`\u{1F510} [DLP] Using ICAP server: ${config.dlpIcapUrl}`);
5970
5254
  }
5971
5255
  const dlpResult = await intersect.dlp.consume(processedData, dlpOptions);
5972
5256
  processedData = dlpResult.data ?? processedData;
5973
5257
  if (dlpResult.findings && dlpResult.findings.length > 0) {
5974
- logger15.log(`\u{1F510} [DLP] Found ${dlpResult.findings.length} sensitive data instance(s)`);
5258
+ logger13.log(`\u{1F510} [DLP] Found ${dlpResult.findings.length} sensitive data instance(s)`);
5975
5259
  }
5976
5260
  } catch (dlpError) {
5977
- logger15.warn(`\u26A0\uFE0F [DLP] Scan failed: ${dlpError.message}`);
5261
+ logger13.warn(`\u26A0\uFE0F [DLP] Scan failed: ${dlpError.message}`);
5978
5262
  }
5979
5263
  }
5980
5264
  if (config.piiMode) {
5981
- logger15.log(`\u{1F510} [Security] Running PII scan (mode: ${config.piiMode}) on input data...`);
5265
+ logger13.log(`\u{1F510} [Security] Running PII scan (mode: ${config.piiMode}) on input data...`);
5982
5266
  try {
5983
5267
  const piiResult = await intersect.pii.consume(processedData, { mode: config.piiMode });
5984
5268
  processedData = piiResult.data ?? processedData;
5985
5269
  if (piiResult.detections && piiResult.detections.length > 0) {
5986
- logger15.log(`\u{1F510} [PII] Found ${piiResult.detections.length} PII instance(s) - mode: ${config.piiMode}`);
5270
+ logger13.log(`\u{1F510} [PII] Found ${piiResult.detections.length} PII instance(s) - mode: ${config.piiMode}`);
5987
5271
  }
5988
5272
  } catch (piiError) {
5989
- logger15.warn(`\u26A0\uFE0F [PII] Scan failed: ${piiError.message}`);
5273
+ logger13.warn(`\u26A0\uFE0F [PII] Scan failed: ${piiError.message}`);
5990
5274
  }
5991
5275
  }
5992
5276
  if (config.moderationEnabled) {
5993
- logger15.log("\u{1F510} [Security] Running moderation scan on input data...");
5277
+ logger13.log("\u{1F510} [Security] Running moderation scan on input data...");
5994
5278
  try {
5995
5279
  const modResult = await intersect.moderation.consume(processedData);
5996
5280
  if (modResult.flagged) {
5997
- logger15.warn(`\u26A0\uFE0F [Moderation] Content flagged: ${JSON.stringify(modResult.categories)}`);
5281
+ logger13.warn(`\u26A0\uFE0F [Moderation] Content flagged: ${JSON.stringify(modResult.categories)}`);
5998
5282
  }
5999
5283
  processedData = modResult.data ?? processedData;
6000
5284
  } catch (modError) {
6001
- logger15.warn(`\u26A0\uFE0F [Moderation] Scan failed: ${modError.message}`);
5285
+ logger13.warn(`\u26A0\uFE0F [Moderation] Scan failed: ${modError.message}`);
6002
5286
  }
6003
5287
  }
6004
5288
  } catch (importError) {
6005
- logger15.warn(`\u26A0\uFE0F [Security] @codenteam/intersect package not available: ${importError.message}`);
6006
- logger15.warn(" Security features (DLP, PII, Moderation) are disabled.");
5289
+ logger13.warn(`\u26A0\uFE0F [Security] @codenteam/intersect package not available: ${importError.message}`);
5290
+ logger13.warn(" Security features (DLP, PII, Moderation) are disabled.");
6007
5291
  }
6008
5292
  return processedData;
6009
5293
  }
@@ -6016,8 +5300,6 @@ var WorkflowExecutor = class {
6016
5300
  this.config = null;
6017
5301
  this.logger = LoggerFactory.getRoot();
6018
5302
  this.env = {};
6019
- /** Active polling cron jobs - keyed by workflowId:nodeId */
6020
- this.pollingCronJobs = /* @__PURE__ */ new Map();
6021
5303
  }
6022
5304
  /**
6023
5305
  * Initialize from in-memory data (no file system access needed)
@@ -6072,7 +5354,7 @@ var WorkflowExecutor = class {
6072
5354
  this.logger.log(` \u{1F511} Environment variables:`);
6073
5355
  for (const key of Object.keys(this.env)) {
6074
5356
  if (key.startsWith("HABITS_")) {
6075
- this.logger.log(` - ${key}: ${this.env[key] !== void 0 ? "(Set but a secret you know)" : "(not set)"}`);
5357
+ this.logger.log(` - ${key}: ${this.env[key]}`);
6076
5358
  }
6077
5359
  }
6078
5360
  this.logger.log(` \u{1F4CB} Resolvable habits params in workflow:`);
@@ -6082,7 +5364,7 @@ var WorkflowExecutor = class {
6082
5364
  if (param.startsWith("habits.env.")) {
6083
5365
  const envVar = param.slice("habits.env.".length);
6084
5366
  const value = this.env[envVar];
6085
- this.logger.log(` - {{${param}}} \u2192 ${value !== void 0 ? "(Set but a secret you know)" : "(not set)"}`);
5367
+ this.logger.log(` - {{${param}}} \u2192 ${value !== void 0 ? value : "(not set)"}`);
6086
5368
  } else {
6087
5369
  this.logger.log(` - {{${param}}} \u2192 (resolved at runtime)`);
6088
5370
  }
@@ -6152,7 +5434,6 @@ var WorkflowExecutor = class {
6152
5434
  \u{1F4E6} Module preloading complete
6153
5435
  `);
6154
5436
  await this.hookPollingTriggers();
6155
- await this.registerBitsPollingTriggers();
6156
5437
  }
6157
5438
  /**
6158
5439
  * Hook polling triggers for all loaded workflows
@@ -6215,145 +5496,6 @@ var WorkflowExecutor = class {
6215
5496
  }
6216
5497
  }
6217
5498
  }
6218
- /**
6219
- * Register bits polling triggers with cron scheduling.
6220
- * Scans workflows for polling trigger nodes, calls their onEnable() to get schedule,
6221
- * then creates cron jobs using croner to periodically call run().
6222
- */
6223
- async registerBitsPollingTriggers() {
6224
- const workflows = this.getAllWorkflows();
6225
- this.logger.log(`
6226
- \u23F0 Scanning ${workflows.length} workflow(s) for polling triggers...`);
6227
- let registeredCount = 0;
6228
- for (const { reference, workflow } of workflows) {
6229
- if (reference.enabled === false) continue;
6230
- const workflowId = reference.id || workflow.id;
6231
- for (const node of workflow.nodes || []) {
6232
- const nodeData = node.data;
6233
- const isTrigger = nodeData?.isTrigger === true || node.type === "trigger";
6234
- const isBits = nodeData?.framework === "bits";
6235
- const hasModule = !!nodeData?.module;
6236
- if (!isTrigger || !isBits || !hasModule) continue;
6237
- const moduleName = nodeData.module;
6238
- const triggerName = nodeData.operation || "default";
6239
- try {
6240
- let bitPiece = null;
6241
- const moduleDefinition = {
6242
- source: nodeData.source || "npm",
6243
- module: moduleName,
6244
- framework: "bits",
6245
- repository: moduleName
6246
- };
6247
- try {
6248
- bitPiece = await pieceFromModule2(moduleDefinition);
6249
- } catch (loadError) {
6250
- this.logger.warn(` \u26A0\uFE0F Could not load module ${moduleName}: ${loadError}`);
6251
- continue;
6252
- }
6253
- const triggers = typeof bitPiece.triggers === "function" ? bitPiece.triggers() : bitPiece.triggers;
6254
- const trigger = triggers?.[triggerName];
6255
- if (!trigger) {
6256
- this.logger.warn(` \u26A0\uFE0F Trigger ${triggerName} not found in module ${moduleName}`);
6257
- continue;
6258
- }
6259
- const triggerType = trigger.type?.toUpperCase?.() || trigger.type;
6260
- if (triggerType !== "POLLING") {
6261
- continue;
6262
- }
6263
- const rawProps = nodeData.params || {};
6264
- const triggerProps = this.resolveParameters(rawProps, {});
6265
- this.logger.log(` \u23F0 Enabling polling trigger: ${workflowId}/${node.id} (${moduleName}:${triggerName})`);
6266
- const result = await bitsTriggerHelper.executeTrigger({
6267
- moduleDefinition,
6268
- triggerName,
6269
- input: triggerProps,
6270
- hookType: "ON_ENABLE" /* ON_ENABLE */,
6271
- trigger,
6272
- workflowId,
6273
- nodeId: node.id
6274
- });
6275
- if (!result.success) {
6276
- this.logger.warn(` \u26A0\uFE0F Failed to enable ${workflowId}/${node.id}: ${result.message}`);
6277
- continue;
6278
- }
6279
- const scheduleOptions = result.scheduleOptions;
6280
- if (!scheduleOptions?.cronExpression) {
6281
- this.logger.warn(` \u26A0\uFE0F No schedule returned from onEnable for ${workflowId}/${node.id}`);
6282
- continue;
6283
- }
6284
- const cronKey = `${workflowId}:${node.id}`;
6285
- const { cronExpression, timezone = "UTC" } = scheduleOptions;
6286
- this.logger.log(` \u{1F4C5} Creating cron job: ${cronExpression} (${timezone}) for ${cronKey}`);
6287
- const cronJob = new Cron(cronExpression, { timezone, name: cronKey }, async () => {
6288
- const triggeredAt = (/* @__PURE__ */ new Date()).toISOString();
6289
- this.logger.log(` \u23F0 Cron fired: ${cronKey} at ${triggeredAt}`);
6290
- try {
6291
- const runResult = await bitsTriggerHelper.executeTrigger({
6292
- moduleDefinition,
6293
- triggerName,
6294
- input: triggerProps,
6295
- hookType: "RUN" /* RUN */,
6296
- trigger,
6297
- workflowId,
6298
- nodeId: node.id
6299
- });
6300
- if (runResult.success && runResult.output && runResult.output.length > 0) {
6301
- this.logger.log(` \u{1F4E6} Trigger returned ${runResult.output.length} item(s), executing workflow for each...`);
6302
- const loadedWorkflow = this.getWorkflow(workflowId);
6303
- if (!loadedWorkflow) {
6304
- this.logger.error(` \u274C Workflow ${workflowId} not found`);
6305
- return;
6306
- }
6307
- for (let i = 0; i < runResult.output.length; i++) {
6308
- const item = runResult.output[i];
6309
- this.logger.log(` \u{1F504} Processing item ${i + 1}/${runResult.output.length}`);
6310
- try {
6311
- const execution = await this.executeWorkflow(loadedWorkflow.workflow, {
6312
- initialContext: {
6313
- "habits.input": item,
6314
- // Single item, not array
6315
- __pollingTrigger: true,
6316
- __pollingNodeId: node.id,
6317
- __triggeredAt: triggeredAt,
6318
- __pollingItemIndex: i
6319
- },
6320
- skipTriggerWait: true,
6321
- triggerNodeId: node.id
6322
- });
6323
- this.logger.log(` \u2705 Item ${i + 1} processed: ${execution.status}`);
6324
- } catch (itemErr) {
6325
- this.logger.error(` \u274C Item ${i + 1} failed: ${itemErr.message}`);
6326
- }
6327
- }
6328
- this.logger.log(` \u2705 Workflow ${workflowId} completed processing ${runResult.output.length} item(s)`);
6329
- } else {
6330
- this.logger.log(` \u23F3 No new items from trigger, skipping workflow execution`);
6331
- }
6332
- } catch (err) {
6333
- this.logger.error(` \u274C Error in polling trigger: ${err.message}`);
6334
- }
6335
- });
6336
- this.pollingCronJobs.set(cronKey, cronJob);
6337
- registeredCount++;
6338
- this.logger.log(` \u2705 Registered: ${workflowId}/${node.id} (${triggerName}) -> ${cronExpression}`);
6339
- } catch (error) {
6340
- this.logger.error(` \u274C Error enabling polling trigger for ${workflowId}/${node.id}: ${error}`);
6341
- }
6342
- }
6343
- }
6344
- this.logger.log(`\u23F0 Enabled ${registeredCount} polling trigger(s)
6345
- `);
6346
- }
6347
- /**
6348
- * Stop all polling cron jobs
6349
- */
6350
- stopPollingTriggers() {
6351
- for (const [key, cron] of this.pollingCronJobs) {
6352
- cron.stop();
6353
- this.logger.log(` \u23F9\uFE0F Stopped polling trigger: ${key}`);
6354
- }
6355
- this.pollingCronJobs.clear();
6356
- }
6357
5499
  /**
6358
5500
  * Find all template params starting with "habits." in a workflow
6359
5501
  */
@@ -6463,7 +5605,7 @@ var WorkflowExecutor = class {
6463
5605
  });
6464
5606
  try {
6465
5607
  const webhookTriggers = this.findWebhookTriggers(workflow.nodes);
6466
- if (webhookTriggers.length > 0 && !options?.skipTriggerWait) {
5608
+ if (webhookTriggers.length > 0) {
6467
5609
  if (!options?.webhookHandler) {
6468
5610
  throw new Error(
6469
5611
  `Workflow "${workflow.name}" contains ${webhookTriggers.length} webhook trigger(s) but no webhookHandler was provided. Webhook triggers are only supported in Node.js server environments. Provide a webhookHandler via options or remove webhook triggers from the workflow.`
@@ -6475,9 +5617,6 @@ var WorkflowExecutor = class {
6475
5617
  this.logger.log(` - Node: ${trigger.nodeId}`);
6476
5618
  }
6477
5619
  this.logger.log("\n\u23F3 Waiting for webhook(s) to be triggered...\n");
6478
- } else if (webhookTriggers.length > 0 && options?.skipTriggerWait) {
6479
- this.logger.log(`
6480
- \u{1F4CB} Detected ${webhookTriggers.length} webhook trigger(s) - using pre-provided payload`);
6481
5620
  }
6482
5621
  const dependencies = this.buildDependencyMap(workflow.nodes, workflow?.edges || []);
6483
5622
  execution.nodeStatuses = workflow.nodes.map((node) => ({
@@ -6485,9 +5624,6 @@ var WorkflowExecutor = class {
6485
5624
  status: "pending"
6486
5625
  }));
6487
5626
  let context = options?.initialContext ? { ...options.initialContext } : {};
6488
- if (options?.oauthTokens) {
6489
- context._oauthTokens = options.oauthTokens;
6490
- }
6491
5627
  if (!context.habits) {
6492
5628
  context.habits = {};
6493
5629
  }
@@ -6556,76 +5692,31 @@ var WorkflowExecutor = class {
6556
5692
  status: "running"
6557
5693
  });
6558
5694
  try {
6559
- const isPollingTriggerNode = context.__pollingTrigger && context.__pollingNodeId === nodeId && (node.type === "trigger" || node.data?.isTrigger);
6560
- if (isPollingTriggerNode) {
6561
- this.logger.log(`\u23F0 Using pre-fetched polling data for trigger node: ${nodeId}`);
6562
- const pollingData = context["habits.input"];
6563
- const scannedResult = await scanInputForSecurity(pollingData, securityConfig, this.logger);
5695
+ if (this.isWebhookTriggerNode(node)) {
5696
+ const webhookResult = await this.handleWebhookTrigger(node, context, execution, options.webhookHandler, options?.webhookTimeout);
5697
+ const scannedResult = await scanInputForSecurity(webhookResult.result, securityConfig, this.logger);
6564
5698
  context[`${nodeId}`] = scannedResult;
6565
5699
  context[nodeId] = scannedResult;
6566
5700
  context.previous_result = scannedResult;
6567
- this.updateNodeStatus(execution, nodeId, "completed", {
5701
+ context.webhookPayload = scannedResult;
5702
+ this.updateNodeStatus(execution, nodeId, webhookResult.success ? "completed" : "failed", {
6568
5703
  result: scannedResult,
6569
- startTime: /* @__PURE__ */ new Date(),
6570
- endTime: /* @__PURE__ */ new Date(),
6571
- duration: 0
5704
+ error: webhookResult.error,
5705
+ startTime: new Date(webhookResult.timestamp.getTime() - webhookResult.duration),
5706
+ endTime: webhookResult.timestamp,
5707
+ duration: webhookResult.duration
6572
5708
  });
6573
5709
  emitStreamEvent({
6574
- type: "node_completed",
5710
+ type: webhookResult.success ? "node_completed" : "node_failed",
6575
5711
  nodeId,
6576
5712
  nodeName: node.data.label,
6577
- status: "completed",
5713
+ status: webhookResult.success ? "completed" : "failed",
6578
5714
  result: scannedResult,
6579
- duration: 0
5715
+ error: webhookResult.error,
5716
+ duration: webhookResult.duration
6580
5717
  });
6581
- } else if (this.isWebhookTriggerNode(node)) {
6582
- const skipWait = options?.skipTriggerWait && (options?.triggerNodeId === nodeId || !options?.triggerNodeId);
6583
- if (skipWait && context.webhookPayload) {
6584
- this.logger.log(`\u{1F514} Using pre-provided webhook payload for trigger node: ${nodeId}`);
6585
- const scannedResult = await scanInputForSecurity(context.webhookPayload, securityConfig, this.logger);
6586
- context[`${nodeId}`] = scannedResult;
6587
- context[nodeId] = scannedResult;
6588
- context.previous_result = scannedResult;
6589
- this.updateNodeStatus(execution, nodeId, "completed", {
6590
- result: scannedResult,
6591
- startTime: /* @__PURE__ */ new Date(),
6592
- endTime: /* @__PURE__ */ new Date(),
6593
- duration: 0
6594
- });
6595
- emitStreamEvent({
6596
- type: "node_completed",
6597
- nodeId,
6598
- nodeName: node.data.label,
6599
- status: "completed",
6600
- result: scannedResult,
6601
- duration: 0
6602
- });
6603
- } else {
6604
- const webhookResult = await this.handleWebhookTrigger(node, context, execution, options.webhookHandler, options?.webhookTimeout);
6605
- const scannedResult = await scanInputForSecurity(webhookResult.result, securityConfig, this.logger);
6606
- context[`${nodeId}`] = scannedResult;
6607
- context[nodeId] = scannedResult;
6608
- context.previous_result = scannedResult;
6609
- context.webhookPayload = scannedResult;
6610
- this.updateNodeStatus(execution, nodeId, webhookResult.success ? "completed" : "failed", {
6611
- result: scannedResult,
6612
- error: webhookResult.error,
6613
- startTime: new Date(webhookResult.timestamp.getTime() - webhookResult.duration),
6614
- endTime: webhookResult.timestamp,
6615
- duration: webhookResult.duration
6616
- });
6617
- emitStreamEvent({
6618
- type: webhookResult.success ? "node_completed" : "node_failed",
6619
- nodeId,
6620
- nodeName: node.data.label,
6621
- status: webhookResult.success ? "completed" : "failed",
6622
- result: scannedResult,
6623
- error: webhookResult.error,
6624
- duration: webhookResult.duration
6625
- });
6626
- if (!webhookResult.success) {
6627
- this.logger.error(`\u274C Webhook trigger ${nodeId} failed: ${webhookResult.error}`);
6628
- }
5718
+ if (!webhookResult.success) {
5719
+ this.logger.error(`\u274C Webhook trigger ${nodeId} failed: ${webhookResult.error}`);
6629
5720
  }
6630
5721
  } else {
6631
5722
  const nodeResult = await this.executeNode(node, context, execution);
@@ -6997,10 +6088,7 @@ var WorkflowExecutor = class {
6997
6088
  triggerName: node.data.operation || "unknown",
6998
6089
  input: fullParams,
6999
6090
  payload: context.triggerPayload || context.webhookPayload || {},
7000
- webhookUrl: context.webhookUrl,
7001
- executor: this,
7002
- workflowId: execution.workflowId,
7003
- nodeId: node.id
6091
+ webhookUrl: context.webhookUrl
7004
6092
  });
7005
6093
  if (!triggerResult.success) {
7006
6094
  throw new Error(triggerResult.message || "Trigger execution failed");
@@ -7015,10 +6103,7 @@ var WorkflowExecutor = class {
7015
6103
  logger: this.logger,
7016
6104
  workflowId: execution.workflowId,
7017
6105
  nodeId: node.id,
7018
- executionId: execution.id,
7019
- executor: this,
7020
- // Pass per-user OAuth tokens from context (for multi-user server mode)
7021
- oauthTokens: context._oauthTokens
6106
+ executionId: execution.id
7022
6107
  });
7023
6108
  nodeResult = output.result;
7024
6109
  }
@@ -7095,34 +6180,9 @@ var WorkflowExecutor = class {
7095
6180
  }
7096
6181
  /**
7097
6182
  * Evaluate a JavaScript expression in the given context
7098
- * Supports default values with || operator: {{habits.input.value || 'default'}}
7099
6183
  */
7100
6184
  evaluateExpression(expression, context) {
7101
6185
  try {
7102
- const defaultMatch = expression.match(/^(.+?)\s*\|\|\s*(['"`])(.*)(\2)$/);
7103
- if (defaultMatch) {
7104
- const [, mainExpr, , defaultValue] = defaultMatch;
7105
- const result = this.evaluateExpression(mainExpr.trim(), context);
7106
- if (result === void 0 || result === null || result === "" || result === mainExpr.trim()) {
7107
- return defaultValue;
7108
- }
7109
- return result;
7110
- }
7111
- const defaultUnquotedMatch = expression.match(/^(.+?)\s*\|\|\s*([^'"`].*)$/);
7112
- if (defaultUnquotedMatch) {
7113
- const [, mainExpr, defaultValue] = defaultUnquotedMatch;
7114
- const result = this.evaluateExpression(mainExpr.trim(), context);
7115
- if (result === void 0 || result === null || result === "" || result === mainExpr.trim()) {
7116
- const trimmedDefault = defaultValue.trim();
7117
- if (trimmedDefault === "true") return true;
7118
- if (trimmedDefault === "false") return false;
7119
- if (trimmedDefault === "null") return null;
7120
- const num = Number(trimmedDefault);
7121
- if (!isNaN(num)) return num;
7122
- return trimmedDefault;
7123
- }
7124
- return result;
7125
- }
7126
6186
  if (expression.startsWith("habits.env.")) {
7127
6187
  const envVar = expression.slice("habits.env.".length);
7128
6188
  const value = this.env[envVar] ?? (typeof process !== "undefined" ? process.env?.[envVar] : void 0);
@@ -7457,6 +6517,7 @@ function assertNotNullOrUndefined(value, fieldName) {
7457
6517
  }
7458
6518
 
7459
6519
  // packages/cortex/core/src/bits/framework.ts
6520
+ import axios4 from "axios";
7460
6521
  var AuthenticationType = /* @__PURE__ */ ((AuthenticationType2) => {
7461
6522
  AuthenticationType2["BEARER_TOKEN"] = "BEARER_TOKEN";
7462
6523
  AuthenticationType2["BASIC"] = "BASIC";
@@ -7477,42 +6538,42 @@ var HttpMethod = /* @__PURE__ */ ((HttpMethod2) => {
7477
6538
  })(HttpMethod || {});
7478
6539
  var httpClient = {
7479
6540
  async sendRequest(request) {
7480
- const headers = { ...request.headers };
6541
+ const config = {
6542
+ url: request.url,
6543
+ method: request.method,
6544
+ headers: { ...request.headers },
6545
+ data: request.body,
6546
+ params: request.queryParams,
6547
+ timeout: request.timeout || 3e4
6548
+ };
7481
6549
  if (request.authentication) {
7482
6550
  switch (request.authentication.type) {
7483
6551
  case "BEARER_TOKEN" /* BEARER_TOKEN */:
7484
- headers["Authorization"] = `Bearer ${request.authentication.token}`;
6552
+ config.headers = {
6553
+ ...config.headers,
6554
+ Authorization: `Bearer ${request.authentication.token}`
6555
+ };
7485
6556
  break;
7486
6557
  case "BASIC" /* BASIC */:
7487
- const credentials = Buffer.from(
7488
- `${request.authentication.username || ""}:${request.authentication.password || ""}`
7489
- ).toString("base64");
7490
- headers["Authorization"] = `Basic ${credentials}`;
6558
+ config.auth = {
6559
+ username: request.authentication.username || "",
6560
+ password: request.authentication.password || ""
6561
+ };
7491
6562
  break;
7492
6563
  case "API_KEY" /* API_KEY */:
7493
6564
  const headerName = request.authentication.headerName || "X-API-Key";
7494
- headers[headerName] = request.authentication.apiKey || "";
6565
+ config.headers = {
6566
+ ...config.headers,
6567
+ [headerName]: request.authentication.apiKey || ""
6568
+ };
7495
6569
  break;
7496
6570
  }
7497
6571
  }
7498
- let url = request.url;
7499
- if (request.queryParams && Object.keys(request.queryParams).length > 0) {
7500
- const params = new URLSearchParams(request.queryParams);
7501
- url += (url.includes("?") ? "&" : "?") + params.toString();
7502
- }
7503
- const response = await fetch2(url, {
7504
- method: request.method,
7505
- headers,
7506
- body: request.body ? JSON.stringify(request.body) : void 0
7507
- });
7508
- const responseHeaders = {};
7509
- response.headers.forEach((value, key) => {
7510
- responseHeaders[key] = value;
7511
- });
6572
+ const response = await axios4(config);
7512
6573
  return {
7513
6574
  status: response.status,
7514
- headers: responseHeaders,
7515
- body: await response.json()
6575
+ headers: response.headers,
6576
+ body: response.data
7516
6577
  };
7517
6578
  }
7518
6579
  };
@@ -7662,24 +6723,13 @@ var BitAuth = {
7662
6723
  },
7663
6724
  OAuth2(config) {
7664
6725
  return {
7665
- type: "OAUTH2",
7666
- displayName: config.displayName,
6726
+ type: "CUSTOM_AUTH",
6727
+ displayName: "OAuth2",
7667
6728
  description: config.description,
7668
6729
  required: config.required,
7669
- authorizationUrl: config.authorizationUrl,
7670
- tokenUrl: config.tokenUrl,
7671
- clientId: config.clientId,
7672
- clientSecret: config.clientSecret,
7673
- scopes: config.scopes,
7674
- pkce: config.pkce ?? true,
7675
- // PKCE enabled by default
7676
- extraAuthParams: config.extraAuthParams
6730
+ ...config
7677
6731
  };
7678
6732
  },
7679
- /** @deprecated Use OAuth2() instead */
7680
- OAuth2PKCE(config) {
7681
- return BitAuth.OAuth2({ ...config, pkce: true });
7682
- },
7683
6733
  BasicAuth(config) {
7684
6734
  return {
7685
6735
  type: "CUSTOM_AUTH",
@@ -7721,7 +6771,6 @@ function createTrigger(config) {
7721
6771
  run: config.run,
7722
6772
  test: config.test,
7723
6773
  onHandshake: config.onHandshake,
7724
- filter: config.filter,
7725
6774
  sampleData: config.sampleData
7726
6775
  };
7727
6776
  }
@@ -7768,7 +6817,6 @@ function createBit(config) {
7768
6817
  }
7769
6818
  }
7770
6819
  return {
7771
- id: config.id,
7772
6820
  displayName: config.displayName,
7773
6821
  description: config.description,
7774
6822
  logoUrl: config.logoUrl,
@@ -7844,530 +6892,14 @@ function createCustomApiCallAction(config) {
7844
6892
  }
7845
6893
  });
7846
6894
  }
7847
-
7848
- // packages/cortex/core/src/bits/oauthDiscovery.ts
7849
- var logger14 = LoggerFactory.create(void 0, void 0, { bitName: "OAuthDiscovery" });
7850
- function resolveEnvExpression(value) {
7851
- if (typeof value !== "string") return value;
7852
- const envPattern = /\{\{habits\.env\.([A-Za-z_][A-Za-z0-9_]*)\}\}/g;
7853
- return value.replace(envPattern, (match, envVar) => {
7854
- return process.env[envVar] || "";
7855
- });
7856
- }
7857
- function extractAuthCredentials(nodeAuth) {
7858
- if (!nodeAuth) return {};
7859
- let clientId = nodeAuth.clientId || nodeAuth.CLIENT_ID || nodeAuth.client_id;
7860
- let clientSecret = nodeAuth.clientSecret || nodeAuth.CLIENT_SECRET || nodeAuth.client_secret;
7861
- if (clientId) clientId = resolveEnvExpression(clientId);
7862
- if (clientSecret) clientSecret = resolveEnvExpression(clientSecret);
7863
- return { clientId, clientSecret };
7864
- }
7865
- function extractBitId(moduleName) {
7866
- const parts = moduleName.split("/");
7867
- return parts[parts.length - 1];
7868
- }
7869
- async function getAuthFromModule(moduleDefinition) {
7870
- const moduleName = getModuleName(moduleDefinition);
7871
- try {
7872
- if (isBundledModule(moduleDefinition.repository)) {
7873
- const loadedModule = getBundledModule(moduleDefinition.repository);
7874
- if (loadedModule) {
7875
- const piece = extractBitsPieceFromModule(loadedModule);
7876
- return { auth: piece.auth, displayName: piece.displayName };
7877
- }
7878
- return null;
7879
- }
7880
- const mainFilePath = getModuleMainFile(moduleDefinition);
7881
- if (!mainFilePath) {
7882
- return null;
7883
- }
7884
- const originalCwd = process.cwd();
7885
- const moduleDir = dirname(mainFilePath);
7886
- let nodeModulesDir = moduleDir;
7887
- while (nodeModulesDir && !nodeModulesDir.endsWith("/node_modules") && nodeModulesDir !== dirname(nodeModulesDir)) {
7888
- nodeModulesDir = dirname(nodeModulesDir);
7889
- }
7890
- try {
7891
- process.chdir(moduleDir);
7892
- const loadedModule = simpleRequire(mainFilePath, nodeModulesDir);
7893
- const piece = extractBitsPieceFromModule(loadedModule);
7894
- process.chdir(originalCwd);
7895
- return { auth: piece.auth, displayName: piece.displayName };
7896
- } catch (error) {
7897
- process.chdir(originalCwd);
7898
- throw error;
7899
- }
7900
- } catch (error) {
7901
- logger14.warn("Failed to load auth from module", { moduleName, error: String(error) });
7902
- return null;
7903
- }
7904
- }
7905
- function isOAuth2(auth) {
7906
- return auth && (auth.type === "OAUTH2" || auth.type === "OAUTH2_PKCE");
7907
- }
7908
- async function discoverOAuthRequirements(workflows) {
7909
- const requirements = [];
7910
- const processedModules = /* @__PURE__ */ new Set();
7911
- for (const [workflowId, workflow] of workflows) {
7912
- for (const node of workflow.nodes) {
7913
- const nodeData = node.data;
7914
- if (nodeData?.framework !== "bits") {
7915
- continue;
7916
- }
7917
- const moduleName = nodeData.module;
7918
- if (!moduleName || processedModules.has(moduleName)) {
7919
- continue;
7920
- }
7921
- processedModules.add(moduleName);
7922
- const moduleDefinition = {
7923
- repository: moduleName,
7924
- source: "npm",
7925
- framework: "bits"
7926
- };
7927
- const moduleAuth = await getAuthFromModule(moduleDefinition);
7928
- if (!moduleAuth || !isOAuth2(moduleAuth.auth)) {
7929
- continue;
7930
- }
7931
- const bitId = extractBitId(moduleName);
7932
- const hasValidToken = oauthTokenStore.hasValidToken(bitId);
7933
- const isExpired = oauthTokenStore.isExpired(bitId);
7934
- let status;
7935
- if (hasValidToken && !isExpired) {
7936
- status = "valid";
7937
- } else if (hasValidToken && isExpired) {
7938
- status = "expired";
7939
- } else {
7940
- status = "needed";
7941
- }
7942
- const nodeAuthCredentials = extractAuthCredentials(nodeData.auth);
7943
- const clientId = nodeAuthCredentials.clientId || moduleAuth.auth.clientId;
7944
- const clientSecret = nodeAuthCredentials.clientSecret || moduleAuth.auth.clientSecret;
7945
- requirements.push({
7946
- bitId,
7947
- moduleName,
7948
- displayName: moduleAuth.displayName,
7949
- config: {
7950
- displayName: moduleAuth.auth.displayName,
7951
- description: moduleAuth.auth.description,
7952
- required: moduleAuth.auth.required,
7953
- authorizationUrl: moduleAuth.auth.authorizationUrl,
7954
- tokenUrl: moduleAuth.auth.tokenUrl,
7955
- clientId,
7956
- clientSecret,
7957
- scopes: moduleAuth.auth.scopes,
7958
- extraAuthParams: moduleAuth.auth.extraAuthParams
7959
- },
7960
- hasValidToken,
7961
- status
7962
- });
7963
- }
7964
- }
7965
- return requirements;
7966
- }
7967
- async function printOAuthRequirements(requirements, getAuthUrl) {
7968
- const neededRequirements = requirements.filter((r) => r.status !== "valid");
7969
- if (neededRequirements.length === 0) {
7970
- logger14.info("All OAuth2 tokens are valid");
7971
- return;
7972
- }
7973
- console.log("\n" + "=".repeat(60));
7974
- console.log("\u{1F510} OAuth2 Authorization Required");
7975
- console.log("=".repeat(60));
7976
- for (const req of neededRequirements) {
7977
- const statusIcon = req.status === "expired" ? "\u26A0\uFE0F (expired)" : "\u274C (missing)";
7978
- console.log(`
7979
- \u{1F4E6} ${req.displayName} ${statusIcon}`);
7980
- console.log(` Module: ${req.moduleName}`);
7981
- console.log(` Scopes: ${req.config.scopes.join(", ")}`);
7982
- const authUrl = await getAuthUrl(req);
7983
- console.log(` \u279C Visit: ${authUrl}`);
7984
- }
7985
- console.log("\n" + "=".repeat(60));
7986
- console.log("Open the URLs above in your browser to authorize access.");
7987
- console.log("After authorization, the tokens will be stored automatically.");
7988
- console.log("=".repeat(60) + "\n");
7989
- }
7990
-
7991
- // packages/cortex/core/src/bits/OAuthFlowManager.ts
7992
- var OAuthFlowManager = class {
7993
- constructor(options) {
7994
- this.pendingFlows = /* @__PURE__ */ new Map();
7995
- this.callbackBaseUrl = options.callbackBaseUrl.replace(/\/$/, "");
7996
- this.logger = options.logger ?? LoggerFactory.create(void 0, void 0, { bitName: "OAuthFlowManager" });
7997
- }
7998
- /**
7999
- * Generate a cryptographically secure random string for PKCE code verifier.
8000
- * RFC 7636 requires 43-128 characters, URL-safe.
8001
- *
8002
- * Uses Web Crypto API for platform compatibility.
8003
- */
8004
- generateCodeVerifier() {
8005
- const randomBytes = new Uint8Array(32);
8006
- if (typeof crypto !== "undefined" && crypto.getRandomValues) {
8007
- crypto.getRandomValues(randomBytes);
8008
- } else {
8009
- for (let i = 0; i < 32; i++) {
8010
- randomBytes[i] = Math.floor(Math.random() * 256);
8011
- }
8012
- }
8013
- return this.base64UrlEncode(randomBytes).slice(0, 43);
8014
- }
8015
- /**
8016
- * Generate code challenge from verifier using SHA256.
8017
- * RFC 7636 S256 method.
8018
- */
8019
- async generateCodeChallenge(codeVerifier) {
8020
- const encoder = new TextEncoder();
8021
- const data = encoder.encode(codeVerifier);
8022
- if (typeof crypto !== "undefined" && crypto.subtle) {
8023
- const hashBuffer = await crypto.subtle.digest("SHA-256", data);
8024
- return this.base64UrlEncode(new Uint8Array(hashBuffer));
8025
- }
8026
- try {
8027
- const nodeCrypto = await import("crypto");
8028
- const hash = nodeCrypto.createHash("sha256").update(codeVerifier).digest();
8029
- return this.base64UrlEncode(new Uint8Array(hash));
8030
- } catch {
8031
- throw new Error("No crypto implementation available for PKCE code challenge");
8032
- }
8033
- }
8034
- /**
8035
- * Generate a random state parameter for CSRF protection.
8036
- */
8037
- generateState() {
8038
- const randomBytes = new Uint8Array(16);
8039
- if (typeof crypto !== "undefined" && crypto.getRandomValues) {
8040
- crypto.getRandomValues(randomBytes);
8041
- } else {
8042
- for (let i = 0; i < 16; i++) {
8043
- randomBytes[i] = Math.floor(Math.random() * 256);
8044
- }
8045
- }
8046
- return Array.from(randomBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
8047
- }
8048
- /**
8049
- * Base64URL encode a Uint8Array (RFC 4648).
8050
- */
8051
- base64UrlEncode(data) {
8052
- let binary = "";
8053
- for (let i = 0; i < data.length; i++) {
8054
- binary += String.fromCharCode(data[i]);
8055
- }
8056
- const base64 = btoa(binary);
8057
- return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
8058
- }
8059
- /**
8060
- * Initiate an OAuth2 flow for a bit.
8061
- *
8062
- * @param bitId - Unique identifier for the bit (e.g., "bit-google-drive")
8063
- * @param config - OAuth2 configuration
8064
- * @returns Authorization URL and flow info
8065
- */
8066
- async initiateFlow(bitId, config) {
8067
- const state = this.generateState();
8068
- const redirectUri = `${this.callbackBaseUrl}/${bitId}/callback`;
8069
- const usePkce = config.pkce !== false;
8070
- const codeVerifier = usePkce ? this.generateCodeVerifier() : void 0;
8071
- const codeChallenge = usePkce && codeVerifier ? await this.generateCodeChallenge(codeVerifier) : void 0;
8072
- const oauthState = {
8073
- codeVerifier,
8074
- codeChallenge,
8075
- state,
8076
- redirectUri,
8077
- bitId,
8078
- createdAt: Date.now(),
8079
- config
8080
- };
8081
- this.pendingFlows.set(state, oauthState);
8082
- this.logger.info("OAuth flow initiated", { bitId, redirectUri, pkce: usePkce });
8083
- const params = new URLSearchParams({
8084
- response_type: "code",
8085
- client_id: config.clientId,
8086
- redirect_uri: redirectUri,
8087
- scope: config.scopes.join(" "),
8088
- state
8089
- });
8090
- if (usePkce && codeChallenge) {
8091
- params.set("code_challenge", codeChallenge);
8092
- params.set("code_challenge_method", "S256");
8093
- }
8094
- if (config.extraAuthParams) {
8095
- for (const [key, value] of Object.entries(config.extraAuthParams)) {
8096
- params.set(key, value);
8097
- }
8098
- }
8099
- const authUrl = `${config.authorizationUrl}?${params.toString()}`;
8100
- return { authUrl, state, redirectUri };
8101
- }
8102
- /**
8103
- * Parse an OAuth callback URL to extract parameters.
8104
- * Supports both query parameters (?code=...) and hash fragments (#access_token=...).
8105
- *
8106
- * @param callbackUrl - Full callback URL received from OAuth provider
8107
- * @returns Parsed callback parameters
8108
- */
8109
- parseCallbackUrl(callbackUrl) {
8110
- const result = {};
8111
- try {
8112
- const url = new URL(callbackUrl);
8113
- const queryParams = url.searchParams;
8114
- if (queryParams.has("code")) {
8115
- result.code = queryParams.get("code") || void 0;
8116
- }
8117
- if (queryParams.has("state")) {
8118
- result.state = queryParams.get("state") || void 0;
8119
- }
8120
- if (queryParams.has("error")) {
8121
- result.error = queryParams.get("error") || void 0;
8122
- result.errorDescription = queryParams.get("error_description") || void 0;
8123
- }
8124
- if (url.hash) {
8125
- const hashParams = new URLSearchParams(url.hash.slice(1));
8126
- if (hashParams.has("access_token")) {
8127
- result.accessToken = hashParams.get("access_token") || void 0;
8128
- result.tokenType = hashParams.get("token_type") || "Bearer";
8129
- const expiresIn = hashParams.get("expires_in");
8130
- if (expiresIn) {
8131
- result.expiresIn = parseInt(expiresIn, 10);
8132
- }
8133
- result.refreshToken = hashParams.get("refresh_token") || void 0;
8134
- }
8135
- if (hashParams.has("state") && !result.state) {
8136
- result.state = hashParams.get("state") || void 0;
8137
- }
8138
- if (hashParams.has("error") && !result.error) {
8139
- result.error = hashParams.get("error") || void 0;
8140
- result.errorDescription = hashParams.get("error_description") || void 0;
8141
- }
8142
- }
8143
- } catch (e) {
8144
- const parts = callbackUrl.split("#");
8145
- if (parts.length > 1) {
8146
- const hashParams = new URLSearchParams(parts[1]);
8147
- result.accessToken = hashParams.get("access_token") || void 0;
8148
- result.tokenType = hashParams.get("token_type") || void 0;
8149
- result.state = hashParams.get("state") || void 0;
8150
- result.error = hashParams.get("error") || void 0;
8151
- result.errorDescription = hashParams.get("error_description") || void 0;
8152
- const expiresIn = hashParams.get("expires_in");
8153
- if (expiresIn) {
8154
- result.expiresIn = parseInt(expiresIn, 10);
8155
- }
8156
- }
8157
- const queryParts = callbackUrl.split("?");
8158
- if (queryParts.length > 1) {
8159
- const queryStr = queryParts[1].split("#")[0];
8160
- const queryParams = new URLSearchParams(queryStr);
8161
- if (!result.code) result.code = queryParams.get("code") || void 0;
8162
- if (!result.state) result.state = queryParams.get("state") || void 0;
8163
- if (!result.error) result.error = queryParams.get("error") || void 0;
8164
- if (!result.errorDescription) result.errorDescription = queryParams.get("error_description") || void 0;
8165
- }
8166
- }
8167
- return result;
8168
- }
8169
- /**
8170
- * Handle a callback URL directly (convenience method combining parse + exchange/handleImplicit).
8171
- *
8172
- * @param callbackUrl - Full callback URL received from OAuth provider
8173
- * @returns Exchange result with bit ID and tokens
8174
- */
8175
- async handleCallback(callbackUrl) {
8176
- const params = this.parseCallbackUrl(callbackUrl);
8177
- if (params.error) {
8178
- throw new Error(`OAuth error: ${params.error}${params.errorDescription ? ` - ${params.errorDescription}` : ""}`);
8179
- }
8180
- if (params.accessToken && params.state) {
8181
- return this.handleImplicitCallback(params);
8182
- }
8183
- if (!params.code || !params.state) {
8184
- throw new Error("Missing code or state parameter in OAuth callback");
8185
- }
8186
- return this.exchangeCode(params.state, params.code);
8187
- }
8188
- /**
8189
- * Handle implicit flow callback (access token directly in callback URL).
8190
- */
8191
- handleImplicitCallback(params) {
8192
- if (!params.state || !params.accessToken) {
8193
- throw new Error("Missing state or access_token for implicit flow");
8194
- }
8195
- const oauthState = this.pendingFlows.get(params.state);
8196
- if (!oauthState) {
8197
- throw new Error("Invalid or expired OAuth state. Please restart the authorization flow.");
8198
- }
8199
- this.pendingFlows.delete(params.state);
8200
- const tokens = {
8201
- accessToken: params.accessToken,
8202
- refreshToken: params.refreshToken,
8203
- tokenType: params.tokenType || "Bearer",
8204
- expiresAt: params.expiresIn ? Date.now() + params.expiresIn * 1e3 : void 0
8205
- };
8206
- oauthTokenStore.setToken(oauthState.bitId, tokens, oauthState.config);
8207
- this.logger.info("OAuth implicit flow completed successfully", { bitId: oauthState.bitId });
8208
- return { bitId: oauthState.bitId, tokens };
8209
- }
8210
- /**
8211
- * Exchange authorization code for tokens.
8212
- *
8213
- * @param state - State parameter from callback
8214
- * @param code - Authorization code from callback
8215
- * @returns Token set or throws error
8216
- */
8217
- async exchangeCode(state, code) {
8218
- const oauthState = this.pendingFlows.get(state);
8219
- if (!oauthState) {
8220
- throw new Error("Invalid or expired OAuth state. Please restart the authorization flow.");
8221
- }
8222
- this.pendingFlows.delete(state);
8223
- const { config, codeVerifier, redirectUri, bitId } = oauthState;
8224
- const params = new URLSearchParams({
8225
- grant_type: "authorization_code",
8226
- code,
8227
- redirect_uri: redirectUri,
8228
- client_id: config.clientId
8229
- });
8230
- if (codeVerifier) {
8231
- params.set("code_verifier", codeVerifier);
8232
- }
8233
- if (config.clientSecret) {
8234
- params.set("client_secret", config.clientSecret);
8235
- }
8236
- this.logger.info("Exchanging authorization code", { bitId });
8237
- const response = await fetch(config.tokenUrl, {
8238
- method: "POST",
8239
- headers: {
8240
- "Content-Type": "application/x-www-form-urlencoded",
8241
- "Accept": "application/json"
8242
- },
8243
- body: params.toString()
8244
- });
8245
- if (!response.ok) {
8246
- const errorText = await response.text();
8247
- this.logger.error("Token exchange failed", { bitId, status: response.status, error: errorText });
8248
- throw new Error(`Token exchange failed: ${response.status} - ${errorText}`);
8249
- }
8250
- const data = await response.json();
8251
- const tokens = {
8252
- accessToken: data.access_token,
8253
- refreshToken: data.refresh_token,
8254
- tokenType: data.token_type || "Bearer",
8255
- expiresAt: data.expires_in ? Date.now() + data.expires_in * 1e3 : void 0,
8256
- scope: data.scope
8257
- };
8258
- oauthTokenStore.setToken(bitId, tokens, config);
8259
- this.logger.info("OAuth flow completed successfully", { bitId });
8260
- return { bitId, tokens };
8261
- }
8262
- /**
8263
- * Get the pending OAuth state for a given state parameter.
8264
- * Useful for validation without consuming the state.
8265
- */
8266
- getPendingFlow(state) {
8267
- return this.pendingFlows.get(state);
8268
- }
8269
- /**
8270
- * Check if a flow is pending for a bit.
8271
- */
8272
- hasPendingFlow(bitId) {
8273
- for (const state of this.pendingFlows.values()) {
8274
- if (state.bitId === bitId) {
8275
- return true;
8276
- }
8277
- }
8278
- return false;
8279
- }
8280
- /**
8281
- * Get pending authorization URL for a bit (if flow already initiated).
8282
- */
8283
- getPendingAuthUrl(bitId) {
8284
- for (const [state, oauthState] of this.pendingFlows.entries()) {
8285
- if (oauthState.bitId === bitId) {
8286
- const { config, codeChallenge, redirectUri } = oauthState;
8287
- const params = new URLSearchParams({
8288
- response_type: "code",
8289
- client_id: config.clientId,
8290
- redirect_uri: redirectUri,
8291
- scope: config.scopes.join(" "),
8292
- state
8293
- });
8294
- if (codeChallenge) {
8295
- params.set("code_challenge", codeChallenge);
8296
- params.set("code_challenge_method", "S256");
8297
- }
8298
- if (config.extraAuthParams) {
8299
- for (const [key, value] of Object.entries(config.extraAuthParams)) {
8300
- params.set(key, value);
8301
- }
8302
- }
8303
- return `${config.authorizationUrl}?${params.toString()}`;
8304
- }
8305
- }
8306
- return null;
8307
- }
8308
- /**
8309
- * Cancel a pending OAuth flow.
8310
- */
8311
- cancelFlow(state) {
8312
- return this.pendingFlows.delete(state);
8313
- }
8314
- /**
8315
- * Cancel all pending flows for a bit.
8316
- */
8317
- cancelFlowsForBit(bitId) {
8318
- let cancelled = 0;
8319
- for (const [state, oauthState] of this.pendingFlows.entries()) {
8320
- if (oauthState.bitId === bitId) {
8321
- this.pendingFlows.delete(state);
8322
- cancelled++;
8323
- }
8324
- }
8325
- return cancelled;
8326
- }
8327
- /**
8328
- * Clean up expired flows (older than 10 minutes).
8329
- */
8330
- cleanupExpiredFlows() {
8331
- const now = Date.now();
8332
- const expirationTime = 10 * 60 * 1e3;
8333
- let cleaned = 0;
8334
- for (const [state, oauthState] of this.pendingFlows.entries()) {
8335
- if (now - oauthState.createdAt > expirationTime) {
8336
- this.pendingFlows.delete(state);
8337
- this.logger.debug("Expired OAuth flow cleaned up", { bitId: oauthState.bitId });
8338
- cleaned++;
8339
- }
8340
- }
8341
- return cleaned;
8342
- }
8343
- /**
8344
- * Get all pending flow states (for debugging/status).
8345
- */
8346
- getPendingFlowStates() {
8347
- return Array.from(this.pendingFlows.entries()).map(([state, oauthState]) => ({
8348
- bitId: oauthState.bitId,
8349
- state,
8350
- createdAt: oauthState.createdAt,
8351
- redirectUri: oauthState.redirectUri
8352
- }));
8353
- }
8354
- };
8355
-
8356
- // packages/core/src/types.ts
8357
- function isFrontendWorkflow(workflow) {
8358
- return "nodes" in workflow && "edges" in workflow && Array.isArray(workflow.nodes) && Array.isArray(workflow.edges);
8359
- }
8360
6895
  export {
8361
6896
  AuthenticationType,
8362
6897
  BitAuth,
8363
6898
  BitCategory,
8364
6899
  HabitsExecutor,
8365
6900
  HttpMethod,
8366
- LoggerFactory,
8367
- OAuthFlowManager,
8368
6901
  PieceAuth,
8369
6902
  PieceCategory,
8370
- PollingStore,
8371
6903
  Property,
8372
6904
  StoreScope,
8373
6905
  TriggerHookType,
@@ -8382,29 +6914,20 @@ export {
8382
6914
  createBitTrigger,
8383
6915
  createCustomApiCallAction,
8384
6916
  createPiece,
8385
- createPollingStore,
8386
6917
  createTrigger,
8387
6918
  customRequire,
8388
- discoverOAuthRequirements,
8389
6919
  ensureModuleInstalled,
8390
6920
  executeActivepiecesModule,
8391
6921
  executeBitsModule,
8392
6922
  executeN8nModule,
8393
6923
  executeScriptModule,
8394
- extractBitsPieceFromModule,
8395
- getBundledModule,
8396
6924
  getLocalModulePath,
8397
6925
  getModuleFullPath,
8398
6926
  getNodesBasePath,
8399
6927
  getNodesPath,
8400
6928
  getSecurityConfig,
8401
6929
  httpClient,
8402
- isBundledModule,
8403
6930
  isFrontendWorkflow,
8404
- oauthTokenStore,
8405
- pieceFromModule2 as pieceFromModule,
8406
- printOAuthRequirements,
8407
- registerBundledModule,
8408
6931
  registerCortexModule,
8409
6932
  scanInputForSecurity,
8410
6933
  triggerHelper