@kadoa/mcp 0.4.2-rc.1 → 0.4.3-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +450 -305
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -43925,6 +43925,90 @@ var init_dist_node = __esm(() => {
43925
43925
  // node_modules/@kadoa/node-sdk/dist/index.mjs
43926
43926
  import { URL as URL$1, URLSearchParams } from "url";
43927
43927
  import assert2 from "assert";
43928
+ function mapChange(raw) {
43929
+ return {
43930
+ id: raw.id,
43931
+ workflowId: raw.workflowId,
43932
+ data: raw.data,
43933
+ differences: coalesceDifferences(raw.differences),
43934
+ url: raw.url,
43935
+ summary: raw.summary,
43936
+ screenshotUrl: raw.screenshotUrl,
43937
+ createdAt: raw.createdAt
43938
+ };
43939
+ }
43940
+ function coalesceDifferences(raw) {
43941
+ if (!raw)
43942
+ return;
43943
+ const addedByRow = /* @__PURE__ */ new Map;
43944
+ const removedByRow = /* @__PURE__ */ new Map;
43945
+ const passthrough = [];
43946
+ for (const diff of raw) {
43947
+ if (diff.type === "added" && diff.rowRef?.currentRowId) {
43948
+ addedByRow.set(diff.rowRef.currentRowId, diff);
43949
+ } else if (diff.type === "removed" && diff.rowRef?.previousRowId) {
43950
+ removedByRow.set(diff.rowRef.previousRowId, diff);
43951
+ } else {
43952
+ passthrough.push(diff);
43953
+ }
43954
+ }
43955
+ const result = [];
43956
+ for (const [rowId, added] of addedByRow) {
43957
+ const removed = removedByRow.get(rowId);
43958
+ if (removed) {
43959
+ removedByRow.delete(rowId);
43960
+ result.push(mergeAddedRemoved(added, removed));
43961
+ } else {
43962
+ result.push(mapDifference(added));
43963
+ }
43964
+ }
43965
+ for (const removed of removedByRow.values()) {
43966
+ result.push(mapDifference(removed));
43967
+ }
43968
+ for (const diff of passthrough) {
43969
+ result.push(mapDifference(diff));
43970
+ }
43971
+ return result;
43972
+ }
43973
+ function mergeAddedRemoved(added, removed) {
43974
+ const previousByKey = /* @__PURE__ */ new Map;
43975
+ for (const f of removed.fields ?? []) {
43976
+ if (f.key !== undefined)
43977
+ previousByKey.set(f.key, f.value);
43978
+ }
43979
+ const fields = (added.fields ?? []).map((f) => ({
43980
+ key: f.key,
43981
+ value: f.value,
43982
+ previousValue: f.key !== undefined ? previousByKey.get(f.key) : undefined
43983
+ }));
43984
+ const addedKeys = new Set((added.fields ?? []).map((f) => f.key));
43985
+ for (const f of removed.fields ?? []) {
43986
+ if (!addedKeys.has(f.key)) {
43987
+ fields.push({ key: f.key, value: undefined, previousValue: f.value });
43988
+ }
43989
+ }
43990
+ return { type: ChangeDifferenceType.Changed, fields };
43991
+ }
43992
+ function mapDifference(raw) {
43993
+ return {
43994
+ type: raw.type,
43995
+ fields: raw.fields?.map(mapField)
43996
+ };
43997
+ }
43998
+ function mapField(raw) {
43999
+ return {
44000
+ key: raw.key,
44001
+ value: raw.value,
44002
+ previousValue: raw.previousValue
44003
+ };
44004
+ }
44005
+ function mapListChangesResponse(raw) {
44006
+ return {
44007
+ changes: (raw.changes ?? []).map(mapChange),
44008
+ pagination: raw.pagination,
44009
+ changesCount: raw.changesCount ?? 0
44010
+ };
44011
+ }
43928
44012
  function setFlattenedQueryParams(urlSearchParams, parameter, key = "") {
43929
44013
  if (parameter == null)
43930
44014
  return;
@@ -44105,6 +44189,7 @@ function createAxiosInstance(params) {
44105
44189
  }
44106
44190
  function createClientDomains(params) {
44107
44191
  const { client } = params;
44192
+ const changesService = new ChangesService(client);
44108
44193
  const userService = new UserService(client);
44109
44194
  const dataFetcherService = new DataFetcherService(client.apis.workflows);
44110
44195
  const channelsService = new NotificationChannelsService(client.apis.notifications, userService);
@@ -44128,6 +44213,7 @@ function createClientDomains(params) {
44128
44213
  const validation = createValidationDomain(coreService, rulesService);
44129
44214
  const crawler = createCrawlerDomain(client);
44130
44215
  return {
44216
+ changes: changesService,
44131
44217
  extractionBuilderService,
44132
44218
  extraction: extractionService,
44133
44219
  workflow: workflowsCoreService,
@@ -44177,7 +44263,31 @@ function createNotificationDomain(params) {
44177
44263
  }
44178
44264
  };
44179
44265
  }
44180
- var import_debug, __require2, BASE_PATH, BaseAPI = class {
44266
+ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkException, KadoaSdkException, ERROR_MESSAGES, KadoaHttpException, createLogger = (namespace) => import_debug.default(`kadoa:${namespace}`), logger, debug, ChangesService = class {
44267
+ constructor(client) {
44268
+ this.client = client;
44269
+ }
44270
+ get workflowsApi() {
44271
+ return this.client.apis.workflows;
44272
+ }
44273
+ async list(options) {
44274
+ debug("list changes %o", options);
44275
+ const response = await this.workflowsApi.v4ChangesGet(options ?? {});
44276
+ return mapListChangesResponse(response.data);
44277
+ }
44278
+ async get(changeId) {
44279
+ debug("get change %s", changeId);
44280
+ const response = await this.workflowsApi.v4ChangesChangeIdGet({ changeId });
44281
+ const change = response.data;
44282
+ if (!change) {
44283
+ throw new KadoaSdkException(`Change not found: ${changeId}`, {
44284
+ code: KadoaErrorCode.NOT_FOUND,
44285
+ details: { changeId }
44286
+ });
44287
+ }
44288
+ return mapChange(change);
44289
+ }
44290
+ }, BASE_PATH, BaseAPI = class {
44181
44291
  constructor(configuration, basePath = BASE_PATH, axios2 = axios_default) {
44182
44292
  this.basePath = basePath;
44183
44293
  this.axios = axios2;
@@ -47261,7 +47371,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
47261
47371
  yield page;
47262
47372
  }
47263
47373
  }
47264
- }, KadoaErrorCode, _KadoaSdkException, KadoaSdkException, ERROR_MESSAGES, KadoaHttpException, createLogger = (namespace) => import_debug.default(`kadoa:${namespace}`), logger, _SchemaBuilder = class _SchemaBuilder2 {
47374
+ }, _SchemaBuilder = class _SchemaBuilder2 {
47265
47375
  constructor() {
47266
47376
  this.fields = [];
47267
47377
  }
@@ -47341,7 +47451,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
47341
47451
  });
47342
47452
  }
47343
47453
  }
47344
- }, SchemaBuilder, debug, SchemasService = class {
47454
+ }, SchemaBuilder, debug2, SchemasService = class {
47345
47455
  constructor(client) {
47346
47456
  this.client = client;
47347
47457
  }
@@ -47376,7 +47486,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
47376
47486
  };
47377
47487
  }
47378
47488
  async getSchema(schemaId) {
47379
- debug("Fetching schema with ID: %s", schemaId);
47489
+ debug2("Fetching schema with ID: %s", schemaId);
47380
47490
  const response = await this.schemasApi.v4SchemasSchemaIdGet({
47381
47491
  schemaId
47382
47492
  });
@@ -47394,7 +47504,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
47394
47504
  return response.data.data;
47395
47505
  }
47396
47506
  async createSchema(body) {
47397
- debug("Creating schema with name: %s", body.name);
47507
+ debug2("Creating schema with name: %s", body.name);
47398
47508
  const response = await this.schemasApi.v4SchemasPost({
47399
47509
  createSchemaBody: body
47400
47510
  });
@@ -47407,7 +47517,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
47407
47517
  return this.getSchema(schemaId);
47408
47518
  }
47409
47519
  async updateSchema(schemaId, body) {
47410
- debug("Updating schema with ID: %s", schemaId);
47520
+ debug2("Updating schema with ID: %s", schemaId);
47411
47521
  await this.schemasApi.v4SchemasSchemaIdPut({
47412
47522
  schemaId,
47413
47523
  updateSchemaBody: body
@@ -47415,7 +47525,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
47415
47525
  return this.getSchema(schemaId);
47416
47526
  }
47417
47527
  async deleteSchema(schemaId) {
47418
- debug("Deleting schema with ID: %s", schemaId);
47528
+ debug2("Deleting schema with ID: %s", schemaId);
47419
47529
  await this.schemasApi.v4SchemasSchemaIdDelete({
47420
47530
  schemaId
47421
47531
  });
@@ -47497,7 +47607,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
47497
47607
  });
47498
47608
  }
