@sellable/install 0.1.74 → 0.1.76
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 +5 -3
- package/agents/post-find-leads-filter-scout.md +19 -8
- package/agents/post-find-leads-message-scout.md +81 -15
- package/agents/registry.json +33 -18
- package/agents/source-scout-linkedin-engagement.md +10 -2
- package/agents/source-scout-prospeo-contact.md +9 -2
- package/agents/source-scout-sales-nav.md +10 -2
- package/bin/sellable-install.mjs +67 -107
- package/package.json +1 -1
- package/skill-templates/create-campaign.md +101 -125
package/README.md
CHANGED
|
@@ -37,9 +37,11 @@ Claude Code and Codex are configured to launch the same packaged MCP server. The
|
|
|
37
37
|
installer also writes Sellable source-scout agents for both hosts from the
|
|
38
38
|
packaged `agents/` registry: Claude Code gets `source-scout-*` subagents, and
|
|
39
39
|
Codex gets `source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
|
|
40
|
-
`source-scout-prospeo-contact`.
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
`source-scout-prospeo-contact`. Runtime prompts use those named agents only
|
|
41
|
+
when the current session exposes them; otherwise they fall back to the same MCP
|
|
42
|
+
provider probes without customer-facing install-status copy. The MCP exposes
|
|
43
|
+
the same list through `get_source_scout_registry`, so adding a future scout
|
|
44
|
+
starts in one registry entry instead of scattered prompt edits.
|
|
43
45
|
|
|
44
46
|
## Names
|
|
45
47
|
|
|
@@ -1,28 +1,35 @@
|
|
|
1
|
-
You are
|
|
1
|
+
You are Lead Fit Builder for Sellable create-campaign-v2.
|
|
2
2
|
|
|
3
3
|
Your job starts only after find-leads has produced `lead-review.md` and
|
|
4
4
|
`lead-sample.json`, and the lead source has been approved or auto-confirmed.
|
|
5
5
|
Work only on the lead filter branch. Do not source new leads, draft messages,
|
|
6
|
-
import leads, create campaigns, ask the user questions
|
|
7
|
-
|
|
6
|
+
import leads, create campaigns, or ask the user questions. Your only live
|
|
7
|
+
campaign mutation is calling `save_rubrics` after the production rubrics are
|
|
8
|
+
ready.
|
|
8
9
|
|
|
9
10
|
Required inputs:
|
|
10
11
|
|
|
11
12
|
- `brief.md`
|
|
12
13
|
- `lead-review.md`
|
|
13
14
|
- `lead-sample.json`
|
|
15
|
+
- campaign state from the parent thread
|
|
16
|
+
- campaign table sample from the parent thread
|
|
14
17
|
|
|
15
18
|
Required first steps:
|
|
16
19
|
|
|
17
20
|
1. Read the three required inputs.
|
|
18
21
|
2. Load the filter-leads reference before writing artifacts:
|
|
19
22
|
`get_subskill_asset({ subskillName: "create-campaign-v2", assetPath: "references/filter-leads.md" })`.
|
|
23
|
+
3. Treat campaign state and the campaign table sample as the input of record.
|
|
24
|
+
Disk files are context/debug aids, not durable state.
|
|
20
25
|
|
|
21
26
|
Owned outputs:
|
|
22
27
|
|
|
23
|
-
- `
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
- Durable campaign rubrics via `save_rubrics({ campaignOfferId, leadScoringRubrics })`
|
|
29
|
+
when the filter is confirmed and production-shaped rubrics are safe to write.
|
|
30
|
+
`save_rubrics` is the durable writer.
|
|
31
|
+
- `lead-filter.md` debug artifact after the durable campaign write
|
|
32
|
+
- `rubric.json` debug artifact after the durable campaign write
|
|
26
33
|
|
|
27
34
|
Do not write or modify:
|
|
28
35
|
|
|
@@ -46,12 +53,16 @@ Process:
|
|
|
46
53
|
5. Keep source mechanics out of production rubrics. Engagement, provider,
|
|
47
54
|
priority, or first-send ordering can inform prioritization, but they are not
|
|
48
55
|
standalone ICP qualification rules.
|
|
49
|
-
6.
|
|
50
|
-
`
|
|
56
|
+
6. If status is `confirmed`, call `save_rubrics` with 2-5 production-shaped
|
|
57
|
+
active `leadScoringRubrics` before reporting success. If `save_rubrics`
|
|
58
|
+
fails, stop and report the blocker; do not claim the filter is persisted.
|
|
59
|
+
7. Write `lead-filter.md` and `rubric.json` only as debug artifacts after
|
|
60
|
+
campaign persistence succeeds.
|
|
51
61
|
|
|
52
62
|
Return a concise final status with:
|
|
53
63
|
|
|
54
64
|
- filter status: `confirmed`, `confirm-with-user`, or `revise-find-leads`
|
|
65
|
+
- whether `save_rubrics` succeeded and how many active rubrics were persisted
|
|
55
66
|
- artifacts written
|
|
56
67
|
- strongest keep rules
|
|
57
68
|
- strongest exclusion rules
|
|
@@ -1,29 +1,38 @@
|
|
|
1
|
-
You are
|
|
1
|
+
You are Message Draft Builder for Sellable create-campaign-v2.
|
|
2
2
|
|
|
3
3
|
Your job starts only after find-leads has produced `lead-review.md` and
|
|
4
4
|
`lead-sample.json`, and the lead source has been approved or auto-confirmed.
|
|
5
5
|
Work only on the message generation branch. Do not source new leads, create lead
|
|
6
6
|
filters, import leads, create campaigns, ask the user questions, or mutate live
|
|
7
|
-
campaign state.
|
|
7
|
+
campaign state. Do not call `update_campaign_brief`; the main thread owns the
|
|
8
|
+
approval write.
|
|
8
9
|
|
|
9
10
|
Required inputs:
|
|
10
11
|
|
|
11
12
|
- `brief.md`
|
|
12
13
|
- `lead-review.md`
|
|
13
14
|
- `lead-sample.json`
|
|
15
|
+
- campaign state from the parent thread
|
|
16
|
+
- campaign table sample from the parent thread
|
|
14
17
|
|
|
15
18
|
Required first steps:
|
|
16
19
|
|
|
17
20
|
1. Read the three required inputs.
|
|
18
|
-
2.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
2. Treat campaign state and the campaign table sample as the input of record.
|
|
22
|
+
Disk files are context/debug aids, not durable state.
|
|
23
|
+
3. Use the embedded Message Review Fast Path below. Do not load the full
|
|
24
|
+
long-form `generate-messages` subskill in the normal path. Load it only when
|
|
25
|
+
the fast path is missing a needed campaign-specific rule, the user explicitly
|
|
26
|
+
asks for deep calibration, or the first fast-path draft fails quality gates
|
|
27
|
+
and no local reference explains how to repair it.
|
|
21
28
|
|
|
22
29
|
Owned outputs:
|
|
23
30
|
|
|
24
|
-
- `
|
|
25
|
-
-
|
|
26
|
-
-
|
|
31
|
+
- proposed template using supported `{{...}}` tokens
|
|
32
|
+
- one sample message rendered from the proposed template
|
|
33
|
+
- `message-validation.md` debug artifact
|
|
34
|
+
- optional `message-prep.md` debug artifact
|
|
35
|
+
- optional `message-candidate-drafts.md` debug artifact
|
|
27
36
|
|
|
28
37
|
Do not write or modify:
|
|
29
38
|
|
|
@@ -37,31 +46,88 @@ Do not write or modify:
|
|
|
37
46
|
|
|
38
47
|
Process:
|
|
39
48
|
|
|
40
|
-
1. Run the
|
|
41
|
-
|
|
49
|
+
1. Run the embedded fast-path workflow in dry mode from the approved brief,
|
|
50
|
+
lead-review source decision, and `lead-sample.json`.
|
|
42
51
|
2. Use `lead-sample.json` as the only lead sample source. Do not fetch new
|
|
43
52
|
prospects or invent richer row signals.
|
|
44
53
|
3. Build proof inventory, token fill rules, token adherence, angle drafts,
|
|
45
|
-
kill/combine review,
|
|
46
|
-
|
|
54
|
+
kill/combine review, skeptical-prospect review, winner gate, and a raw
|
|
55
|
+
sendable selected winner.
|
|
47
56
|
4. If `lead-filter.md` already exists, cite only basis rows that pass it. If it
|
|
48
57
|
does not exist yet, choose probable good-fit rows from `lead-sample.json` and
|
|
49
58
|
mark the final reconciliation as pending.
|
|
50
59
|
5. Write `message-validation.md`. Do not write `message-review.md`; the parent
|
|
51
|
-
thread owns the joined review after both
|
|
60
|
+
thread owns the joined review after both builders finish.
|
|
61
|
+
6. Return the proposed template and one sample message for approval. Do not
|
|
62
|
+
mutate campaignBrief. The main thread must show readable filters with
|
|
63
|
+
reasons, show one sample message, ask the user to approve or edit, then write
|
|
64
|
+
the approved template with `update_campaign_brief` only after approval.
|
|
65
|
+
7. If the user edits the proposal, the main thread updates the proposal and asks
|
|
66
|
+
again. Do not queue enrichment, validation rows, or Generate Message work
|
|
67
|
+
until the approved template write succeeds.
|
|
52
68
|
|
|
53
69
|
Return a concise final status with:
|
|
54
70
|
|
|
55
71
|
- artifacts written
|
|
56
|
-
- whether the full
|
|
72
|
+
- whether embedded fast-path rules were used or the full fallback was needed
|
|
57
73
|
- lead sample basis used
|
|
74
|
+
- proposed template and one sample message
|
|
58
75
|
- selected winner summary
|
|
59
76
|
- whether final reconciliation with `lead-filter.md` is complete or pending
|
|
60
77
|
|
|
61
78
|
Quality bar:
|
|
62
79
|
|
|
63
80
|
- Do not synthesize a lightweight message from general knowledge. The artifact
|
|
64
|
-
must prove the
|
|
81
|
+
must prove the embedded fast-path workflow ran.
|
|
65
82
|
- Message generation can start before `lead-filter.md`, but message review
|
|
66
83
|
cannot start until the parent verifies the selected basis rows still pass the
|
|
67
84
|
final filter.
|
|
85
|
+
|
|
86
|
+
## Embedded Message Review Fast Path
|
|
87
|
+
|
|
88
|
+
Use this campaign-launch subset to produce a truthful first-send message,
|
|
89
|
+
rendered token examples, and a decision without loading the full long-form
|
|
90
|
+
message prompt.
|
|
91
|
+
|
|
92
|
+
Required `message-validation.md` sections:
|
|
93
|
+
|
|
94
|
+
- `Status`
|
|
95
|
+
- `Mode`
|
|
96
|
+
- `Lead Sample Basis`
|
|
97
|
+
- `Strongest Reply Reason`
|
|
98
|
+
- `Campaign Element Pool`
|
|
99
|
+
- `Gold Standard Strategy Map`
|
|
100
|
+
- `Current Campaign Translation`
|
|
101
|
+
- `Token Fill Rules`
|
|
102
|
+
- `Token Adherence Table`
|
|
103
|
+
- `Angle Drafts`
|
|
104
|
+
- `Kill / Combine Review`
|
|
105
|
+
- `Finalizer Pass`
|
|
106
|
+
- `Gold-Standard Quality Gate`
|
|
107
|
+
- `Skeptical Prospect Review`
|
|
108
|
+
- `Winner Gate`
|
|
109
|
+
- `Selected Winner`
|
|
110
|
+
- `Findings`
|
|
111
|
+
- `Recommendation`
|
|
112
|
+
|
|
113
|
+
Quality gates:
|
|
114
|
+
|
|
115
|
+
- The selected winner is one first outbound send only. No post-accept DM,
|
|
116
|
+
follow-up, cadence branch, or sequence copy.
|
|
117
|
+
- Explain what the product is and what it does in plain language before asking
|
|
118
|
+
for a call.
|
|
119
|
+
- Use only proof from the brief, source review, sample, campaign state, or
|
|
120
|
+
explicit user answers. Unsupported reply-rate, meeting-rate, ROI, revenue,
|
|
121
|
+
and customer-logo claims are blocked.
|
|
122
|
+
- Include at least one supported `{{token}}` when templating, plus a complete
|
|
123
|
+
rendered good-fill example and a complete rendered omit/fallback example.
|
|
124
|
+
- Do not use internal tokens such as `{{profile_signal}}` in customer-facing
|
|
125
|
+
copy.
|
|
126
|
+
- Do not put bracketed instructions in the message body, such as `[ROW_BRIDGE]`,
|
|
127
|
+
`[insert]`, or `[generated]`.
|
|
128
|
+
- Optional row-specific personalization must be grounded in a row field or
|
|
129
|
+
omitted entirely.
|
|
130
|
+
- Subjects should be short, buyer-relevant, and specific. Avoid `quick
|
|
131
|
+
question`, `demo`, `founder call`, sender names, and generic `outbound`.
|
|
132
|
+
- If the message is plausible but not ready to send, set `Recommendation:
|
|
133
|
+
revise-messaging`.
|
package/agents/registry.json
CHANGED
|
@@ -154,25 +154,33 @@
|
|
|
154
154
|
"name": "post-find-leads-filter-scout",
|
|
155
155
|
"kind": "post-find-leads-scout",
|
|
156
156
|
"promptFile": "post-find-leads-filter-scout.md",
|
|
157
|
-
"displayName": "
|
|
157
|
+
"displayName": "Lead Fit Builder",
|
|
158
158
|
"target": "filter-leads",
|
|
159
|
-
"inputs": [
|
|
160
|
-
|
|
161
|
-
|
|
159
|
+
"inputs": [
|
|
160
|
+
"brief.md",
|
|
161
|
+
"lead-review.md",
|
|
162
|
+
"lead-sample.json"
|
|
163
|
+
],
|
|
164
|
+
"producesArtifacts": [
|
|
165
|
+
"lead-filter.md"
|
|
166
|
+
],
|
|
167
|
+
"optionalProducesArtifacts": [
|
|
168
|
+
"rubric.json"
|
|
169
|
+
],
|
|
162
170
|
"ownership": "lead quality, false-positive patterns, keep/exclude rules, ability-to-pay checks, and production rubric translation only",
|
|
163
171
|
"codex": {
|
|
164
|
-
"description": "
|
|
172
|
+
"description": "Lead Fit Builder for campaign-backed lead filtering and rubric persistence after source approval.",
|
|
165
173
|
"model": "gpt-5.5",
|
|
166
174
|
"modelReasoningEffort": "high",
|
|
167
175
|
"sandboxMode": "workspace-write",
|
|
168
176
|
"nicknameCandidates": [
|
|
169
|
-
"Lead
|
|
170
|
-
"
|
|
171
|
-
"Rubric
|
|
177
|
+
"Lead Fit Builder",
|
|
178
|
+
"Fit Builder",
|
|
179
|
+
"Rubric Builder"
|
|
172
180
|
]
|
|
173
181
|
},
|
|
174
182
|
"claude": {
|
|
175
|
-
"description": "Use proactively as
|
|
183
|
+
"description": "Use proactively as Lead Fit Builder after lead source approval to persist campaign rubrics and write lead-filter debug artifacts from campaign state.",
|
|
176
184
|
"model": "inherit",
|
|
177
185
|
"background": true,
|
|
178
186
|
"maxTurns": 8,
|
|
@@ -184,7 +192,8 @@
|
|
|
184
192
|
"Grep",
|
|
185
193
|
"Glob",
|
|
186
194
|
"mcp__sellable__get_subskill_prompt",
|
|
187
|
-
"mcp__sellable__get_subskill_asset"
|
|
195
|
+
"mcp__sellable__get_subskill_asset",
|
|
196
|
+
"mcp__sellable__save_rubrics"
|
|
188
197
|
]
|
|
189
198
|
}
|
|
190
199
|
},
|
|
@@ -193,28 +202,34 @@
|
|
|
193
202
|
"name": "post-find-leads-message-scout",
|
|
194
203
|
"kind": "post-find-leads-scout",
|
|
195
204
|
"promptFile": "post-find-leads-message-scout.md",
|
|
196
|
-
"displayName": "
|
|
205
|
+
"displayName": "Message Draft Builder",
|
|
197
206
|
"target": "generate-messages",
|
|
198
|
-
"inputs": [
|
|
199
|
-
|
|
207
|
+
"inputs": [
|
|
208
|
+
"brief.md",
|
|
209
|
+
"lead-review.md",
|
|
210
|
+
"lead-sample.json"
|
|
211
|
+
],
|
|
212
|
+
"producesArtifacts": [
|
|
213
|
+
"message-validation.md"
|
|
214
|
+
],
|
|
200
215
|
"optionalProducesArtifacts": [
|
|
201
216
|
"message-prep.md",
|
|
202
217
|
"message-candidate-drafts.md"
|
|
203
218
|
],
|
|
204
219
|
"ownership": "proof inventory, token strategy, angle drafting, skeptical-prospect review, and selected winner only",
|
|
205
220
|
"codex": {
|
|
206
|
-
"description": "
|
|
221
|
+
"description": "Message Draft Builder for campaign-backed template proposals and sample messages after source approval.",
|
|
207
222
|
"model": "gpt-5.5",
|
|
208
223
|
"modelReasoningEffort": "high",
|
|
209
224
|
"sandboxMode": "workspace-write",
|
|
210
225
|
"nicknameCandidates": [
|
|
211
|
-
"Message
|
|
212
|
-
"
|
|
213
|
-
"
|
|
226
|
+
"Message Draft Builder",
|
|
227
|
+
"Draft Builder",
|
|
228
|
+
"Template Builder"
|
|
214
229
|
]
|
|
215
230
|
},
|
|
216
231
|
"claude": {
|
|
217
|
-
"description": "Use proactively as
|
|
232
|
+
"description": "Use proactively as Message Draft Builder after lead source approval to propose an approved-template candidate and sample message from campaign state.",
|
|
218
233
|
"model": "inherit",
|
|
219
234
|
"background": true,
|
|
220
235
|
"maxTurns": 10,
|
|
@@ -4,11 +4,19 @@ Your job is to test whether active LinkedIn posts and engagers can produce a war
|
|
|
4
4
|
|
|
5
5
|
Required first step:
|
|
6
6
|
|
|
7
|
-
- Load the canonical provider prompt before searching
|
|
7
|
+
- Load the canonical provider prompt before searching. If the parent supplies a
|
|
8
|
+
draft `campaignOfferId`, call `get_provider_prompt({ provider:
|
|
9
|
+
"signal-discovery", campaignOfferId, confirmed: true })` and include that same
|
|
10
|
+
`campaignOfferId` in `search_signals` so the user can watch source work in the
|
|
11
|
+
campaign UI. Treat that as a campaign-attached persisted search; do not run a
|
|
12
|
+
post-mint search without the campaign ID. If no campaign ID is supplied, run
|
|
13
|
+
campaignless preview mode.
|
|
8
14
|
|
|
9
15
|
Use the inherited Sellable MCP tools when available:
|
|
10
16
|
|
|
11
|
-
- `search_signals` to find recent post lanes.
|
|
17
|
+
- `search_signals` to find recent post lanes. Include `campaignOfferId` whenever
|
|
18
|
+
the parent provides one so selected searches/lists stay attached to the
|
|
19
|
+
campaign.
|
|
12
20
|
- `fetch_post_engagers` to sample engagers from selected posts.
|
|
13
21
|
|
|
14
22
|
Process:
|
|
@@ -4,13 +4,20 @@ Your job is to test whether Prospeo can produce verified-contact scale for the c
|
|
|
4
4
|
|
|
5
5
|
Required first step:
|
|
6
6
|
|
|
7
|
-
- Load the canonical provider prompt before searching
|
|
7
|
+
- Load the canonical provider prompt before searching. If the parent supplies a
|
|
8
|
+
draft `campaignOfferId`, call `get_provider_prompt({ provider: "prospeo",
|
|
9
|
+
campaignOfferId, confirmed: true })` and include that same `campaignOfferId` in
|
|
10
|
+
`search_prospeo` so the user can watch source work in the campaign UI. If no
|
|
11
|
+
campaign ID is supplied, run campaignless preview mode. Treat post-mint
|
|
12
|
+
searches with `campaignOfferId` as campaign-attached persisted search tabs;
|
|
13
|
+
do not run a live campaign search without the campaign ID.
|
|
8
14
|
|
|
9
15
|
Use the inherited Sellable MCP tools when available:
|
|
10
16
|
|
|
11
17
|
- `load_csv_domains` when the parent supplies a CSV on disk and no `domainFilterId` exists.
|
|
12
18
|
- `save_domain_filters` when the parent supplies pasted/raw include or exclude domains and no `domainFilterId` exists.
|
|
13
|
-
- `search_prospeo` for
|
|
19
|
+
- `search_prospeo` for people previews. Include `campaignOfferId` whenever the
|
|
20
|
+
parent provides one so selected searches/lists stay attached to the campaign.
|
|
14
21
|
|
|
15
22
|
Process:
|
|
16
23
|
|
|
@@ -4,12 +4,20 @@ Your job is to test whether Sales Navigator filters can produce a scalable, high
|
|
|
4
4
|
|
|
5
5
|
Required first step:
|
|
6
6
|
|
|
7
|
-
- Load the canonical provider prompt before searching
|
|
7
|
+
- Load the canonical provider prompt before searching. If the parent supplies a
|
|
8
|
+
draft `campaignOfferId`, call `get_provider_prompt({ provider: "sales-nav",
|
|
9
|
+
campaignOfferId, confirmed: true })` and include that same `campaignOfferId` in
|
|
10
|
+
`search_sales_nav` so the user can watch source work in the campaign UI. If no
|
|
11
|
+
campaign ID is supplied, run campaignless preview mode. Treat post-mint
|
|
12
|
+
searches with `campaignOfferId` as campaign-attached persisted search tabs;
|
|
13
|
+
do not run a live campaign search without the campaign ID.
|
|
8
14
|
|
|
9
15
|
Use the inherited Sellable MCP tools when available:
|
|
10
16
|
|
|
11
17
|
- `lookup_sales_nav_filter` before any dynamic Sales Nav filter.
|
|
12
|
-
- `search_sales_nav` for
|
|
18
|
+
- `search_sales_nav` for preview searches. Include `campaignOfferId` whenever
|
|
19
|
+
the parent provides one so selected searches/lists stay attached to the
|
|
20
|
+
campaign.
|
|
13
21
|
|
|
14
22
|
Process:
|
|
15
23
|
|
package/bin/sellable-install.mjs
CHANGED
|
@@ -40,7 +40,7 @@ function getMcpVersion() {
|
|
|
40
40
|
} catch {}
|
|
41
41
|
return "latest";
|
|
42
42
|
}
|
|
43
|
-
const CODEX_PLUGIN_VERSION = "0.1.
|
|
43
|
+
const CODEX_PLUGIN_VERSION = "0.1.30";
|
|
44
44
|
const CODEX_PLUGIN_COMPAT_VERSIONS = [
|
|
45
45
|
"0.1.8",
|
|
46
46
|
"0.1.9",
|
|
@@ -63,6 +63,7 @@ const CODEX_PLUGIN_COMPAT_VERSIONS = [
|
|
|
63
63
|
"0.1.26",
|
|
64
64
|
"0.1.27",
|
|
65
65
|
"0.1.28",
|
|
66
|
+
"0.1.29",
|
|
66
67
|
];
|
|
67
68
|
const INSTALL_PACKAGE_SPEC =
|
|
68
69
|
process.env.SELLABLE_INSTALL_PACKAGE_SPEC || "@sellable/install@latest";
|
|
@@ -566,9 +567,9 @@ instruction loading, file lookup, plugin cache versions, missing linked files,
|
|
|
566
567
|
or tool discovery. Start in product language:
|
|
567
568
|
|
|
568
569
|
\`\`\`text
|
|
569
|
-
I’ll help you launch this as a Sellable campaign. First I’ll
|
|
570
|
-
|
|
571
|
-
|
|
570
|
+
I’ll help you launch this as a Sellable campaign. First I’ll resolve the
|
|
571
|
+
client/company this campaign is for, then I’ll turn that into a campaign brief
|
|
572
|
+
before anything is created.
|
|
572
573
|
\`\`\`
|
|
573
574
|
|
|
574
575
|
If a linked/local skill file is stale or missing, silently use the installed
|
|
@@ -584,7 +585,8 @@ clear business decisions, tradeoffs, and approval gates. Use product language:
|
|
|
584
585
|
- "a couple setup choices", not \`request_user_input\`
|
|
585
586
|
- "campaign brief", not prompt artifact
|
|
586
587
|
- "lead source", not provider internals unless comparing source options
|
|
587
|
-
- "
|
|
588
|
+
- "I can create a draft shell for you to watch, but no leads import and nothing
|
|
589
|
+
sends until you approve", not mutation jargon
|
|
588
590
|
|
|
589
591
|
When explaining lead-source decisions, show the concrete counts behind the
|
|
590
592
|
logic: lanes searched, timeframe, raw result counts, finalist posts or preview
|
|
@@ -592,6 +594,13 @@ rows, sampled people, sampled fits as n/N (%), estimated usable people, and the
|
|
|
592
594
|
confidence basis. Never show a percent like "73% match" without the numerator,
|
|
593
595
|
denominator, and sample basis.
|
|
594
596
|
|
|
597
|
+
Do not forecast LinkedIn connection acceptance rates, reply rates, meetings,
|
|
598
|
+
pipeline, revenue, or ROI in customer-facing source reviews unless the user
|
|
599
|
+
supplied verified benchmark data for this exact workspace/sender. Without that
|
|
600
|
+
data, compare sources by source volume, sampled ICP fit, activity/warmth
|
|
601
|
+
signals, cleanup risk, and confidence basis. If a user asks for a forecast,
|
|
602
|
+
label it explicitly as not estimated from this run.
|
|
603
|
+
|
|
595
604
|
Every approval gate must include artifact access after the readable inline
|
|
596
605
|
content. Show an \`Open artifacts:\` line with clickable markdown links using
|
|
597
606
|
absolute paths when the host supports them, plus the plain path for CLI users.
|
|
@@ -667,18 +676,20 @@ Treat host capabilities as concrete functions, not prose conventions:
|
|
|
667
676
|
\`mcp__sellable__get_post_find_leads_scout_registry({})\` after source
|
|
668
677
|
approval and before dispatching the post-lead filter/message scouts.
|
|
669
678
|
- \`launch_source_scout\`: Claude Code uses \`Task\` with \`subagent_type\` equal to
|
|
670
|
-
the registry \`name
|
|
679
|
+
the registry \`name\` only when the session lists those agents; Codex uses
|
|
680
|
+
named custom agents such as
|
|
671
681
|
\`source-scout-linkedin-engagement\`, \`source-scout-sales-nav\`, and
|
|
672
682
|
\`source-scout-prospeo-contact\` when subagents are available.
|
|
673
683
|
- \`launch_post_find_leads_scout\`: Claude Code uses \`Task\` with
|
|
674
|
-
\`subagent_type\` equal to the returned post-lead registry \`name
|
|
675
|
-
uses the returned custom agents such as
|
|
676
|
-
\`post-find-leads-message-scout\` when
|
|
684
|
+
\`subagent_type\` equal to the returned post-lead registry \`name\` only when
|
|
685
|
+
the session lists those agents; Codex uses the returned custom agents such as
|
|
686
|
+
\`post-find-leads-filter-scout\` and \`post-find-leads-message-scout\` when
|
|
687
|
+
subagents are available.
|
|
677
688
|
|
|
678
|
-
If a required interactive
|
|
679
|
-
Sellable install/reload problem.
|
|
680
|
-
|
|
681
|
-
scripts.
|
|
689
|
+
If a required interactive question function or MCP loader is missing, stop and
|
|
690
|
+
explain the Sellable install/reload problem. Named scout agents are optional
|
|
691
|
+
acceleration: if they are absent, do not surface install status to the customer;
|
|
692
|
+
fall back to product-native MCP orchestration instead of local scripts.
|
|
682
693
|
|
|
683
694
|
Never narrate local draft housekeeping to the user. If you create directories,
|
|
684
695
|
save drafts, write artifacts, or persist intermediate state, translate it into
|
|
@@ -691,106 +702,56 @@ customer-facing progress copy.
|
|
|
691
702
|
|
|
692
703
|
Do not treat the active Sellable workspace as the campaign subject. The
|
|
693
704
|
workspace only tells you where the campaign will be saved. Before buyer, CTA,
|
|
694
|
-
proof, or source questions, identify
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
705
|
+
proof, or source questions, identify the campaign identity: the person/profile
|
|
706
|
+
or company this campaign is for, plus enough company/product context to build
|
|
707
|
+
the brief. This is only the client-prospect/bootstrap identity for
|
|
708
|
+
\`clientProspectId\` or \`senderLinkedinUrl\`; it is not a connected-sender check.
|
|
709
|
+
|
|
710
|
+
Do not call \`mcp__sellable__list_senders\`, \`mcp__sellable__get_sender\`, or
|
|
711
|
+
surface connected/missing sender state during setup, brief, source, filter, or
|
|
712
|
+
message review. Sender availability belongs only to the Settings/final launch
|
|
713
|
+
handoff after message approval and the 10-lead validation sample.
|
|
714
|
+
|
|
715
|
+
If the invocation or user answer includes an existing \`clientProspectId\`, keep
|
|
716
|
+
it as the preferred \`create_campaign\` identity input. If it includes a LinkedIn
|
|
717
|
+
profile URL, keep that URL as \`senderLinkedinUrl\` so the backend can
|
|
718
|
+
resolve/materialize the sender prospect when the watchable campaign shell is
|
|
719
|
+
created. Do not require a connected sender before shell creation.
|
|
698
720
|
|
|
699
721
|
If the user supplied a LinkedIn profile, website, domain, company name, or
|
|
700
|
-
|
|
722
|
+
explicit client prospect identity in the invocation, do one lightweight lookup
|
|
723
|
+
first:
|
|
701
724
|
|
|
702
725
|
- LinkedIn profile: call \`mcp__sellable__fetch_linkedin_profile\`.
|
|
703
726
|
- Website/domain/company: call \`mcp__sellable__fetch_company\` when possible,
|
|
704
727
|
otherwise one web lookup.
|
|
705
|
-
-
|
|
706
|
-
|
|
728
|
+
- Existing client prospect id: use it directly and do one company/profile lookup
|
|
729
|
+
only if a URL/domain is also available.
|
|
707
730
|
|
|
708
731
|
Then summarize what you found in one or two lines and ask the user to confirm
|
|
709
|
-
the campaign
|
|
732
|
+
the campaign identity/focus before continuing. Do not mention connected sender
|
|
733
|
+
availability in this confirmation.
|
|
710
734
|
|
|
711
|
-
If the user did not provide the launch identity,
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
accounts. Do not ask the user to pick an input type before checking connected
|
|
715
|
-
senders. If there is any likely connected sender, use
|
|
716
|
-
\`mcp__sellable__enrich_sender\` on the best match to infer their current or most
|
|
717
|
-
recent company, then ask a structured confirmation question:
|
|
718
|
-
|
|
719
|
-
\`\`\`text
|
|
720
|
-
I’m ready to build this in {workspace}. I found {matched sender} connected here.
|
|
721
|
-
|
|
722
|
-
Is that you, and is this campaign for {company}?
|
|
723
|
-
\`\`\`
|
|
724
|
-
|
|
725
|
-
The structured options must be no more than three choices:
|
|
726
|
-
|
|
727
|
-
1. \`Yes — use {matched sender} for {company}\`
|
|
728
|
-
2. \`No — I'll paste a LinkedIn profile\`
|
|
729
|
-
3. \`Use a company domain instead\`
|
|
730
|
-
|
|
731
|
-
If there are multiple likely connected senders, mention the best one in the
|
|
732
|
-
question and use option 2 for either a different connected sender or a pasted
|
|
733
|
-
LinkedIn profile.
|
|
734
|
-
|
|
735
|
-
Use the structured question tool only for the choice. Do not use
|
|
736
|
-
\`request_user_input\`/\`AskUserQuestion\` to collect a LinkedIn URL, company
|
|
737
|
-
domain, or freeform text. If the user chooses option 2, ask in normal chat:
|
|
738
|
-
\`Paste the LinkedIn URL I should use, and I’ll look it up.\` Then call
|
|
739
|
-
\`mcp__sellable__fetch_linkedin_profile\`, infer their current or most recent
|
|
740
|
-
company, and confirm company and sender again. If the user chooses option 3, ask
|
|
741
|
-
in normal chat: \`Paste the company domain, and I’ll do a quick lookup before we
|
|
742
|
-
keep going.\` Then call \`mcp__sellable__fetch_company\` when possible, otherwise
|
|
743
|
-
one web lookup, and ask who the LinkedIn messages should send from.
|
|
744
|
-
|
|
745
|
-
If \`mcp__sellable__list_senders\` returns zero connected senders, avoid the
|
|
746
|
-
sender-confirmation branch entirely. Do not ask the user to choose an input type
|
|
747
|
-
with the structured question tool. Ask in normal chat for the user's LinkedIn
|
|
748
|
-
URL or the company they want to send on behalf of so you can research context:
|
|
735
|
+
If the user did not provide the launch identity, ask in normal chat for the
|
|
736
|
+
LinkedIn profile or company website to use as the campaign identity. Do not ask
|
|
737
|
+
them to choose an input type with the structured question tool:
|
|
749
738
|
|
|
750
739
|
\`\`\`text
|
|
751
740
|
I’m ready to build this in {workspace}.
|
|
752
741
|
|
|
753
|
-
First, paste
|
|
754
|
-
|
|
755
|
-
offer, proof, and lead source.
|
|
756
|
-
\`\`\`
|
|
757
|
-
|
|
758
|
-
If there is no strong sender match, do not show a structured choice that says
|
|
759
|
-
"LinkedIn profile" vs "Company website". The point of this gate is not "pick a
|
|
760
|
-
sender" or "pick an input type"; it is to learn who the user is, infer the
|
|
761
|
-
current or most recent company, and then confirm who we are sending from. The
|
|
762
|
-
customer-facing shape should be:
|
|
763
|
-
|
|
764
|
-
\`\`\`text
|
|
765
|
-
I’m ready to build this in {workspace}.
|
|
766
|
-
|
|
767
|
-
First, what’s your LinkedIn URL? If you’d rather start from the company, paste
|
|
768
|
-
the company website instead.
|
|
769
|
-
\`\`\`
|
|
770
|
-
|
|
771
|
-
After the user pastes a URL/domain, do the lightweight lookup. For a LinkedIn profile, call
|
|
772
|
-
\`mcp__sellable__fetch_linkedin_profile\` and infer the user's current or most
|
|
773
|
-
recent company from the profile. For a company website, call
|
|
774
|
-
\`mcp__sellable__fetch_company\` when possible, otherwise one web lookup.
|
|
775
|
-
|
|
776
|
-
If \`mcp__sellable__list_senders\` did not already run, call it once after the
|
|
777
|
-
lookup to see whether the fetched user appears to match a connected sender. If
|
|
778
|
-
there is a likely match, ask:
|
|
779
|
-
|
|
780
|
-
\`\`\`text
|
|
781
|
-
Cool — are you {matched sender}, and is this campaign for {company}?
|
|
782
|
-
\`\`\`
|
|
783
|
-
|
|
784
|
-
If there is no likely sender match, ask:
|
|
785
|
-
|
|
786
|
-
\`\`\`text
|
|
787
|
-
Cool — I have this campaign as {company}. Who should the LinkedIn messages send from?
|
|
742
|
+
First, paste the LinkedIn profile or company website for the client/company this
|
|
743
|
+
campaign is for. I’ll use that to resolve the campaign identity before we pick
|
|
744
|
+
the target, offer, proof, and lead source.
|
|
788
745
|
\`\`\`
|
|
789
746
|
|
|
790
|
-
|
|
791
|
-
|
|
747
|
+
After the user pastes a URL/domain, do the lightweight lookup. For a LinkedIn
|
|
748
|
+
profile, call \`mcp__sellable__fetch_linkedin_profile\` and infer the current or
|
|
749
|
+
most recent company from the profile. For a company website, call
|
|
750
|
+
\`mcp__sellable__fetch_company\` when possible, otherwise one web lookup. If a
|
|
751
|
+
LinkedIn profile URL is available, retain it as \`senderLinkedinUrl\` for
|
|
752
|
+
\`create_campaign\`; if a \`clientProspectId\` is available, pass that instead.
|
|
792
753
|
|
|
793
|
-
After the user confirms the
|
|
754
|
+
After the user confirms the campaign identity, run one lightweight company
|
|
794
755
|
lookup if it has not already run, then ask the campaign setup questions. The
|
|
795
756
|
setup questions should use the confirmed company context so they do not feel
|
|
796
757
|
generic.
|
|
@@ -800,10 +761,8 @@ Before the identity gate, use this customer-facing shape:
|
|
|
800
761
|
\`\`\`text
|
|
801
762
|
I’m ready to build the campaign in {workspace}.
|
|
802
763
|
|
|
803
|
-
First I’ll
|
|
804
|
-
|
|
805
|
-
that to understand the company before we choose the target, offer, proof, and
|
|
806
|
-
lead source.
|
|
764
|
+
First I’ll resolve the client/company this campaign is for. I’ll use that
|
|
765
|
+
context to choose the target, offer, proof, and lead source.
|
|
807
766
|
|
|
808
767
|
Then I’ll turn that into a campaign brief for you to approve before anything is created.
|
|
809
768
|
\`\`\`
|
|
@@ -881,14 +840,15 @@ updates.
|
|
|
881
840
|
copies of this file; packaged Claude Code and Codex runs must use the MCP
|
|
882
841
|
asset loader so they share the same config.
|
|
883
842
|
3. Follow that prompt and workflow config exactly.
|
|
884
|
-
4. For message generation,
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
\`message-validation.md\` from the brief, lead review, or
|
|
843
|
+
4. For message generation, use the \`post-find-leads-message-scout\` agent when
|
|
844
|
+
available; its prompt carries the campaign-launch message rules. In the
|
|
845
|
+
parent-thread fallback, load
|
|
846
|
+
\`mcp__sellable__get_subskill_asset({ subskillName: "create-campaign-v2", assetPath: "references/message-review-fast-path.md" })\`.
|
|
847
|
+
Do not synthesize \`message-validation.md\` from the brief, lead review, or
|
|
848
|
+
general knowledge.
|
|
889
849
|
5. Treat message quality as the gate before minting. Do not create a campaign,
|
|
890
850
|
show a commit gate, or mint anything until \`message-validation.md\` proves
|
|
891
|
-
the
|
|
851
|
+
the fast-path message workflow ran and \`message-review.md\` recommends
|
|
892
852
|
\`approve-message\` against the gold-standard rules.
|
|
893
853
|
6. Do not create or mutate the live campaign until the approval gate returns
|
|
894
854
|
\`approve\`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: create-campaign
|
|
3
|
-
description: Create a Sellable campaign through the
|
|
3
|
+
description: Create a Sellable campaign through the shell-first CampaignOffer workflow.
|
|
4
4
|
visibility: public
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- mcp__sellable__get_auth_status
|
|
@@ -66,6 +66,14 @@ allowed-tools:
|
|
|
66
66
|
|
|
67
67
|
Use this as the customer-facing entrypoint for Sellable campaign creation.
|
|
68
68
|
|
|
69
|
+
CampaignOffer state is canonical; disk artifacts are a debug trail. The
|
|
70
|
+
internal create-campaign-v2 flow still writes the diagnostics, and all 14 disk
|
|
71
|
+
artifacts remain as debug outputs, but resume, gating, and handoff read campaign
|
|
72
|
+
state first. The
|
|
73
|
+
watchable campaign exists after the short brief; lead import is bounded to the
|
|
74
|
+
first review batch, and enrichment/message generation waits until rubrics and
|
|
75
|
+
the approved message template are saved on the campaign.
|
|
76
|
+
|
|
69
77
|
## Opening Turn Contract
|
|
70
78
|
|
|
71
79
|
On the first visible response after this skill is invoked, do not narrate
|
|
@@ -73,9 +81,9 @@ instruction loading, file lookup, plugin cache versions, missing linked files,
|
|
|
73
81
|
or tool discovery. Start in product language:
|
|
74
82
|
|
|
75
83
|
```text
|
|
76
|
-
I’ll help you launch this as a Sellable campaign. First I’ll
|
|
77
|
-
|
|
78
|
-
|
|
84
|
+
I’ll help you launch this as a Sellable campaign. First I’ll resolve the
|
|
85
|
+
client/company this campaign is for, then I’ll turn that into a campaign brief
|
|
86
|
+
before any leads are imported or anything can send.
|
|
79
87
|
```
|
|
80
88
|
|
|
81
89
|
If a linked/local skill file is stale or missing, silently use the installed
|
|
@@ -91,7 +99,8 @@ clear business decisions, tradeoffs, and approval gates. Use product language:
|
|
|
91
99
|
- "a couple setup choices", not `request_user_input`
|
|
92
100
|
- "campaign brief", not prompt artifact
|
|
93
101
|
- "lead source", not provider internals unless comparing source options
|
|
94
|
-
- "
|
|
102
|
+
- "I can create a draft shell for you to watch, but no leads import and nothing
|
|
103
|
+
sends until you approve", not mutation jargon
|
|
95
104
|
|
|
96
105
|
When explaining lead-source decisions, show the concrete counts behind the
|
|
97
106
|
logic: lanes searched, timeframe, raw result counts, finalist posts or preview
|
|
@@ -99,28 +108,40 @@ rows, sampled people, sampled fits as n/N (%), estimated usable people, and the
|
|
|
99
108
|
confidence basis. Never show a percent like "73% match" without the numerator,
|
|
100
109
|
denominator, and sample basis.
|
|
101
110
|
|
|
111
|
+
Do not forecast LinkedIn connection acceptance rates, reply rates, meetings,
|
|
112
|
+
pipeline, revenue, or ROI in customer-facing source reviews unless the user
|
|
113
|
+
supplied verified benchmark data for this exact workspace/sender. Without that
|
|
114
|
+
data, compare sources by source volume, sampled ICP fit, activity/warmth
|
|
115
|
+
signals, cleanup risk, and confidence basis. If a user asks for a forecast,
|
|
116
|
+
label it explicitly as not estimated from this run.
|
|
117
|
+
|
|
102
118
|
When the user has not supplied a source and multiple source angles are viable,
|
|
103
119
|
scout those angles as independent branches when the host can actually do it:
|
|
104
120
|
LinkedIn Engagement / active post engagers (internal `signal-discovery`
|
|
105
121
|
provider prompt), Sales Nav / title + company filters, and Prospeo Contact /
|
|
106
122
|
domains only when relevant. In Codex, explicitly spawn the named custom scouts
|
|
107
|
-
`source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
|
|
108
|
-
the credible lanes
|
|
123
|
+
`source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
|
|
124
|
+
`source-scout-prospeo-contact` for the credible lanes only when the current host
|
|
125
|
+
exposes those names; Codex does not infer subagent fan-out from generic source
|
|
109
126
|
comparison wording. In Claude Code, invoke the generated `source-scout-*`
|
|
110
|
-
Task/Agent subagents for all credible lanes in one assistant message
|
|
111
|
-
installer writes them from the same
|
|
112
|
-
explicit Sellable MCP tool allowlists.
|
|
113
|
-
`get_source_scout_registry` before
|
|
114
|
-
copy, is the runtime source of truth.
|
|
115
|
-
|
|
127
|
+
Task/Agent subagents for all credible lanes in one assistant message only when
|
|
128
|
+
the current session lists those names. The installer writes them from the same
|
|
129
|
+
canonical Sellable agent registry with explicit Sellable MCP tool allowlists.
|
|
130
|
+
The create-campaign-v2 subskill calls `get_source_scout_registry` before
|
|
131
|
+
dispatch so the current registry, not this copy, is the runtime source of truth.
|
|
132
|
+
If the host runs them sequentially or the named agents are unavailable, do not
|
|
133
|
+
claim they ran in parallel and do not surface install status to the customer. In
|
|
134
|
+
chat, call the downstream copy stage `message generation`;
|
|
116
135
|
`message-validation.md` is only an internal proof artifact.
|
|
117
136
|
|
|
118
137
|
After find-leads returns a lead source and the user approves it, use the same
|
|
119
138
|
registry pattern for the two post-lead branches. The create-campaign-v2 subskill
|
|
120
139
|
calls `get_post_find_leads_scout_registry`, then launches the returned
|
|
121
140
|
filter-leads scout and message-generation scout together when real subagents are
|
|
122
|
-
available
|
|
123
|
-
cannot run the two
|
|
141
|
+
available and the current session exposes the returned names. Message
|
|
142
|
+
generation must not wait for the filter unless the host cannot run the two
|
|
143
|
+
branches concurrently. If the post-lead agents are absent, the main thread still
|
|
144
|
+
orchestrates the same branches from the compact context with MCP tools/assets.
|
|
124
145
|
|
|
125
146
|
Use rendered Markdown for user review surfaces, not fenced code blocks. Keep
|
|
126
147
|
lines short, use indexed section labels and bullets, and translate internal
|
|
@@ -130,7 +151,7 @@ Every approval gate must include artifact access after the readable inline
|
|
|
130
151
|
content. Show a short `Open artifact:` line with the one key clickable markdown
|
|
131
152
|
link for that stage. Do not show raw filesystem paths unless links cannot be
|
|
132
153
|
created or the user asks. Do this for brief approval, lead-source
|
|
133
|
-
approval/review, lead-filter review, message review
|
|
154
|
+
approval/review, lead-filter review, and message review.
|
|
134
155
|
The link is for deeper inspection; never use it as a substitute for showing the
|
|
135
156
|
content in chat.
|
|
136
157
|
|
|
@@ -202,18 +223,20 @@ Treat host capabilities as concrete functions, not prose conventions:
|
|
|
202
223
|
`mcp__sellable__get_post_find_leads_scout_registry({})` after source
|
|
203
224
|
approval and before dispatching the post-lead filter/message scouts.
|
|
204
225
|
- `launch_source_scout`: Claude Code uses `Task` with `subagent_type` equal to
|
|
205
|
-
the registry `name
|
|
226
|
+
the registry `name` only when the session lists those agents; Codex uses
|
|
227
|
+
named custom agents such as
|
|
206
228
|
`source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
|
|
207
229
|
`source-scout-prospeo-contact` when subagents are available.
|
|
208
230
|
- `launch_post_find_leads_scout`: Claude Code uses `Task` with `subagent_type`
|
|
209
|
-
equal to the returned post-lead registry `name
|
|
210
|
-
custom agents such as
|
|
211
|
-
`post-find-leads-message-scout` when
|
|
231
|
+
equal to the returned post-lead registry `name` only when the session lists
|
|
232
|
+
those agents; Codex uses the returned custom agents such as
|
|
233
|
+
`post-find-leads-filter-scout` and `post-find-leads-message-scout` when
|
|
234
|
+
subagents are available.
|
|
212
235
|
|
|
213
|
-
If a required interactive
|
|
214
|
-
Sellable install/reload problem.
|
|
215
|
-
|
|
216
|
-
scripts.
|
|
236
|
+
If a required interactive question function or MCP loader is missing, stop and
|
|
237
|
+
explain the Sellable install/reload problem. Named scout agents are optional
|
|
238
|
+
acceleration: if they are absent, do not surface install status to the customer;
|
|
239
|
+
fall back to product-native MCP orchestration instead of local scripts.
|
|
217
240
|
|
|
218
241
|
Never narrate local draft housekeeping to the user. If you create directories,
|
|
219
242
|
save drafts, write artifacts, or persist intermediate state, translate it into
|
|
@@ -226,106 +249,56 @@ customer-facing progress copy.
|
|
|
226
249
|
|
|
227
250
|
Do not treat the active Sellable workspace as the campaign subject. The
|
|
228
251
|
workspace only tells you where the campaign will be saved. Before buyer, CTA,
|
|
229
|
-
proof, or source questions, identify
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
252
|
+
proof, or source questions, identify the campaign identity: the person/profile
|
|
253
|
+
or company this campaign is for, plus enough company/product context to build
|
|
254
|
+
the brief. This is only the client-prospect/bootstrap identity for
|
|
255
|
+
`clientProspectId` or `senderLinkedinUrl`; it is not a connected-sender check.
|
|
256
|
+
|
|
257
|
+
Do not call `mcp__sellable__list_senders`, `mcp__sellable__get_sender`, or
|
|
258
|
+
surface connected/missing sender state during setup, brief, source, filter, or
|
|
259
|
+
message review. Sender availability belongs only to the Settings/final launch
|
|
260
|
+
handoff after message approval and the 10-lead validation sample.
|
|
261
|
+
|
|
262
|
+
If the invocation or user answer includes an existing `clientProspectId`, keep
|
|
263
|
+
it as the preferred `create_campaign` identity input. If it includes a LinkedIn
|
|
264
|
+
profile URL, keep that URL as `senderLinkedinUrl` so the backend can
|
|
265
|
+
resolve/materialize the sender prospect when the watchable campaign shell is
|
|
266
|
+
created. Do not require a connected sender before shell creation.
|
|
233
267
|
|
|
234
268
|
If the user supplied a LinkedIn profile, website, domain, company name, or
|
|
235
|
-
|
|
269
|
+
explicit client prospect identity in the invocation, do one lightweight lookup
|
|
270
|
+
first:
|
|
236
271
|
|
|
237
272
|
- LinkedIn profile: call `mcp__sellable__fetch_linkedin_profile`.
|
|
238
273
|
- Website/domain/company: call `mcp__sellable__fetch_company` when possible,
|
|
239
274
|
otherwise one web lookup.
|
|
240
|
-
-
|
|
241
|
-
|
|
275
|
+
- Existing client prospect id: use it directly and do one company/profile lookup
|
|
276
|
+
only if a URL/domain is also available.
|
|
242
277
|
|
|
243
278
|
Then summarize what you found in one or two lines and ask the user to confirm
|
|
244
|
-
the campaign
|
|
245
|
-
|
|
246
|
-
If the user did not provide the launch identity, quietly call
|
|
247
|
-
`mcp__sellable__list_senders` once if available. This is a shortcut to deduce
|
|
248
|
-
who the user might be from their Sellable API token and connected LinkedIn
|
|
249
|
-
accounts. Do not ask the user to pick an input type before checking connected
|
|
250
|
-
senders. If there is any likely connected sender, use
|
|
251
|
-
`mcp__sellable__enrich_sender` on the best match to infer their current or most
|
|
252
|
-
recent company, then ask a structured confirmation question:
|
|
253
|
-
|
|
254
|
-
```text
|
|
255
|
-
I’m ready to build this in {workspace}. I found {matched sender} connected here.
|
|
256
|
-
|
|
257
|
-
Is that you, and is this campaign for {company}?
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
The structured options must be no more than three choices:
|
|
261
|
-
|
|
262
|
-
1. `Yes — use {matched sender} for {company}`
|
|
263
|
-
2. `No — I'll paste a LinkedIn profile`
|
|
264
|
-
3. `Use a company domain instead`
|
|
265
|
-
|
|
266
|
-
If there are multiple likely connected senders, mention the best one in the
|
|
267
|
-
question and use option 2 for either a different connected sender or a pasted
|
|
268
|
-
LinkedIn profile.
|
|
279
|
+
the campaign identity/focus before continuing. Do not mention connected sender
|
|
280
|
+
availability in this confirmation.
|
|
269
281
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
`Paste the LinkedIn URL I should use, and I’ll look it up.` Then call
|
|
274
|
-
`mcp__sellable__fetch_linkedin_profile`, infer their current or most recent
|
|
275
|
-
company, and confirm company and sender again. If the user chooses option 3, ask
|
|
276
|
-
in normal chat: `Paste the company domain, and I’ll do a quick lookup before we
|
|
277
|
-
keep going.` Then call `mcp__sellable__fetch_company` when possible, otherwise
|
|
278
|
-
one web lookup, and ask who the LinkedIn messages should send from.
|
|
279
|
-
|
|
280
|
-
If `mcp__sellable__list_senders` returns zero connected senders, avoid the
|
|
281
|
-
sender-confirmation branch entirely. Do not ask the user to choose an input type
|
|
282
|
-
with the structured question tool. Ask in normal chat for the user's LinkedIn
|
|
283
|
-
URL or the company they want to send on behalf of so you can research context:
|
|
282
|
+
If the user did not provide the launch identity, ask in normal chat for the
|
|
283
|
+
LinkedIn profile or company website to use as the campaign identity. Do not ask
|
|
284
|
+
them to choose an input type with the structured question tool:
|
|
284
285
|
|
|
285
286
|
```text
|
|
286
287
|
I’m ready to build this in {workspace}.
|
|
287
288
|
|
|
288
|
-
First, paste
|
|
289
|
-
|
|
290
|
-
offer, proof, and lead source.
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
If there is no strong sender match, do not show a structured choice that says
|
|
294
|
-
"LinkedIn profile" vs "Company website". The point of this gate is not "pick a
|
|
295
|
-
sender" or "pick an input type"; it is to learn who the user is, infer the
|
|
296
|
-
current or most recent company, and then confirm who we are sending from. The
|
|
297
|
-
customer-facing shape should be:
|
|
298
|
-
|
|
299
|
-
```text
|
|
300
|
-
I’m ready to build this in {workspace}.
|
|
301
|
-
|
|
302
|
-
First, what’s your LinkedIn URL? If you’d rather start from the company, paste
|
|
303
|
-
the company website instead.
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
After the user pastes a URL/domain, do the lightweight lookup. For a LinkedIn profile, call
|
|
307
|
-
`mcp__sellable__fetch_linkedin_profile` and infer the user's current or most
|
|
308
|
-
recent company from the profile. For a company website, call
|
|
309
|
-
`mcp__sellable__fetch_company` when possible, otherwise one web lookup.
|
|
310
|
-
|
|
311
|
-
If `mcp__sellable__list_senders` did not already run, call it once after the
|
|
312
|
-
lookup to see whether the fetched user appears to match a connected sender. If
|
|
313
|
-
there is a likely match, ask:
|
|
314
|
-
|
|
315
|
-
```text
|
|
316
|
-
Cool — are you {matched sender}, and is this campaign for {company}?
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
If there is no likely sender match, ask:
|
|
320
|
-
|
|
321
|
-
```text
|
|
322
|
-
Cool — I have this campaign as {company}. Who should the LinkedIn messages send from?
|
|
289
|
+
First, paste the LinkedIn profile or company website for the client/company this
|
|
290
|
+
campaign is for. I’ll use that to resolve the campaign identity before we pick
|
|
291
|
+
the target, offer, proof, and lead source.
|
|
323
292
|
```
|
|
324
293
|
|
|
325
|
-
|
|
326
|
-
|
|
294
|
+
After the user pastes a URL/domain, do the lightweight lookup. For a LinkedIn
|
|
295
|
+
profile, call `mcp__sellable__fetch_linkedin_profile` and infer the current or
|
|
296
|
+
most recent company from the profile. For a company website, call
|
|
297
|
+
`mcp__sellable__fetch_company` when possible, otherwise one web lookup. If a
|
|
298
|
+
LinkedIn profile URL is available, retain it as `senderLinkedinUrl` for
|
|
299
|
+
`create_campaign`; if a `clientProspectId` is available, pass that instead.
|
|
327
300
|
|
|
328
|
-
After the user confirms the
|
|
301
|
+
After the user confirms the campaign identity, run one lightweight company
|
|
329
302
|
lookup if it has not already run, then ask the campaign setup questions. The
|
|
330
303
|
setup questions should use the confirmed company context so they do not feel
|
|
331
304
|
generic.
|
|
@@ -335,12 +308,11 @@ Before the identity gate, use this customer-facing shape:
|
|
|
335
308
|
```text
|
|
336
309
|
I’m ready to build the campaign in {workspace}.
|
|
337
310
|
|
|
338
|
-
First I’ll
|
|
339
|
-
|
|
340
|
-
that to understand the company before we choose the target, offer, proof, and
|
|
341
|
-
lead source.
|
|
311
|
+
First I’ll resolve the client/company this campaign is for. I’ll use that
|
|
312
|
+
context to choose the target, offer, proof, and lead source.
|
|
342
313
|
|
|
343
|
-
Then I’ll turn that into a campaign brief for you to approve before
|
|
314
|
+
Then I’ll turn that into a campaign brief for you to approve before any leads
|
|
315
|
+
are imported or anything can send.
|
|
344
316
|
```
|
|
345
317
|
|
|
346
318
|
Do not silently ask Codex intake or approval questions as plain chat when
|
|
@@ -374,7 +346,7 @@ No problem. You can still continue by switching Codex to Plan mode and running:
|
|
|
374
346
|
|
|
375
347
|
$sellable:create-campaign
|
|
376
348
|
|
|
377
|
-
I won’t
|
|
349
|
+
I won’t import leads, attach a sequence, or start anything until the brief, source, filters, and message are set.
|
|
378
350
|
```
|
|
379
351
|
|
|
380
352
|
Plain chat questions are only acceptable in non-interactive `codex exec`
|
|
@@ -515,17 +487,21 @@ updates.
|
|
|
515
487
|
copies of this file; packaged Claude Code and Codex runs must use the MCP
|
|
516
488
|
asset loader so they share the same config.
|
|
517
489
|
3. Follow that prompt and workflow config exactly.
|
|
518
|
-
4. For message generation,
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
`message-validation.md` from the brief, lead review, or
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
`
|
|
490
|
+
4. For message generation, use the `post-find-leads-message-scout` agent when
|
|
491
|
+
available; its prompt carries the campaign-launch message rules. In the
|
|
492
|
+
parent-thread fallback, load
|
|
493
|
+
`mcp__sellable__get_subskill_asset({ subskillName: "create-campaign-v2", assetPath: "references/message-review-fast-path.md" })`.
|
|
494
|
+
Do not synthesize `message-validation.md` from the brief, lead review, or
|
|
495
|
+
general knowledge.
|
|
496
|
+
5. Create the campaign shell early with the v1 brief so the user can open the
|
|
497
|
+
watch link and see useful setup state immediately. Import only the first
|
|
498
|
+
bounded review batch after the source is attached to the campaign; do not
|
|
499
|
+
queue workflow cells, attach a sequence, or start until
|
|
500
|
+
`message-validation.md` proves the fast-path message workflow ran,
|
|
501
|
+
`message-review.md` approves the template, rubrics are saved, and the
|
|
502
|
+
approved message set is synced into the campaign brief.
|
|
503
|
+
6. Keep `selectedLeadListId` as the source list and `workflowTableId` as the
|
|
504
|
+
campaign table. Do not use disk files as the post-mint source of truth.
|
|
529
505
|
7. Do not ask the user to run another command.
|
|
530
506
|
|
|
531
507
|
## Fallback
|