@sellable/install 0.1.179 → 0.1.181

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
@@ -23,8 +23,8 @@ agent command for launching a campaign:
23
23
  sellable create
24
24
  ```
25
25
 
26
- Campaign creation itself runs inside Claude Code or Codex, where the Sellable
27
- MCP tools and approval flow are available.
26
+ Campaign creation, post drafting, and identity interviews run inside Claude Code
27
+ or Codex, where the Sellable MCP tools and approval flows are available.
28
28
 
29
29
  Install is auth-free by default. If you do not pass a token, the agent handles
30
30
  Sellable sign-in on the first campaign run with a magic-link handoff.
@@ -70,19 +70,21 @@ Use the same public entrypoints in both hosts:
70
70
 
71
71
  - Claude Code: `/sellable:create-campaign`
72
72
  - Claude Code: `/sellable:interview`
73
- - Claude Code: `/sellable:load-voice`
73
+ - Claude Code: `/sellable:create-post`
74
74
  - Codex: `$sellable:create-campaign`
75
75
  - Codex: `$sellable:interview`
76
- - Codex: `$sellable:load-voice`
76
+ - Codex: `$sellable:create-post`
77
77
  - Codex Desktop plugin: `sellable@sellable`
78
78
  - Codex visible skill: `Sellable Create Campaign`
79
79
  - Codex visible skill: `Sellable Identity Interview`
80
- - Codex visible skill: `Sellable Load Voice`
80
+ - Codex visible skill: `Sellable Create Post`
81
81
  - Internal MCP workflow prompt: `create-campaign-v2`
82
82
 
83
83
  Do not ask users to run `/sellable:create-campaign-v2`,
84
- `$sellable:create-campaign-v2`, or `$sellable:sellable:create-campaign`.
85
- `create-campaign-v2` is loaded internally by the skill.
84
+ `$sellable:create-campaign-v2`, `$sellable:load-voice`, or
85
+ `$sellable:sellable:create-campaign`. `create-campaign-v2` is loaded internally
86
+ by the campaign skill. `create-post` loads voice internally, so there is no
87
+ separate public voice-loading command.
86
88
 
87
89
  ## Structured Questions
88
90
 
@@ -31,7 +31,7 @@ function getInstallVersion() {
31
31
  }
32
32
  }
33
33
 
34
- const CODEX_PLUGIN_VERSION = "0.1.34";
34
+ const CODEX_PLUGIN_VERSION = "0.1.36";
35
35
  const CODEX_PLUGIN_COMPAT_VERSIONS = [
36
36
  "0.1.8",
37
37
  "0.1.9",
@@ -59,6 +59,8 @@ const CODEX_PLUGIN_COMPAT_VERSIONS = [
59
59
  "0.1.31",
60
60
  "0.1.32",
61
61
  "0.1.33",
62
+ "0.1.34",
63
+ "0.1.35",
62
64
  ];
63
65
  const INSTALL_PACKAGE_SPEC =
64
66
  process.env.SELLABLE_INSTALL_PACKAGE_SPEC || "@sellable/install@latest";
@@ -149,9 +151,9 @@ Options:
149
151
 
150
152
  Auth:
151
153
  Install is auth-free by default. Sign in happens on the first run of
152
- /sellable:create-campaign in Claude Code or Codex, where the agent walks
153
- you through signup or sign-in and stores credentials in
154
- ~/.sellable/config.json.
154
+ /sellable:create-campaign or /sellable:create-post in Claude Code or Codex,
155
+ where the agent walks you through signup or sign-in and stores credentials
156
+ in ~/.sellable/config.json.
155
157
 
156
158
  For CI/scripted installs, pass --token + --workspace-id or set
157
159
  SELLABLE_TOKEN + SELLABLE_WORKSPACE_ID and the installer will write the
@@ -174,11 +176,15 @@ function printCreateCommandHint() {
174
176
  console.log("");
175
177
  printAgentBox("Using Claude Code?", "claude", [
176
178
  { label: "Campaign", command: "/sellable:create-campaign" },
179
+ { label: "Post", command: "/sellable:create-post" },
180
+ { label: "Interview", command: "/sellable:interview" },
177
181
  ]);
178
182
  console.log("");
179
183
  console.log("");
180
184
  printAgentBox("Using Codex?", "codex", [
181
185
  { label: "Campaign", command: "$sellable:create-campaign" },
186
+ { label: "Post", command: "$sellable:create-post" },
187
+ { label: "Interview", command: "$sellable:interview" },
182
188
  ]);
183
189
  console.log("");
184
190
  console.log(` ${"─".repeat(63)}`);
@@ -839,16 +845,18 @@ automation just because a watch link exists. If \`create_campaign\` returns
839
845
  \`watchHandoff.markdown\`, print that exact value once, directly before the brief
840
846
  approval question. It will use the URL mode to say Codex or Claude Code:
841
847
 
848
+ \`\`\`\`markdown
842
849
  \`\`\`text
843
- ╔══════════════════════════════════════════════════════════════╗
844
- ║ OPEN THIS LINK TO WATCH CODEX BUILD THE CAMPAIGN LIVE
845
- ╚══════════════════════════════════════════════════════════════╝
850
+ +------------------------------------------------------+
851
+ | WATCH CODEX BUILD THE CAMPAIGN LIVE |
852
+ +------------------------------------------------------+
853
+ \`\`\`
846
854
 
847
855
  [Open live campaign builder]({watchUrl})
848
856
 
849
857
  Keep this chat open. I'll ask approval questions here before making decisions
850
858
  that need your judgment.
851
- \`\`\`
859
+ \`\`\`\`
852
860
 
853
861
  The Markdown link is intentional: rendered chat clients turn it into a large
854
862
  click target, and plain terminals still expose the tokenized URL inside the
@@ -1226,6 +1234,7 @@ allowed-tools:
1226
1234
  - mcp__sellable__get_subskill_prompt
1227
1235
  - mcp__sellable__get_subskill_asset
1228
1236
  - mcp__sellable__search_subskill_prompts
1237
+ - mcp__sellable__capture_post_idea
1229
1238
  - Read
1230
1239
  - Write
1231
1240
  - Edit
@@ -1262,6 +1271,14 @@ Desktop, then start a new thread.
1262
1271
  3. Follow the canonical prompt exactly. Save local memory only where that prompt
1263
1272
  directs, under \`~/.sellable/configs/core/**\` and
1264
1273
  \`~/.sellable/interviews/**\`.
1274
+ 4. If the interview captures a content-specific LinkedIn post idea, hook/taste
1275
+ correction, draft-first post calibration note, or voice-note transcript meant
1276
+ as a post idea, the canonical prompt may bridge only that item with
1277
+ \`mcp__sellable__capture_post_idea\` under
1278
+ \`~/.sellable/content/linkedin/ideas/**\`. Core identity, proof, stories,
1279
+ answer-bank entries, transcripts, references, and raw archives must stay in
1280
+ \`~/.sellable/configs/core/**\` and \`~/.sellable/interviews/**\`.
1281
+ Core identity, proof, stories, answer-bank entries, transcripts, references, and raw archives must stay in core/interviews.
1265
1282
 
1266
1283
  ## MCP Prompt Fallback
1267
1284
 
@@ -1271,27 +1288,40 @@ then retry \`get_subskill_prompt\`.
1271
1288
  `;
