@sellable/install 0.1.260 → 0.1.262

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 CHANGED
@@ -31,9 +31,9 @@ agent command for launching a campaign:
31
31
  sellable create
32
32
  ```
33
33
 
34
- Campaign creation, foundation memory, content capture/ideation, and post
35
- drafting run inside Claude Code or Codex, where the Sellable MCP tools and
36
- approval flows are available.
34
+ Campaign creation, sender send refills, foundation memory, content
35
+ capture/ideation, and post drafting run inside Claude Code or Codex, where the
36
+ Sellable MCP tools and approval flows are available.
37
37
 
38
38
  Install is auth-free by default. The normal path is first-run login: launch a
39
39
  Sellable workflow in Claude Code or Codex and the agent handles Sellable
@@ -100,12 +100,14 @@ Use the same public entrypoints in both hosts:
100
100
  - Claude Code: `/sellable:foundation`
101
101
  - Claude Code: `/sellable:content`
102
102
  - Claude Code: `/sellable:create-post`
103
+ - Claude Code: `/sellable:refill-sends`
103
104
  - Codex: `$sellable:create-campaign`
104
105
  - Codex: `$sellable:create-ab-test`
105
106
  - Codex: `$sellable:create-evergreen-campaigns`
106
107
  - Codex: `$sellable:foundation`
107
108
  - Codex: `$sellable:content`
108
109
  - Codex: `$sellable:create-post`
110
+ - Codex: `$sellable:refill-sends`
109
111
  - Codex Desktop plugin: `sellable@sellable`
110
112
  - Codex visible skill: `Sellable Create Campaign`
111
113
  - Codex visible skill: `Sellable Create A/B Test`
@@ -113,7 +115,9 @@ Use the same public entrypoints in both hosts:
113
115
  - Codex visible skill: `Sellable Foundation`
114
116
  - Codex visible skill: `Sellable Content`
115
117
  - Codex visible skill: `Sellable Create Post`
118
+ - Codex visible skill: `Sellable Refill Sends`
116
119
  - Internal MCP workflow prompt: `create-campaign-v2`
120
+ - Internal MCP workflow prompt: `refill-sends-workflow`
117
121
  - Internal/backward-compatible memory prompt: `interview`
118
122
 
119
123
  Do not ask users to run `/sellable:create-campaign-v2`,
@@ -37,7 +37,7 @@ function getInstallVersion() {
37
37
  }
38
38
  }
39
39
 
40
- const CODEX_PLUGIN_VERSION = "0.1.51";
40
+ const CODEX_PLUGIN_VERSION = "0.1.52";
41
41
  const CODEX_PLUGIN_COMPAT_VERSIONS = [
42
42
  "0.1.8",
43
43
  "0.1.9",
@@ -73,6 +73,7 @@ const CODEX_PLUGIN_COMPAT_VERSIONS = [
73
73
  "0.1.39",
74
74
  "0.1.40",
75
75
  "0.1.41",
76
+ "0.1.51",
76
77
  ];
77
78
  const RAW_INSTALL_PACKAGE_SPEC =
78
79
  process.env.SELLABLE_INSTALL_PACKAGE_SPEC || "@sellable/install@latest";
@@ -187,7 +188,8 @@ Options:
187
188
  Auth:
188
189
  Install is auth-free by default. Sign in happens on the first run of
189
190
  /sellable:create-campaign, /sellable:create-evergreen-campaigns,
190
- /sellable:foundation, /sellable:content, or /sellable:create-post in Claude Code or Codex,
191
+ /sellable:foundation, /sellable:content, /sellable:create-post, or
192
+ /sellable:refill-sends in Claude Code or Codex,
191
193
  where the agent walks you through signup or sign-in and stores credentials
192
194
  in ~/.sellable/config.json.
193
195
 
@@ -217,6 +219,7 @@ function printCreateCommandHint() {
217
219
  { label: "Foundation", command: "/sellable:foundation" },
218
220
  { label: "Content", command: "/sellable:content" },
219
221
  { label: "Post", command: "/sellable:create-post" },
222
+ { label: "Refill", command: "/sellable:refill-sends" },
220
223
  ]);
221
224
  console.log("");
222
225
  console.log("");
@@ -227,6 +230,7 @@ function printCreateCommandHint() {
227
230
  { label: "Foundation", command: "$sellable:foundation" },
228
231
  { label: "Content", command: "$sellable:content" },
229
232
  { label: "Post", command: "$sellable:create-post" },
233
+ { label: "Refill", command: "$sellable:refill-sends" },
230
234
  ]);
231
235
  console.log("");
232
236
  console.log(` ${"─".repeat(63)}`);
@@ -874,7 +878,7 @@ function codexPluginManifest(opts) {
874
878
  name: "sellable",
875
879
  version: CODEX_PLUGIN_VERSION,
876
880
  description:
877
- "Sellable MCP tools for campaign creation, foundation memory, content, and workflow sequencing.",
881
+ "Sellable MCP tools for campaign creation, send refills, foundation memory, content, and workflow sequencing.",
878
882
  author: {
879
883
  name: "Sellable",
880
884
  url: "https://sellable.dev/",
@@ -888,7 +892,7 @@ function codexPluginManifest(opts) {
888
892
  displayName: "Sellable",
889
893
  shortDescription: "Sellable MCP tools for outbound campaign workflows",
890
894
  longDescription:
891
- "Loads the Sellable MCP server into Codex Desktop so Sellable skills can create campaigns, find leads, draft messages, and manage approval-gated launch workflows.",
895
+ "Loads the Sellable MCP server into Codex Desktop so Sellable skills can create campaigns, refill sends, find leads, draft messages, and manage approval-gated launch workflows.",
892
896
  developerName: "Sellable",
893
897
  category: "Productivity",
894
898
  capabilities: ["Interactive", "Write"],
@@ -897,6 +901,7 @@ function codexPluginManifest(opts) {
897
901
  termsOfServiceURL: "https://sellable.dev/terms",
898
902
  defaultPrompt: [
899
903
  "Create a Sellable campaign",
904
+ "Refill Sellable sends",
900
905
  "Find LinkedIn leads",
901
906
  "Build an outbound sequence",
902
907
  ],
@@ -1040,6 +1045,54 @@ const CREATE_EVERGREEN_CAMPAIGNS_ALLOWED_TOOLS = [
1040
1045
  "codex_app.send_message_to_thread",
1041
1046
  ];
1042
1047
 
1048
+ const REFILL_SENDS_ALLOWED_TOOLS = [
1049
+ "mcp__sellable__refill_sends",
1050
+ "mcp__sellable__get_auth_status",
1051
+ "mcp__sellable__start_cli_login",
1052
+ "mcp__sellable__wait_for_cli_login",
1053
+ "mcp__sellable__get_active_workspace",
1054
+ "mcp__sellable__list_workspaces",
1055
+ "mcp__sellable__set_active_workspace",
1056
+ "mcp__sellable__get_subskill_prompt",
1057
+ "mcp__sellable__search_subskill_prompts",
1058
+ "mcp__sellable__list_senders",
1059
+ "mcp__sellable__get_sender_routing",
1060
+ "mcp__sellable__get_campaign_waterfall",
1061
+ "mcp__sellable__resolve_campaign_fill_route",
1062
+ "mcp__sellable__get_campaign_refill_state",
1063
+ "mcp__sellable__fill_campaign_horizon",
1064
+ "mcp__sellable__get_campaign",
1065
+ "mcp__sellable__get_campaign_context",
1066
+ "mcp__sellable__update_campaign",
1067
+ "mcp__sellable__get_provider_prompt",
1068
+ "mcp__sellable__get_campaign_message_preparation_status",
1069
+ "mcp__sellable__start_campaign_message_preparation",
1070
+ "mcp__sellable__cancel_campaign_message_preparation",
1071
+ "mcp__sellable__import_leads",
1072
+ "mcp__sellable__wait_for_lead_list_ready",
1073
+ "mcp__sellable__confirm_lead_list",
1074
+ "mcp__sellable__search_signals",
1075
+ "mcp__sellable__select_promising_posts",
1076
+ "mcp__sellable__fetch_post_engagers",
1077
+ "mcp__sellable__search_sales_nav",
1078
+ "mcp__sellable__lookup_sales_nav_filter",
1079
+ "mcp__sellable__search_prospeo",
1080
+ "mcp__sellable__search_prospeo_companies",
1081
+ "mcp__sellable__confirm_prospeo_company_accounts",
1082
+ "mcp__sellable__load_csv_linkedin_leads",
1083
+ "mcp__sellable__load_csv_domains",
1084
+ "mcp__sellable__list_dnc_entries",
1085
+ "mcp__sellable__load_csv_dnc_entries",
1086
+ "mcp__sellable__get_rows",
1087
+ "mcp__sellable__get_rows_minimal",
1088
+ "mcp__sellable__get_table_rows",
1089
+ "mcp__sellable__get_campaign_table_schema",
1090
+ "mcp__sellable__select_campaign_cells",
1091
+ "mcp__sellable__queue_campaign_cells",
1092
+ "mcp__sellable__wait_for_campaign_processing",
1093
+ "mcp__sellable__get_sender",
1094
+ ];
1095
+
1043
1096
  function allowedToolsYaml(tools) {
1044
1097
  return [...new Set(tools)].map((tool) => ` - ${tool}`).join("\n");
1045
1098
  }
@@ -1857,6 +1910,71 @@ then retry \`get_subskill_prompt\`.
1857
1910
  `, host, "create-evergreen-campaigns");
