@sellable/mcp 0.1.314 → 0.1.315

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.
@@ -62,6 +62,12 @@ const normalizeHost = (host) => {
62
62
  }
63
63
  return "unknown";
64
64
  };
65
+ const normalizeHostFromInput = (host, model) => {
66
+ const explicitHost = normalizeHost(host);
67
+ if (explicitHost !== "unknown")
68
+ return explicitHost;
69
+ return normalizeHost(model);
70
+ };
65
71
  const normalizeReasoning = (reasoning) => normalize(reasoning).replace(/[_\s-]+/g, "");
66
72
  const compareVersion = (candidate, minimum) => {
67
73
  const candidateParts = candidate.split(".").map((part) => Number(part));
@@ -78,6 +84,14 @@ const compareVersion = (candidate, minimum) => {
78
84
  return 0;
79
85
  };
80
86
  const extractModelVersions = (model) => Array.from(normalize(model).matchAll(/\b(\d+(?:\.\d+){0,2})\b/g)).map((match) => match[1]);
87
+ function modelContainsOtherHostFamily(model, currentHostConfig, config) {
88
+ const normalizedModel = normalize(model).replace(/[_-]+/g, " ");
89
+ if (!normalizedModel)
90
+ return false;
91
+ return Object.values(config.hosts)
92
+ .filter((hostConfig) => hostConfig !== currentHostConfig)
93
+ .some((hostConfig) => hostConfig.familyKeywords.some((keyword) => normalizedModel.includes(normalize(keyword))));
94
+ }
81
95
  function mergeConfig(rawConfig) {
82
96
  return {
83
97
  ...DEFAULT_MODEL_QUALITY_CONFIG,
@@ -147,7 +161,8 @@ function findAcceptedHostConfig(host, model, config) {
147
161
  ]
148
162
  : [[host, config.hosts[host]]];
149
163
  return candidates.find(([, hostConfig]) => modelMeetsMinimum(model, hostConfig, {
150
- familyKnownFromHost: host !== "unknown",
164
+ familyKnownFromHost: host !== "unknown" &&
165
+ !modelContainsOtherHostFamily(model, hostConfig, config),
151
166
  }));
152
167
  }
153
168
  function looksLikeCodexStaleMetadata(host, model, reasoningEffort, config) {
@@ -168,7 +183,7 @@ function looksLikeCodexStaleMetadata(host, model, reasoningEffort, config) {
168
183
  }
169
184
  export function evaluateCampaignModelQuality(input = {}) {
170
185
  const config = getCampaignModelQualityConfig();
171
- const host = normalizeHost([input.host, input.model].filter(Boolean).join(" "));
186
+ const host = normalizeHostFromInput(input.host, input.model);
172
187
  const model = input.model?.trim() || null;
173
188
  const reasoningEffort = input.reasoningEffort?.trim() || null;
174
189
  const recommendationHost = host === "claude" ? "claude" : "codex";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.314",
3
+ "version": "0.1.315",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -775,9 +775,10 @@ messages, and wait for final launch approval.
775
775
  What's your LinkedIn profile URL or handle?
776
776
  ```
777
777
 
778
- Do not silently ask Codex intake or approval questions as plain chat when
779
- `request_user_input` is unavailable in an interactive session. Stop and tell
780
- the user:
778
+ Codex only: do not silently ask intake or approval questions as plain chat when
779
+ `request_user_input` is unavailable in an interactive Codex session. Claude Code
780
+ uses `AskUserQuestion`; do not apply this Codex setup blocker in Claude Code.
781
+ In Codex, stop and tell the user:
781
782
 
782
783
  ```text
783
784
  I need Codex’s quick question panel to collect campaign inputs and approvals cleanly.
@@ -816,17 +817,18 @@ there.
816
817
  ## Bootstrap
817
818
 
818
819
  MCP tool access is required. First call `mcp__sellable__get_auth_status({})`
819
- directly. If that tool is unavailable, stop and say this is a Codex
820
- install/reload problem, not a campaign problem. Tell the user to
821
- run `curl -fsSL "https://app.sellable.dev/api/v2/cli/install" | sh` so the
822
- packaged MCP server, Codex Desktop plugin, and Sellable skill bundle are
823
- installed. If they want an agent-readable checklist, tell them:
820
+ directly. If that tool is unavailable, stop and say this is a Sellable
821
+ install/reload problem for the current host, not a campaign problem. Tell the
822
+ user to run `curl -fsSL "https://app.sellable.dev/api/v2/cli/install" | sh` so
823
+ the packaged MCP server and the current host integration are installed. If they
824
+ want an agent-readable checklist, tell them:
824
825
  `Install Sellable CLI and skills using https://app.sellable.dev/agent-install.txt`.
825
826
  For CLI verification, tell them to run
826
827
  `sellable --verify-only --host all --json --artifact "$HOME/.local/sellable/app-sellable-dev/installer/.last-verify.json"`.
827
- After that, they must fully quit and reopen Codex Desktop before starting a new
828
- thread. Do not use `scripts/mcp/sellable-tool-call.mjs`, `npm run`, `node`, or
829
- any local harness as a fallback for this interactive skill.
828
+ After that, they must fully quit and reopen the current host app before starting
829
+ a new thread. In Codex, say Codex Desktop. In Claude Code, say Claude Code. Do
830
+ not use `scripts/mcp/sellable-tool-call.mjs`, `npm run`, `node`, or any local
831
+ harness as a fallback for this interactive skill.
830
832
  Do not mention prompt loading, local skill files, missing linked versions,
831
833
  plugin cache paths, MCP namespaces, or runbooks in customer-facing progress
832
834
  updates.
@@ -938,8 +940,10 @@ updates.
938
940
  - Do not call `mcp__sellable__get_campaigns`.
939
941
  - Do not call `mcp__sellable__get_campaign` to hunt for IDs.
940
942
  - Do not call `mcp__sellable__create_campaign({ campaignId: ... })` unless the user supplied that id.
941
- 6. Call `mcp__sellable__bootstrap_create_campaign({ flowVersion: "v2", campaignId?, host?, model?, reasoningEffort? })`.
942
- Pass the current host, model, and reasoning when the host exposes them.
943
+ 6. Call `mcp__sellable__bootstrap_create_campaign({ flowVersion: "v2", campaignId?, host, model?, reasoningEffort? })`.
944
+ Pass the explicit current host label: `host: "Codex"` from Codex and
945
+ `host: "Claude Code"` from Claude Code. Also pass the current model and
946
+ reasoning when the host exposes them.
943
947
  7. If `safeToProceed !== true`, stop and show `blockingErrors` + `nextStep`.
944
948
  8. If `modelQuality.status === "warn"` and `modelQuality.metadataStale !== true`,
945
949
  show `modelQuality.message` before any setup/research and wait for the user