47499
47609
  }
47500
- }, debug2, SUCCESSFUL_RUN_STATES, DEFAULT_OPTIONS, ExtractionService = class {
47610
+ }, debug3, SUCCESSFUL_RUN_STATES, DEFAULT_OPTIONS, ExtractionService = class {
47501
47611
  constructor(workflowsCoreService, dataFetcherService, entityResolverService, notificationSetupService, notificationChannelsService, notificationSettingsService) {
47502
47612
  this.workflowsCoreService = workflowsCoreService;
47503
47613
  this.dataFetcherService = dataFetcherService;
@@ -47585,7 +47695,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
47585
47695
  events: config2.notifications?.events,
47586
47696
  channels: config2.notifications?.channels
47587
47697
  });
47588
- debug2("Notifications setup: %O", result2.map((r) => ({ id: r.id, eventType: r.eventType })));
47698
+ debug3("Notifications setup: %O", result2.map((r) => ({ id: r.id, eventType: r.eventType })));
47589
47699
  }
47590
47700
  if (config2.mode === "submit") {
47591
47701
  return {
@@ -47660,7 +47770,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
47660
47770
  isExtractionSuccessful(runState) {
47661
47771
  return runState ? SUCCESSFUL_RUN_STATES.has(runState.toUpperCase()) : false;
47662
47772
  }
47663
- }, debug3, ExtractionBuilderService = class {
47773
+ }, debug4, ExtractionBuilderService = class {
47664
47774
  constructor(workflowsCoreService, entityResolverService, dataFetcherService, notificationSetupService) {
47665
47775
  this.workflowsCoreService = workflowsCoreService;
47666
47776
  this.entityResolverService = entityResolverService;
@@ -47844,10 +47954,10 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
47844
47954
  }
47845
47955
  const startedJob = await this.workflowsCoreService.runWorkflow(this._workflowId, { variables: options?.variables, limit: options?.limit });
47846
47956
  assert2(startedJob.jobId, "Job ID is not set");
47847
- debug3("Job started: %O", startedJob);
47957
+ debug4("Job started: %O", startedJob);
47848
47958
  this._jobId = startedJob.jobId;
47849
47959
  const finishedJob = await this.workflowsCoreService.waitForJobCompletion(this._workflowId, startedJob.jobId);
47850
- debug3("Job finished: %O", finishedJob);
47960
+ debug4("Job finished: %O", finishedJob);
47851
47961
  return this;
47852
47962
  }
47853
47963
  async submit(options) {
@@ -47864,7 +47974,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
47864
47974
  }
47865
47975
  const submittedJob = await this.workflowsCoreService.runWorkflow(this._workflowId, { variables: options?.variables, limit: options?.limit });
47866
47976
  assert2(submittedJob.jobId, "Job ID is not set");
47867
- debug3("Job submitted: %O", submittedJob);
47977
+ debug4("Job submitted: %O", submittedJob);
47868
47978
  this._jobId = submittedJob.jobId;
47869
47979
  return {
47870
47980
  workflowId: this._workflowId,
@@ -48048,7 +48158,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48048
48158
  });
48049
48159
  }
48050
48160
  }
48051
- }, debug4, NotificationSetupService = class {
48161
+ }, debug5, NotificationSetupService = class {
48052
48162
  constructor(channelsService, settingsService) {
48053
48163
  this.channelsService = channelsService;
48054
48164
  this.settingsService = settingsService;
@@ -48073,7 +48183,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48073
48183
  });
48074
48184
  }
48075
48185
  async setup(requestData) {
48076
- requestData.workflowId ? debug4("Setting up notifications for workflow %s", requestData.workflowId) : debug4("Setting up notifications for workspace");
48186
+ requestData.workflowId ? debug5("Setting up notifications for workflow %s", requestData.workflowId) : debug5("Setting up notifications for workspace");
48077
48187
  const channels = await this.setupChannels({
48078
48188
  workflowId: requestData.workflowId,
48079
48189
  channels: requestData.channels || {}
@@ -48081,7 +48191,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48081
48191
  const events = requestData.events || "all";
48082
48192
  const eventTypes = events === "all" ? await this.settingsService.listAllEvents() : events;
48083
48193
  const channelIds = channels.map((channel) => channel.id).filter(Boolean);
48084
- debug4("Creating notification settings for workflow %s: %O", requestData.workflowId, {
48194
+ debug5("Creating notification settings for workflow %s: %O", requestData.workflowId, {
48085
48195
  events: eventTypes,
48086
48196
  channels: channelIds
48087
48197
  });
@@ -48108,7 +48218,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48108
48218
  eventConfiguration: {}
48109
48219
  });
48110
48220
  }));
48111
- debug4(requestData.workflowId ? "Successfully setup notifications for workflow %s" : "Successfully setup notifications for workspace", requestData.workflowId);
48221
+ debug5(requestData.workflowId ? "Successfully setup notifications for workflow %s" : "Successfully setup notifications for workspace", requestData.workflowId);
48112
48222
  return newSettings;
48113
48223
  }
