@sellable/mcp 0.1.460 → 0.1.461

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.
@@ -6,7 +6,7 @@ async function postSetupEvergreenCampaigns(body) {
6
6
  export const setupEvergreenCampaignsToolDefinitions = [
7
7
  {
8
8
  name: "setup_evergreen_campaigns",
9
- description: "Evergreen campaign setup plan/verify command. Use plan mode first to inspect exact workspace/sender/campaign/table/source state and receive immutable lane packets. `selectedSenderIds` is a legacy shorthand for both scopes; prefer `postEngagerSenderIds` for the Post Engagers sender scope and `sharedSenderIds` for the shared lane sender scope when they differ. If a protected existing Post Engagers campaign must stay unchanged and the operator requested only shared lane execution, pass postEngagerSenderIds:[] and sharedSenderIds; do not include the protected active Post Engagers lane as a reuse packet because it can make the yolo plan non-autoExecutable. The command plans one Post Engagers lane per post-engager sender plus shared Signal Discovery and Shared Cold Fallback lanes for the shared sender set. yolo is only a parent-skill auto-execution hint for safe lane packets; pass yolo only in plan mode and never include yolo on mode:\"verify\" calls. This backend command remains read-only in plan mode and verifies receipts in verify mode. Package-backed prompt authority: the installed public wrapper can be the local Codex skill entrypoint, but lane workers must use get_subskill_prompt and get_subskill_asset for nested `$sellable:create-campaign`, create-campaign-v2, generate-messages, validation, and assets; nested filesystem prompt fallback is a failed UAT. Use mcp__sellable only for workspace selection and product mutations/readbacks. Do not use mcp__sellable_admin, direct DB, Prisma, SQL, built-in web search, browser search, web.run, or any external browsing/search tool as execution or research proof; if Sellable MCP research tools are insufficient, write a blocked receipt instead of browsing externally. Worker-local replans are read-only drift checks and must preserve the exact parent sender scopes, including postEngagerSenderIds:[] when intentionally empty and the exact sharedSenderIds array; if scope, planRevision, actionId, or laneKey drifts, stop with blocked:worker_plan_scope_drift before mutation. Each lane packet includes workerDispatch with preferredRuntime, runtimeFallbackOrder, acceptedRuntimes, rejectedRuntimes, requiresVisibleThreadOrDurableReceipt, receiptArtifactHint, receiptRunId, and receiptMustBeWrittenAfter; pre-existing receipts at old deterministic paths are stale and must not be used, so stop with blocked:stale_receipt_artifact if the receipt was not freshly written for the current receiptRunId. `multi_agent_v1.spawn_agent`/opaque spawn_agent is not accepted for mutating command proof unless the parent has visible thread or durable receipt proof. In local Codex, default to `workerDispatch.preferredRuntime` (`visible-codex-app-thread`): discover Codex app thread tools if needed, then call `codex_app.list_projects` and `codex_app.create_thread` with a local project target; do not create a worktree for lane execution. If Codex app thread tools are unavailable but local Codex CLI is available, use durable streaming workers with `codex -a never -s danger-full-access -c model_reasoning_effort=xhigh exec --skip-git-repo-check -m <worker-model> -C <repo> -o <worker-final-file> -` and include preferredRuntimeAttempt plus fallbackReason in createCampaignWorkflowReceipt; approval, sandbox, and reasoning-effort config flags must appear before `exec`, and current customer CLI installs reject `codex exec --ask-for-approval never` and `codex exec -a never`. Do not rely on default model or default reasoning effort: copy the parent model such as `gpt-5.5` into `-m` and always pass `-c model_reasoning_effort=xhigh`; a child worker that reports GPT 5.5 with high reasoning is a launcher bug to relaunch before mutation, not a user-continue path. Plan responses include approvalSummary; render approvalSummary when asking for bounded delegated approval because it explicitly lists campaignsToCreate, campaignsToUpdate, campaignsToVerifyOnly, campaignsLeftUntouched, attachedSenders, selectedActionIds, allowedSideEffects, forbiddenSideEffects, blockers, and approvalQuestion. When safe-yolo needs normal setup work, the parent skill may ask for bounded delegated approval: one approval over the current planRevision, selected action ids, caps, allowed side-effect classes, and stop conditions lets lane workers execute without per-substep approval while staying inside that packet. In exec/automation mode, do not call request_user_input; if yolo plan autoExecutable:false and no interactive approval can be received, stop with blocked:bounded_approval_unavailable_in_exec_mode before any mutation. Lane workers must explicitly load and use the installed `$sellable:create-campaign` wrapper as the nested workflow entrypoint, then load `create-campaign-v2` and `create-campaign-v2/core/flow.v2.json`; they must execute creation, source import, create-campaign workflow steps, generate-messages, sequence attachment, pause_campaign review-state transition when the current table is still DRAFT, and review readiness through that existing create-campaign workflow/subskills, then return receipts here for verification. Customer-visible verify receipts must set status:'succeeded' or status:'completed'; status:'passed', status:'pass', and status:'passed_with_warnings' are rejected as primary success statuses. Exception: a Post Engagers lane may write status:'blocked' with blocker:'post_engagers_no_sender_posts', 'post_engagers_no_recent_sender_posts', 'post_engagers_no_sender_owned_posts', or 'post_engagers_source_author_mismatch' when Sellable MCP readback proves no usable sender-authored posts/source exists; verify returns these as acceptedLaneBlockers so the parent can report the no-op instead of retrying invalid source repair. Any other blocked receipt, including model-quality/preflight or worker model availability blockers, is not a goal-complete success condition and must not let the parent report evergreen completion. Receipts must include createCampaignStepReceipt with setupPlanCall, createCampaignWorkflowReceipt, campaignBriefReceipt, sourceDecisionReceipt, filterDecisionReceipt, messageDraftingReceipt, reviewBatchReceipt, sequenceReceipt, and verifyCall nested inside createCampaignStepReceipt; top-level-only copies of those objects are not enough and are not promoted by verify. setupPlanCall must use canonical keys: planRevision, actionId, laneKey, workspaceId, senderIds, campaignId, tableId, createIntent. Do not use laneActionId, lanePacketActionId, delegatedPlanRevision, delegatedActionId, or requestedCall text as a substitute for those canonical fields. createCampaignWorkflowReceipt must include skillCommand:'$sellable:create-campaign', skillName:'create-campaign', wrapperSkillLoaded:true, workflowPromptName:'create-campaign-v2', workflowPromptLoadedToHasMoreFalse:true, workflowAssetPath:'create-campaign-v2/core/flow.v2.json', workflowAssetLoaded:true, workerRuntime, workerThreadId or receiptArtifactPath, durableReceiptWritten when using a receipt file, and notAdHoc:true; CLI durable fallback runtimes must also include preferredRuntimeAttempt for visible-codex-app-thread and fallbackReason. messageDraftingReceipt must use exactly statusSource:'branch' or statusSource:'packaged-generate-messages-worker'; descriptive aliases such as statusSource:'package-readback-local-thread' are rejected. It must include proof that generate-messages was loaded, start_campaign_message_preparation/get_campaign_message_preparation_status ran when the packaged worker path is used, validationResult:'passed', a passed qualityReview, and at least 3 concrete sampleMessages with rowId, generatedMessageText, verdict, and issues; Do not substitute `message` for `generatedMessageText`; Do not substitute `passVerdict` for `verdict`. Before writing durable receipts, run a receipt self-check: top-level `planRevision`, `actionId`, `laneKey`, `laneType`, `workspaceId`, and `senderIds` must exist; if the self-check fails, fix the receipt before ending. Use start_campaign_message_preparation with approvalMode:\"mark_ready\" only for evergreen setup. Never call `start_campaign_message_preparation` with `approvalMode:\"approve\"`; approve exactly one semantic Approved cell through select_campaign_cells/update_cell and final proof must show approvedGeneratedMessageCount exactly 1. Shared Cold Fallback samples with a standalone name followed by 'Hey there' are rejected. This command does not launch campaigns, does not schedule sends, does not assign scheduler-owned send fields, does not raw-write campaign status, does not archive/delete cleanup targets, and does not spend paid credits.",
9
+ description: "Evergreen campaign setup plan/verify command. Use plan mode first to inspect exact workspace/sender/campaign/table/source state and receive immutable lane packets. `selectedSenderIds` is a legacy shorthand for both scopes; prefer `postEngagerSenderIds` for the Post Engagers sender scope and `sharedSenderIds` for the shared lane sender scope when they differ. `sharedSenderIds` must include every intended shared-lane sender, not only the named Post Engagers sender; when adding other senders to existing shared evergreen campaigns, resolve those sender ids with list_senders and pass the full shared set. If a protected existing Post Engagers campaign must stay unchanged and the operator requested only shared lane execution, pass postEngagerSenderIds:[] and sharedSenderIds; do not include the protected active Post Engagers lane as a reuse packet because it can make the yolo plan non-autoExecutable. The command plans one Post Engagers lane per post-engager sender plus shared Signal Discovery and Shared Cold Fallback lanes for the shared sender set. Non-archived PAUSED/ACTIVE/DRAFT shared campaigns/tables are the reusable targets; archived campaigns, archived tables, and archived waterfall bindings are stale inventory and must not be counted as valid evergreen slots. If an existing non-archived shared campaign is already attached to additional senders, plan reporting should count those attached senders as existing shared-lane membership rather than treating them as missing or duplicate slots. yolo is only a parent-skill auto-execution hint for safe lane packets; pass yolo only in plan mode and never include yolo on mode:\"verify\" calls. This backend command remains read-only in plan mode and verifies receipts in verify mode. Package-backed prompt authority: the installed public wrapper can be the local Codex skill entrypoint, but lane workers must use get_subskill_prompt and get_subskill_asset for nested `$sellable:create-campaign`, create-campaign-v2, generate-messages, validation, and assets; nested filesystem prompt fallback is a failed UAT. Use mcp__sellable only for workspace selection and product mutations/readbacks. Do not use mcp__sellable_admin, direct DB, Prisma, SQL, built-in web search, browser search, web.run, or any external browsing/search tool as execution or research proof; if Sellable MCP research tools are insufficient, write a blocked receipt instead of browsing externally. Worker-local replans are read-only drift checks and must preserve the exact parent sender scopes, including postEngagerSenderIds:[] when intentionally empty and the exact sharedSenderIds array; if scope, planRevision, actionId, or laneKey drifts, stop with blocked:worker_plan_scope_drift before mutation. Each lane packet includes workerDispatch with preferredRuntime, runtimeFallbackOrder, acceptedRuntimes, rejectedRuntimes, requiresVisibleThreadOrDurableReceipt, receiptArtifactHint, receiptRunId, and receiptMustBeWrittenAfter; pre-existing receipts at old deterministic paths are stale and must not be used, so stop with blocked:stale_receipt_artifact if the receipt was not freshly written for the current receiptRunId. `multi_agent_v1.spawn_agent`/opaque spawn_agent is not accepted for mutating command proof unless the parent has visible thread or durable receipt proof. In local Codex, default to `workerDispatch.preferredRuntime` (`visible-codex-app-thread`): discover Codex app thread tools if needed, then call `codex_app.list_projects` and `codex_app.create_thread` with a local project target; do not create a worktree for lane execution. If Codex app thread tools are unavailable but local Codex CLI is available, use durable streaming workers with `codex -a never -s danger-full-access -c model_reasoning_effort=xhigh exec --skip-git-repo-check -m <worker-model> -C <repo> -o <worker-final-file> -` and include preferredRuntimeAttempt plus fallbackReason in createCampaignWorkflowReceipt; approval, sandbox, and reasoning-effort config flags must appear before `exec`, and current customer CLI installs reject `codex exec --ask-for-approval never` and `codex exec -a never`. Do not rely on default model or default reasoning effort: copy the parent model such as `gpt-5.5` into `-m` and always pass `-c model_reasoning_effort=xhigh`; a child worker that reports GPT 5.5 with high reasoning is a launcher bug to relaunch before mutation, not a user-continue path. Plan responses include approvalSummary; render approvalSummary when asking for bounded delegated approval because it explicitly lists campaignsToCreate, campaignsToUpdate, campaignsToVerifyOnly, campaignsLeftUntouched, attachedSenders, selectedActionIds, allowedSideEffects, forbiddenSideEffects, blockers, and approvalQuestion. When safe-yolo needs normal setup work, the parent skill may ask for bounded delegated approval: one approval over the current planRevision, selected action ids, caps, allowed side-effect classes, and stop conditions lets lane workers execute without per-substep approval while staying inside that packet. In exec/automation mode, do not call request_user_input; if yolo plan autoExecutable:false and no interactive approval can be received, stop with blocked:bounded_approval_unavailable_in_exec_mode before any mutation. Lane workers must explicitly load and use the installed `$sellable:create-campaign` wrapper as the nested workflow entrypoint, then load `create-campaign-v2` and `create-campaign-v2/core/flow.v2.json`; they must execute creation, source import, create-campaign workflow steps, generate-messages, sequence attachment, pause_campaign review-state transition when the current table is still DRAFT, and review readiness through that existing create-campaign workflow/subskills, then return receipts here for verification. Customer-visible verify receipts must set status:'succeeded' or status:'completed'; status:'passed', status:'pass', and status:'passed_with_warnings' are rejected as primary success statuses. Exception: a Post Engagers lane may write status:'blocked' with blocker:'post_engagers_no_sender_posts', 'post_engagers_no_recent_sender_posts', 'post_engagers_no_sender_owned_posts', or 'post_engagers_source_author_mismatch' when Sellable MCP readback proves no usable sender-authored posts/source exists; verify returns these as acceptedLaneBlockers so the parent can report the no-op instead of retrying invalid source repair. Any other blocked receipt, including model-quality/preflight or worker model availability blockers, is not a goal-complete success condition and must not let the parent report evergreen completion. Receipts must include createCampaignStepReceipt with setupPlanCall, createCampaignWorkflowReceipt, campaignBriefReceipt, sourceDecisionReceipt, filterDecisionReceipt, messageDraftingReceipt, reviewBatchReceipt, sequenceReceipt, and verifyCall nested inside createCampaignStepReceipt; top-level-only copies of those objects are not enough and are not promoted by verify. setupPlanCall must use canonical keys: planRevision, actionId, laneKey, workspaceId, senderIds, campaignId, tableId, createIntent. Do not use laneActionId, lanePacketActionId, delegatedPlanRevision, delegatedActionId, or requestedCall text as a substitute for those canonical fields. createCampaignWorkflowReceipt must include skillCommand:'$sellable:create-campaign', skillName:'create-campaign', wrapperSkillLoaded:true, workflowPromptName:'create-campaign-v2', workflowPromptLoadedToHasMoreFalse:true, workflowAssetPath:'create-campaign-v2/core/flow.v2.json', workflowAssetLoaded:true, workerRuntime, workerThreadId or receiptArtifactPath, durableReceiptWritten when using a receipt file, and notAdHoc:true; CLI durable fallback runtimes must also include preferredRuntimeAttempt for visible-codex-app-thread and fallbackReason. messageDraftingReceipt must use exactly statusSource:'branch' or statusSource:'packaged-generate-messages-worker'; descriptive aliases such as statusSource:'package-readback-local-thread' are rejected. It must include proof that generate-messages was loaded, start_campaign_message_preparation/get_campaign_message_preparation_status ran when the packaged worker path is used, validationResult:'passed', a passed qualityReview, and at least 3 concrete sampleMessages with rowId, generatedMessageText, verdict, and issues; Do not substitute `message` for `generatedMessageText`; Do not substitute `passVerdict` for `verdict`. Before writing durable receipts, run a receipt self-check: top-level `planRevision`, `actionId`, `laneKey`, `laneType`, `workspaceId`, and `senderIds` must exist; if the self-check fails, fix the receipt before ending. Use start_campaign_message_preparation with approvalMode:\"mark_ready\" only for evergreen setup. Never call `start_campaign_message_preparation` with `approvalMode:\"approve\"`; approve exactly one semantic Approved cell through select_campaign_cells/update_cell and final proof must show approvedGeneratedMessageCount exactly 1. Shared Cold Fallback samples with a standalone name followed by 'Hey there' are rejected. This command does not launch campaigns, does not schedule sends, does not assign scheduler-owned send fields, does not raw-write campaign status, does not archive/delete cleanup targets, and does not spend paid credits.",
10
10
  inputSchema: {
11
11
  type: "object",
12
12
  properties: {
@@ -31,7 +31,7 @@ export const setupEvergreenCampaignsToolDefinitions = [
31
31
  },
32
32
  allConnectedSenders: {
33
33
  type: "boolean",
34
- description: "Plan sender-owned Post Engagers lanes for all eligible connected senders in the active workspace.",
34
+ description: "Plan sender-owned Post Engagers lanes and shared-lane sender membership for all eligible connected senders in the active workspace. Use only when the operator explicitly asks for all/every connected sender; for shared-only additions prefer postEngagerSenderIds:[] with explicit sharedSenderIds.",
35
35
  },
36
36
  selectedSenderIds: {
37
37
  type: "array",
@@ -49,7 +49,7 @@ export const setupEvergreenCampaignsToolDefinitions = [
49
49
  type: "array",
50
50
  items: { type: "string" },
51
51
  maxItems: 25,
52
- description: "Exact OutboundSenderIdentity ids attached to shared Signal Discovery and Shared Cold Fallback lanes.",
52
+ description: "Exact OutboundSenderIdentity ids that should be attached to shared Signal Discovery and Shared Cold Fallback lanes. Include all intended shared-lane senders, not just the named Post Engagers sender.",
53
53
  },
54
54
  bindings: {
55
55
  type: "array",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.460",
3
+ "version": "0.1.461",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -159,6 +159,14 @@ Post Engagers slots; shared sender scope is the union of senderRefs on the
159
159
  shared Signal Discovery and Shared Cold Fallback waterfall slots. If the
160
160
  waterfall has one clear production evergreen program for the workspace, this is
161
161
  not ambiguous even when `list_senders` returns additional connected senders.
162
+ If non-archived existing shared evergreen campaigns/tables are already attached
163
+ to additional senders, count those attached sender ids as current shared-lane
164
+ membership and include them in the shared-lane report. Do not collapse the
165
+ shared scope down to the one person named for a Post Engagers lane unless the
166
+ operator explicitly asked to limit shared lanes to that person or remove other
167
+ senders. Archived campaigns, archived tables, and archived waterfall bindings
168
+ are stale inventory for scope/counting unless the operator supplied those exact
169
+ ids and explicitly asked for archived dashboard visibility repair.
162
170
  In non-interactive or `--yolo` mode, when more than two connected senders exist
163
171
  and neither the prompt nor product-visible waterfall evidence identifies exact
164
172
  evergreen sender scope, stop before mutation with
@@ -168,6 +176,8 @@ Engagers lanes for extra senders.
168
176
  Short form: Do not pass `allConnectedSenders:true` unless the prompt explicitly says all/every connected sender.
169
177
  Short form: "all 4 campaigns" means explicit sender scope plus two shared lanes, not all connected senders.
170
178
  Short form: Product-visible managed evergreen/prod waterfall senderRefs are exact sender scope.
179
+ Short form: Non-archived shared campaign attachments count as current shared-lane sender scope.
180
+ Short form: A named Post Engagers sender is not automatically the whole shared-lane scope.
171
181
  Short form: Do not report `no_senders` while waterfall senderRefs can be mapped to list_senders.
172
182
  Short form: In `--yolo`, ambiguous multi-sender scope blocks before mutation.
173
183
  </inputs>
@@ -270,7 +280,8 @@ differ, pass both explicit arrays:
270
280
  - `postEngagerSenderIds`: only senders that should have sender-owned Post
271
281
  Engagers campaigns.
272
282
  - `sharedSenderIds`: senders attached to the shared Signal Discovery and Shared
273
- Cold Fallback campaigns.
283
+ Cold Fallback campaigns. This must be the full intended shared sender set,
284
+ not merely the sender named for a Post Engagers lane.
274
285
 
275
286
  If the operator says a sender is shared-only, do not create a Post Engagers lane
276
287
  for that shared-only sender. Example: if Justin already has a Post Engagers