@sellable/mcp 0.1.770 → 0.1.771
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/tools/campaigns.d.ts +9 -1
- package/dist/tools/campaigns.js +47 -8
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getConfig } from "../auth.js";
|
|
2
|
+
import { type Campaign1KickoffHandoffInput, type Campaign1KickoffHandoffValidationResult } from "../utils/campaign1KickoffHandoff.js";
|
|
2
3
|
import { type InteractionMode } from "./interaction-mode.js";
|
|
3
4
|
import type { CampaignOfferNavigation } from "./navigation.js";
|
|
4
|
-
import { type Campaign1KickoffHandoffInput, type Campaign1KickoffHandoffValidationResult } from "../utils/campaign1KickoffHandoff.js";
|
|
5
5
|
declare const LEAD_SOURCE_PROVIDERS: {
|
|
6
6
|
readonly APOLLO: "apollo-ai";
|
|
7
7
|
readonly SALES_NAV: "sales-nav";
|
|
@@ -10,6 +10,14 @@ declare const LEAD_SOURCE_PROVIDERS: {
|
|
|
10
10
|
};
|
|
11
11
|
type LeadSourceProvider = (typeof LEAD_SOURCE_PROVIDERS)[keyof typeof LEAD_SOURCE_PROVIDERS];
|
|
12
12
|
export declare function buildWatchUrl(config: Pick<ReturnType<typeof getConfig>, "apiUrl" | "token" | "activeWorkspaceId" | "workspaceId">, path: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Ask the API to mint a fresh, single-use campaign watch link.
|
|
15
|
+
*
|
|
16
|
+
* The server derives the token from the identity it already resolved, so this
|
|
17
|
+
* works identically for `skt_*` CLI/MCP tokens and `sat_*` agent credentials.
|
|
18
|
+
* Falls back to the locally-built link if the mint call fails.
|
|
19
|
+
*/
|
|
20
|
+
export declare function mintCampaignWatchUrl(campaignId: string): Promise<string>;
|
|
13
21
|
export type CampaignBuilderWatchMode = "claude" | "codex" | "hermes";
|
|
14
22
|
export declare function getCampaignBuilderWatchModeParam(): CampaignBuilderWatchMode;
|
|
15
23
|
export declare function getCampaignBuilderWatchModeDriverLabel(mode?: CampaignBuilderWatchMode): "Claude Code" | "Codex" | "Hermes";
|
package/dist/tools/campaigns.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { getApi } from "../api.js";
|
|
2
2
|
import { getConfig, getEffectiveConfiguredWorkspaceId } from "../auth.js";
|
|
3
|
+
import { parseCampaign1KickoffHandoff, } from "../utils/campaign1KickoffHandoff.js";
|
|
3
4
|
import { assertCreateCampaignPromptLoaded, assertNetNewCreateCampaignResearchReady, } from "./flow-preflight.js";
|
|
4
5
|
import { setCampaignInteractionMode, } from "./interaction-mode.js";
|
|
5
6
|
import { isLinkedInProfileInput, normalizeLinkedInProfileInput, } from "./linkedin-url.js";
|
|
6
7
|
import { fetchCampaignRubrics } from "./processing.js";
|
|
7
|
-
import { parseCampaign1KickoffHandoff, } from "../utils/campaign1KickoffHandoff.js";
|
|
8
8
|
const LEAD_SOURCE_PROVIDERS = {
|
|
9
9
|
APOLLO: "apollo-ai",
|
|
10
10
|
SALES_NAV: "sales-nav",
|
|
@@ -96,7 +96,13 @@ const WATCH_NARRATION_TOOL_SCHEMA = {
|
|
|
96
96
|
messageDraftOutput: { type: ["object", "null"] },
|
|
97
97
|
error: { type: ["string", "null"] },
|
|
98
98
|
},
|
|
99
|
-
required: [
|
|
99
|
+
required: [
|
|
100
|
+
"statusSource",
|
|
101
|
+
"status",
|
|
102
|
+
"startedAt",
|
|
103
|
+
"updatedAt",
|
|
104
|
+
"basis",
|
|
105
|
+
],
|
|
100
106
|
},
|
|
101
107
|
},
|
|
102
108
|
additionalProperties: false,
|
|
@@ -120,11 +126,40 @@ export function buildWatchUrl(config, path) {
|
|
|
120
126
|
if (workspaceId && !url.searchParams.has("workspaceId")) {
|
|
121
127
|
url.searchParams.set("workspaceId", workspaceId);
|
|
122
128
|
}
|
|
123
|
-
|
|
129
|
+
// Only `skt_*` API tokens can be exchanged at `/auth/continue`. Sellable Agent
|
|
130
|
+
// callers hold `sat_*` service credentials, which live in a different table
|
|
131
|
+
// entirely — attaching one here produces a link that always fails with
|
|
132
|
+
// "Invalid token format", so leave the link token-less and let the caller mint
|
|
133
|
+
// a real watch token via `mintCampaignWatchUrl`.
|
|
134
|
+
if (config.token &&
|
|
135
|
+
config.token.startsWith("skt_") &&
|
|
136
|
+
!url.searchParams.has("token")) {
|
|
124
137
|
url.searchParams.set("token", config.token);
|
|
125
138
|
}
|
|
126
139
|
return url.toString();
|
|
127
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Ask the API to mint a fresh, single-use campaign watch link.
|
|
143
|
+
*
|
|
144
|
+
* The server derives the token from the identity it already resolved, so this
|
|
145
|
+
* works identically for `skt_*` CLI/MCP tokens and `sat_*` agent credentials.
|
|
146
|
+
* Falls back to the locally-built link if the mint call fails.
|
|
147
|
+
*/
|
|
148
|
+
export async function mintCampaignWatchUrl(campaignId) {
|
|
149
|
+
const config = getConfig();
|
|
150
|
+
const fallback = buildWatchUrl(config, buildCampaignBuilderWatchPath(campaignId));
|
|
151
|
+
try {
|
|
152
|
+
const result = await getApi().get(`/api/v3/mcp/campaigns/${campaignId}?mode=${getCampaignBuilderWatchModeParam()}`);
|
|
153
|
+
if (result?.watchUrl &&
|
|
154
|
+
isValidBriefHandoffWatchUrl(result.watchUrl, campaignId)) {
|
|
155
|
+
return result.watchUrl;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// Fall through to the locally-built link.
|
|
160
|
+
}
|
|
161
|
+
return fallback;
|
|
162
|
+
}
|
|
128
163
|
const CAMPAIGN_BUILDER_AGENT_WATCH_MODES = new Set([
|
|
129
164
|
"claude",
|
|
130
165
|
"codex",
|
|
@@ -600,10 +635,15 @@ export async function getCampaign(campaignId) {
|
|
|
600
635
|
const config = getConfig();
|
|
601
636
|
// Fetch campaign context and rubrics in parallel
|
|
602
637
|
const [result, rubricsResult] = await Promise.all([
|
|
603
|
-
api.get(`/api/v3/mcp/campaigns/${campaignId}`),
|
|
638
|
+
api.get(`/api/v3/mcp/campaigns/${campaignId}?mode=${getCampaignBuilderWatchModeParam()}`),
|
|
604
639
|
fetchCampaignRubrics(campaignId).catch(() => null),
|
|
605
640
|
]);
|
|
606
|
-
|
|
641
|
+
// Prefer the server-minted watch link. It carries a fresh single-use token
|
|
642
|
+
// that works for both `skt_*` and `sat_*` callers; the local builder is only a
|
|
643
|
+
// fallback for older deployments that do not mint one.
|
|
644
|
+
const watchUrl = result.watchUrl && isValidBriefHandoffWatchUrl(result.watchUrl, campaignId)
|
|
645
|
+
? result.watchUrl
|
|
646
|
+
: buildWatchUrl(config, buildCampaignBuilderWatchPath(campaignId));
|
|
607
647
|
// Merge rubrics into campaignOffer
|
|
608
648
|
const rubrics = (rubricsResult?.rubrics || []).map((r) => ({
|
|
609
649
|
id: r.id || "",
|
|
@@ -890,11 +930,10 @@ function buildResumeNextStep() {
|
|
|
890
930
|
}
|
|
891
931
|
export async function createCampaign(input) {
|
|
892
932
|
const api = getApi();
|
|
893
|
-
const config = getConfig();
|
|
894
933
|
// Idempotent resume path
|
|
895
934
|
if (input.campaignId) {
|
|
896
935
|
const existing = await api.get(`/api/v2/campaign-offers/${input.campaignId}`);
|
|
897
|
-
const watchUrl =
|
|
936
|
+
const watchUrl = await mintCampaignWatchUrl(existing.id);
|
|
898
937
|
const hasCreateFields = input.name ||
|
|
899
938
|
input.clientProspectId ||
|
|
900
939
|
input.offerPositioning !== undefined ||
|
|
@@ -1020,7 +1059,7 @@ export async function createCampaign(input) {
|
|
|
1020
1059
|
},
|
|
1021
1060
|
};
|
|
1022
1061
|
const result = await api.post(`/api/v2/campaign-offers`, formattedInput);
|
|
1023
|
-
const watchUrl =
|
|
1062
|
+
const watchUrl = await mintCampaignWatchUrl(result.id);
|
|
1024
1063
|
// Serialize to only essential fields for context efficiency
|
|
1025
1064
|
return {
|
|
1026
1065
|
id: result.id,
|