@sellable/install 0.1.340-phase981.20260711223346 → 0.1.342

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.
@@ -22,14 +22,6 @@ import {
22
22
  REQUIRED_SELLABLE_MCP_TOOLS,
23
23
  verifySellableMcpRuntime,
24
24
  } from "../lib/runtime-verify.mjs";
25
- import {
26
- activateCodexCandidateSelection,
27
- installCodexCandidateCache,
28
- readCodexPluginSelection,
29
- resolveCodexPluginSelectionPaths,
30
- restoreCodexPluginSelection,
31
- snapshotCodexPluginSelection,
32
- } from "../lib/codex-plugin-selection.mjs";
33
25
 
34
26
  const DEFAULT_API_URL = "https://app.sellable.dev";
35
27
  const DEFAULT_SERVER_PACKAGE =
@@ -48,7 +40,7 @@ function getInstallVersion() {
48
40
  }
49
41
  }
50
42
 
51
- const CODEX_PLUGIN_VERSION = "0.1.70-phase981.20260711223346";
43
+ const CODEX_PLUGIN_VERSION = "0.1.71";
52
44
  const CODEX_PLUGIN_COMPAT_VERSIONS = [
53
45
  "0.1.8",
54
46
  "0.1.9",
@@ -89,6 +81,22 @@ const CODEX_PLUGIN_COMPAT_VERSIONS = [
89
81
  "0.1.53",
90
82
  "0.1.54",
91
83
  "0.1.55",
84
+ "0.1.56",
85
+ "0.1.57",
86
+ "0.1.58",
87
+ "0.1.59",
88
+ "0.1.60",
89
+ "0.1.61",
90
+ "0.1.62",
91
+ "0.1.63",
92
+ "0.1.64",
93
+ "0.1.65",
94
+ "0.1.66",
95
+ "0.1.67",
96
+ "0.1.68",
97
+ "0.1.69",
98
+ "0.1.70",
99
+ "0.1.70-phase981.20260711223346+codex.20260712010246",
92
100
  ];
93
101
  const RAW_INSTALL_PACKAGE_SPEC =
94
102
  process.env.SELLABLE_INSTALL_PACKAGE_SPEC || "@sellable/install@latest";
@@ -180,8 +188,6 @@ Commands:
180
188
  Save the ask-first prompt-sharing preference.
181
189
  setup claude-permissions --allow-common-setup
182
190
  Add common Sellable Bash permissions to Claude settings.
183
- codex plugin-selection snapshot|install-cache|activate|restore|status
184
- Approval-gated Phase 98 exact-cache selection controls.
185
191
  hermes profile bootstrap Create a profile-local Hermes config, Sellable auth config,
186
192
  configs dir, skills, and optional Slack .env.
187
193
  uninstall Remove Sellable host config and installed artifacts.
@@ -648,12 +654,6 @@ function getMcpVersion() {
648
654
  return "latest";
649
655
  }
650
656
 
651
- function getConfiguredMcpVersion(opts = {}) {
652
- const match = /^@sellable\/mcp@(.+)$/.exec(opts.mcpPackage || "");
653
- const configured = match?.[1];
654
- return configured && configured !== "latest" ? configured : getMcpVersion();
655
- }
656
-
657
657
  function normalizeOptionalPath(value) {
658
658
  const trimmed = String(value || "").trim();
659
659
  return trimmed ? resolve(trimmed) : "";
@@ -1001,6 +1001,7 @@ function codexPluginManifest(opts) {
1001
1001
  "Create a Sellable campaign",
1002
1002
  "Refill Sellable sends",
1003
1003
  "Find LinkedIn leads",
1004
+ "Build an outbound sequence",
1004
1005
  ],
1005
1006
  brandColor: "#8B5CF6",
1006
1007
  screenshots: [],
@@ -2094,55 +2095,7 @@ then retry \`get_subskill_prompt\`.
2094
2095
  `, host, "create-evergreen-campaigns");
2095
2096
  }
