@sellable/mcp 0.1.549 → 0.1.550

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/dist/api.js CHANGED
@@ -3,7 +3,7 @@ import { mkdir, rename, rm, stat } from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { Readable } from "node:stream";
5
5
  import { pipeline } from "node:stream/promises";
6
- import { getConfig, getConfigPath } from "./auth.js";
6
+ import { getConfig, getConfigPath, getEffectiveConfiguredWorkspaceId, resolveWorkspaceIdForRequest, } from "./auth.js";
7
7
  export class SellableApiError extends Error {
8
8
  status;
9
9
  body;
@@ -42,9 +42,12 @@ export class SellableApi {
42
42
  // Re-read config on every request so workspace switches take effect immediately
43
43
  const config = getConfig();
44
44
  const url = `${config.apiUrl}${path}`;
45
- const workspaceId = options && Object.prototype.hasOwnProperty.call(options, "workspaceId")
45
+ const requestedWorkspaceId = options && Object.prototype.hasOwnProperty.call(options, "workspaceId")
46
46
  ? options.workspaceId
47
- : config.activeWorkspaceId || config.workspaceId || null;
47
+ : getEffectiveConfiguredWorkspaceId(config);
48
+ const workspaceId = options && Object.prototype.hasOwnProperty.call(options, "workspaceId")
49
+ ? resolveWorkspaceIdForRequest(requestedWorkspaceId, `${method} ${path}`)
50
+ : requestedWorkspaceId;
48
51
  const response = await fetch(url, {
49
52
  method,
50
53
  headers: {
package/dist/auth.d.ts CHANGED
@@ -40,6 +40,12 @@ export type SkillState = {
40
40
  export declare function setConfigFile(fileName: string): void;
41
41
  export declare function getResolvedConfigsDir(): string | null;
42
42
  export declare function getConfigPath(): string;
43
+ export declare function getLockedWorkspaceId(): string | null;
44
+ export declare function isWorkspaceLockRequired(): boolean;
45
+ export declare function workspaceLockRequiredMessage(action?: string): string;
46
+ export declare function assertWorkspaceLockSatisfied(action?: string): void;
47
+ export declare function getEffectiveConfiguredWorkspaceId(config: Pick<SellableConfig, "activeWorkspaceId" | "workspaceId">): string | null;
48
+ export declare function resolveWorkspaceIdForRequest(requestedWorkspaceId: string | null | undefined, action?: string): string | null;
43
49
  export declare function getConfig(): SellableConfig;
44
50
  export declare function updateActiveWorkspace(params: {
45
51
  workspaceId: string;
package/dist/auth.js CHANGED
@@ -2,6 +2,8 @@ import * as fs from "fs";
2
2
  import * as os from "os";
3
3
  import * as path from "path";
4
4
  const DEFAULT_API_URL = "https://app.sellable.dev";
5
+ const WORKSPACE_LOCK_ENV = "SELLABLE_LOCK_WORKSPACE_ID";
6
+ const REQUIRE_WORKSPACE_LOCK_ENV = "SELLABLE_REQUIRE_WORKSPACE_LOCK";
5
7
  // No caching — re-read config on every call so token/workspace changes
6
8
  // made by the LLM (editing sellable.json) take effect immediately
7
9
  // without requiring an MCP server restart.
@@ -85,6 +87,44 @@ function normalizeConfig(raw) {
85
87
  apiUrl: raw.apiUrl || DEFAULT_API_URL,
86
88
  };
87
89
  }
90
+ export function getLockedWorkspaceId() {
91
+ const value = process.env[WORKSPACE_LOCK_ENV]?.trim();
92
+ return value || null;
93
+ }
94
+ export function isWorkspaceLockRequired() {
95
+ const value = process.env[REQUIRE_WORKSPACE_LOCK_ENV]?.trim().toLowerCase();
96
+ return value === "1" || value === "true" || value === "yes";
97
+ }
98
+ export function workspaceLockRequiredMessage(action = "Sellable request") {
99
+ return (`Workspace lock required: ${action} cannot run because ` +
100
+ `${REQUIRE_WORKSPACE_LOCK_ENV}=1 but ${WORKSPACE_LOCK_ENV} is missing. ` +
101
+ "Ask the sellable-admin profile to provision this customer profile with an approved customer workspace.");
102
+ }
103
+ export function assertWorkspaceLockSatisfied(action = "Sellable request") {
104
+ if (isWorkspaceLockRequired() && !getLockedWorkspaceId()) {
105
+ throw new Error(workspaceLockRequiredMessage(action));
106
+ }
107
+ }
108
+ function normalizeWorkspaceId(value) {
109
+ return typeof value === "string" && value.trim() ? value.trim() : null;
110
+ }
111
+ export function getEffectiveConfiguredWorkspaceId(config) {
112
+ assertWorkspaceLockSatisfied("workspace resolution");
113
+ return (getLockedWorkspaceId() ||
114
+ normalizeWorkspaceId(config.activeWorkspaceId) ||
115
+ normalizeWorkspaceId(config.workspaceId));
116
+ }
117
+ export function resolveWorkspaceIdForRequest(requestedWorkspaceId, action = "Sellable request") {
118
+ assertWorkspaceLockSatisfied(action);
119
+ const lockedWorkspaceId = getLockedWorkspaceId();
120
+ const requested = normalizeWorkspaceId(requestedWorkspaceId);
121
+ if (!lockedWorkspaceId)
122
+ return requested;
123
+ if (requested && requested !== lockedWorkspaceId) {
124
+ throw new Error(`Workspace lock violation: ${action} requested workspace ${requested}, but this profile is locked to ${lockedWorkspaceId}.`);
125
+ }
126
+ return lockedWorkspaceId;
127
+ }
88
128
  export function getConfig() {
89
129
  // Config cache removed 2026-05-04: we always re-read from disk so
90
130
  // workspace switches (set_active_workspace) take effect immediately
@@ -139,6 +179,7 @@ export function getConfig() {
139
179
  }
140
180
  }
141
181
  export function updateActiveWorkspace(params) {
182
+ resolveWorkspaceIdForRequest(params.workspaceId, "set_active_workspace");
142
183
  const configPath = getConfigPath();
143
184
  const configDir = path.dirname(configPath);
144
185
  if (!fs.existsSync(configDir)) {
@@ -226,6 +267,7 @@ function writeRawConfigFile(configPath, raw) {
226
267
  * new config without an MCP server restart.
227
268
  */
228
269
  export function writeNewConfig(opts) {
270
+ resolveWorkspaceIdForRequest(opts.activeWorkspaceId, "write Sellable auth config");
229
271
  const configPath = getConfigWritePath();
230
272
  let raw = {};
231
273
  if (fs.existsSync(configPath)) {
@@ -283,7 +325,7 @@ function getActiveEnvConfigRef(raw) {
283
325
  }
284
326
  export function getEngageState() {
285
327
  const config = getConfig();
286
- const workspaceId = config.activeWorkspaceId || config.workspaceId || null;
328
+ const workspaceId = getEffectiveConfiguredWorkspaceId(config);
287
329
  if (!workspaceId) {
288
330
  return { activeWorkspaceId: null, state: null };
289
331
  }
@@ -294,7 +336,7 @@ export function updateEngageState(patch) {
294
336
  const { configPath, raw } = readRawConfigFile();
295
337
  const { envConfig, set } = getActiveEnvConfigRef(raw);
296
338
  const normalized = normalizeConfig(envConfig);
297
- const workspaceId = normalized.activeWorkspaceId || normalized.workspaceId || null;
339
+ const workspaceId = getEffectiveConfiguredWorkspaceId(normalized);
298
340
  if (!workspaceId) {
299
341
  throw new Error("No active workspace selected. Run list_workspaces then set_active_workspace.");
300
342
  }
package/dist/index-dev.js CHANGED
File without changes
package/dist/index.js CHANGED
File without changes
@@ -0,0 +1,34 @@
1
+ export type RefillDateWindowSource = "default_scheduler_forward" | "horizon_send_days" | "until_date" | "target_date";
2
+ export type NormalizedRefillDateSelector = {
3
+ source: RefillDateWindowSource;
4
+ targetDate: string | null;
5
+ untilDate: string | null;
6
+ horizonSendDays: number | null;
7
+ };
8
+ export type RefillRunDateWindow = NormalizedRefillDateSelector & {
9
+ version: 1;
10
+ selectedDates: string[];
11
+ senderWindows?: Array<{
12
+ senderId: string | null;
13
+ timeZone: string | null;
14
+ selectedDates: string[];
15
+ }>;
16
+ };
17
+ type DateSelectorInput = {
18
+ targetDate?: unknown;
19
+ untilDate?: unknown;
20
+ horizonSendDays?: unknown;
21
+ };
22
+ export declare function normalizeRefillDateSelector(input: DateSelectorInput): NormalizedRefillDateSelector;
23
+ export declare function refillDateSelectorBody(selector: NormalizedRefillDateSelector): {
24
+ targetDate?: string;
25
+ untilDate?: string;
26
+ horizonSendDays?: number;
27
+ };
28
+ export declare function dateWindowFromSelector(selector: NormalizedRefillDateSelector): RefillRunDateWindow;
29
+ export declare function dateWindowFromPlan(plan: Record<string, unknown>, selector: NormalizedRefillDateSelector): RefillRunDateWindow;
30
+ export declare function dateWindowFromRunState(runState: unknown): RefillRunDateWindow | null;
31
+ export declare function selectorFromDateWindow(window: RefillRunDateWindow): NormalizedRefillDateSelector;
32
+ export declare function dateSelectorMatchesWindow(selector: NormalizedRefillDateSelector, window: RefillRunDateWindow): boolean;
33
+ export declare function schedulerSweepTargetDates(window: RefillRunDateWindow): string[];
34
+ export {};
@@ -0,0 +1,210 @@
1
+ function isRecord(value) {
2
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3
+ }
4
+ function stringValue(value) {
5
+ return typeof value === "string" && value.trim() ? value.trim() : null;
6
+ }
7
+ function numberValue(value) {
8
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
9
+ }
10
+ function arrayValue(value) {
11
+ return Array.isArray(value) ? value : [];
12
+ }
13
+ function isValidDateKey(value) {
14
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value))
15
+ return false;
16
+ const [year, month, day] = value.split("-").map(Number);
17
+ const date = new Date(Date.UTC(year, month - 1, day));
18
+ return (date.getUTCFullYear() === year &&
19
+ date.getUTCMonth() === month - 1 &&
20
+ date.getUTCDate() === day);
21
+ }
22
+ function normalizeDateKey(value, field) {
23
+ if (value === undefined || value === null || value === "")
24
+ return null;
25
+ if (typeof value !== "string") {
26
+ throw new Error(`${field} must be a string in YYYY-MM-DD format.`);
27
+ }
28
+ const trimmed = value.trim();
29
+ if (!isValidDateKey(trimmed)) {
30
+ throw new Error(`${field} must be a valid YYYY-MM-DD calendar date.`);
31
+ }
32
+ return trimmed;
33
+ }
34
+ function normalizeHorizonSendDays(value) {
35
+ if (value === undefined)
36
+ return null;
37
+ if (typeof value !== "number" ||
38
+ !Number.isInteger(value) ||
39
+ value < 1 ||
40
+ value > 7) {
41
+ throw new Error("horizonSendDays must be an integer between 1 and 7.");
42
+ }
43
+ return value;
44
+ }
45
+ export function normalizeRefillDateSelector(input) {
46
+ const targetDate = normalizeDateKey(input.targetDate, "targetDate");
47
+ const untilDate = normalizeDateKey(input.untilDate, "untilDate");
48
+ const horizonSendDays = normalizeHorizonSendDays(input.horizonSendDays);
49
+ if (targetDate) {
50
+ return {
51
+ source: "target_date",
52
+ targetDate,
53
+ untilDate: null,
54
+ horizonSendDays: null,
55
+ };
56
+ }
57
+ if (untilDate) {
58
+ return {
59
+ source: "until_date",
60
+ targetDate: null,
61
+ untilDate,
62
+ horizonSendDays: null,
63
+ };
64
+ }
65
+ if (horizonSendDays !== null) {
66
+ return {
67
+ source: "horizon_send_days",
68
+ targetDate: null,
69
+ untilDate: null,
70
+ horizonSendDays,
71
+ };
72
+ }
73
+ return {
74
+ source: "default_scheduler_forward",
75
+ targetDate: null,
76
+ untilDate: null,
77
+ horizonSendDays: null,
78
+ };
79
+ }
80
+ export function refillDateSelectorBody(selector) {
81
+ if (selector.source === "target_date" && selector.targetDate) {
82
+ return { targetDate: selector.targetDate };
83
+ }
84
+ if (selector.source === "until_date" && selector.untilDate) {
85
+ return { untilDate: selector.untilDate };
86
+ }
87
+ if (selector.source === "horizon_send_days" &&
88
+ selector.horizonSendDays !== null) {
89
+ return { horizonSendDays: selector.horizonSendDays };
90
+ }
91
+ return {};
92
+ }
93
+ export function dateWindowFromSelector(selector) {
94
+ return {
95
+ version: 1,
96
+ ...selector,
97
+ selectedDates: selector.targetDate ? [selector.targetDate] : [],
98
+ };
99
+ }
100
+ function selectedDatesFromPlan(plan) {
101
+ const packet = isRecord(plan.packet) ? plan.packet : {};
102
+ const target = isRecord(packet.target) ? packet.target : {};
103
+ const window = isRecord(target.window) ? target.window : {};
104
+ const senderWindows = arrayValue(window.senderWindows).filter(isRecord);
105
+ const fromWindows = senderWindows.flatMap((senderWindow) => arrayValue(senderWindow.selectedDates)
106
+ .map((entry) => stringValue(entry))
107
+ .filter((entry) => Boolean(entry)));
108
+ if (fromWindows.length > 0)
109
+ return Array.from(new Set(fromWindows)).sort();
110
+ const senderRefillPlans = arrayValue(target.senderRefillPlans).filter(isRecord);
111
+ return Array.from(new Set(senderRefillPlans.flatMap((senderPlan) => {
112
+ const horizon = isRecord(senderPlan.horizon) ? senderPlan.horizon : {};
113
+ return arrayValue(horizon.selectedDays)
114
+ .filter(isRecord)
115
+ .map((day) => stringValue(day.date))
116
+ .filter((entry) => Boolean(entry));
117
+ }))).sort();
118
+ }
119
+ function senderWindowsFromPlan(plan) {
120
+ const packet = isRecord(plan.packet) ? plan.packet : {};
121
+ const target = isRecord(packet.target) ? packet.target : {};
122
+ const window = isRecord(target.window) ? target.window : {};
123
+ return arrayValue(window.senderWindows)
124
+ .filter(isRecord)
125
+ .map((senderWindow) => ({
126
+ senderId: stringValue(senderWindow.senderId),
127
+ timeZone: stringValue(senderWindow.timeZone),
128
+ selectedDates: arrayValue(senderWindow.selectedDates)
129
+ .map((entry) => stringValue(entry))
130
+ .filter((entry) => Boolean(entry)),
131
+ }));
132
+ }
133
+ export function dateWindowFromPlan(plan, selector) {
134
+ const packet = isRecord(plan.packet) ? plan.packet : {};
135
+ const request = isRecord(packet.request) ? packet.request : {};
136
+ const targetDate = stringValue(request.targetDate) ?? selector.targetDate ?? null;
137
+ const untilDate = stringValue(request.untilDate) ?? selector.untilDate ?? null;
138
+ const horizonSendDays = numberValue(request.horizonSendDays) ?? selector.horizonSendDays ?? null;
139
+ const source = targetDate
140
+ ? "target_date"
141
+ : untilDate
142
+ ? "until_date"
143
+ : horizonSendDays !== null
144
+ ? "horizon_send_days"
145
+ : selector.source;
146
+ const selectedDates = selectedDatesFromPlan(plan);
147
+ return {
148
+ version: 1,
149
+ source,
150
+ targetDate: source === "target_date" ? targetDate : null,
151
+ untilDate: source === "until_date" ? untilDate : null,
152
+ horizonSendDays: source === "horizon_send_days" ? horizonSendDays : null,
153
+ selectedDates: selectedDates.length > 0
154
+ ? selectedDates
155
+ : targetDate
156
+ ? [targetDate]
157
+ : [],
158
+ senderWindows: senderWindowsFromPlan(plan),
159
+ };
160
+ }
161
+ export function dateWindowFromRunState(runState) {
162
+ const state = isRecord(runState) ? runState : {};
163
+ const raw = isRecord(state.dateWindow) ? state.dateWindow : null;
164
+ if (!raw || raw.version !== 1)
165
+ return null;
166
+ const source = raw.source === "target_date" ||
167
+ raw.source === "until_date" ||
168
+ raw.source === "horizon_send_days" ||
169
+ raw.source === "default_scheduler_forward"
170
+ ? raw.source
171
+ : null;
172
+ if (!source)
173
+ return null;
174
+ return {
175
+ version: 1,
176
+ source,
177
+ targetDate: source === "target_date" ? stringValue(raw.targetDate) : null,
178
+ untilDate: source === "until_date" ? stringValue(raw.untilDate) : null,
179
+ horizonSendDays: source === "horizon_send_days"
180
+ ? numberValue(raw.horizonSendDays)
181
+ : null,
182
+ selectedDates: arrayValue(raw.selectedDates)
183
+ .map((entry) => stringValue(entry))
184
+ .filter((entry) => Boolean(entry)),
185
+ };
186
+ }
187
+ export function selectorFromDateWindow(window) {
188
+ return {
189
+ source: window.source,
190
+ targetDate: window.targetDate,
191
+ untilDate: window.untilDate,
192
+ horizonSendDays: window.horizonSendDays,
193
+ };
194
+ }
195
+ export function dateSelectorMatchesWindow(selector, window) {
196
+ return (selector.source === window.source &&
197
+ selector.targetDate === window.targetDate &&
198
+ selector.untilDate === window.untilDate &&
199
+ selector.horizonSendDays === window.horizonSendDays);
200
+ }
201
+ export function schedulerSweepTargetDates(window) {
202
+ if (window.source === "target_date" && window.targetDate) {
203
+ return [window.targetDate];
204
+ }
205
+ if (window.source === "until_date" ||
206
+ window.source === "horizon_send_days") {
207
+ return window.selectedDates;
208
+ }
209
+ return [];
210
+ }
package/dist/server.js CHANGED
@@ -338,7 +338,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
338
338
  }
339
339
  break;
340
340
  case "duplicate_campaign":
341
- result = await duplicateCampaign(args?.campaignId, args?.name);
341
+ result = await duplicateCampaign(args?.campaignId);
342
342
  if (result?.campaignOfferId) {
343
343
  markCampaignContextDirty(result.campaignOfferId, "duplicate_campaign");
344
344
  }
@@ -11,6 +11,11 @@ export type AuthStatus = {
11
11
  tokenPresent: boolean;
12
12
  tokenPrefix: string | null;
13
13
  workspacesCount: number | null;
14
+ workspaceLock: {
15
+ enabled: boolean;
16
+ workspaceId: string | null;
17
+ required: boolean;
18
+ };
14
19
  checkedAt: string;
15
20
  /** Short message the LLM MUST show the user after auth succeeds. */
16
21
  _userNotice: string | null;
@@ -1,6 +1,6 @@
1
1
  import * as fs from "fs";
2
2
  import { getApi, SellableApiError } from "../api.js";
3
- import { getConfig, getConfigPath, getResolvedConfigsDir } from "../auth.js";
3
+ import { getConfig, getConfigPath, getEffectiveConfiguredWorkspaceId, getLockedWorkspaceId, getResolvedConfigsDir, isWorkspaceLockRequired, workspaceLockRequiredMessage, } from "../auth.js";
4
4
  import { checkForUpdates } from "../update-check.js";
5
5
  function maskToken(token) {
6
6
  if (token.length <= 10)
@@ -38,6 +38,8 @@ export async function getAuthStatus() {
38
38
  const checkedAt = new Date().toISOString();
39
39
  const update = await getUpdateStatus();
40
40
  let tokenPresent = false;
41
+ const workspaceLockRequired = isWorkspaceLockRequired();
42
+ const lockedWorkspaceId = getLockedWorkspaceId();
41
43
  const base = {
42
44
  ok: false,
43
45
  configPath,
@@ -50,27 +52,47 @@ export async function getAuthStatus() {
50
52
  tokenPresent: false,
51
53
  tokenPrefix: null,
52
54
  workspacesCount: null,
55
+ workspaceLock: {
56
+ enabled: Boolean(lockedWorkspaceId),
57
+ workspaceId: lockedWorkspaceId,
58
+ required: workspaceLockRequired,
59
+ },
53
60
  _userNotice: appendUpdateNotice(null, update),
54
61
  update,
55
62
  checkedAt,
56
63
  };
64
+ if (workspaceLockRequired && !lockedWorkspaceId) {
65
+ return {
66
+ ...base,
67
+ error: {
68
+ type: "workspace",
69
+ message: "Customer profile workspace lock is missing.",
70
+ guidance: workspaceLockRequiredMessage("get_auth_status"),
71
+ },
72
+ };
73
+ }
57
74
  try {
58
75
  const config = getConfig();
59
76
  tokenPresent = Boolean(config.token);
60
77
  base.activeEnvName = config.activeEnvName || null;
61
78
  const api = getApi();
62
79
  const { workspaces } = await api.get("/api/v3/workspaces");
63
- const activeWorkspaceId = config.activeWorkspaceId || config.workspaceId || null;
80
+ const activeWorkspaceId = getEffectiveConfiguredWorkspaceId(config);
64
81
  const activeWorkspace = activeWorkspaceId
65
82
  ? workspaces.find((ws) => ws.id === activeWorkspaceId)
66
83
  : null;
84
+ const visibleWorkspacesCount = lockedWorkspaceId
85
+ ? activeWorkspace
86
+ ? 1
87
+ : 0
88
+ : workspaces.length;
67
89
  if (!activeWorkspaceId) {
68
90
  return {
69
91
  ...base,
70
92
  apiUrl: config.apiUrl || null,
71
93
  tokenPresent,
72
94
  tokenPrefix: maskToken(config.token),
73
- workspacesCount: workspaces.length,
95
+ workspacesCount: visibleWorkspacesCount,
74
96
  error: {
75
97
  type: "workspace",
76
98
  message: "No active workspace selected.",
@@ -87,22 +109,26 @@ export async function getAuthStatus() {
87
109
  apiUrl: config.apiUrl || null,
88
110
  tokenPresent,
89
111
  tokenPrefix: maskToken(config.token),
90
- workspacesCount: workspaces.length,
112
+ workspacesCount: visibleWorkspacesCount,
91
113
  error: {
92
114
  type: "workspace",
93
115
  message: `Active workspace ${activeWorkspaceId} not found in access list.`,
94
- guidance: available
95
- ? `Available: ${available}. Run set_active_workspace with a valid ID.`
96
- : "Run list_workspaces to view available workspaces, then set_active_workspace.",
116
+ guidance: lockedWorkspaceId
117
+ ? "This profile is locked to a workspace that the configured Sellable token cannot access. Re-provision the customer profile from sellable-admin with the correct workspace token."
118
+ : available
119
+ ? `Available: ${available}. Run set_active_workspace with a valid ID.`
120
+ : "Run list_workspaces to view available workspaces, then set_active_workspace.",
97
121
  },
98
122
  };
99
123
  }
100
124
  const workspaceName = activeWorkspace.name || config.activeWorkspaceName || null;
101
125
  const envLabel = config.activeEnvName || null;
102
126
  const wsLabel = workspaceName || activeWorkspaceId;
103
- const notice = envLabel
104
- ? `You're in ${wsLabel} (${envLabel}).`
105
- : `You're in ${wsLabel}.`;
127
+ const noticePrefix = lockedWorkspaceId
128
+ ? `You're locked to ${wsLabel}.`
129
+ : envLabel
130
+ ? `You're in ${wsLabel} (${envLabel}).`
131
+ : `You're in ${wsLabel}.`;
106
132
  return {
107
133
  ok: true,
108
134
  configPath,
@@ -114,8 +140,19 @@ export async function getAuthStatus() {
114
140
  activeWorkspaceName: workspaceName,
115
141
  tokenPresent,
116
142
  tokenPrefix: maskToken(config.token),
117
- workspacesCount: workspaces.length,
118
- _userNotice: appendUpdateNotice(notice, update),
143
+ workspacesCount: visibleWorkspacesCount,
144
+ workspaceLock: lockedWorkspaceId
145
+ ? {
146
+ enabled: true,
147
+ workspaceId: lockedWorkspaceId,
148
+ required: workspaceLockRequired,
149
+ }
150
+ : {
151
+ enabled: false,
152
+ workspaceId: null,
153
+ required: workspaceLockRequired,
154
+ },
155
+ _userNotice: appendUpdateNotice(noticePrefix, update),
119
156
  update,
120
157
  checkedAt,
121
158
  error: null,
@@ -136,7 +136,6 @@ export interface CreateCampaignInput {
136
136
  }
137
137
  export interface UpdateCampaignInput {
138
138
  flowVersion?: "v1" | "v2";
139
- name?: string;
140
139
  offerPositioning?: unknown;
141
140
  campaignBrief?: unknown;
142
141
  leadSourceType?: string | null;
@@ -162,55 +161,12 @@ export declare const campaignToolDefinitions: ({
162
161
  type: string;
163
162
  description: string;
164
163
  };
165
- name?: undefined;
166
- limit?: undefined;
167
- tableId?: undefined;
168
- leadLimit?: undefined;
169
- page?: undefined;
170
- filters?: undefined;
171
- clientProspectId?: undefined;
172
- senderLinkedinUrl?: undefined;
173
- offerPositioning?: undefined;
174
- campaignBrief?: undefined;
175
- messageGenerationMode?: undefined;
176
- currentStep?: undefined;
177
- watchNarration?: undefined;
178
- leadSourceType?: undefined;
179
- leadSourceProvider?: undefined;
180
- selectedLeadListId?: undefined;
181
- senderIds?: undefined;
182
- currentStepTransition?: undefined;
183
- clearCurrentStepIfMatches?: undefined;
184
- interactionMode?: undefined;
185
- enableICPFilters?: undefined;
186
- useMessagingTemplate?: undefined;
187
- rubric?: undefined;
188
- flowVersion?: undefined;
189
- workspaceId?: undefined;
190
- };
191
- required: string[];
192
- additionalProperties: boolean;
193
- };
194
- } | {
195
- name: string;
196
- description: string;
197
- inputSchema: {
198
- type: string;
199
- properties: {
200
- campaignId: {
201
- type: string;
202
- description: string;
203
- };
204
- name: {
205
- type: string;
206
- maxLength: number;
207
- description: string;
208
- };
209
164
  limit?: undefined;
210
165
  tableId?: undefined;
211
166
  leadLimit?: undefined;
212
167
  page?: undefined;
213
168
  filters?: undefined;
169
+ name?: undefined;
214
170
  clientProspectId?: undefined;
215
171
  senderLinkedinUrl?: undefined;
216
172
  offerPositioning?: undefined;
@@ -245,11 +201,11 @@ export declare const campaignToolDefinitions: ({
245
201
  description: string;
246
202
  };
247
203
  campaignId?: undefined;
248
- name?: undefined;
249
204
  tableId?: undefined;
250
205
  leadLimit?: undefined;
251
206
  page?: undefined;
252
207
  filters?: undefined;
208
+ name?: undefined;
253
209
  clientProspectId?: undefined;
254
210
  senderLinkedinUrl?: undefined;
255
211
  offerPositioning?: undefined;
@@ -283,12 +239,12 @@ export declare const campaignToolDefinitions: ({
283
239
  type: string;
284
240
  description: string;
285
241
  };
286
- name?: undefined;
287
242
  limit?: undefined;
288
243
  tableId?: undefined;
289
244
  leadLimit?: undefined;
290
245
  page?: undefined;
291
246
  filters?: undefined;
247
+ name?: undefined;
292
248
  clientProspectId?: undefined;
293
249
  senderLinkedinUrl?: undefined;
294
250
  offerPositioning?: undefined;
@@ -369,8 +325,8 @@ export declare const campaignToolDefinitions: ({
369
325
  additionalProperties: boolean;
370
326
  };
371
327
  };
372
- name?: undefined;
373
328
  limit?: undefined;
329
+ name?: undefined;
374
330
  clientProspectId?: undefined;
375
331
  senderLinkedinUrl?: undefined;
376
332
  offerPositioning?: undefined;
@@ -407,7 +363,6 @@ export declare const campaignToolDefinitions: ({
407
363
  name: {
408
364
  type: string;
409
365
  description: string;
410
- maxLength?: undefined;
411
366
  };
412
367
  clientProspectId: {
413
368
  type: string;
@@ -600,11 +555,6 @@ export declare const campaignToolDefinitions: ({
600
555
  type: string;
601
556
  description: string;
602
557
  };
603
- name: {
604
- type: string;
605
- maxLength: number;
606
- description: string;
607
- };
608
558
  offerPositioning: {
609
559
  type: string;
610
560
  description: string;
@@ -792,6 +742,7 @@ export declare const campaignToolDefinitions: ({
792
742
  leadLimit?: undefined;
793
743
  page?: undefined;
794
744
  filters?: undefined;
745
+ name?: undefined;
795
746
  clientProspectId?: undefined;
796
747
  senderLinkedinUrl?: undefined;
797
748
  messageGenerationMode?: undefined;
@@ -814,12 +765,12 @@ export declare const campaignToolDefinitions: ({
814
765
  type: string;
815
766
  description: string;
816
767
  };
817
- name?: undefined;
818
768
  limit?: undefined;
819
769
  tableId?: undefined;
820
770
  leadLimit?: undefined;
821
771
  page?: undefined;
822
772
  filters?: undefined;
773
+ name?: undefined;
823
774
  clientProspectId?: undefined;
824
775
  senderLinkedinUrl?: undefined;
825
776
  offerPositioning?: undefined;
@@ -856,12 +807,12 @@ export declare const campaignToolDefinitions: ({
856
807
  type: string;
857
808
  description: string;
858
809
  };
859
- name?: undefined;
860
810
  limit?: undefined;
861
811
  tableId?: undefined;
862
812
  leadLimit?: undefined;
863
813
  page?: undefined;
864
814
  filters?: undefined;
815
+ name?: undefined;
865
816
  clientProspectId?: undefined;
866
817
  senderLinkedinUrl?: undefined;
867
818
  offerPositioning?: undefined;
@@ -932,7 +883,7 @@ export declare function archiveCampaign(campaignId: string): Promise<{
932
883
  cellsReset?: number;
933
884
  workflowTableId?: string;
934
885
  }>;
935
- export declare function duplicateCampaign(campaignId: string, name?: string): Promise<{
886
+ export declare function duplicateCampaign(campaignId: string): Promise<{
936
887
  campaignOfferId: string;
937
888
  campaignName: string;
938
889
  workflowTableId: string | null;