48114
48224
  async setupChannels(requestData) {
@@ -48165,7 +48275,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48165
48275
  const channels = await Promise.all(channelsByName.map(async ([channelType]) => {
48166
48276
  const existingChannel = channelType === NotificationChannelType.WEBSOCKET ? existingChannels.find((channel2) => channel2.channelType === channelType) : existingChannels.find((channel2) => channel2.channelType === channelType && channel2.name === NotificationChannelsService.DEFAULT_CHANNEL_NAME);
48167
48277
  if (existingChannel) {
48168
- debug4("Using existing default channel: %O", {
48278
+ debug5("Using existing default channel: %O", {
48169
48279
  workflowId,
48170
48280
  channelType,
48171
48281
  channelId: existingChannel.id
@@ -48173,7 +48283,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48173
48283
  return existingChannel;
48174
48284
  }
48175
48285
  const channel = await this.channelsService.createChannel(channelType);
48176
- debug4("Created default channel %O", {
48286
+ debug5("Created default channel %O", {
48177
48287
  workflowId,
48178
48288
  channelType,
48179
48289
  channel
@@ -48194,7 +48304,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48194
48304
  const channelName = config2.name || NotificationChannelsService.DEFAULT_CHANNEL_NAME;
48195
48305
  const existingChannel = existingChannels.find((channel2) => channel2.channelType === channelType && (channel2.name || NotificationChannelsService.DEFAULT_CHANNEL_NAME) === channelName);
48196
48306
  if (existingChannel) {
48197
- debug4("Using existing channel: %O", {
48307
+ debug5("Using existing channel: %O", {
48198
48308
  workflowId,
48199
48309
  channelType,
48200
48310
  channelName,
@@ -48207,7 +48317,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48207
48317
  name: channelName,
48208
48318
  config: channelConfig
48209
48319
  });
48210
- debug4("Created channel with custom config %O", {
48320
+ debug5("Created channel with custom config %O", {
48211
48321
  workflowId,
48212
48322
  channelType,
48213
48323
  channelName,
@@ -48217,7 +48327,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48217
48327
  }));
48218
48328
  return channels;
48219
48329
  }
48220
- }, PUBLIC_API_URI, WSS_API_URI, REALTIME_API_URI, SDK_VERSION = "0.26.0", SDK_NAME = "kadoa-node-sdk", SDK_LANGUAGE = "node", debug5, isDrainControlMessage = (message) => message.type === "control.draining", isRealtimeEvent = (message) => message.type !== "heartbeat" && message.type !== "control.draining", _Realtime = class _Realtime2 {
48330
+ }, PUBLIC_API_URI, WSS_API_URI, REALTIME_API_URI, SDK_VERSION = "0.27.0", SDK_NAME = "kadoa-node-sdk", SDK_LANGUAGE = "node", debug6, isDrainControlMessage = (message) => message.type === "control.draining", isRealtimeEvent = (message) => message.type !== "heartbeat" && message.type !== "control.draining", _Realtime = class _Realtime2 {
48221
48331
  constructor(config2) {
48222
48332
  this.drainingSockets = /* @__PURE__ */ new Set;
48223
48333
  this.lastHeartbeat = Date.now();
@@ -48245,7 +48355,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48245
48355
  await this.openSocket(access_token, team_id, "active");
48246
48356
  this.hasConnectedOnce = true;
48247
48357
  } catch (err) {
48248
- debug5("Failed to connect: %O", err);
48358
+ debug6("Failed to connect: %O", err);
48249
48359
  this.isConnecting = false;
48250
48360
  this.notifyErrorListeners(err);
48251
48361
  if (!this.hasConnectedOnce) {
@@ -48282,7 +48392,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48282
48392
  this.isConnecting = false;
48283
48393
  this.lastHeartbeat = Date.now();
48284
48394
  this.startHeartbeatCheck();
48285
- debug5("Connected to WebSocket");
48395
+ debug6("Connected to WebSocket");
48286
48396
  if (!settled) {
48287
48397
  settled = true;
48288
48398
  resolve();
@@ -48347,7 +48457,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48347
48457
  headers: { "Content-Type": "application/json" },
48348
48458
  body: JSON.stringify({ id: data.id })
48349
48459
  }).catch((error48) => {
48350
- debug5("Failed to acknowledge event %s: %O", data.id, error48);
48460
+ debug6("Failed to acknowledge event %s: %O", data.id, error48);
48351
48461
  });
48352
48462
  }
48353
48463
  if (this.isDuplicateEvent(data.id)) {
@@ -48355,14 +48465,14 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48355
48465
  }
48356
48466
  this.notifyEventListeners(data);
48357
48467
  } catch (err) {
48358
- debug5("Failed to parse incoming message: %O", err);
48468
+ debug6("Failed to parse incoming message: %O", err);
48359
48469
  }
48360
48470
  }
48361
48471
  handleDrainSignal(socket, message) {
48362
48472
  if (socket !== this.activeSocket || this.isClosed) {
48363
48473
  return;
48364
48474
  }
48365
- debug5("Received drain signal, preparing replacement socket");
48475
+ debug6("Received drain signal, preparing replacement socket");
48366
48476
  this.drainingSockets.add(socket);
48367
48477
  this.scheduleDrainReconnect(message.retryAfterMs);
48368
48478
  }
@@ -48378,7 +48488,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48378
48488
  return;
48379
48489
  }
48380
48490
  if (this.drainingSockets.size > 0) {
48381
- debug5("Draining socket closed after replacement was scheduled");
48491
+ debug6("Draining socket closed after replacement was scheduled");
48382
48492
  return;
48383
48493
  }
48384
48494
  this.handleUnexpectedDisconnect("Connection closed");
@@ -48402,7 +48512,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48402
48512
  const { access_token, team_id } = await this.getOAuthToken();
48403
48513
  await this.openSocket(access_token, team_id, replacement ? "replacement" : "active");
48404
48514
  } catch (err) {
48405
- debug5("Reconnect failed: %O", err);
48515
+ debug6("Reconnect failed: %O", err);
48406
48516
  this.isConnecting = false;
48407
48517
  this.notifyErrorListeners(err);
48408
48518
  this.scheduleReconnect(replacement);
@@ -48427,7 +48537,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48427
48537
  const { access_token, team_id } = await this.getOAuthToken();
48428
48538
  await this.openSocket(access_token, team_id, "replacement");
48429
48539
  } catch (err) {
48430
- debug5("Reconnect failed: %O", err);
48540
+ debug6("Reconnect failed: %O", err);
48431
48541
  this.isConnecting = false;
48432
48542
  this.notifyErrorListeners(err);
48433
48543
  this.scheduleReconnect(true);
@@ -48458,7 +48568,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48458
48568
  return false;
48459
48569
  }
48460
48570
  handleHeartbeat() {
48461
- debug5("Heartbeat received");
48571
+ debug6("Heartbeat received");
48462
48572
  this.lastHeartbeat = Date.now();
48463
48573
  }
48464
48574
  notifyEventListeners(event) {
@@ -48466,7 +48576,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48466
48576
  try {
48467
48577
  listener(event);
48468
48578
  } catch (error48) {
48469
- debug5("Error in event listener: %O", error48);
48579
+ debug6("Error in event listener: %O", error48);
48470
48580
  }
48471
48581
  });
48472
48582
  }
@@ -48475,7 +48585,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48475
48585
  try {
48476
48586
  listener(connected, reason);
48477
48587
  } catch (error48) {
48478
- debug5("Error in connection listener: %O", error48);
48588
+ debug6("Error in connection listener: %O", error48);
48479
48589
  }
48480
48590
  });
48481
48591
  }
@@ -48484,7 +48594,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48484
48594
  try {
48485
48595
  listener(error48);
48486
48596
  } catch (listenerError) {
48487
- debug5("Error in error listener: %O", listenerError);
48597
+ debug6("Error in error listener: %O", listenerError);
48488
48598
  }
48489
48599
  });
48490
48600
  }
@@ -48492,7 +48602,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48492
48602
  this.stopHeartbeatCheck();
48493
48603
  this.missedHeartbeatCheckTimer = setInterval(() => {
48494
48604
  if (this.activeSocket && Date.now() - this.lastHeartbeat > this.missedHeartbeatsLimit) {
48495
- debug5("No heartbeat received in 30 seconds! Closing connection.");
48605
+ debug6("No heartbeat received in 30 seconds! Closing connection.");
48496
48606
  this.activeSocket.close();
48497
48607
  }
48498
48608
  }, this.heartbeatInterval);
@@ -48545,7 +48655,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48545
48655
  isConnected() {
48546
48656
  return this.activeSocket?.readyState === WebSocket.OPEN;
48547
48657
  }
48548
- }, Realtime, debug6, TemplatesService = class {
48658
+ }, Realtime, debug7, TemplatesService = class {
48549
48659
  constructor(client) {
48550
48660
  this.client = client;
48551
48661
  }
@@ -48553,12 +48663,12 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48553
48663
  return this.client.apis.templates;
48554
48664
  }
48555
48665
  async list() {
48556
- debug6("Listing all templates");
48666
+ debug7("Listing all templates");
48557
48667
  const response = await this.templatesApi.v4TemplatesGet();
48558
48668
  return response.data.data ?? [];
48559
48669
  }
48560
48670
  async get(templateId) {
48561
- debug6("Fetching template with ID: %s", templateId);
48671
+ debug7("Fetching template with ID: %s", templateId);
48562
48672
  const response = await this.templatesApi.v4TemplatesTemplateIdGet({
48563
48673
  templateId
48564
48674
  });
@@ -48572,7 +48682,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48572
48682
  return template;
48573
48683
  }
48574
48684
  async create(body) {
48575
- debug6("Creating template with name: %s", body.name);
48685
+ debug7("Creating template with name: %s", body.name);
48576
48686
  const response = await this.templatesApi.v4TemplatesPost({
48577
48687
  createTemplateBody: body
48578
48688
  });
@@ -48585,7 +48695,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48585
48695
  return template;
48586
48696
  }
48587
48697
  async update(templateId, body) {
48588
- debug6("Updating template with ID: %s", templateId);
48698
+ debug7("Updating template with ID: %s", templateId);
48589
48699
  const response = await this.templatesApi.v4TemplatesTemplateIdPut({
48590
48700
  templateId,
48591
48701
  updateTemplateBody: body
@@ -48600,13 +48710,13 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48600
48710
  return template;
48601
48711
  }
48602
48712
  async delete(templateId) {
48603
- debug6("Deleting template with ID: %s", templateId);
48713
+ debug7("Deleting template with ID: %s", templateId);
48604
48714
  await this.templatesApi.v4TemplatesTemplateIdDelete({
48605
48715
  templateId
48606
48716
  });
48607
48717
  }
48608
48718
  async createVersion(templateId, body) {
48609
- debug6("Creating version for template: %s", templateId);
48719
+ debug7("Creating version for template: %s", templateId);
48610
48720
  const response = await this.templatesApi.v4TemplatesTemplateIdVersionsPost({
48611
48721
  templateId,
48612
48722
  createTemplateVersionBody: body
@@ -48621,21 +48731,21 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48621
48731
  return version2;
48622
48732
  }
48623
48733
  async listSchemas(templateId) {
48624
- debug6("Listing schemas for template: %s", templateId);
48734
+ debug7("Listing schemas for template: %s", templateId);
48625
48735
  const response = await this.templatesApi.v4TemplatesTemplateIdSchemasGet({
48626
48736
  templateId
48627
48737
  });
48628
48738
  return response.data.data ?? [];
48629
48739
  }
48630
48740
  async listWorkflows(templateId) {
48631
- debug6("Listing workflows for template: %s", templateId);
48741
+ debug7("Listing workflows for template: %s", templateId);
48632
48742
  const response = await this.templatesApi.v4TemplatesTemplateIdWorkflowsGet({
48633
48743
  templateId
48634
48744
  });
48635
48745
  return response.data.data ?? [];
48636
48746
  }
48637
48747
  async linkWorkflows(templateId, body) {
48638
- debug6("Linking %d workflows to template: %s", body.workflowIds.length, templateId);
48748
+ debug7("Linking %d workflows to template: %s", body.workflowIds.length, templateId);
48639
48749
  const response = await this.templatesApi.v4TemplatesTemplateIdLinkPost({
48640
48750
  templateId,
48641
48751
  linkWorkflowsBody: body
@@ -48643,7 +48753,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48643
48753
  return response.data;
48644
48754
  }
48645
48755
  async unlinkWorkflows(templateId, body) {
48646
- debug6("Unlinking %d workflows from template: %s", body.workflowIds.length, templateId);
48756
+ debug7("Unlinking %d workflows from template: %s", body.workflowIds.length, templateId);
48647
48757
  const response = await this.templatesApi.v4TemplatesTemplateIdUnlinkPost({
48648
48758
  templateId,
48649
48759
  unlinkWorkflowsBody: body
@@ -48651,7 +48761,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48651
48761
  return response.data;
48652
48762
  }
48653
48763
  async applyUpdate(templateId, body) {
48654
- debug6("Applying version %d to %d workflows for template: %s", body.targetVersion, body.workflowIds.length, templateId);
48764
+ debug7("Applying version %d to %d workflows for template: %s", body.targetVersion, body.workflowIds.length, templateId);
48655
48765
  const response = await this.templatesApi.v4TemplatesTemplateIdApplyPost({
48656
48766
  templateId,
48657
48767
  applyTemplateUpdateBody: body
@@ -48659,7 +48769,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48659
48769
  return response.data;
48660
48770
  }
48661
48771
  async createFromWorkflow(body) {
48662
- debug6("Creating template from workflow: %s", body.workflowId);
48772
+ debug7("Creating template from workflow: %s", body.workflowId);
48663
48773
  const response = await this.templatesApi.v4TemplatesFromWorkflowPost({
48664
48774
  saveFromWorkflowBody: body
48665
48775
  });
@@ -48917,7 +49027,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48917
49027
  }
48918
49028
  return response.data.data;
48919
49029
  }
48920
- }, debug7, VariablesService = class {
49030
+ }, debug8, VariablesService = class {
48921
49031
  constructor(client) {
48922
49032
  this.client = client;
48923
49033
  }
@@ -48929,7 +49039,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48929
49039
  return response.data.variables ?? [];
48930
49040
  }
48931
49041
  async get(variableId) {
48932
- debug7("Fetching variable with ID: %s", variableId);
49042
+ debug8("Fetching variable with ID: %s", variableId);
48933
49043
  const response = await this.variablesApi.v4VariablesVariableIdGet({
48934
49044
  variableId
48935
49045
  });
@@ -48943,7 +49053,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48943
49053
  return variable;
48944
49054
  }
48945
49055
  async create(body) {
48946
- debug7("Creating variable with key: %s", body.key);
49056
+ debug8("Creating variable with key: %s", body.key);
48947
49057
  const response = await this.variablesApi.v4VariablesPost({
48948
49058
  createVariableBody: body
48949
49059
  });
@@ -48956,7 +49066,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48956
49066
  return variable;
48957
49067
  }
48958
49068
  async update(variableId, body) {
48959
- debug7("Updating variable with ID: %s", variableId);
49069
+ debug8("Updating variable with ID: %s", variableId);
48960
49070
  const response = await this.variablesApi.v4VariablesVariableIdPatch({
48961
49071
  variableId,
48962
49072
  updateVariableBody: body
@@ -48971,12 +49081,12 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
48971
49081
  return variable;
48972
49082
  }
48973
49083
  async delete(variableId) {
48974
- debug7("Deleting variable with ID: %s", variableId);
49084
+ debug8("Deleting variable with ID: %s", variableId);
48975
49085
  await this.variablesApi.v4VariablesVariableIdDelete({
48976
49086
  variableId
48977
49087
  });
48978
49088
  }
48979
- }, JobStateEnum, TERMINAL_JOB_STATES, TERMINAL_RUN_STATES, debug8, WorkflowsCoreService = class {
49089
+ }, JobStateEnum, TERMINAL_JOB_STATES, TERMINAL_RUN_STATES, debug9, WorkflowsCoreService = class {
48980
49090
  constructor(workflowsApi) {
48981
49091
  this.workflowsApi = workflowsApi;
48982
49092
  }
@@ -49092,7 +49202,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
49092
49202
  async wait(id, options) {
49093
49203
  const result = await pollUntil(async () => {
49094
49204
  const current = await this.get(id);
49095
- debug8("workflow %s state: %s", id, current.runState);
49205
+ debug9("workflow %s state: %s", id, current.runState);
49096
49206
  return current;
49097
49207
  }, (current) => {
49098
49208
  if (options?.targetState && current.state === options.targetState) {
@@ -49138,7 +49248,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
49138
49248
  async waitForJobCompletion(workflowId, jobId, options) {
49139
49249
  const result = await pollUntil(async () => {
49140
49250
  const current = await this.getJobStatus(workflowId, jobId);
49141
- debug8("workflow run %s state: %s", jobId, current.state);
49251
+ debug9("workflow run %s state: %s", jobId, current.state);
49142
49252
  return current;
49143
49253
  }, (current) => {
49144
49254
  if (options?.targetStatus && current.state === options.targetStatus) {
@@ -49211,6 +49321,7 @@ var import_debug, __require2, BASE_PATH, BaseAPI = class {
49211
49321
  });
49212
49322
  this.apis = new ApiRegistry(this._apiKey, this._baseUrl, this._axiosInstance, headers);
49213
49323
  const domains = createClientDomains({ client: this });
49324
+ this.changes = domains.changes;
49214
49325
  this.user = domains.user;
49215
49326
  this.extraction = domains.extraction;
49216
49327
  this.workflow = domains.workflow;
@@ -49300,6 +49411,222 @@ var init_dist2 = __esm(() => {
49300
49411
  return __require.apply(this, arguments);
49301
49412
  throw Error('Dynamic require of "' + x + '" is not supported');
49302
49413
  });
49414
+ ChangeDifferenceType = {
49415
+ Added: "added",
49416
+ Removed: "removed",
49417
+ Changed: "changed"
49418
+ };
49419
+ KadoaErrorCode = {
49420
+ VALIDATION_ERROR: "VALIDATION_ERROR",
49421
+ BAD_REQUEST: "BAD_REQUEST",
49422
+ NOT_FOUND: "NOT_FOUND",
49423
+ INTERNAL_ERROR: "INTERNAL_ERROR"
49424
+ };
49425
+ _KadoaSdkException = class _KadoaSdkException2 extends Error {
49426
+ constructor(message, options) {
49427
+ super(message);
49428
+ this.name = "KadoaSdkException";
49429
+ this.code = options?.code ?? "UNKNOWN";
49430
+ this.details = options?.details;
49431
+ if (options && "cause" in options)
49432
+ this.cause = options.cause;
49433
+ Error.captureStackTrace?.(this, _KadoaSdkException2);
49434
+ }
49435
+ static from(error48, details) {
49436
+ if (error48 instanceof _KadoaSdkException2)
49437
+ return error48;
49438
+ const message = error48 instanceof Error ? error48.message : typeof error48 === "string" ? error48 : "Unexpected error";
49439
+ return new _KadoaSdkException2(message, {
49440
+ code: "UNKNOWN",
49441
+ details,
49442
+ cause: error48
49443
+ });
49444
+ }
49445
+ toJSON() {
49446
+ return {
49447
+ name: this.name,
49448
+ message: this.message,
49449
+ code: this.code,
49450
+ details: this.details
49451
+ };
49452
+ }
49453
+ toString() {
49454
+ return [this.name, this.code, this.message].filter(Boolean).join(": ");
49455
+ }
49456
+ toDetailedString() {
49457
+ const parts = [`${this.name}: ${this.message}`, `Code: ${this.code}`];
49458
+ if (this.details && Object.keys(this.details).length > 0) {
49459
+ parts.push(`Details: ${JSON.stringify(this.details, null, 2)}`);
49460
+ }
49461
+ if (this.cause) {
49462
+ parts.push(`Cause: ${this.cause}`);
49463
+ }
49464
+ return parts.join(`
49465
+ `);
49466
+ }
49467
+ static isInstance(error48) {
49468
+ return error48 instanceof _KadoaSdkException2;
49469
+ }
49470
+ static wrap(error48, extra) {
49471
+ if (error48 instanceof _KadoaSdkException2)
49472
+ return error48;
49473
+ const message = extra?.message || (error48 instanceof Error ? error48.message : typeof error48 === "string" ? error48 : "Unexpected error");
49474
+ return new _KadoaSdkException2(message, {
49475
+ code: "UNKNOWN",
49476
+ details: extra?.details,
49477
+ cause: error48
49478
+ });
49479
+ }
49480
+ };
49481
+ _KadoaSdkException.ERROR_MESSAGES = {
49482
+ CONFIG_ERROR: "Invalid configuration provided",
49483
+ AUTH_FAILED: "Authentication failed. Please check your API key",
49484
+ RATE_LIMITED: "Rate limit exceeded. Please try again later",
49485
+ NETWORK_ERROR: "Network error occurred",
49486
+ SERVER_ERROR: "Server error occurred",
49487
+ PARSE_ERROR: "Failed to parse response",
49488
+ BAD_REQUEST: "Bad request",
49489
+ ABORTED: "Aborted",
49490
+ NOT_FOUND: "Not found",
49491
+ NO_WORKFLOW_ID: "Failed to start extraction process - no ID received",
49492
+ WORKFLOW_CREATE_FAILED: "Failed to create workflow",
49493
+ WORKFLOW_TIMEOUT: "Workflow processing timed out",
49494
+ WORKFLOW_UNEXPECTED_STATUS: "Extraction completed with unexpected status",
49495
+ PROGRESS_CHECK_FAILED: "Failed to check extraction progress",
49496
+ DATA_FETCH_FAILED: "Failed to retrieve extracted data from workflow",
49497
+ NO_URLS: "At least one URL is required for extraction",
49498
+ NO_API_KEY: "API key is required for entity detection",
49499
+ LINK_REQUIRED: "Link is required for entity field detection",
49500
+ NO_PREDICTIONS: "No entity predictions returned from the API",
49501
+ EXTRACTION_FAILED: "Data extraction failed for the provided URLs",
49502
+ ENTITY_FETCH_FAILED: "Failed to fetch entity fields",
49503
+ ENTITY_INVARIANT_VIOLATION: "No valid entity provided",
49504
+ SCHEMA_NOT_FOUND: "Schema not found",
49505
+ SCHEMA_FETCH_ERROR: "Failed to fetch schema",
49506
+ SCHEMAS_FETCH_ERROR: "Failed to fetch schemas",
49507
+ SCHEMA_CREATE_FAILED: "Failed to create schema",
49508
+ SCHEMA_UPDATE_FAILED: "Failed to update schema",
49509
+ SCHEMA_DELETE_FAILED: "Failed to delete schema",
49510
+ VARIABLE_NOT_FOUND: "Variable not found",
49511
+ VARIABLE_CREATE_FAILED: "Failed to create variable",
49512
+ VARIABLE_UPDATE_FAILED: "Failed to update variable",
49513
+ TEMPLATE_NOT_FOUND: "Template not found",
49514
+ TEMPLATE_CREATE_FAILED: "Failed to create template",
49515
+ TEMPLATE_UPDATE_FAILED: "Failed to update template",
49516
+ TEMPLATE_VERSION_CREATE_FAILED: "Failed to create template version",
49517
+ TEMPLATE_FROM_WORKFLOW_FAILED: "Failed to create template from workflow"
49518
+ };
49519
+ KadoaSdkException = _KadoaSdkException;
49520
+ ERROR_MESSAGES = KadoaSdkException.ERROR_MESSAGES;
49521
+ KadoaHttpException = class _KadoaHttpException extends KadoaSdkException {
49522
+ constructor(message, options) {
49523
+ super(message, {
49524
+ code: options?.code,
49525
+ details: options?.details,
49526
+ cause: options?.cause
49527
+ });
49528
+ this.name = "KadoaHttpException";
49529
+ this.httpStatus = options?.httpStatus;
49530
+ this.requestId = options?.requestId;
49531
+ this.endpoint = options?.endpoint;
49532
+ this.method = options?.method;
49533
+ this.responseBody = options?.responseBody;
49534
+ }
49535
+ static fromAxiosError(error48, extra) {
49536
+ const status = error48.response?.status;
49537
+ const requestId = error48.response?.headers?.["x-request-id"] || error48.response?.headers?.["x-amzn-requestid"];
49538
+ const method = error48.config?.method?.toUpperCase();
49539
+ const url3 = error48.config?.url;
49540
+ return new _KadoaHttpException(extra?.message || error48.message, {
49541
+ code: _KadoaHttpException.mapStatusToCode(error48),
49542
+ httpStatus: status,
49543
+ requestId,
49544
+ endpoint: url3,
49545
+ method,
49546
+ responseBody: error48.response?.data,
49547
+ details: extra?.details
49548
+ });
49549
+ }
49550
+ toJSON() {
49551
+ return {
49552
+ ...super.toJSON(),
49553
+ httpStatus: this.httpStatus,
49554
+ requestId: this.requestId,
49555
+ endpoint: this.endpoint,
49556
+ method: this.method,
49557
+ responseBody: this.responseBody
49558
+ };
49559
+ }
49560
+ toDetailedString() {
49561
+ const parts = [`${this.name}: ${this.message}`, `Code: ${this.code}`];
49562
+ if (this.httpStatus) {
49563
+ parts.push(`HTTP Status: ${this.httpStatus}`);
49564
+ }
49565
+ if (this.method && this.endpoint) {
49566
+ parts.push(`Request: ${this.method} ${this.endpoint}`);
49567
+ }
49568
+ if (this.requestId) {
49569
+ parts.push(`Request ID: ${this.requestId}`);
49570
+ }
49571
+ if (this.responseBody) {
49572
+ parts.push(`Response Body: ${JSON.stringify(this.responseBody, null, 2)}`);
49573
+ }
49574
+ if (this.details && Object.keys(this.details).length > 0) {
49575
+ parts.push(`Details: ${JSON.stringify(this.details, null, 2)}`);
49576
+ }
49577
+ if (this.cause) {
49578
+ parts.push(`Cause: ${this.cause}`);
49579
+ }
49580
+ return parts.join(`
49581
+ `);
49582
+ }
49583
+ static wrap(error48, extra) {
49584
+ if (error48 instanceof _KadoaHttpException)
49585
+ return error48;
49586
+ if (error48 instanceof KadoaSdkException)
49587
+ return error48;
49588
+ if (isAxiosError2(error48)) {
49589
+ return _KadoaHttpException.fromAxiosError(error48, extra);
49590
+ }
49591
+ return KadoaSdkException.wrap(error48, extra);
49592
+ }
49593
+ static mapStatusToCode(errorOrStatus) {
49594
+ const status = typeof errorOrStatus === "number" ? errorOrStatus : errorOrStatus.response?.status;
49595
+ if (!status) {
49596
+ if (typeof errorOrStatus === "number")
49597
+ return "UNKNOWN";
49598
+ return errorOrStatus.code === "ECONNABORTED" ? "TIMEOUT" : errorOrStatus.request ? "NETWORK_ERROR" : "UNKNOWN";
49599
+ }
49600
+ if (status === 401 || status === 403)
49601
+ return "AUTH_ERROR";
49602
+ if (status === 404)
49603
+ return "NOT_FOUND";
49604
+ if (status === 408)
49605
+ return "TIMEOUT";
49606
+ if (status === 429)
49607
+ return "RATE_LIMITED";
49608
+ if (status >= 400 && status < 500)
49609
+ return "VALIDATION_ERROR";
49610
+ if (status >= 500)
49611
+ return "HTTP_ERROR";
49612
+ return "UNKNOWN";
49613
+ }
49614
+ };
49615
+ logger = {
49616
+ changes: createLogger("changes"),
49617
+ client: createLogger("client"),
49618
+ wss: createLogger("wss"),
49619
+ extraction: createLogger("extraction"),
49620
+ http: createLogger("http"),
49621
+ workflow: createLogger("workflow"),
49622
+ crawl: createLogger("crawl"),
49623
+ notifications: createLogger("notifications"),
49624
+ schemas: createLogger("schemas"),
49625
+ validation: createLogger("validation"),
49626
+ templates: createLogger("templates"),
49627
+ variables: createLogger("variables")
49628
+ };
49629
+ debug = logger.changes;
49303
49630
  BASE_PATH = "https://api.kadoa.com".replace(/\/+$/, "");
49304
49631
  RequiredError = class extends Error {
49305
49632
  constructor(field, msg) {
@@ -49636,215 +49963,6 @@ var init_dist2 = __esm(() => {
49636
49963
  Text: DataFieldDataTypeEnum.String,
49637
49964
  Url: DataFieldDataTypeEnum.Link
49638
49965
  };
49639
- KadoaErrorCode = {
49640
- VALIDATION_ERROR: "VALIDATION_ERROR",
49641
- BAD_REQUEST: "BAD_REQUEST",
49642
- NOT_FOUND: "NOT_FOUND",
49643
- INTERNAL_ERROR: "INTERNAL_ERROR"
49644
- };
49645
- _KadoaSdkException = class _KadoaSdkException2 extends Error {
49646
- constructor(message, options) {
49647
- super(message);
49648
- this.name = "KadoaSdkException";
49649
- this.code = options?.code ?? "UNKNOWN";
49650
- this.details = options?.details;
49651
- if (options && "cause" in options)
49652
- this.cause = options.cause;
49653
- Error.captureStackTrace?.(this, _KadoaSdkException2);
49654
- }
49655
- static from(error48, details) {
49656
- if (error48 instanceof _KadoaSdkException2)
49657
- return error48;
49658
- const message = error48 instanceof Error ? error48.message : typeof error48 === "string" ? error48 : "Unexpected error";
49659
- return new _KadoaSdkException2(message, {
49660
- code: "UNKNOWN",
49661
- details,
49662
- cause: error48
49663
- });
49664
- }
49665
- toJSON() {
49666
- return {
49667
- name: this.name,
49668
- message: this.message,
49669
- code: this.code,
49670
- details: this.details
49671
- };
49672
- }
49673
- toString() {
49674
- return [this.name, this.code, this.message].filter(Boolean).join(": ");
49675
- }
49676
- toDetailedString() {
49677
- const parts = [`${this.name}: ${this.message}`, `Code: ${this.code}`];
49678
- if (this.details && Object.keys(this.details).length > 0) {
49679
- parts.push(`Details: ${JSON.stringify(this.details, null, 2)}`);
49680
- }
49681
- if (this.cause) {
49682
- parts.push(`Cause: ${this.cause}`);
49683
- }
49684
- return parts.join(`
49685
- `);
49686
- }
49687
- static isInstance(error48) {
49688
- return error48 instanceof _KadoaSdkException2;
49689
- }
49690
- static wrap(error48, extra) {
49691
- if (error48 instanceof _KadoaSdkException2)
49692
- return error48;
49693
- const message = extra?.message || (error48 instanceof Error ? error48.message : typeof error48 === "string" ? error48 : "Unexpected error");
49694
- return new _KadoaSdkException2(message, {
49695
- code: "UNKNOWN",
49696
- details: extra?.details,
49697
- cause: error48
49698
- });
49699
- }
49700
- };
49701
- _KadoaSdkException.ERROR_MESSAGES = {
49702
- CONFIG_ERROR: "Invalid configuration provided",
49703
- AUTH_FAILED: "Authentication failed. Please check your API key",
49704
- RATE_LIMITED: "Rate limit exceeded. Please try again later",
49705
- NETWORK_ERROR: "Network error occurred",
49706
- SERVER_ERROR: "Server error occurred",
49707
- PARSE_ERROR: "Failed to parse response",
49708
- BAD_REQUEST: "Bad request",
49709
- ABORTED: "Aborted",
49710
- NOT_FOUND: "Not found",
49711
- NO_WORKFLOW_ID: "Failed to start extraction process - no ID received",
49712
- WORKFLOW_CREATE_FAILED: "Failed to create workflow",
49713
- WORKFLOW_TIMEOUT: "Workflow processing timed out",
49714
- WORKFLOW_UNEXPECTED_STATUS: "Extraction completed with unexpected status",
49715
- PROGRESS_CHECK_FAILED: "Failed to check extraction progress",
49716
- DATA_FETCH_FAILED: "Failed to retrieve extracted data from workflow",
49717
- NO_URLS: "At least one URL is required for extraction",
49718
- NO_API_KEY: "API key is required for entity detection",
49719
- LINK_REQUIRED: "Link is required for entity field detection",
49720
- NO_PREDICTIONS: "No entity predictions returned from the API",
49721
- EXTRACTION_FAILED: "Data extraction failed for the provided URLs",
49722
- ENTITY_FETCH_FAILED: "Failed to fetch entity fields",
49723
- ENTITY_INVARIANT_VIOLATION: "No valid entity provided",
49724
- SCHEMA_NOT_FOUND: "Schema not found",
49725
- SCHEMA_FETCH_ERROR: "Failed to fetch schema",
49726
- SCHEMAS_FETCH_ERROR: "Failed to fetch schemas",
49727
- SCHEMA_CREATE_FAILED: "Failed to create schema",
49728
- SCHEMA_UPDATE_FAILED: "Failed to update schema",
49729
- SCHEMA_DELETE_FAILED: "Failed to delete schema",
49730
- VARIABLE_NOT_FOUND: "Variable not found",
49731
- VARIABLE_CREATE_FAILED: "Failed to create variable",
49732
- VARIABLE_UPDATE_FAILED: "Failed to update variable",
49733
- TEMPLATE_NOT_FOUND: "Template not found",
49734
- TEMPLATE_CREATE_FAILED: "Failed to create template",
49735
- TEMPLATE_UPDATE_FAILED: "Failed to update template",
49736
- TEMPLATE_VERSION_CREATE_FAILED: "Failed to create template version",
49737
- TEMPLATE_FROM_WORKFLOW_FAILED: "Failed to create template from workflow"
49738
- };
49739
- KadoaSdkException = _KadoaSdkException;
49740
- ERROR_MESSAGES = KadoaSdkException.ERROR_MESSAGES;
49741
- KadoaHttpException = class _KadoaHttpException extends KadoaSdkException {
49742
- constructor(message, options) {
49743
- super(message, {
49744
- code: options?.code,
49745
- details: options?.details,
49746
- cause: options?.cause
49747
- });
49748
- this.name = "KadoaHttpException";
49749
- this.httpStatus = options?.httpStatus;
49750
- this.requestId = options?.requestId;
49751
- this.endpoint = options?.endpoint;
49752
- this.method = options?.method;
49753
- this.responseBody = options?.responseBody;
49754
- }
49755
- static fromAxiosError(error48, extra) {
49756
- const status = error48.response?.status;
49757
- const requestId = error48.response?.headers?.["x-request-id"] || error48.response?.headers?.["x-amzn-requestid"];
49758
- const method = error48.config?.method?.toUpperCase();
49759
- const url3 = error48.config?.url;
49760
- return new _KadoaHttpException(extra?.message || error48.message, {
49761
- code: _KadoaHttpException.mapStatusToCode(error48),
49762
- httpStatus: status,
49763
- requestId,
49764
- endpoint: url3,
49765
- method,
49766
- responseBody: error48.response?.data,
49767
- details: extra?.details
49768
- });
49769
- }
49770
- toJSON() {
49771
- return {
49772
- ...super.toJSON(),
49773
- httpStatus: this.httpStatus,
49774
- requestId: this.requestId,
49775
- endpoint: this.endpoint,
49776
- method: this.method,
49777
- responseBody: this.responseBody
49778
- };
49779
- }
49780
- toDetailedString() {
49781
- const parts = [`${this.name}: ${this.message}`, `Code: ${this.code}`];
49782
- if (this.httpStatus) {
49783
- parts.push(`HTTP Status: ${this.httpStatus}`);
49784
- }
49785
- if (this.method && this.endpoint) {
49786
- parts.push(`Request: ${this.method} ${this.endpoint}`);
49787
- }
49788
- if (this.requestId) {
49789
- parts.push(`Request ID: ${this.requestId}`);
49790
- }
49791
- if (this.responseBody) {
49792
- parts.push(`Response Body: ${JSON.stringify(this.responseBody, null, 2)}`);
49793
- }
49794
- if (this.details && Object.keys(this.details).length > 0) {
49795
- parts.push(`Details: ${JSON.stringify(this.details, null, 2)}`);
49796
- }
49797
- if (this.cause) {
49798
- parts.push(`Cause: ${this.cause}`);
49799
- }
49800
- return parts.join(`
49801
- `);
49802
- }
49803
- static wrap(error48, extra) {
49804
- if (error48 instanceof _KadoaHttpException)
49805
- return error48;
49806
- if (error48 instanceof KadoaSdkException)
49807
- return error48;
49808
- if (isAxiosError2(error48)) {
49809
- return _KadoaHttpException.fromAxiosError(error48, extra);
49810
- }
49811
- return KadoaSdkException.wrap(error48, extra);
49812
- }
49813
- static mapStatusToCode(errorOrStatus) {
49814
- const status = typeof errorOrStatus === "number" ? errorOrStatus : errorOrStatus.response?.status;
49815
- if (!status) {
49816
- if (typeof errorOrStatus === "number")
49817
- return "UNKNOWN";
49818
- return errorOrStatus.code === "ECONNABORTED" ? "TIMEOUT" : errorOrStatus.request ? "NETWORK_ERROR" : "UNKNOWN";
49819
- }
49820
- if (status === 401 || status === 403)
49821
- return "AUTH_ERROR";
49822
- if (status === 404)
49823
- return "NOT_FOUND";
49824
- if (status === 408)
49825
- return "TIMEOUT";
49826
- if (status === 429)
49827
- return "RATE_LIMITED";
49828
- if (status >= 400 && status < 500)
49829
- return "VALIDATION_ERROR";
49830
- if (status >= 500)
49831
- return "HTTP_ERROR";
49832
- return "UNKNOWN";
49833
- }
49834
- };
49835
- logger = {
49836
- client: createLogger("client"),
49837
- wss: createLogger("wss"),
49838
- extraction: createLogger("extraction"),
49839
- http: createLogger("http"),
49840
- workflow: createLogger("workflow"),
49841
- crawl: createLogger("crawl"),
49842
- notifications: createLogger("notifications"),
49843
- schemas: createLogger("schemas"),
49844
- validation: createLogger("validation"),
49845
- templates: createLogger("templates"),
49846
- variables: createLogger("variables")
49847
- };
49848
49966
  _SchemaBuilder.FIELD_NAME_PATTERN = /^[A-Za-z0-9]+$/;
49849
49967
  _SchemaBuilder.TYPES_REQUIRING_EXAMPLE = [
49850
49968
  "STRING",
@@ -49854,8 +49972,8 @@ var init_dist2 = __esm(() => {
49854
49972
  "ARRAY"
49855
49973
  ];
49856
49974
  SchemaBuilder = _SchemaBuilder;
49857
- debug = logger.schemas;
49858
- debug2 = logger.extraction;
49975
+ debug2 = logger.schemas;
49976
+ debug3 = logger.extraction;
49859
49977
  SUCCESSFUL_RUN_STATES = /* @__PURE__ */ new Set(["FINISHED", "SUCCESS"]);
49860
49978
  DEFAULT_OPTIONS = {
49861
49979
  mode: "run",
@@ -49866,7 +49984,7 @@ var init_dist2 = __esm(() => {
49866
49984
  bypassPreview: true,
49867
49985
  autoStart: true
49868
49986
  };
49869
- debug3 = logger.extraction;
49987
+ debug4 = logger.extraction;
49870
49988
  NotificationChannelType = {
49871
49989
  EMAIL: "EMAIL",
49872
49990
  SLACK: "SLACK",
@@ -49876,19 +49994,19 @@ var init_dist2 = __esm(() => {
49876
49994
  EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
49877
49995
  _NotificationChannelsService.DEFAULT_CHANNEL_NAME = "default";
49878
49996
  NotificationChannelsService = _NotificationChannelsService;
49879
- debug4 = logger.notifications;
49997
+ debug5 = logger.notifications;
49880
49998
  PUBLIC_API_URI = process.env.KADOA_PUBLIC_API_URI ?? "https://api.kadoa.com";
49881
49999
  WSS_API_URI = process.env.KADOA_WSS_API_URI ?? "wss://realtime.kadoa.com";
49882
50000
  process.env.KADOA_WSS_NEO_API_URI;
49883
50001
  REALTIME_API_URI = process.env.KADOA_REALTIME_API_URI ?? "https://realtime.kadoa.com";
49884
- debug5 = logger.wss;
50002
+ debug6 = logger.wss;
49885
50003
  if (typeof WebSocket === "undefined") {
49886
50004
  global.WebSocket = __require2("ws");
49887
50005
  }
49888
50006
  _Realtime.DEFAULT_RECONNECT_DELAY_MS = 5000;
49889
50007
  _Realtime.MAX_RECONNECT_DELAY_MS = 60000;
49890
50008
  Realtime = _Realtime;
49891
- debug6 = logger.templates;
50009
+ debug7 = logger.templates;
49892
50010
  DEFAULT_POLLING_OPTIONS = {
49893
50011
  pollIntervalMs: 1e4,
49894
50012
  timeoutMs: 5 * 60 * 1000
@@ -49897,7 +50015,7 @@ var init_dist2 = __esm(() => {
49897
50015
  ABORTED: "ABORTED",
49898
50016
  TIMEOUT: "TIMEOUT"
49899
50017
  };
49900
- debug7 = logger.variables;
50018
+ debug8 = logger.variables;
49901
50019
  JobStateEnum = {
49902
50020
  Finished: "FINISHED",
49903
50021
  Failed: "FAILED",
@@ -49918,7 +50036,7 @@ var init_dist2 = __esm(() => {
49918
50036
  "STOPPED",
49919
50037
  "CANCELLED"
49920
50038
  ]);
49921
- debug8 = logger.workflow;
50039
+ debug9 = logger.workflow;
49922
50040
  });
49923
50041
 
49924
50042
  // src/client.ts
@@ -50608,6 +50726,56 @@ function registerTools(server, ctx) {
50608
50726
  total: data.pagination?.totalCount || data.data.length
50609
50727
  });
50610
50728
  }));
50729
+ server.registerTool("list_changes", {
50730
+ description: "List detected data changes across one or more real-time monitoring workflows. " + "Returns structured diffs showing added, removed, and changed records. " + "Only works for workflows with real-time monitoring enabled.",
50731
+ inputSchema: {
50732
+ workflowIds: exports_external.preprocess(coerceArray(true), exports_external.array(exports_external.string())).optional().describe("Workflow IDs to filter by. If omitted, returns changes for all ACTIVE monitoring workflows."),
50733
+ startDate: exports_external.string().optional().describe("Start date filter (ISO format, e.g. 2025-01-01)"),
50734
+ endDate: exports_external.string().optional().describe("End date filter (ISO format, e.g. 2025-12-31)"),
50735
+ skip: exports_external.preprocess(coerceNumber(), exports_external.number()).optional().describe("Number of records to skip for pagination"),
50736
+ limit: exports_external.preprocess(coerceNumber(), exports_external.number()).optional().describe("Maximum number of changes to return")
50737
+ },
50738
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true }
50739
+ }, withErrorHandling("list_changes", async (args) => {
50740
+ const result = await ctx.client.changes.list({
50741
+ workflowIds: args.workflowIds?.join(","),
50742
+ startDate: args.startDate,
50743
+ endDate: args.endDate,
50744
+ skip: args.skip,
50745
+ limit: args.limit ?? 25
50746
+ });
50747
+ return jsonResult({
50748
+ changes: result.changes.map((c) => ({
50749
+ id: c.id,
50750
+ workflowId: c.workflowId,
50751
+ url: c.url,
50752
+ summary: c.summary,
50753
+ differences: c.differences,
50754
+ createdAt: c.createdAt
50755
+ })),
50756
+ pagination: result.pagination,
50757
+ changesCount: result.changesCount
50758
+ });
50759
+ }));
50760
+ server.registerTool("get_change", {
50761
+ description: "Get detailed information about a specific detected change, including the full data snapshot and diff.",
50762
+ inputSchema: {
50763
+ changeId: exports_external.string().describe("The change ID")
50764
+ },
50765
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true }
50766
+ }, withErrorHandling("get_change", async (args) => {
50767
+ const change = await ctx.client.changes.get(args.changeId);
50768
+ return jsonResult({
50769
+ id: change.id,
50770
+ workflowId: change.workflowId,
50771
+ url: change.url,
50772
+ summary: change.summary,
50773
+ screenshotUrl: change.screenshotUrl,
50774
+ data: change.data,
50775
+ differences: change.differences,
50776
+ createdAt: change.createdAt
50777
+ });
50778
+ }));
50611
50779
  server.registerTool("delete_workflow", {
50612
50780
  description: "Delete a workflow permanently. This is irreversible. " + "You MUST first call this tool without confirmed=true to preview what will be deleted, " + "then show the user the workflow name and ask for confirmation, " + "then call again with confirmed=true only after the user explicitly agrees.",
50613
50781
  inputSchema: {
@@ -51083,7 +51251,7 @@ function registerTools(server, ctx) {
51083
51251
  });
51084
51252
  }));
51085
51253
  server.registerTool("list_templates", {
51086
- description: "List all templates in the current team. Templates define reusable configurations (prompt, schema, validation, notifications) that can be linked to multiple workflows.",
51254
+ description: "List all templates in the current team. Templates define reusable configurations (prompt, schema, notifications) that can be linked to multiple workflows.",
51087
51255
  inputSchema: strictSchema({}),
51088
51256
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true }
51089
51257
  }, withErrorHandling("list_templates", async () => {
@@ -51101,7 +51269,7 @@ function registerTools(server, ctx) {
51101
51269
  return jsonResult({ template });
51102
51270
  }));
51103
51271
  server.registerTool("create_template", {
51104
- description: "Create a new template. Templates define reusable configurations that can be linked to workflows. After creation, use create_template_version to publish a version with prompt, schema, and validation rules.",
51272
+ description: "Create a new template. Templates define reusable configurations that can be linked to workflows. After creation, use create_template_version to publish a version with prompt, schema, and notifications.",
51105
51273
  inputSchema: strictSchema({
51106
51274
  name: exports_external.string().describe("Template name (1-255 chars)"),
51107
51275
  description: exports_external.string().optional().describe("Template description (max 2000 chars)")
@@ -51171,37 +51339,13 @@ function registerTools(server, ctx) {
51171
51339
  isKey: exports_external.preprocess(coerceBoolean(), exports_external.boolean()).optional().describe("Whether the field is a key field")
51172
51340
  };
51173
51341
  server.registerTool("create_template_version", {
51174
- description: "Publish a new version of a template. Versions capture the full workflow config: prompt, schema, validation rules, and notifications. All fields are optional — include only what this version should set.",
51342
+ description: "Publish a new version of a template. Versions capture the full workflow config: prompt, schema, and notifications. All fields are optional — include only what this version should set.",
51175
51343
  inputSchema: strictSchema({
51176
51344
  templateId: exports_external.string().describe("The template ID to publish a version for"),
51177
51345
  prompt: exports_external.string().optional().describe("User prompt to copy into workflow config"),
51178
51346
  schemaId: exports_external.string().optional().describe("Existing schema ID to reference (mutually exclusive with schemaFields)"),
51179
51347
  schemaFields: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.object(TemplateSchemaFieldShape))).optional().describe("Inline schema fields to create a new schema (mutually exclusive with schemaId)"),
51180
51348
  schemaEntity: exports_external.string().optional().describe("Entity name for the inline schema"),
51181
- dataValidation: exports_external.preprocess(coerceJson(), exports_external.object({
51182
- config: exports_external.object({
51183
- enabled: exports_external.preprocess(coerceBoolean(), exports_external.boolean()).describe("Whether data validation is enabled"),
51184
- alerting: exports_external.object({
51185
- system: exports_external.object({
51186
- enabled: exports_external.preprocess(coerceBoolean(), exports_external.boolean()),
51187
- threshold: exports_external.preprocess(coerceNumber(), exports_external.number()).optional()
51188
- }).optional().describe("System alerting configuration"),
51189
- user: exports_external.object({
51190
- enabled: exports_external.preprocess(coerceBoolean(), exports_external.boolean()),
51191
- threshold: exports_external.preprocess(coerceNumber(), exports_external.number()).optional()
51192
- }).optional().describe("User alerting configuration")
51193
- }).optional().describe("Alerting configuration")
51194
- }).optional().describe("Data validation config to copy into workflow.config.dataValidation"),
51195
- rules: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.object({
51196
- name: exports_external.string().describe("Rule name"),
51197
- description: exports_external.string().optional().describe("Rule description"),
51198
- ruleType: exports_external.enum(["regex", "custom_sql", "llm"]).describe("Type of validation rule"),
51199
- targetColumns: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.string())).optional().describe("Columns this rule targets"),
51200
- parameters: exports_external.preprocess(coerceJson(), exports_external.record(exports_external.string(), exports_external.unknown())).describe("Rule parameters (e.g., {sql: '...', pattern: '...'})"),
51201
- status: exports_external.enum(["preview", "enabled", "disabled"]).optional().describe("Initial rule status (defaults to 'enabled')"),
51202
- metadata: exports_external.preprocess(coerceJson(), exports_external.record(exports_external.string(), exports_external.unknown())).optional().describe("Additional metadata")
51203
- }))).optional().describe("Validation rules to clone as data_validation rows")
51204
- })).optional().describe("Data validation configuration: { config?: { enabled, alerting? }, rules?: [{ name, ruleType, parameters, ... }] }"),
51205
51349
  notifications: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.object({
51206
51350
  eventType: exports_external.string().describe("Notification event type"),
51207
51351
  eventConfiguration: exports_external.preprocess(coerceJson(), exports_external.record(exports_external.string(), exports_external.unknown())).optional(),
@@ -51287,7 +51431,7 @@ function registerTools(server, ctx) {
51287
51431
  });
51288
51432
  }));
51289
51433
  server.registerTool("apply_template_update", {
51290
- description: "Apply a specific template version to workflows. Updates the workflows' config (prompt, schema, validation, notifications) to match the specified version.",
51434
+ description: "Apply a specific template version to workflows. Updates the workflows' config (prompt, schema, notifications) to match the specified version.",
51291
51435
  inputSchema: strictSchema({
51292
51436
  templateId: exports_external.string().describe("The template ID"),
51293
51437
  targetVersion: exports_external.preprocess(coerceNumber(), exports_external.number().int().min(1)).describe("Version number to apply"),
@@ -51306,7 +51450,7 @@ function registerTools(server, ctx) {
51306
51450
  });
51307
51451
  }));
51308
51452
  server.registerTool("save_workflow_as_template", {
51309
- description: "Create a template from an existing workflow's configuration (prompt, schema, validation, notifications). " + "Provide 'name' to create a new template, or 'templateId' to add a new version to an existing template.",
51453
+ description: "Create a template from an existing workflow's configuration (prompt, schema, notifications). " + "Provide 'name' to create a new template, or 'templateId' to add a new version to an existing template.",
51310
51454
  inputSchema: strictSchema({
51311
51455
  workflowId: exports_external.string().describe("Source workflow ID to extract config from"),
51312
51456
  name: exports_external.string().optional().describe("Name for the new template (required if templateId is not set)"),
@@ -51359,7 +51503,7 @@ var package_default;
51359
51503
  var init_package = __esm(() => {
51360
51504
  package_default = {
51361
51505
  name: "@kadoa/mcp",
51362
- version: "0.4.2-rc.1",
51506
+ version: "0.4.3-rc.1",
51363
51507
  description: "Kadoa MCP Server — manage workflows from Claude Desktop, Cursor, and other MCP clients",
51364
51508
  type: "module",
51365
51509
  main: "dist/index.js",
@@ -51377,13 +51521,13 @@ var init_package = __esm(() => {
51377
51521
  build: "bun build src/index.ts --outdir=dist --target=node --external express --external ioredis",
51378
51522
  "check-types": "tsc --noEmit",
51379
51523
  test: "BUN_TEST=1 bun test",
51380
- "test:unit": "BUN_TEST=1 bun test tests/unit --timeout=120000",
51524
+ "test:unit": "BUN_TEST=1 bun test tests/unit/server.test.ts --timeout=120000 && BUN_TEST=1 bun test $(find tests/unit -maxdepth 1 -name '*.test.ts' ! -name 'server.test.ts') --timeout=120000",
51381
51525
  "test:e2e": "BUN_TEST=1 bun test tests/e2e --timeout=600000",
51382
51526
  "test:eval": "BUN_TEST=1 bun test tests/evals --timeout=300000",
51383
51527
  prepublishOnly: "bun run check-types && bun run test:unit && bun run build"
51384
51528
  },
51385
51529
  dependencies: {
51386
- "@kadoa/node-sdk": "^0.26.0",
51530
+ "@kadoa/node-sdk": "^0.27.0",
51387
51531
  "@modelcontextprotocol/sdk": "^1.26.0",
51388
51532
  express: "^5.2.1",
51389
51533
  ioredis: "^5.6.1",
@@ -56610,6 +56754,7 @@ function createServer(auth) {
56610
56754
  "Workflow lifecycle: create_workflow \u2192 get_workflow (check status) \u2192 fetch_data (get results). Workflows run asynchronously \u2014 never poll or sleep-wait.",
56611
56755
  "",
56612
56756
  "Use create_realtime_monitor only when the user wants continuous change detection with alerts. For one-time or scheduled extraction, use create_workflow.",
56757
+ "Use list_changes and get_change to retrieve detected diffs from real-time monitoring workflows.",
56613
56758
  "",
56614
56759
  "Schema tips: Use descriptive field names and examples. Group related data under one entity.",
56615
56760
  "The AI agent uses the schema + prompt to understand what to extract \u2014 a detailed prompt with a comprehensive schema produces better results than multiple simple workflows."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kadoa/mcp",
3
- "version": "0.4.2-rc.1",
3
+ "version": "0.4.3-rc.1",
4
4
  "description": "Kadoa MCP Server — manage workflows from Claude Desktop, Cursor, and other MCP clients",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -18,13 +18,13 @@
18
18
  "build": "bun build src/index.ts --outdir=dist --target=node --external express --external ioredis",
19
19
  "check-types": "tsc --noEmit",
20
20
  "test": "BUN_TEST=1 bun test",
21
- "test:unit": "BUN_TEST=1 bun test tests/unit --timeout=120000",
21
+ "test:unit": "BUN_TEST=1 bun test tests/unit/server.test.ts --timeout=120000 && BUN_TEST=1 bun test $(find tests/unit -maxdepth 1 -name '*.test.ts' ! -name 'server.test.ts') --timeout=120000",
22
22
  "test:e2e": "BUN_TEST=1 bun test tests/e2e --timeout=600000",
23
23
  "test:eval": "BUN_TEST=1 bun test tests/evals --timeout=300000",
24
24
  "prepublishOnly": "bun run check-types && bun run test:unit && bun run build"
25
25
  },
26
26
  "dependencies": {
27
- "@kadoa/node-sdk": "^0.26.0",
27
+ "@kadoa/node-sdk": "^0.27.0",
28
28
  "@modelcontextprotocol/sdk": "^1.26.0",
29
29
  "express": "^5.2.1",
30
30
  "ioredis": "^5.6.1",