2096
2097
 
2097
- const REFILL_SENDS_FALLBACK_CONTRACT = `<!-- REFILL_CONTRACT_GENERATED:START -->
2098
- contractVersion: 2.0.0
2099
- cacheVersion: refill-contract-v1
2100
- contractHash: e54ba0f80bc534fd70fd8c10c1caab109fe9a91c205cfc423f5f6735cd53fdc1
2101
- scope: workspace_id, target_date, sender_selectors, campaign_selectors, approval_mode, contract_identity, installed_identity
2102
- gates: approval_packet, one_primitive, fresh_reread, normalized_accounting, prep_circuit
2103
- forbidden: direct_send, raw_scheduler_write, campaign_create, campaign_archive_delete, threshold_lowering, unselected_source_mutation, unapproved_campaign_start, sender_config_write
2104
- terminal: projected_full, concrete_blocker, deadline_reached, iteration_limit, operator_stopped
2105
- ready_buffer_exists_is_not_complete
2106
- mcpPackageVersion: installed MCP package spec in host MCP config
2107
- installPackageVersion: ${getInstallVersion()}
2108
- codexPluginVersion: ${CODEX_PLUGIN_VERSION}
2109
- <!-- REFILL_CONTRACT_GENERATED:END -->`;
2110
-
2111
- function refillReleaseIdentityBlock(host, opts = {}) {
2112
- const match = /^@sellable\/mcp@(.+)$/.exec(opts.mcpPackage || "");
2113
- const mcpVersion = match?.[1] || String(opts.mcpPackage || "unknown");
2114
- const pluginVersion = host === "codex" ? CODEX_PLUGIN_VERSION : "not-applicable";
2115
- const cacheIdentity =
2116
- host === "codex"
2117
- ? `codex-plugin:${pluginVersion}|mcp:${mcpVersion}`
2118
- : `${host}-host|mcp:${mcpVersion}`;
2119
- return `## Installed release identity
2120
-
2121
- expectedMcpPackageVersion: ${mcpVersion}
2122
- expectedInstallPackageVersion: ${getInstallVersion()}
2123
- expectedCodexPluginVersion: ${pluginVersion}
2124
- expectedPluginCacheIdentity: ${cacheIdentity}
2125
-
2126
- Immediately after \`get_auth_status\`, require
2127
- \`update.mcp.currentVersion\` to equal \`${mcpVersion}\`. If it is missing or
2128
- different, stop with \`installed_mcp_identity_mismatch\` before any product mutation.
2129
- Do not call \`get_refill_target_plan\`, \`refill_sends\`, or another mutating
2130
- workflow tool. Explain that Codex is still using a stale Sellable MCP runtime,
2131
- then fully quit and reopen Codex Desktop and start a new thread.`;
2132
- }
2133
-
2134
- function stampRefillReleaseIdentity(markdown, host, opts) {
2135
- const marker = markdown.includes("## Bootstrap and execute")
2136
- ? "## Bootstrap and execute"
2137
- : "## Bootstrap";
2138
- if (!markdown.includes(marker)) return markdown;
2139
- return markdown.replace(
2140
- marker,
2141
- `${refillReleaseIdentityBlock(host, opts)}\n\n${marker}`
2142
- );
2143
- }
2144
-
2145
- function refillSendsSkillMd(host = "shared", opts = {}) {
2098
+ function refillSendsSkillMd(host = "shared") {
2146
2099
  try {
2147
2100
  const here = dirname(fileURLToPath(import.meta.url));
2148
2101
  const templatePath = join(
@@ -2151,18 +2104,11 @@ function refillSendsSkillMd(host = "shared", opts = {}) {
2151
2104
  "skill-templates",
2152
2105
  "refill-sends.md"
2153
2106
  );
2154
- if (
2155
- process.env.SELLABLE_FORCE_REFILL_TEMPLATE_MISSING !== "1" &&
2156
- existsSync(templatePath)
2157
- ) {
2107
+ if (existsSync(templatePath)) {
2158
2108
  return stampInstalledHost(
2159
- stampRefillReleaseIdentity(
2160
- addOrReplaceAllowedTools(
2161
- readFileSync(templatePath, "utf8"),
2162
- REFILL_SENDS_ALLOWED_TOOLS
2163
- ),
2164
- host,
2165
- opts
2109
+ addOrReplaceAllowedTools(
2110
+ readFileSync(templatePath, "utf8"),
2111
+ REFILL_SENDS_ALLOWED_TOOLS
2166
2112
  ),
2167
2113
  host,
2168
2114
  "refill-sends"
@@ -2171,7 +2117,7 @@ function refillSendsSkillMd(host = "shared", opts = {}) {
2171
2117
  } catch {
2172
2118
  // fall through to hardcoded fallback below
2173
2119
  }
2174
- return stampInstalledHost(stampRefillReleaseIdentity(`---
2120
+ return stampInstalledHost(`---
2175
2121
  name: refill-sends
2176
2122
  description: Refill Sellable sender sends through the approval-gated refill workflow.
2177
2123
  visibility: public
@@ -2181,14 +2127,6 @@ ${allowedToolsYaml(REFILL_SENDS_ALLOWED_TOOLS)}
2181
2127
 
2182
2128
  # Sellable Refill Sends
2183
2129
 
2184
- ${REFILL_SENDS_FALLBACK_CONTRACT}
2185
-
2186
- fallbackSource: embedded
2187
-
2188
- Load \`refill-sends-workflow\`, then \`core/flow.v1.json\`, then
2189
- \`core/contract.v2.json\`, each through the Sellable MCP prompt tools until
2190
- \`hasMore:false\`. Fail closed on unsupported major or stale contract hash.
2191
-
2192
2130
  Use this as the customer-facing entrypoint for the Sellable \`refill-sends\`
2193
2131
  workflow. It supports \`--yolo\` and optional repeated \`--sender <name-or-id>\`
2194
2132
  selectors. It also supports \`--target-date YYYY-MM-DD\` to fill one exact
@@ -2238,7 +2176,7 @@ Desktop, then start a new thread.
2238
2176
  If exact subskill lookup fails, use
2239
2177
  \`mcp__sellable__search_subskill_prompts({ query: "refill-sends", includePublic: true, includeInternal: true })\`,
2240
2178
  then retry \`get_subskill_prompt\`.
2241
- `, host, opts), host, "refill-sends");
2179
+ `, host, "refill-sends");
2242
2180
  }
2243
2181
 
2244
2182
  function refreshSenderEngagementSkillMd(host = "shared") {
@@ -2750,7 +2688,7 @@ will change or after they approve the settings update.
2750
2688
  `;
2751
2689
  }
2752
2690
 
2753
- function codexPluginSkills(opts = {}) {
2691
+ function codexPluginSkills() {
2754
2692
  return [
2755
2693
  {
2756
2694
  dir: "sellable-find-leads",
@@ -2805,7 +2743,7 @@ function codexPluginSkills(opts = {}) {
2805
2743
  dir: "sellable-refill-sends",
2806
2744
  displayName: "Sellable Refill Sends",
2807
2745
  description: "Refill sender sends with approval-gated campaign selection",
2808
- skillMd: refillSendsSkillMd("codex", opts),
2746
+ skillMd: refillSendsSkillMd("codex"),
2809
2747
  },
2810
2748
  ];
2811
2749
  }
@@ -2996,7 +2934,7 @@ then retry \`get_subskill_prompt\`.
2996
2934
  );
2997
2935
  }
2998
2936
 
2999
- function hermesSkillDefinitions(opts = {}) {
2937
+ function hermesSkillDefinitions() {
3000
2938
  return [
3001
2939
  {
3002
2940
  commandName: "find-leads",
@@ -3061,7 +2999,7 @@ function hermesSkillDefinitions(opts = {}) {
3061
2999
  commandName: "refill-sends",
3062
3000
  dir: hermesCommandName("refill-sends"),
3063
3001
  skillMd: normalizeHermesSkillMarkdown(
3064
- refillSendsSkillMd("hermes", opts),
3002
+ refillSendsSkillMd("hermes"),
3065
3003
  "refill-sends"
3066
3004
  ),
3067
3005
  },
@@ -3254,7 +3192,7 @@ ${stripFrontmatter(command.skillMd)}
3254
3192
  `;
3255
3193
  }
3256
3194
 
3257
- function claudeCommands(opts = {}) {
3195
+ function claudeCommands() {
3258
3196
  return [
3259
3197
  {
3260
3198
  name: "find-leads",
@@ -3319,7 +3257,7 @@ function claudeCommands(opts = {}) {
3319
3257
  description:
3320
3258
  "Refill Sellable sender sends through the approval-gated refill workflow.",
3321
3259
  argumentHint: "[--yolo] [--sender name-or-id ...]",
3322
- skillMd: refillSendsSkillMd("claude", opts),
3260
+ skillMd: refillSendsSkillMd("claude"),
3323
3261
  allowedTools: ["AskUserQuestion", ...REFILL_SENDS_ALLOWED_TOOLS],
3324
3262
  },
3325
3263
  {
@@ -3344,7 +3282,7 @@ function claudeCommands(opts = {}) {
3344
3282
  }
3345
3283
 
3346
3284
  function writeCodexPluginSkills(pluginRoot, opts) {
3347
- const skills = codexPluginSkills(opts);
3285
+ const skills = codexPluginSkills();
3348
3286
  const currentSkillDirs = new Set(skills.map((skill) => skill.dir));
3349
3287
  const skillsRoot = join(pluginRoot, "skills");
3350
3288
 
@@ -3408,7 +3346,7 @@ function writeClaudeCustomAgents(opts) {
3408
3346
 
3409
3347
  function writeClaudeCommands(opts) {
3410
3348
  const home = claudeHome();
3411
- for (const command of claudeCommands(opts)) {
3349
+ for (const command of claudeCommands()) {
3412
3350
  writeFile(join(home, "commands", command.filename), command.content, opts);
3413
3351
  }
3414
3352
  }
@@ -3649,19 +3587,8 @@ const WATCH_MODE_DRIVER_ENV = {
3649
3587
  };
3650
3588
 
3651
3589
  function mcpEnvForHost(host, opts) {
3652
- const mcpVersionMatch = /^@sellable\/mcp@(.+)$/.exec(opts.mcpPackage || "");
3653
- const mcpVersion = mcpVersionMatch?.[1] || String(opts.mcpPackage || "unknown");
3654
- const pluginVersion = host === "codex" ? CODEX_PLUGIN_VERSION : "not-applicable";
3655
- const cacheIdentity =
3656
- host === "codex"
3657
- ? `codex-plugin:${CODEX_PLUGIN_VERSION}|mcp:${mcpVersion}`
3658
- : `${host}-host|mcp:${mcpVersion}`;
3659
3590
  const env = {
3660
3591
  SELLABLE_WATCH_MODE_DRIVER: host,
3661
- SELLABLE_INSTALL_PACKAGE_VERSION: getInstallVersion(),
3662
- SELLABLE_MCP_PACKAGE_VERSION: mcpVersion,
3663
- SELLABLE_CODEX_PLUGIN_VERSION: pluginVersion,
3664
- SELLABLE_PLUGIN_CACHE_IDENTITY: cacheIdentity,
3665
3592
  };
3666
3593
  if (opts.server === "hosted") return env;
3667
3594
  if (opts.sellableConfigPath) {
@@ -3920,7 +3847,7 @@ function writeHermesMcpServer(opts) {
3920
3847
 
3921
3848
  function installHermesSkills(opts) {
3922
3849
  const root = hermesSkillsRoot(opts);
3923
- for (const skill of hermesSkillDefinitions(opts)) {
3850
+ for (const skill of hermesSkillDefinitions()) {
3924
3851
  const skillRoot = join(root, skill.dir);
3925
3852
  writeFile(join(skillRoot, "SKILL.md"), skill.skillMd, opts);
3926
3853
  if (skill.soulMd) {
@@ -5407,7 +5334,7 @@ function printInstallAgentBox(title, installCmd, docsUrl) {
5407
5334
  console.log(bot);
5408
5335
  }
5409
5336
 
5410
- function printNextSteps(installedHosts, authReused, opts = {}) {
5337
+ function printNextSteps(installedHosts, authReused) {
5411
5338
  console.log("");
5412
5339
 
5413
5340
  if (installedHosts.length === 0) {
@@ -5449,7 +5376,7 @@ function printNextSteps(installedHosts, authReused, opts = {}) {
5449
5376
  );
5450
5377
  console.log("");
5451
5378
  const installV = getInstallVersion();
5452
- const mcpV = getConfiguredMcpVersion(opts);
5379
+ const mcpV = getMcpVersion();
5453
5380
  console.log(
5454
5381
  ` ${C.grey}@sellable/install v${installV} · @sellable/mcp v${mcpV} · Codex plugin v${CODEX_PLUGIN_VERSION}${C.reset}`
5455
5382
  );
@@ -5552,7 +5479,7 @@ function printNextSteps(installedHosts, authReused, opts = {}) {
5552
5479
  );
5553
5480
  console.log("");
5554
5481
  const installV = getInstallVersion();
5555
- const mcpV = getConfiguredMcpVersion(opts);
5482
+ const mcpV = getMcpVersion();
5556
5483
  console.log(
5557
5484
  ` ${C.grey}@sellable/install v${installV} · @sellable/mcp v${mcpV} · Codex plugin v${CODEX_PLUGIN_VERSION}${C.reset}`
5558
5485
  );
@@ -5972,73 +5899,6 @@ async function main() {
5972
5899
  printCreateCommandHint();
5973
5900
  process.exit(0);
5974
5901
  }
5975
- if (rawArgs[0] === "codex" && rawArgs[1] === "plugin-selection") {
5976
- const command = rawArgs[2];
5977
- const flags = new Map();
5978
- for (let index = 3; index < rawArgs.length; index += 2) {
5979
- const flag = rawArgs[index];
5980
- const value = rawArgs[index + 1];
5981
- if (!flag?.startsWith("--") || !value || value.startsWith("--")) {
5982
- throw new Error(`Invalid Codex plugin-selection option: ${flag ?? "<missing>"}`);
5983
- }
5984
- flags.set(flag, value);
5985
- }
5986
- const required = (name) => {
5987
- const value = flags.get(name);
5988
- if (!value) throw new Error(`Missing value for ${name}`);
5989
- return value;
5990
- };
5991
- const paths = resolveCodexPluginSelectionPaths({ home: homedir() });
5992
- let result;
5993
- if (command === "status") {
5994
- result = readCodexPluginSelection({ paths, stableVersion: flags.get("--stable-version") });
5995
- } else if (command === "snapshot") {
5996
- result = snapshotCodexPluginSelection({
5997
- paths,
5998
- snapshotRoot: required("--snapshot-root"),
5999
- });
6000
- } else if (command === "install-cache") {
6001
- result = installCodexCandidateCache({
6002
- paths,
6003
- sourcePluginRoot: required("--source"),
6004
- version: required("--version"),
6005
- });
6006
- } else if (command === "activate") {
6007
- result = activateCodexCandidateSelection({
6008
- paths,
6009
- snapshotManifestPath: required("--snapshot"),
6010
- expectedSnapshotHash: required("--snapshot-hash"),
6011
- candidateVersion: required("--candidate-version"),
6012
- expectedCandidateHash: required("--candidate-hash"),
6013
- approvalId: required("--approval-id"),
6014
- approvedAt: required("--approved-at"),
6015
- restoreBy: required("--restore-by"),
6016
- now: required("--now"),
6017
- });
6018
- } else if (command === "restore") {
6019
- result = restoreCodexPluginSelection({
6020
- paths,
6021
- snapshotManifestPath: required("--snapshot"),
6022
- expectedSnapshotHash: required("--snapshot-hash"),
6023
- activationPath: required("--activation"),
6024
- now: required("--now"),
6025
- recoveryReason: flags.get("--recovery-reason") || undefined,
6026
- taskEvidence:
6027
- flags.has("--task-id") && flags.has("--resolved-candidate-hash")
6028
- ? {
6029
- taskId: flags.get("--task-id"),
6030
- resolvedCandidateHash: flags.get("--resolved-candidate-hash"),
6031
- }
6032
- : undefined,
6033
- });
6034
- } else {
6035
- throw new Error(
6036
- "Usage: sellable codex plugin-selection snapshot|install-cache|activate|restore|status"
6037
- );
6038
- }
6039
- console.log(JSON.stringify(result, null, 2));
6040
- process.exit(0);
6041
- }
6042
5902
  if (
6043
5903
  rawArgs[0] === "hermes" &&
6044
5904
  rawArgs[1] === "profile" &&
@@ -6113,7 +5973,7 @@ async function main() {
6113
5973
  }
6114
5974
 
6115
5975
  if (!opts.verifyOnly) {
6116
- printNextSteps(installedHosts, authReused, opts);
5976
+ printNextSteps(installedHosts, authReused);
6117
5977
  }
6118
5978
  } catch (error) {
6119
5979
  console.error(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/install",
3
- "version": "0.1.340-phase981.20260711223346",
3
+ "version": "0.1.342",
4
4
  "type": "module",
5
5
  "description": "One-command installer for Sellable MCP in Claude Code, Codex, and Hermes",
6
6
  "bin": {
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: refill-sends-v2
3
3
  description: Execute refill sends v2 through the fenced evergreen refill loop, with dry-run and resume support.
4
- visibility: internal
4
+ visibility: public
5
5
  allowed-tools:
6
- - mcp__sellable__refill_sends
6
+ - mcp__sellable__refill_sends_v2
7
7
  - mcp__sellable__get_refill_plan_v2
8
8
  - mcp__sellable__get_subskill_prompt
9
9
  - mcp__sellable__get_subskill_asset
@@ -24,7 +24,7 @@ Host command names:
24
24
  - Claude Code: `/sellable:refill-sends-v2`
25
25
  - Codex: `$sellable:refill-sends-v2`
26
26
 
27
- `refill_sends` is the execution surface. In real-run mode it starts or
27
+ `refill_sends_v2` is the execution surface. In real-run mode it starts or
28
28
  resumes a fenced refill run, reads a fresh packet, executes only the packet's
29
29
  named bounded work, verifies the result, and returns either a terminal report, a
30
30
  blocked report, or an in-progress resume handle. In dry-run mode it stays
@@ -40,19 +40,19 @@ with `WORKSPACE_REQUIRED`; do not switch the shared active workspace.
40
40
  For a real refill run:
41
41
 
42
42
  ```text
43
- refill_sends({ workspaceId, intent:"auto", senderIds?, approvalMode? })
43
+ refill_sends_v2({ workspaceId, intent:"auto", senderIds?, approvalMode? })
44
44
  ```
45
45
 
46
46
  For read-only inspection:
47
47
 
48
48
  ```text
49
- refill_sends({ workspaceId, dryRun:true, intent:"auto", senderIds? })
49
+ refill_sends_v2({ workspaceId, dryRun:true, intent:"auto", senderIds? })
50
50
  ```
51
51
 
52
52
  To resume an in-progress run, pass the handle back exactly:
53
53
 
54
54
  ```text
55
- refill_sends({ workspaceId, runId, fence })
55
+ refill_sends_v2({ workspaceId, runId, fence })
56
56
  ```
57
57
 
58
58
  If a stale handle loses the lease, the tool reports the holder status and the