@sellable/install 0.1.100 → 0.1.102
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 +4 -1
- package/bin/sellable-install.mjs +133 -28
- package/package.json +1 -1
- package/skill-templates/create-campaign.md +28 -5
package/README.md
CHANGED
|
@@ -55,12 +55,15 @@ starts in one registry entry instead of scattered prompt edits.
|
|
|
55
55
|
|
|
56
56
|
## Names
|
|
57
57
|
|
|
58
|
-
Use the same public
|
|
58
|
+
Use the same public entrypoints in both hosts:
|
|
59
59
|
|
|
60
60
|
- Claude Code: `/sellable:create-campaign`
|
|
61
|
+
- Claude Code: `/sellable:interview`
|
|
61
62
|
- Codex: `$sellable:create-campaign`
|
|
63
|
+
- Codex: `$sellable:interview`
|
|
62
64
|
- Codex Desktop plugin: `sellable@sellable`
|
|
63
65
|
- Codex visible skill: `Sellable Create Campaign`
|
|
66
|
+
- Codex visible skill: `Sellable Identity Interview`
|
|
64
67
|
- Internal MCP workflow prompt: `create-campaign-v2`
|
|
65
68
|
|
|
66
69
|
Do not ask users to run `/sellable:create-campaign-v2`,
|
package/bin/sellable-install.mjs
CHANGED
|
@@ -134,7 +134,7 @@ Usage:
|
|
|
134
134
|
npx -y @sellable/install@latest -- [options]
|
|
135
135
|
|
|
136
136
|
Commands:
|
|
137
|
-
create Show how to launch
|
|
137
|
+
create Show how to launch public Sellable workflows.
|
|
138
138
|
auth set <token> Save a Sellable API token for first-run auth.
|
|
139
139
|
uninstall Remove Sellable host config and installed artifacts.
|
|
140
140
|
|
|
@@ -167,7 +167,7 @@ Auth:
|
|
|
167
167
|
function printCreateCommandHint() {
|
|
168
168
|
printBanner();
|
|
169
169
|
console.log(
|
|
170
|
-
` ${C.bold}
|
|
170
|
+
` ${C.bold}Run Sellable from Claude Code or Codex.${C.reset}`
|
|
171
171
|
);
|
|
172
172
|
console.log("");
|
|
173
173
|
console.log(
|
|
@@ -175,14 +175,20 @@ function printCreateCommandHint() {
|
|
|
175
175
|
);
|
|
176
176
|
console.log("");
|
|
177
177
|
console.log(` ${"═".repeat(63)}`);
|
|
178
|
-
console.log(` ${C.bold}Start a Sellable
|
|
178
|
+
console.log(` ${C.bold}Start a Sellable workflow:${C.reset}`);
|
|
179
179
|
console.log(` ${"═".repeat(63)}`);
|
|
180
180
|
console.log("");
|
|
181
181
|
console.log("");
|
|
182
|
-
printAgentBox("Using Claude Code?", "claude",
|
|
182
|
+
printAgentBox("Using Claude Code?", "claude", [
|
|
183
|
+
{ label: "Campaign", command: "/sellable:create-campaign" },
|
|
184
|
+
{ label: "Identity", command: "/sellable:interview" },
|
|
185
|
+
]);
|
|
183
186
|
console.log("");
|
|
184
187
|
console.log("");
|
|
185
|
-
printAgentBox("Using Codex?", "codex",
|
|
188
|
+
printAgentBox("Using Codex?", "codex", [
|
|
189
|
+
{ label: "Campaign", command: "$sellable:create-campaign" },
|
|
190
|
+
{ label: "Identity", command: "$sellable:interview" },
|
|
191
|
+
]);
|
|
186
192
|
console.log("");
|
|
187
193
|
console.log(` ${"─".repeat(63)}`);
|
|
188
194
|
console.log(` ${C.grey}If those commands are missing, run:${C.reset}`);
|
|
@@ -640,6 +646,25 @@ data, compare sources by source volume, sampled ICP fit, activity/warmth
|
|
|
640
646
|
signals, cleanup risk, and confidence basis. If a user asks for a forecast,
|
|
641
647
|
label it explicitly as not estimated from this run.
|
|
642
648
|
|
|
649
|
+
Before any provider prompt, search, source scout, or signal-discovery call,
|
|
650
|
+
show a short source-plan gate and ask for approval. The gate should say:
|
|
651
|
+
|
|
652
|
+
- given this campaign, the viable source options
|
|
653
|
+
- the recommended first lane
|
|
654
|
+
- why that lane fits the buyer, offer, and likely public activity
|
|
655
|
+
- what will be tested next
|
|
656
|
+
- the fallback lane if relevant posts or ICP engagement look thin
|
|
657
|
+
- that approval authorizes scouting/search only, not lead import or sending
|
|
658
|
+
|
|
659
|
+
If active prospects likely engage with relevant LinkedIn content, recommend
|
|
660
|
+
LinkedIn post engagement / Signal Discovery and name the post themes you will
|
|
661
|
+
look for. If the niche is too private, low-volume, or unlikely to have relevant
|
|
662
|
+
public posts, recommend Sales Nav recent activity, broader Sales Nav role/title
|
|
663
|
+
filters, or Prospeo, and explain the tradeoff. Do not call \`search_signals\`,
|
|
664
|
+
\`search_sales_nav\`, \`search_prospeo\`, \`fetch_post_engagers\`, or provider-scoped
|
|
665
|
+
subagents until the user approves this source plan or explicitly chooses a
|
|
666
|
+
different source.
|
|
667
|
+
|
|
643
668
|
For campaign-attached Signal Discovery sampling, promote/select the exact posts
|
|
644
669
|
with \`select_promising_posts\` before \`fetch_post_engagers\` so the user can see
|
|
645
670
|
which posts are being sampled in the watched app. The watch guide should say
|
|
@@ -937,15 +962,19 @@ updates.
|
|
|
937
962
|
queue workflow cells, attach a sequence, or start until filter choice is
|
|
938
963
|
resolved, rubrics are saved when filters are enabled, template/token rules
|
|
939
964
|
are approved on the default Use Template path, and the approved message set
|
|
940
|
-
is synced into the campaign brief.
|
|
941
|
-
|
|
942
|
-
|
|
965
|
+
is synced into the campaign brief. When filters are approved, immediately
|
|
966
|
+
call \`mcp__sellable__update_campaign({ campaignId, enableICPFilters: true, currentStep: "create-icp-rubric", watchNarration })\`
|
|
967
|
+
so the watched app moves to Filter Rules while rubrics are drafted/saved.
|
|
968
|
+
After rubrics save, pause and say the fit rules are saved; approve the
|
|
969
|
+
message template next; after approval, queue the bounded review-batch
|
|
970
|
+
\`enrichCellId\` cells to kick off enrichment/filtering.
|
|
943
971
|
Product Generate Message cells must not run from the background template
|
|
944
972
|
path before that template/token approval. AI Generated uses the
|
|
945
973
|
product's AI-generated path and cancels or ignores the background template
|
|
946
974
|
draft.
|
|
947
975
|
6. The main thread owns watch navigation: use \`filter-choice\` after the 15-row
|
|
948
|
-
review batch, \`
|
|
976
|
+
review batch, \`create-icp-rubric\` as soon as filters are approved,
|
|
977
|
+
\`messages\` for the Use Template / AI Generated mode choice,
|
|
949
978
|
\`auto-execute-messaging\` for approved message work or the product's
|
|
950
979
|
AI-generated path, and \`awaiting-user-greenlight\` for the final handoff.
|
|
951
980
|
\`validate-sample\` is recovery/legacy only if reached.
|
|
@@ -1000,6 +1029,59 @@ If subskill lookup fails, use \`mcp__sellable__search_subskill_prompts({ query:
|
|
|
1000
1029
|
`;
|
|
1001
1030
|
}
|
|
1002
1031
|
|
|
1032
|
+
function interviewSkillMd() {
|
|
1033
|
+
return `---
|
|
1034
|
+
name: interview
|
|
1035
|
+
description: Build Sellable core identity/company memory for writing workflows.
|
|
1036
|
+
allowed-tools:
|
|
1037
|
+
- mcp__sellable__get_subskill_prompt
|
|
1038
|
+
- mcp__sellable__get_subskill_asset
|
|
1039
|
+
- mcp__sellable__search_subskill_prompts
|
|
1040
|
+
- Read
|
|
1041
|
+
- Write
|
|
1042
|
+
- Edit
|
|
1043
|
+
- Glob
|
|
1044
|
+
- Grep
|
|
1045
|
+
---
|
|
1046
|
+
|
|
1047
|
+
# Sellable Identity Interview
|
|
1048
|
+
|
|
1049
|
+
Use this as the customer-facing entrypoint for the Sellable \`interview\`
|
|
1050
|
+
workflow. It builds durable identity/company memory, proof hygiene, reusable
|
|
1051
|
+
answers, transcript references, and anti-AI writing rules for downstream
|
|
1052
|
+
Sellable writing workflows.
|
|
1053
|
+
|
|
1054
|
+
## Bootstrap
|
|
1055
|
+
|
|
1056
|
+
MCP prompt access is required. Do not inspect repo files, run shell commands,
|
|
1057
|
+
use \`npm\`, \`node\`, local harness scripts, or read local prompt files to
|
|
1058
|
+
emulate this workflow.
|
|
1059
|
+
|
|
1060
|
+
If the Sellable MCP prompt tools are unavailable, stop and say this is a Codex
|
|
1061
|
+
install/reload problem. Tell the user to run
|
|
1062
|
+
\`npx -y ${INSTALL_PACKAGE_SPEC} --host all\`, fully quit and reopen Codex
|
|
1063
|
+
Desktop, then start a new thread.
|
|
1064
|
+
|
|
1065
|
+
## Execute Workflow
|
|
1066
|
+
|
|
1067
|
+
1. Load the canonical prompt via
|
|
1068
|
+
\`mcp__sellable__get_subskill_prompt({ subskillName: "interview" })\`.
|
|
1069
|
+
If the response has \`hasMore=true\`, continue with \`nextOffset\` until
|
|
1070
|
+
\`hasMore=false\`.
|
|
1071
|
+
2. When the canonical prompt asks for \`references/*.md\`, load those files
|
|
1072
|
+
with \`mcp__sellable__get_subskill_asset({ subskillName: "interview", assetPath: "references/<file>.md" })\`.
|
|
1073
|
+
3. Follow the canonical prompt exactly. Save local memory only where that prompt
|
|
1074
|
+
directs, under \`.sellable/configs/core/**\` and
|
|
1075
|
+
\`.sellable/interviews/**\`.
|
|
1076
|
+
|
|
1077
|
+
## MCP Prompt Fallback
|
|
1078
|
+
|
|
1079
|
+
If exact subskill lookup fails, use
|
|
1080
|
+
\`mcp__sellable__search_subskill_prompts({ query: "interview", includePublic: true })\`,
|
|
1081
|
+
then retry \`get_subskill_prompt\`.
|
|
1082
|
+
`;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1003
1085
|
function createCampaignSoulMd() {
|
|
1004
1086
|
return `# Sellable Campaign GTM Engineer Soul
|
|
1005
1087
|
|
|
@@ -1189,6 +1271,12 @@ function codexPluginSkills() {
|
|
|
1189
1271
|
skillMd: createCampaignSkillMd(),
|
|
1190
1272
|
soulMd: createCampaignSoulMd(),
|
|
1191
1273
|
},
|
|
1274
|
+
{
|
|
1275
|
+
dir: "sellable-interview",
|
|
1276
|
+
displayName: "Sellable Identity Interview",
|
|
1277
|
+
description: "Build durable identity and company memory",
|
|
1278
|
+
skillMd: interviewSkillMd(),
|
|
1279
|
+
},
|
|
1192
1280
|
];
|
|
1193
1281
|
}
|
|
1194
1282
|
|
|
@@ -1795,16 +1883,21 @@ function verify(opts) {
|
|
|
1795
1883
|
".codex-plugin",
|
|
1796
1884
|
"plugin.json"
|
|
1797
1885
|
);
|
|
1798
|
-
const
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1886
|
+
const skillPaths = codexPluginSkills().map((skill) =>
|
|
1887
|
+
join(
|
|
1888
|
+
codexHome(),
|
|
1889
|
+
"plugins",
|
|
1890
|
+
"cache",
|
|
1891
|
+
"sellable",
|
|
1892
|
+
"sellable",
|
|
1893
|
+
CODEX_PLUGIN_VERSION,
|
|
1894
|
+
"skills",
|
|
1895
|
+
skill.dir,
|
|
1896
|
+
"SKILL.md"
|
|
1897
|
+
)
|
|
1898
|
+
);
|
|
1899
|
+
const hasSkillBundles = skillPaths.every((skillPath) =>
|
|
1900
|
+
existsSync(skillPath)
|
|
1808
1901
|
);
|
|
1809
1902
|
checks.push({
|
|
1810
1903
|
ok: existsSync(pluginPath),
|
|
@@ -1813,10 +1906,10 @@ function verify(opts) {
|
|
|
1813
1906
|
: "Codex Desktop plugin missing",
|
|
1814
1907
|
});
|
|
1815
1908
|
checks.push({
|
|
1816
|
-
ok:
|
|
1817
|
-
label:
|
|
1818
|
-
? "Codex skill
|
|
1819
|
-
: "Codex skill
|
|
1909
|
+
ok: hasSkillBundles,
|
|
1910
|
+
label: hasSkillBundles
|
|
1911
|
+
? "Codex skill bundles present"
|
|
1912
|
+
: "Codex skill bundles missing",
|
|
1820
1913
|
});
|
|
1821
1914
|
const codexAgentPaths = codexCustomAgents().map((agent) =>
|
|
1822
1915
|
join(codexHome(), "agents", agent.filename)
|
|
@@ -1878,10 +1971,13 @@ function visibleLen(s) {
|
|
|
1878
1971
|
return s.replace(/\x1b\[[0-9;]*m/g, "").length;
|
|
1879
1972
|
}
|
|
1880
1973
|
|
|
1881
|
-
function printAgentBox(title, terminalCmd,
|
|
1974
|
+
function printAgentBox(title, terminalCmd, agentCommands) {
|
|
1882
1975
|
// Inner width between │ ... │ — i.e. the printable area excluding the borders.
|
|
1883
1976
|
const W = 58;
|
|
1884
1977
|
const agentName = title.replace("Using ", "").replace("?", "");
|
|
1978
|
+
const commands = Array.isArray(agentCommands)
|
|
1979
|
+
? agentCommands
|
|
1980
|
+
: [{ label: "", command: agentCommands }];
|
|
1885
1981
|
|
|
1886
1982
|
const line = (text) => {
|
|
1887
1983
|
const pad = Math.max(0, W - visibleLen(text));
|
|
@@ -1902,7 +1998,10 @@ function printAgentBox(title, terminalCmd, agentCmd) {
|
|
|
1902
1998
|
console.log(blank());
|
|
1903
1999
|
console.log(line(` ${C.bold}STEP 2${C.reset} Then in ${agentName}, run:`));
|
|
1904
2000
|
console.log(blank());
|
|
1905
|
-
|
|
2001
|
+
for (const item of commands) {
|
|
2002
|
+
const label = item.label ? `${item.label.padEnd(8)} ` : "";
|
|
2003
|
+
console.log(line(` ${label}${C.cyan}${item.command}${C.reset}`));
|
|
2004
|
+
}
|
|
1906
2005
|
console.log(blank());
|
|
1907
2006
|
console.log(bot);
|
|
1908
2007
|
}
|
|
@@ -2015,18 +2114,24 @@ function printNextSteps(installedHosts, authReused) {
|
|
|
2015
2114
|
console.log("");
|
|
2016
2115
|
console.log("");
|
|
2017
2116
|
console.log(` ${"═".repeat(63)}`);
|
|
2018
|
-
console.log(` ${C.bold}To launch
|
|
2117
|
+
console.log(` ${C.bold}To launch a Sellable workflow:${C.reset}`);
|
|
2019
2118
|
console.log(` ${"═".repeat(63)}`);
|
|
2020
2119
|
console.log("");
|
|
2021
2120
|
console.log("");
|
|
2022
2121
|
|
|
2023
2122
|
if (hasClaude) {
|
|
2024
|
-
printAgentBox("Using Claude Code?", "claude",
|
|
2123
|
+
printAgentBox("Using Claude Code?", "claude", [
|
|
2124
|
+
{ label: "Campaign", command: "/sellable:create-campaign" },
|
|
2125
|
+
{ label: "Identity", command: "/sellable:interview" },
|
|
2126
|
+
]);
|
|
2025
2127
|
console.log("");
|
|
2026
2128
|
console.log("");
|
|
2027
2129
|
}
|
|
2028
2130
|
if (hasCodex) {
|
|
2029
|
-
printAgentBox("Using Codex?", "codex",
|
|
2131
|
+
printAgentBox("Using Codex?", "codex", [
|
|
2132
|
+
{ label: "Campaign", command: "$sellable:create-campaign" },
|
|
2133
|
+
{ label: "Identity", command: "$sellable:interview" },
|
|
2134
|
+
]);
|
|
2030
2135
|
console.log("");
|
|
2031
2136
|
}
|
|
2032
2137
|
|
package/package.json
CHANGED
|
@@ -117,6 +117,25 @@ data, compare sources by source volume, sampled ICP fit, activity/warmth
|
|
|
117
117
|
signals, cleanup risk, and confidence basis. If a user asks for a forecast,
|
|
118
118
|
label it explicitly as not estimated from this run.
|
|
119
119
|
|
|
120
|
+
Before any provider prompt, search, source scout, or signal-discovery call,
|
|
121
|
+
show a short source-plan gate and ask for approval. The gate should say:
|
|
122
|
+
|
|
123
|
+
- given this campaign, the viable source options
|
|
124
|
+
- the recommended first lane
|
|
125
|
+
- why that lane fits the buyer, offer, and likely public activity
|
|
126
|
+
- what will be tested next
|
|
127
|
+
- the fallback lane if relevant posts or ICP engagement look thin
|
|
128
|
+
- that approval authorizes scouting/search only, not lead import or sending
|
|
129
|
+
|
|
130
|
+
If active prospects likely engage with relevant LinkedIn content, recommend
|
|
131
|
+
LinkedIn post engagement / Signal Discovery and name the post themes you will
|
|
132
|
+
look for. If the niche is too private, low-volume, or unlikely to have relevant
|
|
133
|
+
public posts, recommend Sales Nav recent activity, broader Sales Nav role/title
|
|
134
|
+
filters, or Prospeo, and explain the tradeoff. Do not call `search_signals`,
|
|
135
|
+
`search_sales_nav`, `search_prospeo`, `fetch_post_engagers`, or provider-scoped
|
|
136
|
+
subagents until the user approves this source plan or explicitly chooses a
|
|
137
|
+
different source.
|
|
138
|
+
|
|
120
139
|
When the user has not supplied a source and multiple source angles are viable,
|
|
121
140
|
scout those angles as independent branches when the host can actually do it:
|
|
122
141
|
LinkedIn Engagement / active post engagers (internal `signal-discovery`
|
|
@@ -577,9 +596,12 @@ updates.
|
|
|
577
596
|
queue workflow cells, attach a sequence, or start until the filter choice is
|
|
578
597
|
resolved, rubrics are saved when filters are enabled, template/token rules
|
|
579
598
|
are approved on the default Use Template path, and the approved message set
|
|
580
|
-
is synced into the campaign brief.
|
|
581
|
-
|
|
582
|
-
|
|
599
|
+
is synced into the campaign brief. When filters are approved, immediately
|
|
600
|
+
call `mcp__sellable__update_campaign({ campaignId, enableICPFilters: true, currentStep: "create-icp-rubric", watchNarration })`
|
|
601
|
+
so the watched app moves to Filter Rules while rubrics are drafted/saved.
|
|
602
|
+
After rubrics save, pause and say the fit rules are saved; approve the
|
|
603
|
+
message template next; after approval, queue the bounded review-batch
|
|
604
|
+
`enrichCellId` cells to kick off enrichment/filtering.
|
|
583
605
|
Product Generate Message cells must not run from the background template
|
|
584
606
|
path before that template/token approval.
|
|
585
607
|
Do not ask the user to approve the brief before shell creation unless they
|
|
@@ -588,8 +610,9 @@ updates.
|
|
|
588
610
|
`mcp__sellable__update_campaign({ campaignId, currentStep })` before major
|
|
589
611
|
visible work so the user can watch progress in the app: `create-offer` for
|
|
590
612
|
the brief, `pick-provider` or the selected provider step while sourcing,
|
|
591
|
-
`filter-choice` after the 15-row review batch, `
|
|
592
|
-
|
|
613
|
+
`filter-choice` after the 15-row review batch, `create-icp-rubric` as soon
|
|
614
|
+
as filters are approved, `messages` for the Use Template / AI Generated mode
|
|
615
|
+
choice, `auto-execute-messaging` for approved
|
|
593
616
|
message work or the product's AI-generated path, `awaiting-user-greenlight`
|
|
594
617
|
for the final handoff, `settings` for sender selection, `sequence` after
|
|
595
618
|
sender attach, and `send` once the recommended sequence is attached.
|