1272
1289
  }
1273
1290
 
1274
- function loadVoiceSkillMd() {
1291
+ function createPostSkillMd() {
1275
1292
  return `---
1276
- name: load-voice
1277
- description: Load Sellable voice/company memory for answering questions, writing posts, applications, replies, and reviews in the user's voice.
1293
+ name: create-post
1294
+ description: Capture rough LinkedIn post ideas, research currently working hooks, and save validated drafts in the user's voice.
1278
1295
  allowed-tools:
1296
+ - mcp__sellable__get_auth_status
1279
1297
  - mcp__sellable__get_subskill_prompt
1298
+ - mcp__sellable__get_subskill_asset
1280
1299
  - mcp__sellable__search_subskill_prompts
1281
- - Read
1282
- - Glob
1283
- - Grep
1300
+ - mcp__sellable__get_engage_memory
1301
+ - mcp__sellable__capture_post_idea
1302
+ - mcp__sellable__get_post_idea
1303
+ - mcp__sellable__list_post_ideas
1304
+ - mcp__sellable__save_hook_research
1305
+ - mcp__sellable__save_post_draft
1306
+ - mcp__sellable__get_post_draft
1307
+ - mcp__sellable__mark_post_published
1308
+ - mcp__sellable__list_published_posts
1309
+ - mcp__sellable__search_engagement_posts
1310
+ - mcp__sellable__fetch_linkedin_posts
1311
+ - mcp__sellable__fetch_linkedin_profile
1312
+ - mcp__sellable__record_engage_proven_search
1284
1313
  ---
1285
1314
 
1286
- # Sellable Load Voice
1315
+ # Sellable Create Post
1287
1316
 
1288
- Use this as the customer-facing entrypoint for loading Sellable voice/company
1289
- memory before drafting, answering, rewriting, reviewing, or calibrating copy in
1290
- the user's voice.
1317
+ Use this as the customer-facing entrypoint for the Sellable \`create-post\`
1318
+ workflow. It captures raw LinkedIn post ideas, preserves the user's source
1319
+ wording, researches currently working hooks, validates proof/voice/AI tells, and
1320
+ saves drafts under \`~/.sellable/content/linkedin/**\`.
1291
1321
 
1292
1322
  ## Bootstrap
1293
1323
 
1294
- MCP prompt access and local read tools are required. Do not run shell commands,
1324
+ MCP prompt access is required. Do not inspect repo files, run shell commands,
1295
1325
  use \`npm\`, \`node\`, local harness scripts, or read local prompt files to
1296
1326
  emulate this workflow.
1297
1327
 
@@ -1302,20 +1332,24 @@ Desktop, then start a new thread.
1302
1332
 
1303
1333
  ## Execute Workflow
1304
1334
 
1305
- 1. Load the canonical prompt via
1306
- \`mcp__sellable__get_subskill_prompt({ subskillName: "load-voice" })\`.
1335
+ 1. Call \`mcp__sellable__get_auth_status({})\` so hook research failures can be
1336
+ distinguished from local content capture.
1337
+ 2. Load the canonical prompt via
1338
+ \`mcp__sellable__get_subskill_prompt({ subskillName: "create-post" })\`.
1307
1339
  If the response has \`hasMore=true\`, continue with \`nextOffset\` until
1308
1340
  \`hasMore=false\`.
1309
- 2. Follow the canonical prompt exactly. Read the relevant
1310
- \`~/.sellable/configs/**\` memory files it names.
1311
- 3. Apply the loaded memory silently to the user's requested writing or answer.
1312
- If the user only asked to load voice, summarize the active rules briefly and
1313
- ask what they want drafted, answered, or reviewed.
1341
+ 3. Load every required create-post reference with
1342
+ \`mcp__sellable__get_subskill_asset({ subskillName: "create-post", assetPath: "references/<file>.md" })\`.
1343
+ If any asset response has \`hasMore=true\`, continue with \`nextOffset\`
1344
+ until \`hasMore=false\`.
1345
+ 4. Follow the canonical prompt exactly. Use the content tools for ideas,
1346
+ research, drafts, and published records. Do not write repo-local prompt files
1347
+ or append to legacy flat draft files.
1314
1348
 
1315
1349
  ## MCP Prompt Fallback
1316
1350
 
1317
1351
  If exact subskill lookup fails, use
1318
- \`mcp__sellable__search_subskill_prompts({ query: "load-voice", includePublic: true })\`,
1352
+ \`mcp__sellable__search_subskill_prompts({ query: "create-post", includePublic: true, includeInternal: true })\`,
1319
1353
  then retry \`get_subskill_prompt\`.
1320
1354
  `;
1321
1355
  }
@@ -1524,10 +1558,10 @@ function codexPluginSkills() {
1524
1558
  skillMd: interviewSkillMd(),
1525
1559
  },
1526
1560
  {
1527
- dir: "sellable-load-voice",
1528
- displayName: "Sellable Load Voice",
1529
- description: "Load voice memory for writing and answers",
1530
- skillMd: loadVoiceSkillMd(),
1561
+ dir: "sellable-create-post",
1562
+ displayName: "Sellable Create Post",
1563
+ description: "Capture ideas and draft LinkedIn posts in your voice",
1564
+ skillMd: createPostSkillMd(),
1531
1565
  },
1532
1566
  ];
