@sellable/mcp 0.1.299 → 0.1.300

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.
@@ -284,6 +284,7 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
284
284
  error?: undefined;
285
285
  sourceShortfall?: undefined;
286
286
  warning?: undefined;
287
+ materializing?: undefined;
287
288
  } | {
288
289
  ready: boolean;
289
290
  reason: string;
@@ -297,6 +298,7 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
297
298
  error?: undefined;
298
299
  sourceShortfall?: undefined;
299
300
  warning?: undefined;
301
+ materializing?: undefined;
300
302
  } | {
301
303
  ready: boolean;
302
304
  reason: string;
@@ -310,6 +312,7 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
310
312
  error: string;
311
313
  sourceShortfall?: undefined;
312
314
  warning?: undefined;
315
+ materializing?: undefined;
313
316
  } | {
314
317
  ready: boolean;
315
318
  reason: string;
@@ -323,6 +326,7 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
323
326
  error: string | null;
324
327
  sourceShortfall?: undefined;
325
328
  warning?: undefined;
329
+ materializing?: undefined;
326
330
  } | {
327
331
  ready: boolean;
328
332
  leadListId: string;
@@ -336,6 +340,7 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
336
340
  warning: string | undefined;
337
341
  reason?: undefined;
338
342
  error?: undefined;
343
+ materializing?: undefined;
339
344
  } | {
340
345
  ready: boolean;
341
346
  reason: string;
@@ -346,6 +351,7 @@ export declare function waitForLeadListReady(input: WaitForLeadListReadyInput):
346
351
  rowCount: number | null;
347
352
  status: string | undefined;
348
353
  targetLeadCount: number | undefined;
354
+ materializing: boolean | undefined;
349
355
  warning: string | undefined;
350
356
  error: string | undefined;
351
357
  sourceShortfall?: undefined;
@@ -101,7 +101,7 @@ export const readinessToolDefinitions = [
101
101
  },
102
102
  targetLeadCount: {
103
103
  type: "number",
104
- description: "Target number of leads requested. Used as a fallback completion check when status is unavailable. For Signal Discovery, pass the approved source-candidate target; if the completed source list lands below it, the tool still returns ready with a source_shortfall warning so the confirmed list can be copied and campaign setup can proceed.",
104
+ description: "Target number of leads requested. Used as a fallback completion check when status is unavailable. For Signal Discovery, pass the approved source-candidate target; if the completed source list lands below it, the tool still returns ready with a source_shortfall warning after completed source rows are stable so the confirmed list can be copied and campaign setup can proceed.",
105
105
  },
106
106
  timeoutMs: {
107
107
  type: "number",
@@ -209,6 +209,8 @@ export async function waitForLeadListReady(input) {
209
209
  let missingJobId = false;
210
210
  let signalPendingSince = null;
211
211
  let signalPendingFingerprint = null;
212
+ let signalCompleteFingerprint = null;
213
+ let materializingSourceRows = false;
212
214
  while (Date.now() - start <= effectiveTimeoutMs) {
213
215
  attempts += 1;
214
216
  try {
@@ -472,6 +474,26 @@ export async function waitForLeadListReady(input) {
472
474
  }
473
475
  }
474
476
  if ((!requireRows || rowCount > 0) && importComplete) {
477
+ const shouldVerifyStableSignalRows = provider === "signal-discovery" &&
478
+ requireComplete &&
479
+ rowCount > 0 &&
480
+ configStatus === "complete";
481
+ if (shouldVerifyStableSignalRows) {
482
+ const nextCompleteFingerprint = JSON.stringify({
483
+ rowCount,
484
+ status: configStatus,
485
+ phase: importProgress?.phase ?? null,
486
+ processed: importProgress?.processed ?? null,
487
+ total: importProgress?.total ?? null,
488
+ leadsImported: importProgress?.leadsImported ?? null,
489
+ });
490
+ if (signalCompleteFingerprint !== nextCompleteFingerprint) {
491
+ signalCompleteFingerprint = nextCompleteFingerprint;
492
+ materializingSourceRows = true;
493
+ await sleep(intervalMs);
494
+ continue;
495
+ }
496
+ }
475
497
  const signalSourceShortfallTarget = provider === "signal-discovery" && typeof targetLeadCount === "number"
476
498
  ? targetLeadCount
477
499
  : null;
@@ -503,13 +525,15 @@ export async function waitForLeadListReady(input) {
503
525
  const stillRunningWithRows = requireComplete && timedOutWithRows;
504
526
  const timeoutReason = missingJobId
505
527
  ? "missing_job_id"
506
- : stillRunningWithRows
507
- ? "import_still_running"
508
- : timedOutWithRows
509
- ? "timeout_with_rows"
510
- : guardApplied
511
- ? "tool_timeout_guard"
512
- : "timeout";
528
+ : materializingSourceRows
529
+ ? "materializing"
530
+ : stillRunningWithRows
531
+ ? "import_still_running"
532
+ : timedOutWithRows
533
+ ? "timeout_with_rows"
534
+ : guardApplied
535
+ ? "tool_timeout_guard"
536
+ : "timeout";
513
537
  return {
514
538
  ready: !requireComplete && !missingJobId && timedOutWithRows,
515
539
  reason: timeoutReason,
@@ -520,13 +544,16 @@ export async function waitForLeadListReady(input) {
520
544
  rowCount: lastRowCount,
521
545
  status: lastStatus ?? undefined,
522
546
  targetLeadCount: targetLeadCount ?? undefined,
523
- warning: stillRunningWithRows
524
- ? `Import still appears to be running with ${lastRowCount?.toLocaleString("en-US") ?? "some"} row(s) available. Re-run wait_for_lead_list_ready to keep polling, or only call confirm_lead_list with allowPartialSourceList after the user explicitly asks to continue early.`
525
- : !missingJobId && timedOutWithRows
526
- ? "Timed out waiting for import status, but rows exist."
527
- : guardApplied
528
- ? `Stopped after ${effectiveTimeoutMs}ms to avoid host tool timeout (requested ${requestedTimeoutMs}ms). Re-run wait_for_lead_list_ready to keep polling.`
529
- : undefined,
547
+ materializing: materializingSourceRows || undefined,
548
+ warning: materializingSourceRows
549
+ ? `Source import completed but source rows are still materializing. Re-run wait_for_lead_list_ready before confirm_lead_list; do not call confirm_lead_list until this tool returns ready: true.`
550
+ : stillRunningWithRows
551
+ ? `Import still appears to be running with ${lastRowCount?.toLocaleString("en-US") ?? "some"} row(s) available. Re-run wait_for_lead_list_ready to keep polling, or only call confirm_lead_list with allowPartialSourceList after the user explicitly asks to continue early.`
552
+ : !missingJobId && timedOutWithRows
553
+ ? "Timed out waiting for import status, but rows exist."
554
+ : guardApplied
555
+ ? `Stopped after ${effectiveTimeoutMs}ms to avoid host tool timeout (requested ${requestedTimeoutMs}ms). Re-run wait_for_lead_list_ready to keep polling.`
556
+ : undefined,
530
557
  error: lastError ?? undefined,
531
558
  };
532
559
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.299",
3
+ "version": "0.1.300",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",