@sellable/install 0.1.3 → 0.1.5

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,6 +31,7 @@ Auth is stored once at:
31
31
  Claude Code and Codex are configured to launch the same packaged MCP server.
32
32
 
33
33
  For Codex Desktop, the installer also writes a local Sellable plugin bundle into
34
- `~/.sellable/codex-marketplace` and enables it in `~/.codex/config.toml`.
34
+ `~/.sellable/codex-marketplace`, includes the Sellable skill entrypoints, and
35
+ enables it in `~/.codex/config.toml`.
35
36
 
36
37
  If only one host is installed, `--host all` installs the available host and tells you how to add the other one later.
@@ -9,7 +9,8 @@ import { createInterface } from "node:readline/promises";
9
9
  const DEFAULT_API_URL = "https://app.sellable.dev";
10
10
  const DEFAULT_SERVER_PACKAGE =
11
11
  process.env.SELLABLE_MCP_PACKAGE || "@sellable/mcp";
12
- const CODEX_PLUGIN_VERSION = "0.1.3";
12
+ const CODEX_PLUGIN_VERSION = "0.1.5";
13
+ const INSTALL_PACKAGE_SPEC = `@sellable/install@${CODEX_PLUGIN_VERSION}`;
13
14
 
14
15
  function usage() {
15
16
  return `Sellable agent installer
@@ -177,7 +178,7 @@ async function promptForMissingAuth(opts) {
177
178
  [
178
179
  "Missing Sellable token/workspace id.",
179
180
  `Create a token at ${opts.apiUrl}/settings, then rerun:`,
180
- " npx -y @sellable/install --host all --token <token> --workspace-id <workspace_id>",
181
+ ` npx -y ${INSTALL_PACKAGE_SPEC} --host all --token <token> --workspace-id <workspace_id>`,
181
182
  "",
182
183
  "You can also use SELLABLE_TOKEN and SELLABLE_WORKSPACE_ID.",
183
184
  ].join("\n")
@@ -331,6 +332,227 @@ function codexPluginMcp(opts) {
331
332
  };
332
333
  }
333
334
 
335
+ const CREATE_CAMPAIGN_ALLOWED_TOOLS = [
336
+ "mcp__sellable__get_auth_status",
337
+ "mcp__sellable__bootstrap_create_campaign",
338
+ "mcp__sellable__get_subskill_prompt",
339
+ "mcp__sellable__search_subskill_prompts",
340
+ "mcp__sellable__get_provider_prompt",
341
+ "mcp__sellable__get_message_prompt",
342
+ "mcp__sellable__get_active_workspace",
343
+ "mcp__sellable__list_senders",
344
+ "mcp__sellable__get_sender",
345
+ "mcp__sellable__enrich_sender",
346
+ "mcp__sellable__complete_sender_research",
347
+ "mcp__sellable__fetch_linkedin_profile",
348
+ "mcp__sellable__fetch_linkedin_posts",
349
+ "mcp__sellable__get_linkedin_profile",
350
+ "mcp__sellable__fetch_company",
351
+ "mcp__sellable__fetch_company_posts",
352
+ "mcp__sellable__lookup_sales_nav_filter",
353
+ "mcp__sellable__search_sales_nav",
354
+ "mcp__sellable__search_prospeo",
355
+ "mcp__sellable__search_signals",
356
+ "mcp__sellable__fetch_post_engagers",
357
+ "mcp__sellable__enrich_with_prospeo",
358
+ "mcp__sellable__bulk_enrich_with_prospeo",
359
+ "mcp__sellable__save_domain_filters",
360
+ "mcp__sellable__add_rubric_item",
361
+ "mcp__sellable__upsert_rubric",
362
+ "mcp__sellable__set_headline_icp_criteria",
363
+ "mcp__sellable__check_rubric",
364
+ "mcp__sellable__create_campaign",
365
+ "mcp__sellable__save_rubrics",
366
+ "mcp__sellable__wait_for_rubric_results",
367
+ "mcp__sellable__update_campaign_brief",
368
+ "mcp__sellable__update_campaign",
369
+ "mcp__sellable__get_campaign",
370
+ "mcp__sellable__get_campaign_context",
371
+ "mcp__sellable__get_campaign_framework",
372
+ "mcp__sellable__get_campaign_navigation_state",
373
+ "mcp__sellable__confirm_lead_list",
374
+ "mcp__sellable__import_leads",
375
+ "mcp__sellable__wait_for_lead_list_ready",
376
+ "mcp__sellable__wait_for_campaign_table_ready",
377
+ "mcp__sellable__get_rows",
378
+ "mcp__sellable__get_rows_minimal",
379
+ "mcp__sellable__get_table_rows",
380
+ "mcp__sellable__load_csv_linkedin_leads",
381
+ "mcp__sellable__load_csv_domains",
382
+ "mcp__sellable__queue_cells",
383
+ "mcp__sellable__generate_messages",
384
+ "mcp__sellable__get_campaign_messages_preview",
385
+ "mcp__sellable__attach_sequence",
386
+ "mcp__sellable__attach_recommended_sequence",
387
+ "mcp__sellable__start_campaign",
388
+ ];
389
+
390
+ function allowedToolsYaml(tools) {
391
+ return tools.map((tool) => ` - ${tool}`).join("\n");
392
+ }
393
+
394
+ function codexSkillOpenAiYaml(displayName, description) {
395
+ return `interface:
396
+ display_name: "${displayName.replaceAll('"', '\\"')}"
397
+ short_description: "${description.replaceAll('"', '\\"')}"
398
+ `;
399
+ }
400
+
401
+ function createCampaignSkillMd() {
402
+ return `---
403
+ name: sellable:create-campaign
404
+ description: Create a Sellable campaign through the approval-gated workflow.
405
+ allowed-tools:
406
+ ${allowedToolsYaml(CREATE_CAMPAIGN_ALLOWED_TOOLS)}
407
+ ---
408
+
409
+ # Sellable Create Campaign
410
+
411
+ Use this as the customer-facing entrypoint for Sellable campaign creation.
412
+
413
+ ## Bootstrap
414
+
415
+ MCP tool access is required. First call \`mcp__sellable__get_auth_status({})\`
416
+ directly. If that tool is unavailable, stop and say this is a Codex
417
+ install/reload problem, not a campaign problem. Tell the user to
418
+ run \`npx -y ${INSTALL_PACKAGE_SPEC} --host all\` so the packaged MCP server,
419
+ Codex Desktop plugin, and Sellable skill bundle are installed. If they want a
420
+ CLI verification, tell them to run \`sellable --verify-only --host all\`. After
421
+ that, they must fully quit and reopen Codex Desktop before starting a new
422
+ thread. Do not use \`scripts/mcp/sellable-tool-call.mjs\`, \`npm run\`,
423
+ \`node\`, or any local harness as a fallback for this interactive skill.
424
+
425
+ 1. Call \`mcp__sellable__get_auth_status({})\`.
426
+ 2. If auth is not OK, stop and show the returned guidance.
427
+ 3. Detect optional campaign id in the user request (\`cmp_...\`).
428
+ 4. If no campaign id is provided, stay in fresh-create mode and do not call campaign discovery/resume helpers to find one.
429
+ - Do not call \`mcp__sellable__get_campaigns\`.
430
+ - Do not call \`mcp__sellable__get_campaign\` to hunt for IDs.
431
+ - Do not call \`mcp__sellable__create_campaign({ campaignId: ... })\` unless the user supplied that id.
432
+ 5. Call \`mcp__sellable__bootstrap_create_campaign({ flowVersion: "v2", campaignId? })\`.
433
+ 6. If \`safeToProceed !== true\`, stop and show \`blockingErrors\` + \`nextStep\`.
434
+
435
+ ## Execute Workflow
436
+
437
+ 1. Load canonical prompt via
438
+ \`mcp__sellable__get_subskill_prompt({ subskillName: "create-campaign-v2" })\`.
439
+ 2. Follow that prompt exactly.
440
+ 3. For message generation, load the full \`generate-messages\` prompt in the
441
+ same run with chunked
442
+ \`mcp__sellable__get_subskill_prompt({ subskillName: "generate-messages", offset, limit })\`
443
+ calls until \`hasMore\` is false. Do not synthesize
444
+ \`message-validation.md\` from the brief, lead review, or general knowledge.
445
+ 4. Treat message quality as the gate before minting. Do not create a campaign,
446
+ show a commit gate, or mint anything until \`message-validation.md\` proves
447
+ the full generate-messages workflow ran and \`message-review.md\` recommends
448
+ \`approve-message\` against the gold-standard rules.
449
+ 5. Do not create or mutate the live campaign until the approval gate returns
450
+ \`approve\`.
451
+ 6. Do not ask the user to run another command.
452
+
453
+ ## Fallback
454
+
455
+ If subskill lookup fails, use
456
+ \`mcp__sellable__search_subskill_prompts({ query: "create-campaign-v2" })\`,
457
+ then retry \`get_subskill_prompt\`.
458
+ `;
459
+ }
460
+
461
+ function genericSellableSkillMd({ name, title, description }) {
462
+ return `---
463
+ name: sellable:${name}
464
+ description: ${description}
465
+ allowed-tools:
466
+ - mcp__sellable__get_auth_status
467
+ - mcp__sellable__get_subskill_prompt
468
+ - mcp__sellable__search_subskill_prompts
469
+ ---
470
+
471
+ # ${title}
472
+
473
+ Use this as the customer-facing entrypoint for the Sellable \`${name}\` workflow.
474
+
475
+ ## Bootstrap
476
+
477
+ MCP tool access is required. First call \`mcp__sellable__get_auth_status({})\`
478
+ directly. Do not inspect repo files, run shell commands, use \`npm\`, \`node\`,
479
+ local harness scripts, or read local prompt files to emulate this workflow.
480
+
481
+ If the Sellable MCP tool is unavailable, stop and say this is a Codex
482
+ install/reload problem. Tell the user to run
483
+ \`npx -y ${INSTALL_PACKAGE_SPEC} --host all\`, fully quit and reopen Codex
484
+ Desktop, then start a new thread.
485
+
486
+ 1. Call \`mcp__sellable__get_auth_status({})\`.
487
+ 2. If auth is not OK, stop and show the returned guidance.
488
+
489
+ ## Execute Workflow
490
+
491
+ 1. Load canonical prompt via \`mcp__sellable__get_subskill_prompt({ subskillName: "${name}" })\`.
492
+ 2. Follow that prompt exactly.
493
+
494
+ ## MCP Prompt Fallback
495
+
496
+ If subskill lookup fails, use \`mcp__sellable__search_subskill_prompts({ query: "${name}" })\`, then retry \`get_subskill_prompt\`.
497
+ `;
498
+ }
499
+
500
+ function codexPluginSkills() {
501
+ return [
502
+ {
503
+ dir: "sellable-create-campaign",
504
+ displayName: "Sellable Create Campaign",
505
+ description: "Create a Sellable campaign with approval gates",
506
+ skillMd: createCampaignSkillMd(),
507
+ },
508
+ {
509
+ dir: "sellable-engage",
510
+ displayName: "Sellable Engage",
511
+ description: "Discover posts and draft comments for a comment campaign",
512
+ skillMd: genericSellableSkillMd({
513
+ name: "engage",
514
+ title: "Sellable Engage",
515
+ description:
516
+ "Find high-signal LinkedIn posts and draft thoughtful engagement comments, then load approved comments into the sender's comment campaign.",
517
+ }),
518
+ },
519
+ {
520
+ dir: "sellable-interview",
521
+ displayName: "Sellable Interview",
522
+ description: "Build a commenting style guide and ICP profile",
523
+ skillMd: genericSellableSkillMd({
524
+ name: "interview",
525
+ title: "Sellable Interview",
526
+ description:
527
+ "Voice-first interview to build your commenting style guide and ICP profile.",
528
+ }),
529
+ },
530
+ {
531
+ dir: "sellable-workflow-sequences",
532
+ displayName: "Sellable Workflow Sequences",
533
+ description: "Create workflow tables and attach outbound sequences",
534
+ skillMd: genericSellableSkillMd({
535
+ name: "workflow-sequences",
536
+ title: "Sellable Workflow Sequences",
537
+ description:
538
+ "Create workflow tables via Sellable MCP, attach outbound sequence templates, and avoid manual sequence-column runCondition mistakes.",
539
+ }),
540
+ },
541
+ ];
542
+ }
543
+
544
+ function writeCodexPluginSkills(pluginRoot, opts) {
545
+ for (const skill of codexPluginSkills()) {
546
+ const skillRoot = join(pluginRoot, "skills", skill.dir);
547
+ writeFile(join(skillRoot, "SKILL.md"), skill.skillMd, opts);
548
+ writeFile(
549
+ join(skillRoot, "agents", "openai.yaml"),
550
+ codexSkillOpenAiYaml(skill.displayName, skill.description),
551
+ opts
552
+ );
553
+ }
554
+ }
555
+
334
556
  function installCodexDesktopPlugin(opts) {
335
557
  const home = codexHome();
336
558
  const configPath = join(home, "config.toml");
@@ -371,6 +593,7 @@ function installCodexDesktopPlugin(opts) {
371
593
  opts
372
594
  );
373
595
  writeFile(join(pluginRoot, ".mcp.json"), `${JSON.stringify(mcp, null, 2)}\n`, opts);
596
+ writeCodexPluginSkills(pluginRoot, opts);
374
597
 
375
598
  if (!opts.dryRun) {
376
599
  rmSync(cacheRoot, { recursive: true, force: true });
@@ -381,6 +604,7 @@ function installCodexDesktopPlugin(opts) {
381
604
  opts
382
605
  );
383
606
  writeFile(join(pluginCache, ".mcp.json"), `${JSON.stringify(mcp, null, 2)}\n`, opts);
607
+ writeCodexPluginSkills(pluginCache, opts);
384
608
 
385
609
  if (!opts.dryRun) {
386
610
  mkdirSync(home, { recursive: true, mode: 0o700 });
@@ -527,7 +751,19 @@ function verify(opts) {
527
751
  ".codex-plugin",
528
752
  "plugin.json"
529
753
  );
754
+ const skillPath = join(
755
+ codexHome(),
756
+ "plugins",
757
+ "cache",
758
+ "sellable",
759
+ "sellable",
760
+ CODEX_PLUGIN_VERSION,
761
+ "skills",
762
+ "sellable-create-campaign",
763
+ "SKILL.md"
764
+ );
530
765
  console.log(existsSync(pluginPath) ? "Codex Desktop plugin present" : "Codex Desktop plugin missing");
766
+ console.log(existsSync(skillPath) ? "Codex skill bundle present" : "Codex skill bundle missing");
531
767
  }
532
768
  }
533
769
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/install",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "type": "module",
5
5
  "description": "One-command installer for Sellable MCP in Claude Code and Codex",
6
6
  "bin": {