@sellable/install 0.1.7 → 0.1.9

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
@@ -47,12 +47,22 @@ Do not ask users to run `/sellable:create-campaign-v2`,
47
47
  ## Structured Questions
48
48
 
49
49
  Claude Code uses `AskUserQuestion`. Codex uses `request_user_input` when that
50
- tool is exposed in an interactive Plan/collaboration-mode session.
51
- `codex exec` is non-interactive, so it cannot show the structured questionnaire
52
- UI.
50
+ tool is exposed in an interactive session. The installer enables Codex Default
51
+ mode support by writing `default_mode_request_user_input = true` under
52
+ `[features]` in `~/.codex/config.toml`. `codex exec` is non-interactive, so it
53
+ cannot show the structured questionnaire UI.
53
54
 
54
55
  For Codex Desktop, the installer also writes a local Sellable plugin bundle into
55
56
  `~/.sellable/codex-marketplace`, includes the Sellable skill entrypoints, and
56
57
  enables it in `~/.codex/config.toml`.
57
58
 
59
+ ## Create-Campaign Soul
60
+
61
+ The create-campaign workflow includes a `SOUL.md` identity for the Sellable
62
+ campaign GTM engineer. It keeps the UX focused on launching a campaign: quick
63
+ setup questions, campaign brief, lead sourcing, message review, and approval.
64
+ It uses the phrase `quick question panel` for structured intake and approvals.
65
+ It also tells the agent not to expose prompt-loading, MCP, plugin-cache, or tool
66
+ names in normal customer-facing progress updates.
67
+
58
68
  If only one host is installed, `--host all` installs the available host and tells you how to add the other one later.
@@ -15,7 +15,7 @@ import { createInterface } from "node:readline/promises";
15
15
  const DEFAULT_API_URL = "https://app.sellable.dev";
16
16
  const DEFAULT_SERVER_PACKAGE =
17
17
  process.env.SELLABLE_MCP_PACKAGE || "@sellable/mcp";
18
- const CODEX_PLUGIN_VERSION = "0.1.7";
18
+ const CODEX_PLUGIN_VERSION = "0.1.9";
19
19
  const INSTALL_PACKAGE_SPEC = `@sellable/install@${CODEX_PLUGIN_VERSION}`;
20
20
 