1533
1567
  }
@@ -1700,7 +1734,22 @@ function claudeCustomAgents() {
1700
1734
  }
1701
1735
 
1702
1736
  function writeCodexPluginSkills(pluginRoot, opts) {
1703
- for (const skill of codexPluginSkills()) {
1737
+ const skills = codexPluginSkills();
1738
+ const currentSkillDirs = new Set(skills.map((skill) => skill.dir));
1739
+ const skillsRoot = join(pluginRoot, "skills");
1740
+
1741
+ if (existsSync(skillsRoot)) {
1742
+ for (const entry of readdirSync(skillsRoot, { withFileTypes: true })) {
1743
+ if (!entry.isDirectory() || currentSkillDirs.has(entry.name)) continue;
1744
+ const stalePath = join(skillsRoot, entry.name);
1745
+ logVerbose(
1746
+ `${C.grey}Removing stale Codex plugin skill ${stalePath}${C.reset}`
1747
+ );
1748
+ if (!opts.dryRun) rmSync(stalePath, { recursive: true, force: true });
1749
+ }
1750
+ }
1751
+
1752
+ for (const skill of skills) {
1704
1753
  const skillRoot = join(pluginRoot, "skills", skill.dir);
1705
1754
  writeFile(join(skillRoot, "SKILL.md"), skill.skillMd, opts);
1706
1755
  if (skill.soulMd) {
@@ -2500,6 +2549,8 @@ function printNextSteps(installedHosts, authReused) {
2500
2549
  if (hasClaude) {
2501
2550
  printAgentBox("Using Claude Code?", "claude", [
2502
2551
  { label: "Campaign", command: "/sellable:create-campaign" },
2552
+ { label: "Post", command: "/sellable:create-post" },
2553
+ { label: "Interview", command: "/sellable:interview" },
2503
2554
  ]);
2504
2555
  console.log("");
2505
2556
  console.log("");
@@ -2507,6 +2558,8 @@ function printNextSteps(installedHosts, authReused) {
2507
2558
  if (hasCodex) {
2508
2559
  printAgentBox("Using Codex?", "codex", [
2509
2560
  { label: "Campaign", command: "$sellable:create-campaign" },
2561
+ { label: "Post", command: "$sellable:create-post" },
2562
+ { label: "Interview", command: "$sellable:interview" },
2510
2563
  ]);
2511
2564
  console.log("");
2512
2565
  }
@@ -2777,7 +2830,11 @@ async function main() {
2777
2830
  console.log(` apiUrl: ${apiUrl}`);
2778
2831
  console.log(` Continue in your agent:`);
2779
2832
  console.log(` Claude Code: /sellable:create-campaign`);
2833
+ console.log(` Claude Code: /sellable:create-post`);
2834
+ console.log(` Claude Code: /sellable:interview`);
2780
2835
  console.log(` Codex: $sellable:create-campaign`);
2836
+ console.log(` Codex: $sellable:create-post`);
2837
+ console.log(` Codex: $sellable:interview`);
2781
2838
  process.exit(0);
2782
2839
  }
2783
2840
  if (rawArgs[0] === "uninstall") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/install",
3
- "version": "0.1.179",
3
+ "version": "0.1.181",
4
4
  "type": "module",
5
5
  "description": "One-command installer for Sellable MCP in Claude Code and Codex",
6
6
  "bin": {
@@ -408,16 +408,18 @@ automation just because a watch link exists. If `create_campaign` returns
408
408
  `watchHandoff.markdown`, print that exact value once, directly before the brief
409
409
  approval question. It will use the URL mode to say Codex or Claude Code:
410
410
 
411
+ ````markdown
411
412
  ```text
412
- ╔══════════════════════════════════════════════════════════════╗
413
- ║ OPEN THIS LINK TO WATCH CODEX BUILD THE CAMPAIGN LIVE
414
- ╚══════════════════════════════════════════════════════════════╝
413
+ +------------------------------------------------------+
414
+ | WATCH CODEX BUILD THE CAMPAIGN LIVE |
415
+ +------------------------------------------------------+
416
+ ```
415
417
 
416
418
  [Open live campaign builder]({watchUrl})
417
419
 
418
420
  Keep this chat open. I'll ask approval questions here before making decisions
419
421
  that need your judgment.
420
- ```
422
+ ````
421
423
 
422
424
  The Markdown link is intentional: rendered chat clients turn it into a large
423
425
  click target, and plain terminals still expose the tokenized URL inside the