Skip to content

feat(promote): add ce-promote skill for post-ship announcement copy#888

Open
imwm wants to merge 1 commit into
mainfrom
nervous-gould-7bce37
Open

feat(promote): add ce-promote skill for post-ship announcement copy#888
imwm wants to merge 1 commit into
mainfrom
nervous-gould-7bce37

Conversation

@imwm
Copy link
Copy Markdown
Collaborator

@imwm imwm commented Jun 1, 2026

What & why

After a feature ships, the user-facing messaging — a tweet/thread, a changelog blurb, a LinkedIn post, an email — is usually written later, by someone without the shipping context. ce-promote pulls that drafting into the engineering workflow: it figures out what shipped (from a description, or derived from the merged PR / diff / changelog / commits), picks sensible channels, and produces copy-pasteable drafts. It drafts only — never posts, publishes, or touches git.

Design notes

  • Lightweight footprint. Two product files (SKILL.md + one reference) plus two README rows; no new dependencies.
  • Spiral is an optional enhancement, not a dependency. With the Spiral CLI installed and authed, drafts are voice-matched and humanized. Without it, ce-promote ships a lite layer of editorial & social-media expertise to write strong copy on its own — modest by design (brand-voice matching, humanization, saved styles, and campaign orchestration are where the Spiral path goes further).

Spiral integration details

  • Three-state detection (ready / installed-unauthed / absent). Ready → voice-matched via spiral write … --instant --json.
  • First-run nudge to set up, never naggy: when Spiral isn't ready, the skill offers setup once (run spiral login and surface the link, or point to the one-step install). A single dismissal records a per-repo opt-out, so the user is never asked twice — important since this is a per-ship action.
  • Encodes Spiral's multi-channel / cue-word behavior: campaign phrasing returns one set of drafts per channel and ignores --num-drafts; single-channel variations need --num-drafts and must avoid cue words. Verified live against CLI v1.6.1.

Testing

  • Validated live against the real Spiral CLI: single-channel variations and multi-channel campaign both behave as documented.
  • Simulated the unauthed / absent / opted-out states; confirmed the nudge fires once and the opt-out suppresses it on later runs.
  • bun test (frontmatter + shell-safety) green; bun run release:validate in sync (39 skills).

Open for review (draft)

  • Per-repo opt-out lives in the per-worktree gitignored config, so a new worktree could re-show the offer once. Acceptable, or should it be user-global?
  • spiral login in v1.6.1 is a create-a-key link flow, not one-click device-auth, so sign-in still has a paste-the-key step.
  • Comfort check on naming the Spiral CLI / @every-env/spiral-cli package in an OSS plugin.

@imwm imwm force-pushed the nervous-gould-7bce37 branch from 991c8bb to 55b896c Compare June 1, 2026 04:56
Copy link
Copy Markdown
Collaborator

@tmchow tmchow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the skill end-to-end — really clean work. The graceful-degradation (three-state detect, never-block-on-Spiral) and the drafts-only safety stance are the strong parts, and Path B is substantive rather than a degraded teaser. Two small change requests on the opt-out config write before merge (inline). Everything else is polish.


### Record the opt-out (best-effort)

Resolve the repo root, then add `ce_promote_spiral_optout: true` as a top-level key to `<root>/.compound-engineering/config.local.yaml`, using the native file-write/edit tool — create the file (and its `.compound-engineering/` directory) if absent, or append the key if the file already exists without it. If the root can't be resolved or the write fails, proceed to Path B anyway; the opt-out is a convenience, never a blocker.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change request — gitignore hygiene. This creates .compound-engineering/config.local.yaml if absent, but doesn't ensure the file is gitignored. ce-setup — the canonical creator of this file — explicitly checks and offers to add the .gitignore entry when it creates it (ce-setup/SKILL.md:98,104). A user who runs /ce-promote before /ce-setup ends up with an un-ignored config file holding machine-local opt-out state that can get committed by accident.

