@sellable/mcp 0.1.209 → 0.1.210
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/agents/post-find-leads-message-scout.md +72 -63
- package/agents/registry.json +7 -50
- package/dist/tools/leads.js +9 -8
- package/dist/tools/prompts.js +22 -30
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +26 -27
- package/skills/create-campaign-v2/SKILL.md +36 -37
- package/skills/create-campaign-v2/SOUL.md +28 -26
- package/skills/create-campaign-v2/core/flow.v2.json +1 -1
- package/skills/create-campaign-v2/references/watch-guide-narration.md +7 -6
- package/skills/generate-messages/SKILL.md +32 -12
- package/agents/post-find-leads-filter-scout.md +0 -81
|
@@ -17,20 +17,19 @@ campaign state. The main thread owns approval and campaign writes.
|
|
|
17
17
|
|
|
18
18
|
## Source Of Truth
|
|
19
19
|
|
|
20
|
-
Use the
|
|
20
|
+
Use the lean handoff supplied by the parent thread:
|
|
21
21
|
|
|
22
22
|
- `campaignId`
|
|
23
|
-
- campaign revision or `campaignUpdatedAt`
|
|
24
|
-
- campaign brief summary from the parent, then the current `campaignBrief` /
|
|
25
|
-
campaign brief content loaded through Sellable tools
|
|
26
|
-
- selected source decision and provider state
|
|
27
|
-
- `selectedLeadListId` or selected source list context
|
|
28
23
|
- `workflowTableId`
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
-
|
|
24
|
+
- concise brief summary: offer, buyer, source context, safe proof, blocked claims
|
|
25
|
+
- concise source summary and source-use rule
|
|
26
|
+
- 3-5 sample workflow-table rows with `rowId`, name, title, company, and short
|
|
27
|
+
signal
|
|
28
|
+
- optional `campaignName`, `selectedLeadListId`, and filter choice
|
|
29
|
+
|
|
30
|
+
Do not require campaign revision, brief hash, copied row count, review-batch
|
|
31
|
+
count, row hash, or a long review-batch row-id list. The branch can verify the
|
|
32
|
+
current state with live Sellable tools.
|
|
34
33
|
|
|
35
34
|
Do not require or hunt for `brief.md`, `lead-review.md`, or `lead-sample.json`.
|
|
36
35
|
Those files are optional debug context only when the parent explicitly provides
|
|
@@ -40,34 +39,47 @@ read stale local markdown files to reconstruct campaign state.
|
|
|
40
39
|
All live reads must come from scoped MCP/product tools by campaign and
|
|
41
40
|
workspace, such as `get_campaign`, `get_campaign_context`, and
|
|
42
41
|
`get_rows_minimal({ tableId: workflowTableId })`, or from equivalent parent
|
|
43
|
-
thread payloads. Load the current campaign brief and the
|
|
44
|
-
rows
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
thread payloads. Load the current campaign brief/context and use the provided
|
|
43
|
+
sample rows as the drafting sample. Reject the task as `blocked` if the campaign
|
|
44
|
+
id, workspace, or `workflowTableId` does not match the branch input.
|
|
45
|
+
|
|
46
|
+
Reference assets are packaged MCP assets. Load them only through
|
|
47
|
+
`get_subskill_asset`; do not use shell commands, local `Read`, `rg`, `cat`,
|
|
48
|
+
`wc`, plugin-cache paths, repo paths, or `/Users/...` paths to find them. If a
|
|
49
|
+
required message reference cannot be loaded through the MCP asset loader, return
|
|
50
|
+
`blocked` or `retry-needed`.
|
|
47
51
|
|
|
48
|
-
## Required
|
|
52
|
+
## Required Work Loop
|
|
49
53
|
|
|
50
|
-
1. Load
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
Do not ask the parent to paste row data or a long row-id list.
|
|
56
|
-
2. Load the full normal-path message prompt:
|
|
54
|
+
1. Load live campaign context:
|
|
55
|
+
`get_campaign`, `get_campaign_context`, and row details for the provided
|
|
56
|
+
sample row ids when available. Do not ask the parent for hashes or row-count
|
|
57
|
+
bookkeeping.
|
|
58
|
+
2. Load the full normal-path message prompt, all chunks:
|
|
57
59
|
|
|
58
60
|
`get_subskill_prompt({ subskillName: "generate-messages" })`
|
|
59
61
|
|
|
60
|
-
3. Load
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
5. Draft
|
|
67
|
-
|
|
68
|
-
6.
|
|
69
|
-
|
|
70
|
-
7.
|
|
62
|
+
3. Load every packaged reference asset required by that prompt's Reference Asset
|
|
63
|
+
Loading section with `get_subskill_asset`. If a required asset cannot load
|
|
64
|
+
through the MCP asset loader, return `blocked` or `retry-needed` instead of
|
|
65
|
+
drafting from memory.
|
|
66
|
+
4. Build positioning in a compact working note: buyer, pain, product, mechanism,
|
|
67
|
+
proof boundary, source-use rule, and CTA.
|
|
68
|
+
5. Draft 3 distinct first-message options: signal-led, product/mechanism-led,
|
|
69
|
+
and proof/credibility-led.
|
|
70
|
+
6. Combine the strongest opener, product line, mechanism line, proof treatment,
|
|
71
|
+
and CTA into one reusable template.
|
|
72
|
+
7. Define token fill rules and fallbacks, then render one good sample.
|
|
73
|
+
8. Before returning, load the validation prompt:
|
|
74
|
+
|
|
75
|
+
`get_subskill_prompt({ subskillName: "create-campaign-v2-validation" })`
|
|
76
|
+
|
|
77
|
+
Use it only as a validation contract for the candidate message in this live
|
|
78
|
+
campaign branch. Do not write dry-mode artifacts. Run the final candidate
|
|
79
|
+
against token safety, proof safety, source safety, Thomas filters, AI tells,
|
|
80
|
+
single-send rule, and "would I take this call?". If it fails, revise once and
|
|
81
|
+
validate again.
|
|
82
|
+
9. Keep the work provisional until the user chooses `Use Template` in Messages.
|
|
71
83
|
|
|
72
84
|
## Owned Output
|
|
73
85
|
|
|
@@ -76,15 +88,14 @@ Return the following to the parent thread:
|
|
|
76
88
|
- proposed first-message template using supported `{{...}}` tokens
|
|
77
89
|
- token fill rules and fallbacks
|
|
78
90
|
- one rendered good-fill sample for a plausible passing campaign-table row
|
|
79
|
-
- one omit/fallback sample when the row signal is not safe
|
|
80
|
-
- pass/fail notes against the generate-messages quality gates
|
|
81
|
-
- `qaReceipt` / validation notes showing token safety, proof safety, fit
|
|
82
|
-
uncertainty, bad-fill avoidance, and "would I take this call?" judgment
|
|
83
91
|
- message-draft runtime status: `ready`, `blocked`, `retry-needed`, or `stale`
|
|
84
|
-
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
92
|
+
- approve-or-revise recommendation
|
|
93
|
+
- validation status only: `passed`, `revised-then-passed`, or `blocked`
|
|
94
|
+
- output timestamp/hash and any blocked/retry detail
|
|
95
|
+
|
|
96
|
+
Do not return or render `renderedFallbackSample`, `concerns`, or a full
|
|
97
|
+
`qaReceipt` in the normal happy path. Validation is an internal gate; summarize
|
|
98
|
+
only if blocked or retry-needed.
|
|
88
99
|
|
|
89
100
|
Do not write local markdown/json artifacts in normal live campaign runs. Return
|
|
90
101
|
the recommendation directly to the parent thread. Emit debug artifacts only when
|
|
@@ -108,23 +119,21 @@ exists and points at the current non-empty campaign-table execution slice.
|
|
|
108
119
|
## Basis Changes And Rewrites
|
|
109
120
|
|
|
110
121
|
The first completed recommendation is the default message review candidate.
|
|
111
|
-
Do not automatically retry or regenerate only because
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
Treat later filter/enrichment data as optional rewrite context. If campaign id
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
and report `status: ready` with `basisStatus: "usable_initial"` or
|
|
122
|
+
Do not automatically retry or regenerate only because filters were saved, Filter
|
|
123
|
+
Leads completed, enrichment cells populated, or more row data became available
|
|
124
|
+
after this branch started.
|
|
125
|
+
|
|
126
|
+
Treat later filter/enrichment data as optional rewrite context. If campaign id
|
|
127
|
+
and `workflowTableId` still match, keep the initial recommendation usable and
|
|
128
|
+
report `status: ready` with `basisStatus: "usable_initial"` or
|
|
119
129
|
`"enriched_rewrite_available"`. The parent thread may offer the user a choice
|
|
120
130
|
to keep the initial draft or rewrite with enriched/filter data, but the rewrite
|
|
121
131
|
must be explicit user opt-in.
|
|
122
132
|
|
|
123
133
|
Retry or regenerate without asking only when the initial recommendation is
|
|
124
134
|
missing, failed, structurally invalid, unsafe, or mismatched on campaign id,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
blocker.
|
|
135
|
+
`workflowTableId`, or provided sample rows. Filter/rubric/enrichment basis drift
|
|
136
|
+
alone is not a stale blocker.
|
|
128
137
|
|
|
129
138
|
## User Revision Feedback And QA
|
|
130
139
|
|
|
@@ -132,17 +141,19 @@ If the parent sends user feedback, a QA request, or a rewrite request about the
|
|
|
132
141
|
template before `approve-message`, treat it as Message Drafting work, not a
|
|
133
142
|
campaign write. Use the current `messageDraftRecommendation`, basis token/hash,
|
|
134
143
|
campaign/table basis, and latest user feedback as inputs. Load or reuse the full
|
|
135
|
-
`generate-messages` contract
|
|
136
|
-
QA-only recommendation
|
|
144
|
+
`generate-messages` contract, all referenced assets, and
|
|
145
|
+
`create-campaign-v2-validation`, then return a revised or QA-only recommendation
|
|
146
|
+
with:
|
|
137
147
|
|
|
138
148
|
- revised proposed template
|
|
139
149
|
- what changed and why
|
|
140
150
|
- token fill rule/fallback changes, if any
|
|
141
151
|
- one rendered good-fill sample
|
|
142
|
-
-
|
|
143
|
-
- pass/fail notes against the same quality gates
|
|
152
|
+
- validation status: `passed`, `revised-then-passed`, or `blocked`
|
|
144
153
|
- updated output timestamp/hash and basis token
|
|
145
154
|
|
|
155
|
+
Do not return a full QA receipt unless the result is blocked or retry-needed.
|
|
156
|
+
|
|
146
157
|
Keep the revision grounded in the same source/list/table rows unless the parent
|
|
147
158
|
explicitly supplies a new selected list or review slice. Do not call
|
|
148
159
|
`update_campaign_brief`, do not persist the template, and do not approve your
|
|
@@ -201,20 +212,18 @@ enablement`, or omit it.
|
|
|
201
212
|
Return a concise status with:
|
|
202
213
|
|
|
203
214
|
- prompt basis loaded: `generate-messages`
|
|
215
|
+
- validation prompt loaded: `create-campaign-v2-validation`
|
|
204
216
|
- live campaign basis used
|
|
205
217
|
- proposed template
|
|
206
218
|
- token fill rules/fallbacks
|
|
207
219
|
- one rendered passing-row sample
|
|
208
|
-
- one rendered omit/fallback sample
|
|
209
|
-
- quality-gate pass/fail summary
|
|
210
220
|
- whether final template review is ready or needs revision
|
|
211
221
|
|
|
212
222
|
When the parent will show the recommendation in chat, keep the customer-facing
|
|
213
223
|
message review lightweight. Format only the approval target and one strong
|
|
214
|
-
good-fill example as Markdown with distinct copy blocks. Keep
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
approval; do not print them in the default chat approval packet.
|
|
224
|
+
good-fill example as Markdown with distinct copy blocks. Keep validation notes,
|
|
225
|
+
bad-fill avoidance notes, and QA details internal unless blocked; do not print
|
|
226
|
+
them in the default chat approval packet.
|
|
218
227
|
|
|
219
228
|
````markdown
|
|
220
229
|
## Message Template
|
package/agents/registry.json
CHANGED
|
@@ -150,50 +150,6 @@
|
|
|
150
150
|
]
|
|
151
151
|
}
|
|
152
152
|
},
|
|
153
|
-
{
|
|
154
|
-
"id": "filter-leads",
|
|
155
|
-
"name": "post-find-leads-filter-scout",
|
|
156
|
-
"kind": "post-find-leads-scout",
|
|
157
|
-
"promptFile": "post-find-leads-filter-scout.md",
|
|
158
|
-
"displayName": "Prospect Filters",
|
|
159
|
-
"target": "filter-leads",
|
|
160
|
-
"inputs": [
|
|
161
|
-
"campaignId",
|
|
162
|
-
"campaignBrief summary plus branch-loaded current campaignBrief",
|
|
163
|
-
"source decision and selectedLeadList/source state",
|
|
164
|
-
"workflowTableId",
|
|
165
|
-
"compact review-batch count/hash or branch-loaded review rows"
|
|
166
|
-
],
|
|
167
|
-
"producesArtifacts": [],
|
|
168
|
-
"optionalProducesArtifacts": [],
|
|
169
|
-
"ownership": "prospect-fit criteria, false-positive patterns, keep/exclude rules, ability-to-pay checks, and production rubric translation only",
|
|
170
|
-
"codex": {
|
|
171
|
-
"description": "Prospect Filters worker for campaign-backed fit criteria and rubric persistence after review-batch import and filter approval.",
|
|
172
|
-
"model": "gpt-5.5",
|
|
173
|
-
"modelReasoningEffort": "high",
|
|
174
|
-
"sandboxMode": "read-only",
|
|
175
|
-
"nicknameCandidates": [
|
|
176
|
-
"Prospect Filters",
|
|
177
|
-
"Fit Criteria",
|
|
178
|
-
"Rubric Builder"
|
|
179
|
-
]
|
|
180
|
-
},
|
|
181
|
-
"claude": {
|
|
182
|
-
"description": "Use proactively as Prospect Filters after review-batch import and filter approval to persist campaign rubrics from campaign state.",
|
|
183
|
-
"model": "inherit",
|
|
184
|
-
"background": true,
|
|
185
|
-
"maxTurns": 8,
|
|
186
|
-
"color": "yellow",
|
|
187
|
-
"tools": [
|
|
188
|
-
"mcp__sellable__get_subskill_prompt",
|
|
189
|
-
"mcp__sellable__get_subskill_asset",
|
|
190
|
-
"mcp__sellable__get_campaign",
|
|
191
|
-
"mcp__sellable__get_campaign_context",
|
|
192
|
-
"mcp__sellable__get_rows_minimal",
|
|
193
|
-
"mcp__sellable__save_rubrics"
|
|
194
|
-
]
|
|
195
|
-
}
|
|
196
|
-
},
|
|
197
153
|
{
|
|
198
154
|
"id": "message-generation",
|
|
199
155
|
"name": "post-find-leads-message-scout",
|
|
@@ -203,16 +159,17 @@
|
|
|
203
159
|
"target": "generate-messages",
|
|
204
160
|
"inputs": [
|
|
205
161
|
"campaignId",
|
|
206
|
-
"campaignBrief",
|
|
207
|
-
"selected source state",
|
|
208
|
-
"selectedLeadListId",
|
|
209
162
|
"workflowTableId",
|
|
210
|
-
"
|
|
163
|
+
"concise brief summary",
|
|
164
|
+
"concise source summary/source-use rule",
|
|
165
|
+
"3-5 sample workflow-table rows",
|
|
166
|
+
"optional campaignName, selectedLeadListId, filter choice"
|
|
211
167
|
],
|
|
212
168
|
"producesArtifacts": [
|
|
213
169
|
"template recommendation",
|
|
214
170
|
"token fill rules",
|
|
215
|
-
"rendered sample"
|
|
171
|
+
"one rendered good-fill sample",
|
|
172
|
+
"validation status"
|
|
216
173
|
],
|
|
217
174
|
"optionalProducesArtifacts": [],
|
|
218
175
|
"ownership": "message strategy, proof inventory, token rules, skeptical-prospect review, and selected winner only",
|
|
@@ -234,8 +191,8 @@
|
|
|
234
191
|
"maxTurns": 10,
|
|
235
192
|
"color": "magenta",
|
|
236
193
|
"tools": [
|
|
237
|
-
"Read",
|
|
238
194
|
"mcp__sellable__get_subskill_prompt",
|
|
195
|
+
"mcp__sellable__get_subskill_asset",
|
|
239
196
|
"mcp__sellable__get_campaign",
|
|
240
197
|
"mcp__sellable__get_campaign_context",
|
|
241
198
|
"mcp__sellable__get_rows_minimal"
|
package/dist/tools/leads.js
CHANGED
|
@@ -660,12 +660,10 @@ function analyzeFilterChoiceSample(sampleRows) {
|
|
|
660
660
|
const fitRatio = fitCount / sampleCount;
|
|
661
661
|
const cleanupRatio = cleanupCount / sampleCount;
|
|
662
662
|
const adjacentRatio = adjacentIndexes.length / sampleCount;
|
|
663
|
-
const
|
|
664
|
-
const recommendation =
|
|
665
|
-
cleanupCount <= maxCleanRiskCount &&
|
|
666
|
-
adjacentRatio <= 0.3
|
|
663
|
+
const allReviewedRowsLookFit = fitCount === sampleCount && cleanupCount === 0;
|
|
664
|
+
const recommendation = allReviewedRowsLookFit && adjacentRatio <= 0.3
|
|
667
665
|
? "skip"
|
|
668
|
-
: fitRatio >= 0.
|
|
666
|
+
: fitRatio >= 0.75 && cleanupRatio <= 0.3
|
|
669
667
|
? "light-filter"
|
|
670
668
|
: "add-filter";
|
|
671
669
|
return {
|
|
@@ -697,17 +695,20 @@ function buildFilterChoiceWatchNarration({ sourceLeadCount, reviewRowCount, samp
|
|
|
697
695
|
: "Sample rows were not available to inspect, so this is a manual filter decision.";
|
|
698
696
|
const fitExamples = formatExamples("Fit examples:", assessment.strongExamples);
|
|
699
697
|
const riskExamples = formatExamples("Cleanup examples:", assessment.riskExamples);
|
|
698
|
+
const lightFilterReason = cleanupCount > 0
|
|
699
|
+
? `${cleanupCount} of ${assessment.sampleCount} need cleanup or manual review`
|
|
700
|
+
: `${assessment.adjacentCount} of ${assessment.sampleCount} look adjacent instead of clear target-role fits`;
|
|
700
701
|
const headline = assessment.recommendation === "skip"
|
|
701
|
-
? "
|
|
702
|
+
? "Filters optional for clean sample"
|
|
702
703
|
: assessment.recommendation === "light-filter"
|
|
703
704
|
? "I recommend light cleanup filters"
|
|
704
705
|
: assessment.recommendation === "manual-review"
|
|
705
706
|
? "Review filters or skip"
|
|
706
707
|
: "I recommend adding filters";
|
|
707
708
|
const agentIntent = assessment.recommendation === "skip"
|
|
708
|
-
? `Codex is not recommending filters because
|
|
709
|
+
? `Codex is not recommending filters because every reviewed row already looks like a target-role fit. ${fitExamples} Add filters only if the user wants an extra narrow exclusion.`
|
|
709
710
|
: assessment.recommendation === "light-filter"
|
|
710
|
-
? `Codex is recommending light filters because
|
|
711
|
+
? `Codex is recommending light filters because the sample is strong but not perfectly clean: ${lightFilterReason}. ${riskExamples}`
|
|
711
712
|
: assessment.recommendation === "manual-review"
|
|
712
713
|
? "Codex could not inspect the review rows, so it is pausing for a manual filter decision instead of assuming filters are required."
|
|
713
714
|
: `Codex is recommending filters because ${cleanupCount} of ${assessment.sampleCount} sampled rows look adjacent, unknown, or risky before message review. ${riskExamples}`;
|
package/dist/tools/prompts.js
CHANGED
|
@@ -157,7 +157,7 @@ export const promptToolDefinitions = [
|
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
159
|
name: "get_post_find_leads_scout_registry",
|
|
160
|
-
description: "Return the canonical Sellable
|
|
160
|
+
description: "Return the canonical Sellable Message Drafting worker name after Start Import copies confirmed source rows. Normal create-campaign uses only this one post-import background agent.",
|
|
161
161
|
inputSchema: {
|
|
162
162
|
type: "object",
|
|
163
163
|
properties: {},
|
|
@@ -271,12 +271,11 @@ export function getPostFindLeadsScoutRegistry() {
|
|
|
271
271
|
trigger: "prospect_setup_after_confirm_lead_list",
|
|
272
272
|
requiredInputs: [
|
|
273
273
|
"campaignId",
|
|
274
|
-
"campaign revision or campaignUpdatedAt",
|
|
275
|
-
"campaignBrief",
|
|
276
|
-
"source decision and selectedLeadList/source state",
|
|
277
274
|
"workflowTableId",
|
|
278
|
-
"
|
|
279
|
-
"
|
|
275
|
+
"concise brief summary",
|
|
276
|
+
"concise source summary and source-use rule",
|
|
277
|
+
"3-5 sample workflow-table rows with rowId/name/title/company/signal",
|
|
278
|
+
"optional selectedLeadListId, campaignName, and filter choice",
|
|
280
279
|
],
|
|
281
280
|
scouts: scouts.map((agent) => ({
|
|
282
281
|
id: String(agent.id || ""),
|
|
@@ -305,14 +304,10 @@ export function getPostFindLeadsScoutRegistry() {
|
|
|
305
304
|
})),
|
|
306
305
|
joinGate: {
|
|
307
306
|
afterAllComplete: true,
|
|
308
|
-
requiredState: ["
|
|
307
|
+
requiredState: ["messageDraftRecommendation"],
|
|
309
308
|
noFilterRequiredState: ["messageDraftRecommendation"],
|
|
310
|
-
skipFilterRule: "
|
|
311
|
-
show: [
|
|
312
|
-
"readable_filters_with_reasons",
|
|
313
|
-
"sample_message_for_approval",
|
|
314
|
-
"message_qa_receipt",
|
|
315
|
-
],
|
|
309
|
+
skipFilterRule: "Filters are parent-thread MCP work. The only background worker is Message Drafting; messageDraftRecommendation is required before template review.",
|
|
310
|
+
show: ["sample_message_for_approval"],
|
|
316
311
|
nextStage: "message-review",
|
|
317
312
|
},
|
|
318
313
|
messageDraftBranchContract: {
|
|
@@ -330,41 +325,38 @@ export function getPostFindLeadsScoutRegistry() {
|
|
|
330
325
|
"startedAt",
|
|
331
326
|
"updatedAt",
|
|
332
327
|
"basisToken",
|
|
333
|
-
"basis.selectedLeadListId",
|
|
334
328
|
"basis.workflowTableId",
|
|
335
|
-
"basis.
|
|
336
|
-
"basis.reviewSampleRowHash",
|
|
329
|
+
"basis.sampleRowIds",
|
|
337
330
|
],
|
|
338
|
-
promptRequired: 'Load current campaign brief/table state through scoped tools, then get_subskill_prompt({ subskillName: "generate-messages" })
|
|
331
|
+
promptRequired: 'Load current campaign brief/table state through scoped tools, then get_subskill_prompt({ subskillName: "generate-messages" }) for all chunks. Load every asset named in the generate-messages Reference Asset Loading pack through get_subskill_asset. Before returning, load get_subskill_prompt({ subskillName: "create-campaign-v2-validation" }) and use it as the final internal message-validation gate. Do not use shell/local filesystem reads, repo paths, plugin-cache paths, or /Users paths for message references. If required prompts/assets cannot be loaded through MCP tools, return blocked/retry-needed instead of drafting from memory.',
|
|
339
332
|
basisFields: [
|
|
340
|
-
"
|
|
341
|
-
"brief hash",
|
|
342
|
-
"selectedLeadListId",
|
|
333
|
+
"campaignId",
|
|
343
334
|
"workflowTableId",
|
|
344
|
-
"
|
|
345
|
-
"
|
|
346
|
-
"
|
|
335
|
+
"concise brief summary",
|
|
336
|
+
"concise source summary/source-use rule",
|
|
337
|
+
"3-5 sample workflow-table rows",
|
|
338
|
+
"optional selectedLeadListId and filter choice",
|
|
347
339
|
],
|
|
348
340
|
messageDraftOutputFields: [
|
|
349
341
|
"templateRecommendation",
|
|
350
342
|
"tokenFillRules",
|
|
351
|
-
"
|
|
352
|
-
"concerns",
|
|
343
|
+
"renderedGoodSample",
|
|
353
344
|
"revisionNotes when user feedback triggered a revision",
|
|
354
345
|
"status",
|
|
355
346
|
"basisStatus",
|
|
356
347
|
"basisToken",
|
|
357
|
-
"
|
|
348
|
+
"approveOrReviseRecommendation",
|
|
349
|
+
"validationStatus only; full QA details only when blocked/retry-needed",
|
|
358
350
|
"outputAt",
|
|
359
351
|
"outputHash",
|
|
360
352
|
"error or retry detail",
|
|
361
353
|
],
|
|
362
|
-
reusePolicy: "The first completed Message Drafting recommendation remains the default review candidate. Later
|
|
354
|
+
reusePolicy: "The first completed Message Drafting recommendation remains the default review candidate. Later filters, Filter Leads, enrichment, or rubric completion may make an enriched rewrite available, but does not automatically retry or replace the initial draft unless campaign/table/sample identity mismatches or the initial output failed. User copy feedback before approve-message is an explicit Message Drafting revision and must be routed back through the message branch with the current recommendation and basis.",
|
|
363
355
|
},
|
|
364
356
|
usage: {
|
|
365
|
-
codex: "After confirm_lead_list copies source rows and the initial campaign-table execution slice exists, ask the filter-choice question immediately. Do not spawn anything before that question.
|
|
366
|
-
claude: "After confirm_lead_list copies source rows and the initial campaign-table execution slice exists, ask the filter-choice question immediately. Do not invoke any Task/Agent before that question.
|
|
367
|
-
parentThreadRule: '
|
|
357
|
+
codex: "After confirm_lead_list copies source rows and the initial campaign-table execution slice exists, ask the filter-choice question immediately. Do not spawn anything before that question. After the answer, launch only Message Drafting whenever Codex agent-launch policy is satisfied. If filters are chosen, the parent stays on Filter Rules and drafts/saves rubrics with MCP tools while Message Drafting runs in the background. If filters are skipped, move to Messages/message review after Message Drafting is ready. Treat YOLO/autonomous mode as campaign-scoped permission for this single post-import worker. If the user has not enabled YOLO and has not explicitly asked for background agents/subagents/parallel agents/delegation/message bg agent in this campaign, ask once before loading the long message prompt in the parent. If permission is granted and the named Message Drafting custom agent is unavailable, spawn a generic gpt-5.5 xhigh Message Drafting background agent with the same lean campaign/table basis.",
|
|
358
|
+
claude: "After confirm_lead_list copies source rows and the initial campaign-table execution slice exists, ask the filter-choice question immediately. Do not invoke any Task/Agent before that question. After the answer, invoke only Message Drafting. If filters are chosen, parent drafts/saves rubrics with MCP tools while Message Drafting runs, asks filter approval, then joins Message Drafting. If filters are skipped, invoke only Message Drafting and move to Messages/message review.",
|
|
359
|
+
parentThreadRule: 'The only normal post-import background worker is Message Drafting; source scouts and separate filter workers stay out of the normal create-campaign path. After the filter-choice answer, launch post-find-leads-message-scout only. If filters are chosen, the parent thread remains the filter writer: keep the browser on Filter Rules, load the filter reference, draft/save rubrics through MCP tools, ask filter approval, then move to Filter Leads while waiting for Message Drafting if needed. Do not move into message review, queue cells, or call update_campaign_brief until saved filters are approved when filters are enabled and messageDraftRecommendation is ready. If filters are skipped, launch only Message Drafting. In Codex, YOLO/autonomous mode counts as campaign-scoped permission for this single post-import worker; if the user has not enabled YOLO and has not explicitly asked for background agents/subagents/parallel agents/delegation/message bg agent in this campaign, ask once for permission before loading the long message prompt in the parent. If Message Drafting is allowed but the named worker is unavailable, use a generic gpt-5.5 xhigh Message Drafting background agent. Do not silently fall back to parent-thread message drafting. The Message Drafting handoff must be lean: campaignId, workflowTableId, brief summary, source summary/source-use rule, and 3-5 sample workflow-table rows with rowId/name/title/company/signal; optional campaignName, selectedLeadListId, and filter choice are allowed. Do not paste copied row counts, brief hashes, review-batch hashes, full reviewBatchRowIds, broad row data, or local debug artifacts into the message spawn prompt. The message branch must load current campaign brief/context, provided sample rows, the full generate-messages prompt, every referenced asset through get_subskill_asset, and before returning get_subskill_prompt({ subskillName: "create-campaign-v2-validation" }) for the internal validation gate. Local markdown/json files are not normal-path inputs. Message reference assets must be loaded with get_subskill_asset from the installed MCP package; do not use shell/local filesystem reads, repo paths, plugin-cache paths, or /Users paths to satisfy message references. The filter-choice question is the first post-import user gate; do not load this registry or filter references before it. Message drafting starts after the filter-choice answer and must reject mismatched workflowTableId/campaign/workspace input. Do not use any alternate or examples-only message prompt. User copy feedback, message QA, or rewrite requests before approve-message must be routed back to Message Drafting with the current recommendation, lean campaign/table basis, and latest user text; the parent must not rewrite or QA the template from memory and must not call update_campaign_brief before approve-message. The worker validates internally and returns only templateRecommendation, tokenFillRules, renderedGoodSample, status, approveOrReviseRecommendation, validationStatus, outputAt, outputHash, and blocked/retry detail. Do not render renderedFallbackSample, concerns, or a qaReceipt on the normal happy path. On the filter path, the parent thread keeps the browser on Filter Rules after save_rubrics so the user can approve the saved criteria; only then move to Filter Leads, show `Filters saved + waiting for message approval`, and wait there for message approval. Enrichment, filtering, Generate Message cells, sender setup, sequence attach, and launch wait for template approval on the Use Template path. On the skip path, move to Messages/message review and wait for message approval before enrichment or Settings. Do not render message review from checklist or shortcut instructions; message review requires a messageDraftRecommendation whose basis proves the generate-messages prompt, assets, and validation prompt ran for the current campaign/table execution slice. Do not automatically rerun Message Drafting after filters/enrichment finish; show the initial draft by default and offer an enriched rewrite only with explicit user opt-in.',
|
|
368
360
|
},
|
|
369
361
|
};
|
|
370
362
|
}
|
package/package.json
CHANGED
|
@@ -279,14 +279,15 @@ Messages/message review. Enrichment/filtering and Generate Message cells wait
|
|
|
279
279
|
for message approval. AI Generated is an explicit opt-out from the template
|
|
280
280
|
path.
|
|
281
281
|
|
|
282
|
-
The Message Drafting handoff must stay
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
282
|
+
The Message Drafting handoff must stay lean. Include only `campaignId`,
|
|
283
|
+
`workflowTableId`, a concise brief summary, concise source summary/source-use
|
|
284
|
+
rule, and 3-5 sample workflow-table rows with `rowId`, name, title, company, and
|
|
285
|
+
signal. Optional: campaign name, `selectedLeadListId`, and filter choice. Do not
|
|
286
|
+
paste copied row counts, brief hashes, review-batch hashes, full row ID lists,
|
|
287
|
+
broad row data, or local debug artifacts into the spawn prompt. Message Drafting
|
|
288
|
+
must load the current campaign brief/context, full `generate-messages` prompt,
|
|
289
|
+
all referenced assets, and `create-campaign-v2-validation`; validation is an
|
|
290
|
+
internal gate before it returns the concise review-ready recommendation.
|
|
290
291
|
|
|
291
292
|
Use rendered Markdown for user review surfaces, not fenced code blocks. Keep
|
|
292
293
|
lines short, use indexed section labels and bullets, and translate internal
|
|
@@ -421,19 +422,15 @@ Treat host capabilities as concrete functions, not prose conventions:
|
|
|
421
422
|
not call it in the normal create-campaign source path.
|
|
422
423
|
- `load_post_find_leads_scout_registry`: call
|
|
423
424
|
`mcp__sellable__get_post_find_leads_scout_registry({})` after source
|
|
424
|
-
import and before dispatching
|
|
425
|
-
- `launch_prospect_filters`: Claude Code uses `Task` with `subagent_type`
|
|
426
|
-
`post-find-leads-filter-scout` when filters are chosen; Codex uses the
|
|
427
|
-
returned compatibility agent. Prospect Filters must save or return production
|
|
428
|
-
rubrics before message review can proceed.
|
|
425
|
+
import and before dispatching Message Drafting only.
|
|
429
426
|
- `launch_message_drafting`: Claude Code uses `Task` with `subagent_type`
|
|
430
427
|
`post-find-leads-message-scout` when listed; Codex uses the returned
|
|
431
428
|
compatibility agent or a generic `gpt-5.5` / `xhigh` Message Drafting agent.
|
|
432
429
|
|
|
433
430
|
If a required interactive question function or MCP loader is missing, stop and
|
|
434
431
|
explain the Sellable install/reload problem. Source work uses product-native MCP
|
|
435
|
-
orchestration in the parent; the
|
|
436
|
-
|
|
432
|
+
orchestration in the parent; filters also stay in the parent with MCP tools. The
|
|
433
|
+
only normal post-import background branch is Message Drafting.
|
|
437
434
|
|
|
438
435
|
Never narrate local draft housekeeping to the user. If you create directories,
|
|
439
436
|
save drafts, write artifacts, or persist intermediate state, translate it into
|
|
@@ -750,10 +747,10 @@ updates.
|
|
|
750
747
|
asset loader so they share the same config.
|
|
751
748
|
3. Follow that prompt and workflow config exactly.
|
|
752
749
|
4. For filter and message setup, keep the parent thread as a lean orchestrator.
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
750
|
+
The only normal background agent is `post-find-leads-message-scout` for
|
|
751
|
+
Message Drafting. When filters are chosen, launch Message Drafting, then keep
|
|
752
|
+
filters in the parent thread: load `references/filter-leads.md`, draft
|
|
753
|
+
production rubrics, call `save_rubrics`, ask filter approval, and then join
|
|
757
754
|
Message Drafting for template review. When filters are skipped, launch only
|
|
758
755
|
Message Drafting.
|
|
759
756
|
5. For message generation, keep the parent thread as a lean orchestrator and
|
|
@@ -768,7 +765,7 @@ updates.
|
|
|
768
765
|
permission before loading the long message prompt in the parent. If
|
|
769
766
|
permission is granted but the named custom agent is not
|
|
770
767
|
available, spawn a generic background agent with `model: "gpt-5.5"` and
|
|
771
|
-
`reasoning_effort: "xhigh"` using the same campaign/table basis. Do not
|
|
768
|
+
`reasoning_effort: "xhigh"` using the same lean campaign/table basis. Do not
|
|
772
769
|
silently fall back to parent-thread message drafting; parent fallback is
|
|
773
770
|
allowed only when the user explicitly says to continue without a background
|
|
774
771
|
agent.
|
|
@@ -779,21 +776,23 @@ updates.
|
|
|
779
776
|
initial campaign-table execution slice rows as the source of truth; do not read stale local
|
|
780
777
|
markdown such as `message-validation.md`, inspect the database directly, or
|
|
781
778
|
synthesize local validation artifacts from general knowledge. The handoff to
|
|
782
|
-
Message Drafting should pass
|
|
783
|
-
branch loads current brief/
|
|
779
|
+
Message Drafting should pass lean basis only, not hashes, counts, or a long
|
|
780
|
+
row-id list; the branch loads current brief/context, the full
|
|
781
|
+
`generate-messages` prompt, all referenced assets, and
|
|
782
|
+
`create-campaign-v2-validation` itself. Do not render fallback sample,
|
|
783
|
+
concerns, or a QA receipt on the normal happy path.
|
|
784
784
|
6. Create the campaign shell early with the v1 brief so the user can open the
|
|
785
785
|
watch link and see useful setup state immediately. Materialize the approved
|
|
786
786
|
source list, copy confirmed rows into the campaign, and internally process the
|
|
787
787
|
first campaign-table execution slice after the source is attached to the
|
|
788
788
|
campaign; do not load prospect-setup registries/prompts before asking add
|
|
789
|
-
filters vs skip filters. Once the user answers, launch
|
|
790
|
-
|
|
791
|
-
filters are skipped. Do not queue workflow cells, attach a
|
|
789
|
+
filters vs skip filters. Once the user answers, launch only Message Drafting.
|
|
790
|
+
If filters are chosen, draft/save filters in the parent thread. Do not queue workflow cells, attach a
|
|
792
791
|
sequence, or start until saved filters and the
|
|
793
792
|
message template/token rules are approved. When filters are chosen, immediately
|
|
794
793
|
call `mcp__sellable__update_campaign({ campaignId, enableICPFilters: true, currentStep: "create-icp-rubric", watchNarration })`
|
|
795
|
-
so the watched app moves to Filter Rules while
|
|
796
|
-
rubrics.
|
|
794
|
+
so the watched app moves to Filter Rules while the parent drafts/saves
|
|
795
|
+
rubrics and Message Drafting runs.
|
|
797
796
|
After rubrics save, keep Filter Rules visible for approval; after approval,
|
|
798
797
|
move to Filter Leads and show `Filters saved + waiting for message approval`
|
|
799
798
|
until the template is approved.
|