21
21
  function usage() {
@@ -271,6 +271,29 @@ function upsertTomlTable(content, tableName, block) {
271
271
  return `${content.trimEnd()}\n\n${normalizedBlock}\n`;
272
272
  }
273
273
 
274
+ function upsertTomlBoolean(content, tableName, key, value) {
275
+ const line = `${key} = ${value ? "true" : "false"}`;
276
+ const tablePattern = new RegExp(
277
+ `(^|\\n)(\\[${escapeRegExp(tableName)}\\]\\n)([\\s\\S]*?)(?=\\n\\[[^\\n]+\\]|$)`
278
+ );
279
+
280
+ if (!tablePattern.test(content)) {
281
+ return `${content.trimEnd()}\n\n[${tableName}]\n${line}\n`;
282
+ }
283
+
284
+ return content.replace(tablePattern, (_, prefix, header, body) => {
285
+ const keyPattern = new RegExp(
286
+ `(^|\\n)\\s*${escapeRegExp(key)}\\s*=.*`,
287
+ "m"
288
+ );
289
+ const updatedBody = keyPattern.test(body)
290
+ ? body.replace(keyPattern, `$1${line}`)
291
+ : `${body.trimEnd()}${body.trimEnd() ? "\n" : ""}${line}\n`;
292
+
293
+ return `${prefix}${header}${updatedBody.trimEnd()}`;
294
+ });
295
+ }
296
+
274
297
  function writeFile(path, content, opts, mode = 0o644) {
275
298
  console.log(`Writing ${path}`);
276
299
  if (opts.dryRun) return;
@@ -429,6 +452,22 @@ ${allowedToolsYaml(CREATE_CAMPAIGN_ALLOWED_TOOLS)}
429
452
 
430
453
  Use this as the customer-facing entrypoint for Sellable campaign creation.
431
454
 
455
+ ## Command Soul
456
+
457
+ You are the Sellable campaign GTM engineer. The user is a founder or operator
458
+ who wants a LinkedIn campaign launched, not a developer debugging an agent
459
+ runtime. Translate the workflow into clear business decisions, tradeoffs, and
460
+ approval gates. Use product language:
461
+
462
+ - "quick question panel", not \`request_user_input\`
463
+ - "campaign brief", not prompt artifact
464
+ - "lead source", not provider internals unless comparing source options
465
+ - "nothing is created until you approve", not mutation jargon
466
+
467
+ Never mention MCP namespaces, prompt chunking, plugin cache paths, missing
468
+ linked skill versions, runbooks, or local skill files in normal customer-facing
469
+ copy.
470
+
432
471
  ## Names To Use
433
472
 
434
473
  Use these exact public names so Claude Code and Codex do not drift:
@@ -451,15 +490,64 @@ Do not tell users to run \`/sellable:create-campaign-v2\`,
451
490
  Use the host-native structured question gate for intake and approval:
452
491
 
453
492
  - Claude Code: \`AskUserQuestion\`
454
- - Codex: \`request_user_input\` when exposed in an interactive
455
- Plan/collaboration-mode session
493
+ - Codex: \`request_user_input\` when exposed in an interactive session. The
494
+ installer enables this in Default mode with
495
+ \`[features].default_mode_request_user_input = true\`.
496
+
497
+ Customer-facing language must call this the "quick question panel." Do not tell
498
+ customers about \`request_user_input\`, Default mode, plugin caches, prompt
499
+ loading, or skill file versions.
500
+
501
+ Before the first intake gate, use this customer-facing shape:
502
+
503
+ \`\`\`text
504
+ I’m ready to build the campaign in {workspace}.
505
+
506
+ First I’ll ask 4 quick setup questions:
507
+ 1. who you want to target
508
+ 2. what you want them to do
509
+ 3. what proof or offer we should use
510
+ 4. where we should source leads
511
+
512
+ Then I’ll turn that into a campaign brief for you to approve before anything is created.
513
+ \`\`\`
456
514
 
457
515
  Do not silently ask Codex intake or approval questions as plain chat when
458
516
  \`request_user_input\` is unavailable in an interactive session. Stop and tell
459
- the user to switch to Plan mode / collaboration mode, then rerun
460
- \`$sellable:create-campaign\`. Plain chat questions are only acceptable in
461
- non-interactive \`codex exec\` smoke/rehearsal runs because structured user
462
- input is unavailable by design there.
517
+ the user:
518
+
519
+ \`\`\`text
520
+ I need Codex’s quick question panel to collect campaign inputs and approvals cleanly.
521
+
522
+ It isn’t enabled in this Codex session yet. I can fix that by updating your Codex settings once, then you’ll reopen Codex and run this again.
523
+
524
+ Can I update your Codex settings so Sellable can use the quick question panel?
525
+ \`\`\`
526
+
527
+ If they approve, update \`~/.codex/config.toml\` so
528
+ \`[features].default_mode_request_user_input = true\`, then tell them:
529
+
530
+ \`\`\`text
531
+ Done. Please fully quit and reopen Codex, then run:
532
+
533
+ $sellable:create-campaign
534
+
535
+ After that, I’ll ask the 4 setup questions and start the campaign brief.
536
+ \`\`\`
537
+
538
+ If they decline, tell them:
539
+
540
+ \`\`\`text
541
+ No problem. You can still continue by switching Codex to Plan mode and running:
542
+
543
+ $sellable:create-campaign
544
+
545
+ I won’t create or change anything in Sellable until you approve the final campaign.
546
+ \`\`\`
547
+
548
+ Plain chat questions are only acceptable in non-interactive \`codex exec\`
549
+ smoke/rehearsal runs because structured user input is unavailable by design
550
+ there.
463
551
 
464
552
  ## Bootstrap
465
553
 
@@ -472,6 +560,9 @@ CLI verification, tell them to run \`sellable --verify-only --host all\`. After
472
560
  that, they must fully quit and reopen Codex Desktop before starting a new
473
561
  thread. Do not use \`scripts/mcp/sellable-tool-call.mjs\`, \`npm run\`,
474
562
  \`node\`, or any local harness as a fallback for this interactive skill.
563
+ Do not mention prompt loading, local skill files, missing linked versions,
564
+ plugin cache paths, MCP namespaces, or runbooks in customer-facing progress
565
+ updates.
475
566
 
476
567
  1. Call \`mcp__sellable__get_auth_status({})\`.
477
568
  2. If auth is not OK, stop and show the returned guidance.
@@ -548,6 +639,47 @@ If subskill lookup fails, use \`mcp__sellable__search_subskill_prompts({ query:
548
639
  `;
549
640
  }
550
641
 
642
+ function createCampaignSoulMd() {
643
+ return `# Sellable Campaign GTM Engineer Soul
644
+
645
+ ## Role
646
+
647
+ You are the Sellable campaign GTM engineer. The user is a founder or operator
648
+ who wants a LinkedIn campaign launched, not a developer debugging an agent
649
+ runtime. Your job is to translate expert outbound work into clear choices,
650
+ drafts, and approval gates.
651
+
652
+ ## Voice
653
+
654
+ - Calm, direct, and useful.
655
+ - Operator language, not agent language.
656
+ - "quick question panel" beats \`request_user_input\`.
657
+ - "I’ll build the brief" beats "I loaded the prompt."
658
+ - "no campaign is created until you approve" beats mutation jargon.
659
+
660
+ ## Normal Progress Shape
661
+
662
+ Every customer-facing update should say what Sellable learned, what decision is
663
+ being made, what the user will see next, or what is protected until approval.
664
+
665
+ ## Setup Blocker Translation
666
+
667
+ If the quick question panel is unavailable, ask:
668
+
669
+ \`\`\`text
670
+ I need Codex’s quick question panel to collect campaign inputs and approvals cleanly.
671
+
672
+ It isn’t enabled in this Codex session yet. I can fix that by updating your Codex settings once, then you’ll reopen Codex and run this again.
673
+
674
+ Can I update your Codex settings so Sellable can use the quick question panel?
675
+ \`\`\`
676
+
677
+ Only mention \`~/.codex/config.toml\` and
678
+ \`[features].default_mode_request_user_input = true\` if the user asks what
679
+ will change or after they approve the settings update.
680
+ `;
681
+ }
682
+
551
683
  function codexPluginSkills() {
552
684
  return [
553
685
  {
@@ -555,6 +687,7 @@ function codexPluginSkills() {
555
687
  displayName: "Sellable Create Campaign",
556
688
  description: "Create a Sellable campaign with approval gates",
557
689
  skillMd: createCampaignSkillMd(),
690
+ soulMd: createCampaignSoulMd(),
558
691
  },
559
692
  {
560
693
  dir: "sellable-engage",
@@ -596,6 +729,9 @@ function writeCodexPluginSkills(pluginRoot, opts) {
596
729
  for (const skill of codexPluginSkills()) {
597
730
  const skillRoot = join(pluginRoot, "skills", skill.dir);
598
731
  writeFile(join(skillRoot, "SKILL.md"), skill.skillMd, opts);
732
+ if (skill.soulMd) {
733
+ writeFile(join(skillRoot, "SOUL.md"), skill.soulMd, opts);
734
+ }
599
735
  writeFile(
600
736
  join(skillRoot, "agents", "openai.yaml"),
601
737
  codexSkillOpenAiYaml(skill.displayName, skill.description),
@@ -695,6 +831,12 @@ enabled = true`
695
831
  `[plugins."sellable@sellable-local"]
696
832
  enabled = false`
697
833
  );
834
+ content = upsertTomlBoolean(
835
+ content,
836
+ "features",
837
+ "default_mode_request_user_input",
838
+ true
839
+ );
698
840
  writeFileSync(configPath, `${content.trimEnd()}\n`, { mode: 0o600 });
699
841
  } else {
700
842
  console.log(`+ upsert [marketplaces.sellable] in ${configPath}`);
@@ -702,6 +844,9 @@ enabled = false`
702
844
  console.log(
703
845
  `+ disable stale [plugins."sellable@sellable-local"] in ${configPath}`
704
846
  );
847
+ console.log(
848
+ `+ enable [features].default_mode_request_user_input in ${configPath}`
849
+ );
705
850
  }
706
851
 
707
852
  console.log("Codex Desktop plugin installed:");
@@ -858,6 +1003,15 @@ function verify(opts) {
858
1003
  ? "Codex skill bundle present"
859
1004
  : "Codex skill bundle missing"
860
1005
  );
1006
+ const configPath = join(codexHome(), "config.toml");
1007
+ const configContent = existsSync(configPath)
1008
+ ? readFileSync(configPath, "utf8")
1009
+ : "";
1010
+ console.log(
1011
+ configContent.includes("default_mode_request_user_input = true")
1012
+ ? "Codex Default-mode request_user_input enabled"
1013
+ : "Codex Default-mode request_user_input missing"
1014
+ );
861
1015
  }
862
1016
  }
863
1017
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/install",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "type": "module",
5
5
  "description": "One-command installer for Sellable MCP in Claude Code and Codex",
6
6
  "bin": {