1858
1911
  }
1859
1912
 
1913
+ function refillSendsSkillMd(host = "shared") {
1914
+ try {
1915
+ const here = dirname(fileURLToPath(import.meta.url));
1916
+ const templatePath = join(
1917
+ here,
1918
+ "..",
1919
+ "skill-templates",
1920
+ "refill-sends.md"
1921
+ );
1922
+ if (existsSync(templatePath)) {
1923
+ return stampInstalledHost(
1924
+ addOrReplaceAllowedTools(
1925
+ readFileSync(templatePath, "utf8"),
1926
+ REFILL_SENDS_ALLOWED_TOOLS
1927
+ ),
1928
+ host,
1929
+ "refill-sends"
1930
+ );
1931
+ }
1932
+ } catch {
1933
+ // fall through to hardcoded fallback below
1934
+ }
1935
+ return stampInstalledHost(`---
1936
+ name: refill-sends
1937
+ description: Refill Sellable sender sends through the approval-gated refill workflow.
1938
+ visibility: public
1939
+ allowed-tools:
1940
+ ${allowedToolsYaml(REFILL_SENDS_ALLOWED_TOOLS)}
1941
+ ---
1942
+
1943
+ # Sellable Refill Sends
1944
+
1945
+ Use this as the customer-facing entrypoint for the Sellable \`refill-sends\`
1946
+ workflow. It supports \`--yolo\` and optional repeated \`--sender <name-or-id>\`
1947
+ selectors.
1948
+
1949
+ ## Bootstrap
1950
+
1951
+ MCP prompt and command access are required. Do not inspect repo files, run shell
1952
+ commands, use \`npm\`, \`node\`, local harness scripts, or read local prompt
1953
+ files to emulate this workflow.
1954
+
1955
+ If the Sellable MCP prompt tools are unavailable, stop and say this is a Codex
1956
+ install/reload problem. Tell the user to run
1957
+ \`curl -fsSL "https://app.sellable.dev/api/v2/cli/install" | sh\`, fully quit and reopen Codex
1958
+ Desktop, then start a new thread.
1959
+
1960
+ ## Execute Workflow
1961
+
1962
+ 1. Call \`mcp__sellable__get_auth_status({})\`.
1963
+ 2. Normalize invocation arguments with \`mcp__sellable__refill_sends({ yolo, senders, senderIds, senderNames })\` when the host exposes typed MCP tools.
1964
+ 3. Load the canonical prompt via
1965
+ \`mcp__sellable__get_subskill_prompt({ subskillName: "refill-sends" })\`,
1966
+ then load \`mcp__sellable__get_subskill_prompt({ subskillName: "refill-sends-workflow" })\`.
1967
+ 4. Follow the canonical prompt exactly. Do not launch, start, archive, delete,
1968
+ or write scheduler rows as part of refill sends.
1969
+
1970
+ ## MCP Prompt Fallback
1971
+
1972
+ If exact subskill lookup fails, use
1973
+ \`mcp__sellable__search_subskill_prompts({ query: "refill-sends", includePublic: true, includeInternal: true })\`,
1974
+ then retry \`get_subskill_prompt\`.
1975
+ `, host, "refill-sends");
1976
+ }
1977
+
1860
1978
  function genericSellableSkillMd({ name, title, description, host = "shared" }) {
1861
1979
  return stampInstalledHost(`---
1862
1980
  name: ${name}
@@ -2330,6 +2448,12 @@ function codexPluginSkills() {
2330
2448
  description: "Capture ideas and draft LinkedIn posts in your voice",
2331
2449
  skillMd: createPostSkillMd(),
2332
2450
  },
2451
+ {
2452
+ dir: "sellable-refill-sends",
2453
+ displayName: "Sellable Refill Sends",
2454
+ description: "Refill sender sends with approval-gated campaign selection",
2455
+ skillMd: refillSendsSkillMd("codex"),
2456
+ },
2333
2457
  ];
2334
2458
  }
2335
2459
 
@@ -2555,6 +2679,16 @@ function claudeCommands() {
2555
2679
  argumentHint: "[post idea or source material]",
2556
2680
  skillMd: createPostSkillMd(),
2557
2681
  },
2682
+ {
2683
+ name: "refill-sends",
2684
+ title: "Refill Sends",
2685
+ filename: join("sellable", "refill-sends.md"),
2686
+ description:
2687
+ "Refill Sellable sender sends through the approval-gated refill workflow.",
2688
+ argumentHint: "[--yolo] [--sender name-or-id ...]",
2689
+ skillMd: refillSendsSkillMd("claude"),
2690
+ allowedTools: ["AskUserQuestion", ...REFILL_SENDS_ALLOWED_TOOLS],
2691
+ },
2558
2692
  {
2559
2693
  name: "create-evergreen-campaigns",
2560
2694
  title: "Create Evergreen Campaigns",
@@ -3852,6 +3986,7 @@ function printNextSteps(installedHosts, authReused) {
3852
3986
  { label: "Foundation", command: "/sellable:foundation" },
3853
3987
  { label: "Content", command: "/sellable:content" },
3854
3988
  { label: "Post", command: "/sellable:create-post" },
3989
+ { label: "Refill", command: "/sellable:refill-sends" },
3855
3990
  ]);
3856
3991
  console.log("");
3857
3992
  console.log("");
@@ -3863,6 +3998,7 @@ function printNextSteps(installedHosts, authReused) {
3863
3998
  { label: "Foundation", command: "$sellable:foundation" },
3864
3999
  { label: "Content", command: "$sellable:content" },
3865
4000
  { label: "Post", command: "$sellable:create-post" },
4001
+ { label: "Refill", command: "$sellable:refill-sends" },
3866
4002
  ]);
3867
4003
  console.log("");
3868
4004
  }
@@ -4153,11 +4289,13 @@ async function main() {
4153
4289
  console.log(` Claude Code: /sellable:foundation`);
4154
4290
  console.log(` Claude Code: /sellable:content`);
4155
4291
  console.log(` Claude Code: /sellable:create-post`);
4292
+ console.log(` Claude Code: /sellable:refill-sends`);
4156
4293
  console.log(` Codex: $sellable:create-campaign`);
4157
4294
  console.log(` Codex: $sellable:create-evergreen-campaigns`);
4158
4295
  console.log(` Codex: $sellable:foundation`);
4159
4296
  console.log(` Codex: $sellable:content`);
4160
4297
  console.log(` Codex: $sellable:create-post`);
4298
+ console.log(` Codex: $sellable:refill-sends`);
4161
4299
  process.exit(0);
4162
4300
  }
4163
4301
  if (rawArgs[0] === "prefs") {
@@ -30,6 +30,7 @@ export const REQUIRED_SELLABLE_MCP_TOOLS = [
30
30
  "attach_recommended_sequence",
31
31
  "resolve_campaign_fill_route",
32
32
  "get_campaign_refill_state",
33
+ "refill_sends",
33
34
  "setup_evergreen_campaigns",
34
35
  "start_campaign_message_preparation",
35
36
  "get_campaign_message_preparation_status",
@@ -70,6 +71,14 @@ export const CREATE_CAMPAIGN_SMOKE_CALLS = [
70
71
  limit: 1200,
71
72
  },
72
73
  },
74
+ {
75
+ name: "refill_sends",
76
+ arguments: {
77
+ yolo: false,
78
+ senders: ["smoke"],
79
+ horizonSendDays: 2,
80
+ },
81
+ },
73
82
  {
74
83
  name: "get_subskill_asset",
75
84
  arguments: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/install",
3
- "version": "0.1.260",
3
+ "version": "0.1.262",
4
4
  "type": "module",
5
5
  "description": "One-command installer for Sellable MCP in Claude Code and Codex",
6
6
  "bin": {
@@ -123,6 +123,7 @@ such as "fill campaigns", "fill up", "refill sends", "max out sends", or
123
123
  ```text
124
124
  get_subskill_prompt({ subskillName: "refill-sends-workflow" })
125
125
  resolve_campaign_fill_route({ intent:"plain" })
126
+ list_senders
126
127
  get_campaign_refill_state
127
128
  ```
128
129
 
@@ -133,15 +134,27 @@ campaign refill. Route outcomes are `route:"evergreen_horizon"`,
133
134
  returns `route:"ask_create"`, ask whether to create a normal campaign or
134
135
  evergreen campaigns. Campaign creation is allowed only after this route and
135
136
  explicit user selection; it is never the default response to plain fill. When
136
- more leads are needed, the refill workflow must recommend same-campaign
137
- source-ladder replenishment; do not create warm-post-engager side campaigns,
138
- on-demand campaigns, or unrelated campaigns. Surface sender-health blockers
139
- separately from prepared/approved/scheduled counts.
137
+ choosing among active targets, use refill-state scheduled-count evidence to
138
+ continue the campaign that most recently had scheduler-owned sends for the
139
+ relevant sender set; do not treat every active campaign as a refill candidate.
140
+ In `--yolo` fill/refill mode, default to one best recent-send campaign and a
141
+ two-send-day horizon: subtract future scheduler-owned scheduled sends and
142
+ ready-to-schedule rows from healthy sender daily capacity, then prepare only
143
+ that bounded gap.
144
+ When more leads are needed, the refill workflow must recommend same-campaign
145
+ source-ladder replenishment first; do not create warm-post-engager side
146
+ campaigns, on-demand campaigns, or unrelated campaigns. If same-source copy hits
147
+ `USER_ADDED_ROWS_LIMIT_EXCEEDED`, split the current source into a bounded
148
+ same-source LinkedIn profile list, confirm that smaller list into the same
149
+ campaign, and operate on the copied review batch first. Surface sender-health
150
+ blockers separately from prepared/approved/scheduled counts.
140
151
 
141
152
  Treat active fills as capacity-fill preparation: calculate the bounded target
142
153
  from sender capacity when needed, then use the refill workflow to decide source
143
- replenishment, enrichment/prep, approval policy, and scheduler proof. Mutation
144
- requires exact visible approval and a fresh `get_campaign_refill_state` reread.
154
+ replenishment, enrichment/prep, approval policy, and scheduler proof. Present
155
+ operator decisions by campaign name and sender name first, with campaign/table
156
+ ids as proof only. Mutation requires exact visible approval and a fresh
157
+ `get_campaign_refill_state` reread.
145
158
  For already-running regular campaigns that need Signal Discovery source
146
159
  replenishment, the refill workflow owns the guarded recovery: clear
147
160
  `currentStep` only with `clearCurrentStepIfMatches:"running"`, load the
@@ -1024,16 +1024,31 @@ artifact path, allowed repair side effects, failed sample snippets, failed
1024
1024
  quality codes, and the banned phrase list. The repair prompt must say
1025
1025
  `Do not include existing receipt JSON; load current product state through
1026
1026
  Sellable MCP readbacks and rewrite the durable receipt from fresh readbacks`.
1027
+ It must also say that the worker should verify the packaged Sellable MCP
1028
+ surface is loaded before declaring MCP unavailable, including `get_auth_status`,
1029
+ `get_subskill_prompt`, and the campaign readback tools. If a repair worker still
1030
+ cannot access Sellable MCP, it must write a separate repair-blocked artifact
1031
+ under `repair-blocked/` or its repair final file and must not overwrite the
1032
+ canonical lane receipt. Repair workers must stage successful repaired receipts
1033
+ under `repair-staged/` first; only after fresh MCP readbacks, improved current
1034
+ samples, exactly one approved generated route-proof row, and a local JSON
1035
+ self-check pass may the worker atomically replace the canonical lane receipt.
1027
1036
  After the repair worker completes the final product readbacks
1028
1037
  (`get_campaign_messages_preview`, `get_campaign`, navigation/table readback),
1029
- it must rewrite the durable receipt immediately before any extended narration,
1030
- analysis, or final answer. If the repair worker cannot rewrite the durable
1031
- receipt in one bounded pass, it must exit with
1032
- `blocked: repair_receipt_write_timeout`. The parent must treat an unchanged
1033
- receipt mtime, missing repair final file, or missing updated
1038
+ it must stage and then rewrite the durable receipt immediately before any
1039
+ extended narration, analysis, or final answer. If the repair worker cannot
1040
+ rewrite the durable receipt in one bounded pass, it must exit with
1041
+ `blocked: repair_receipt_write_timeout` without modifying the canonical lane
1042
+ receipt. The parent must treat an unchanged receipt mtime, missing repair final
1043
+ file, missing staged success artifact, or missing updated
1034
1044
  `messageDraftingReceipt.sampleMessages` after repair as blocked, never success.
1045
+ The parent must also treat a repair-blocked artifact as a failed run, but it
1046
+ must keep the pre-repair canonical receipt available for diagnostics and must
1047
+ not promote the blocked repair artifact as the lane receipt.
1035
1048
  Short form: repair prompts use compact repair packets, not full receipt JSON.
1036
1049
  Short form: Do not include existing receipt JSON in repair prompts.
1050
+ Short form: repair workers stage repaired receipts before replacing canonical receipts.
1051
+ Short form: repair blockers never overwrite canonical success receipts.
1037
1052
  Short form: repair workers write the durable receipt immediately after final readbacks.
1038
1053
  Short form: missing repair receipt rewrite is `blocked: repair_receipt_write_timeout`.
1039
1054
 
@@ -3,8 +3,18 @@ name: refill-sends
3
3
  description: Plan regular campaign and evergreen campaign send refill work through the skill-led refill workflow.
4
4
  visibility: public
5
5
  allowed-tools:
6
+ - mcp__sellable__refill_sends
7
+ - mcp__sellable__get_auth_status
8
+ - mcp__sellable__start_cli_login
9
+ - mcp__sellable__wait_for_cli_login
10
+ - mcp__sellable__get_active_workspace
11
+ - mcp__sellable__list_workspaces
12
+ - mcp__sellable__set_active_workspace
6
13
  - mcp__sellable__get_subskill_prompt
7
14
  - mcp__sellable__search_subskill_prompts
15
+ - mcp__sellable__list_senders
16
+ - mcp__sellable__get_sender_routing
17
+ - mcp__sellable__get_campaign_waterfall
8
18
  - mcp__sellable__resolve_campaign_fill_route
9
19
  - mcp__sellable__get_campaign_refill_state
10
20
  - mcp__sellable__fill_campaign_horizon
@@ -35,14 +45,50 @@ allowed-tools:
35
45
  - mcp__sellable__get_table_rows
36
46
  - mcp__sellable__get_campaign_table_schema
37
47
  - mcp__sellable__select_campaign_cells
48
+ - mcp__sellable__queue_campaign_cells
38
49
  - mcp__sellable__wait_for_campaign_processing
39
50
  - mcp__sellable__get_sender
40
51
  ---
41
52
 
42
53
  # Refill Sends
43
54
 
44
- Use this public wrapper for plain operator requests such as "fill", "refill sends",
45
- "max out sends", "load everyone up", or "fill horizon sends".
55
+ Use this public command wrapper for plain operator requests such as "fill",
56
+ "refill sends", "max out sends", "load everyone up", or "fill horizon sends".
57
+
58
+ Host command names:
59
+
60
+ - Claude Code: `/sellable:refill-sends`
61
+ - Codex: `$sellable:refill-sends`
62
+
63
+ Accepted invocation flags in the same user request:
64
+
65
+ - `--yolo`: auto-accept the rendered bounded refill packet after the required
66
+ fresh state reread.
67
+ - `--sender <name-or-id>`: scope to a specific sender; repeat for multiple
68
+ senders.
69
+ - `senderIds: <id>, <id>` or `senderNames: <name>, <name>`: explicit selector
70
+ alternatives when the host preserves natural-language arguments better than
71
+ shell-style flags.
72
+
73
+ When the host can call typed MCP tools, start with:
74
+
75
+ ```text
76
+ refill_sends({ yolo?: boolean, senders?: string[], senderIds?: string[], senderNames?: string[], horizonSendDays?: number })
77
+ ```
78
+
79
+ That command helper only normalizes arguments and returns the execution
80
+ contract. It does not mutate. Continue with the workflow below for route
81
+ selection, state rereads, approval gating, source import, preparation, and
82
+ bounded approval.
83
+
84
+ First call `get_auth_status({})`. If auth or active workspace is not OK, follow
85
+ the returned login/workspace guidance before route resolution. Do not run refill
86
+ research against an implicit or guessed workspace.
87
+
88
+ Treat "refill senders", "fill senders", "load everyone up", and "max out
89
+ senders" as sender-scoped requests. The target set is senders enrolled in active
90
+ campaign-backed sequence campaigns, not the first active campaign returned by a
91
+ resolver.
46
92
 
47
93
  Load the internal workflow prompt before taking any operational step:
48
94
 
@@ -51,10 +97,52 @@ get_subskill_prompt({ subskillName: "refill-sends-workflow" })
51
97
  ```
52
98
 
53
99
  Then follow that workflow exactly. The default path is read-only research:
54
- resolve the route, read target refill state, report the next safe step, and stop
55
- before mutation unless the user has explicitly approved the exact workspace,
56
- campaign/table/source ids, caps/dates, approval mode, expected side effects,
57
- and stop/rollback condition.
100
+ resolve the route, identify the sender-relevant campaign that most recently had
101
+ scheduler-owned sends, read refill state for that target, report the next safe
102
+ step using campaign names first, and stop before mutation unless the user has
103
+ explicitly approved the exact workspace, campaign/table/source ids, caps/dates,
104
+ approval mode, expected side effects, and stop/rollback condition.
105
+
106
+ For interactive Codex or Claude Code sessions, that approval must use the
107
+ host-native structured question gate, not plain chat:
108
+
109
+ - Codex: use `request_user_input`.
110
+ - Claude Code: use `AskUserQuestion`.
111
+
112
+ The approval question must present the final refill step with exactly two
113
+ choices: `Accept` and `Decline`. The question body must include the operator
114
+ output packet: workspace, sender scope, a campaign-by-campaign table with
115
+ campaign name, sender names, action, target count/cap, source/list, and
116
+ blocker/skip reason, then exact ids, expected side effects, forbidden actions,
117
+ and the stop condition. Treat `Accept` as permission for only the rendered
118
+ target, caps, mode, and side effects. Treat `Decline` as a hard stop with no
119
+ mutation.
120
+
121
+ If Christian includes `--yolo` in the same refill request, treat that flag as
122
+ auto-accept for the rendered bounded refill packet after the required fresh state
123
+ reread. For sender-scoped language with no named senders, `--yolo` means all
124
+ eligible healthy senders enrolled in active campaign-backed sequence campaigns in
125
+ the active workspace. Without `--yolo`, if Christian did not name senders, ask
126
+ which eligible enrolled senders to refill before choosing campaigns or mutating.
127
+
128
+ `--yolo` only covers the exact sender set, per-sender target campaigns, caps,
129
+ approval mode, and side effects in the packet. It does not authorize
130
+ launch/start, sending, archive or delete cleanup, direct scheduler writes, sender
131
+ reassignment, or campaigns outside those selected for the eligible sender set.
132
+ Stop and re-plan if the route, sender set, ids, caps, blockers, or side-effect
133
+ class drift before mutation.
134
+
135
+ In `--yolo`, the default two-day fill horizon is two send days. For each target
136
+ sender, compute the bounded gap from that sender's healthy daily capacity,
137
+ existing future scheduler-owned scheduled sends, and rows already ready to
138
+ schedule across active campaigns enrolled with that sender. Then pick the best
139
+ same-sender campaign to fill the gap: prefer recent/future scheduler-owned sends
140
+ for that sender, then strongest recent result evidence, then source health. Do
141
+ not stop after filling only one sender when the request was sender-scoped. If a
142
+ same-source copy hits the campaign-table row cap, split the current source into
143
+ a bounded LinkedIn profile source list, confirm only that smaller list into the
144
+ same campaign, and operate on the copied review batch. Do not fall back to
145
+ on-demand campaigns or unrelated active-campaign fills.
58
146
 
59
147
  Public concepts are regular campaign and evergreen campaign. Internal direct
60
148
  campaign types are unsupported refill targets. `fill_campaign_horizon` is only a