Suggest mirroring ce-setup here: when creating the file, verify/offer the .gitignore entry — or only append the key when the file already exists, leaving first-time creation (with gitignore handling) to ce-setup.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, updated: when the opt-out write has to create the config, it ensures .compound-engineering/*.local.yaml is gitignored and then tells the user so. if the file exists it just appends the key. did mirroring rather than append-only to avoid silent failure if the config doesn't exist yet. and if it can't resolve or the write fails it just goes ahead to draft using the lite guidance in the plugin.

cat "$(git rev-parse --show-toplevel 2>/dev/null)/.compound-engineering/config.local.yaml" 2>/dev/null || echo '__NO_CONFIG__'
```

If the contents include `ce_promote_spiral_optout: true`, **skip Path 0** and go straight to Path B. Otherwise, offer setup.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change request — document the new config key. ce_promote_spiral_optout is a new top-level key in .compound-engineering/config.local.yaml, but it isn't in ce-setup/references/config-template.yaml — the self-documenting schema ce-setup seeds new configs from. Add it there (commented) so the config surface stays documented and discoverable.

Note: that's a cross-skill file outside this PR's current diff, so it'll need to be added to the changeset.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup – added a commented ce_promote_spiral_optout entry under a new # --- ce-promote --- section in ce-setup/references/config-template.yaml

@imwm imwm force-pushed the nervous-gould-7bce37 branch from 55b896c to f984658 Compare June 1, 2026 20:04
@imwm imwm marked this pull request as ready for review June 1, 2026 22:34
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f984658cb4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

API key required. Usage: spiral auth login --token <spiral_sk_...>
Create a key at: https://app.writewithspiral.com/settings/api-keys
```
Surface that link to the user. They open it, create a key, and either paste the `spiral_sk_...` key back so the agent runs `spiral auth login --token spiral_sk_...`, or run that command themselves. Then re-run `spiral auth status`; if a `spiral_sk_...` key now appears, proceed with Path A, else fall to Path B. (In v1.6.1 `spiral login` is the create-a-key link flow, not a one-click browser approve.)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid asking users to paste API keys into chat

When Spiral is installed but unauthenticated, this flow tells the user they can paste a spiral_sk_... API key back so the agent runs the login command. In that scenario the credential is exposed to the model transcript, tool logs, and any session-history tooling, even though the same paragraph already supports the safer path of having the user run spiral auth login --token ... locally. Please keep the key out of chat and instruct the user to run the command themselves.

Useful? React with 👍 / 👎.

Generate user-facing announcement copy (X post/thread, changelog blurb,
LinkedIn, email, blog, demo script) for a feature that just shipped,
right inside the engineering workflow. Spiral-agnostic by default;
voice-matched via the optional Spiral CLI when installed and authed.

- Derives what shipped from a description or from the merged PR / diff /
  changelog / commits, and leads with user value over implementation.
- Three-state Spiral detection (ready / unauthed / absent) with a
  one-time, declinable first-run setup nudge; a single dismissal records
  a per-repo opt-out so this per-ship skill never nags.
- Encodes Spiral's multi-channel / cue-word behavior (verified live
  against CLI v1.6.1) and degrades gracefully to direct drafting when
  Spiral is absent, without giving away Spiral's voice-matching.
- Drafts only: never posts, publishes, or touches git.
@imwm imwm force-pushed the nervous-gould-7bce37 branch from f984658 to 786dc9e Compare June 1, 2026 22:41
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 786dc9eeeb

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Resolve the repo root, then add `ce_promote_spiral_optout: true` as a top-level key to `<root>/.compound-engineering/config.local.yaml`, using the native file-write/edit tool:

- **File already exists:** append the key if it isn't already present.
- **File absent:** create it (and its `.compound-engineering/` directory) with the key, AND ensure the machine-local config is gitignored — mirroring `ce-setup`, the canonical creator of this file. Check whether the path is already ignored (`git check-ignore -q .compound-engineering/config.local.yaml`); if it isn't, append `.compound-engineering/*.local.yaml` to the repo-root `.gitignore`. Without this, a user who runs `/ce-promote` before `/ce-setup` ends up with an un-ignored config holding machine-local opt-out state that can get committed by accident.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid dirtying the user's repo on a draft-only decline

When a user declines Spiral setup in a repo that has not run /ce-setup, this instruction automatically appends .compound-engineering/*.local.yaml to the repo-root .gitignore. That leaves an unstaged/tracked-file change even though /ce-promote is explicitly positioned as drafts-only and the user only chose to draft without Spiral; using an already-ignored location such as .git/info/exclude, or asking before editing .gitignore, would avoid surprising post-ship working tree churn.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants