@sellable/mcp 0.1.313 → 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,
|
|
@@ -126,11 +140,12 @@ function acceptsReasoning(reasoning, hostConfig) {
|
|
|
126
140
|
.map((value) => normalizeReasoning(value))
|
|
127
141
|
.includes(normalized);
|
|
128
142
|
}
|
|
129
|
-
function modelMeetsMinimum(model, hostConfig) {
|
|
143
|
+
function modelMeetsMinimum(model, hostConfig, options = {}) {
|
|
130
144
|
const normalizedModel = normalize(model).replace(/[_-]+/g, " ");
|
|
131
145
|
if (!normalizedModel)
|
|
132
146
|
return false;
|
|
133
|
-
const familyMatches =
|
|
147
|
+
const familyMatches = options.familyKnownFromHost === true ||
|
|
148
|
+
hostConfig.familyKeywords.every((keyword) => normalizedModel.includes(normalize(keyword)));
|
|
134
149
|
if (!familyMatches)
|
|
135
150
|
return false;
|
|
136
151
|
const versions = extractModelVersions(normalizedModel);
|
|
@@ -145,7 +160,10 @@ function findAcceptedHostConfig(host, model, config) {
|
|
|
145
160
|
["codex", config.hosts.codex],
|
|
146
161
|
]
|
|
147
162
|
: [[host, config.hosts[host]]];
|
|
148
|
-
return candidates.find(([, hostConfig]) => modelMeetsMinimum(model, hostConfig
|
|
163
|
+
return candidates.find(([, hostConfig]) => modelMeetsMinimum(model, hostConfig, {
|
|
164
|
+
familyKnownFromHost: host !== "unknown" &&
|
|
165
|
+
!modelContainsOtherHostFamily(model, hostConfig, config),
|
|
166
|
+
}));
|
|
149
167
|
}
|
|
150
168
|
function looksLikeCodexStaleMetadata(host, model, reasoningEffort, config) {
|
|
151
169
|
if (host !== "codex")
|
|
@@ -165,7 +183,7 @@ function looksLikeCodexStaleMetadata(host, model, reasoningEffort, config) {
|
|
|
165
183
|
}
|
|
166
184
|
export function evaluateCampaignModelQuality(input = {}) {
|
|
167
185
|
const config = getCampaignModelQualityConfig();
|
|
168
|
-
const host =
|
|
186
|
+
const host = normalizeHostFromInput(input.host, input.model);
|
|
169
187
|
const model = input.model?.trim() || null;
|
|
170
188
|
const reasoningEffort = input.reasoningEffort?.trim() || null;
|
|
171
189
|
const recommendationHost = host === "claude" ? "claude" : "codex";
|
package/package.json
CHANGED
|
@@ -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
|
-
|
|
779
|
-
`request_user_input` is unavailable in an interactive session.
|
|
780
|
-
|
|
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
|
|
820
|
-
install/reload problem, not a campaign problem. Tell the
|
|
821
|
-
run `curl -fsSL "https://app.sellable.dev/api/v2/cli/install" | sh` so
|
|
822
|
-
packaged MCP server
|
|
823
|
-
|
|
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
|
|
828
|
-
thread.
|
|
829
|
-
|
|
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
|
|
942
|
-
Pass the current host
|
|
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
|