@sellable/mcp 0.1.312 → 0.1.314

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/README.md CHANGED
@@ -97,8 +97,11 @@ startup/auth update check and tells the agent to run
97
97
  installed runtime is behind npm.
98
98
 
99
99
  For CI/scripted installs, set `SELLABLE_TOKEN` and `SELLABLE_WORKSPACE_ID`
100
- before running the installer. Direct `npx -y @sellable/install@latest --host all`
101
- is a fallback only when Node/npm/npx are already known-good.
100
+ before running the curl installer. The public path remains:
101
+
102
+ ```bash
103
+ curl -fsSL "https://app.sellable.dev/api/v2/cli/install" | sh
104
+ ```
102
105
 
103
106
  ### Publishing `@sellable/mcp`
104
107
 
@@ -14,6 +14,7 @@ export type CampaignModelQualityResult = {
14
14
  recommendedReasoningEffort: string;
15
15
  minimumSummary: string;
16
16
  confirmationRequired: boolean;
17
+ metadataStale: boolean;
17
18
  message: string;
18
19
  };
19
20
  export type CampaignModelQualityHostConfig = {
@@ -33,6 +34,7 @@ export type CampaignModelQualityConfig = {
33
34
  };
34
35
  warningCopy: {
35
36
  ok: string;
37
+ staleCodexMetadata: string;
36
38
  unknownSettings: string;
37
39
  belowMinimum: string;
38
40
  };
@@ -37,6 +37,7 @@ const DEFAULT_MODEL_QUALITY_CONFIG = {
37
37
  },
38
38
  warningCopy: {
39
39
  ok: "Campaign model settings meet the configured minimum: {minimumSummary}.",
40
+ staleCodexMetadata: "Codex host metadata appears stale: it can report GPT-5/default or GPT-5/high even when the UI is set to GPT 5.5 Extra High. Treating this as acceptable; continue without asking the user to switch.",
40
41
  unknownSettings: "Model settings were not provided by the host. Best campaigns need at least {minimumSummary}. Confirm the user is on one of those settings, or ask them to switch before continuing.",
41
42
  belowMinimum: "Best campaigns need at least {minimumSummary}. Current settings look below that: {currentSettings}. Please switch before continuing, or explicitly say to continue anyway.",
42
43
  },
@@ -125,11 +126,12 @@ function acceptsReasoning(reasoning, hostConfig) {
125
126
  .map((value) => normalizeReasoning(value))
126
127
  .includes(normalized);
127
128
  }
128
- function modelMeetsMinimum(model, hostConfig) {
129
+ function modelMeetsMinimum(model, hostConfig, options = {}) {
129
130
  const normalizedModel = normalize(model).replace(/[_-]+/g, " ");
130
131
  if (!normalizedModel)
131
132
  return false;
132
- const familyMatches = hostConfig.familyKeywords.every((keyword) => normalizedModel.includes(normalize(keyword)));
133
+ const familyMatches = options.familyKnownFromHost === true ||
134
+ hostConfig.familyKeywords.every((keyword) => normalizedModel.includes(normalize(keyword)));
133
135
  if (!familyMatches)
134
136
  return false;
135
137
  const versions = extractModelVersions(normalizedModel);
@@ -144,7 +146,25 @@ function findAcceptedHostConfig(host, model, config) {
144
146
  ["codex", config.hosts.codex],
145
147
  ]
146
148
  : [[host, config.hosts[host]]];
147
- return candidates.find(([, hostConfig]) => modelMeetsMinimum(model, hostConfig));
149
+ return candidates.find(([, hostConfig]) => modelMeetsMinimum(model, hostConfig, {
150
+ familyKnownFromHost: host !== "unknown",
151
+ }));
152
+ }
153
+ function looksLikeCodexStaleMetadata(host, model, reasoningEffort, config) {
154
+ if (host !== "codex")
155
+ return false;
156
+ if (!model || !reasoningEffort)
157
+ return false;
158
+ const normalizedModel = normalize(model).replace(/[_-]+/g, " ");
159
+ const normalizedReasoning = normalizeReasoning(reasoningEffort);
160
+ if (!normalizedModel.includes("gpt"))
161
+ return false;
162
+ const versions = extractModelVersions(normalizedModel);
163
+ const looksLikeBaseGpt5 = versions.some((version) => version === "5" || version === "5.0");
164
+ if (!looksLikeBaseGpt5)
165
+ return false;
166
+ return (["default", "auto", "standard"].includes(normalizedReasoning) ||
167
+ acceptsReasoning(reasoningEffort, config.hosts.codex));
148
168
  }
149
169
  export function evaluateCampaignModelQuality(input = {}) {
150
170
  const config = getCampaignModelQualityConfig();
@@ -166,6 +186,7 @@ export function evaluateCampaignModelQuality(input = {}) {
166
186
  recommendedReasoningEffort,
167
187
  minimumSummary,
168
188
  confirmationRequired: true,
189
+ metadataStale: false,
169
190
  message: formatCopy(config.warningCopy.unknownSettings, {
170
191
  minimumSummary,
171
192
  currentSettings: "unknown",
@@ -185,12 +206,30 @@ export function evaluateCampaignModelQuality(input = {}) {
185
206
  recommendedReasoningEffort,
186
207
  minimumSummary,
187
208
  confirmationRequired: false,
209
+ metadataStale: false,
188
210
  message: formatCopy(config.warningCopy.ok, {
189
211
  minimumSummary,
190
212
  currentSettings: "current settings",
191
213
  }),
192
214
  };
193
215
  }
216
+ if (looksLikeCodexStaleMetadata(host, model, reasoningEffort, config)) {
217
+ return {
218
+ status: "ok",
219
+ host,
220
+ model,
221
+ reasoningEffort,
222
+ recommendedModel,
223
+ recommendedReasoningEffort,
224
+ minimumSummary,
225
+ confirmationRequired: false,
226
+ metadataStale: true,
227
+ message: formatCopy(config.warningCopy.staleCodexMetadata, {
228
+ minimumSummary,
229
+ currentSettings: "stale Codex host metadata",
230
+ }),
231
+ };
232
+ }
194
233
  const currentSettings = [
195
234
  model ? `model "${model}"` : "unknown model",
196
235
  reasoningEffort ? `reasoning "${reasoningEffort}"` : "unknown reasoning",
@@ -204,6 +243,7 @@ export function evaluateCampaignModelQuality(input = {}) {
204
243
  recommendedReasoningEffort,
205
244
  minimumSummary,
206
245
  confirmationRequired: true,
246
+ metadataStale: false,
207
247
  message: formatCopy(config.warningCopy.belowMinimum, {
208
248
  minimumSummary,
209
249
  currentSettings,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.312",
3
+ "version": "0.1.314",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -179,11 +179,17 @@ person/company this campaign is for, then I’ll turn that into a campaign brief
179
179
  before we move into lead sourcing.
180
180
  ```
181
181
 
182
- Exception: if `bootstrap_create_campaign.modelQuality.status === "warn"`,
183
- the first visible campaign message must be the model-quality warning from
182
+ Exception: if `bootstrap_create_campaign.modelQuality.status === "warn"` and
183
+ `bootstrap_create_campaign.modelQuality.metadataStale !== true`, the first
184
+ visible campaign message must be the model-quality warning from
184
185
  `modelQuality.message`. Ask the user to switch to the configured minimum model
185
186
  or explicitly continue anyway before identity setup, research, lead filtering,
186
- message generation, or launch review.
187
+ message generation, or launch review. If `metadataStale === true`, continue
188
+ normally and do not ask the user to switch.
189
+
190
+ If `bootstrap_create_campaign.modelQuality.metadataStale === true`, continue
191
+ normally. Do not ask the user to switch models; this is an accepted Codex host
192
+ metadata mismatch.
187
193
 
188
194
  If a linked/local skill file is stale or missing, silently use the installed
189
195
  `sellable@sellable` plugin copy. Do not tell the user about the stale link,
@@ -935,8 +941,10 @@ updates.
935
941
  6. Call `mcp__sellable__bootstrap_create_campaign({ flowVersion: "v2", campaignId?, host?, model?, reasoningEffort? })`.
936
942
  Pass the current host, model, and reasoning when the host exposes them.
937
943
  7. If `safeToProceed !== true`, stop and show `blockingErrors` + `nextStep`.
938
- 8. If `modelQuality.status === "warn"`, show `modelQuality.message` before any
939
- setup/research and wait for the user to switch or explicitly continue.
944
+ 8. If `modelQuality.status === "warn"` and `modelQuality.metadataStale !== true`,
945
+ show `modelQuality.message` before any setup/research and wait for the user
946
+ to switch or explicitly continue. If `metadataStale === true`, continue
947
+ normally and do not tell the user to switch.
940
948
 
941
949
  ## Execute Workflow
942
950
 
@@ -22,6 +22,7 @@
22
22
  },
23
23
  "warningCopy": {
24
24
  "ok": "Campaign model settings meet the configured minimum: {minimumSummary}.",
25
+ "staleCodexMetadata": "Codex host metadata appears stale: it can report GPT-5/default or GPT-5/high even when the UI is set to GPT 5.5 Extra High. Treating this as acceptable; continue without asking the user to switch.",
25
26
  "unknownSettings": "Model settings were not provided by the host. Best campaigns need at least {minimumSummary}. Confirm the user is on one of those settings, or ask them to switch before continuing.",
26
27
  "belowMinimum": "Best campaigns need at least {minimumSummary}. Current settings look below that: {currentSettings}. Please switch before continuing, or explicitly say to continue anyway."
27
28
  }