feat(promote): add ce-promote skill for post-ship announcement copy#888
feat(promote): add ce-promote skill for post-ship announcement copy#888imwm wants to merge 1 commit into
Conversation
991c8bb to
55b896c
Compare
tmchow
left a comment
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
yup – added a commented ce_promote_spiral_optout entry under a new # --- ce-promote --- section in ce-setup/references/config-template.yaml
55b896c to
f984658
Compare
There was a problem hiding this comment.
💡 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.) |
There was a problem hiding this comment.
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 👍 / 👎.
f984658 to
786dc9e
Compare
There was a problem hiding this comment.
💡 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. |
There was a problem hiding this comment.
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 👍 / 👎.
786dc9e to
cf31ef9
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cf31ef9a8b
ℹ️ 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".
| 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. |
There was a problem hiding this comment.
Parse the opt-out key instead of substring-matching comments
This substring check treats the commented template entry as a real opt-out: /ce-setup copies references/config-template.yaml into .compound-engineering/config.local.yaml with # ce_promote_spiral_optout: true, so any project that accepted the default setup template will skip Path 0 even though the user never declined Spiral. Please parse the YAML/top-level key or ignore commented lines before deciding to suppress the setup offer.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
good catch :) opt-out check now required uncommented ce_promote_spiral_output: true so the example no longer reads as an opt-out
cf31ef9 to
aa6e9b6
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: aa6e9b60e4
ℹ️ 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. |
There was a problem hiding this comment.
Append an active opt-out despite template comments
When this file already exists because ce-setup copied references/config-template.yaml, it contains the commented example # ce_promote_spiral_optout: true; this instruction only says to append the key “if it isn't already present,” so the agent can treat the commented template line as present and skip writing an uncommented opt-out. Fresh evidence beyond the earlier opt-out parsing issue is the write path here: the read path now ignores comments, but the record path can leave only the commented line, causing users who explicitly choose “Draft directly without Spiral” to be prompted again on the next run.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
fixed, write path ensures an uncommented ce_promote_spiral_output: true is there, mirroring the above fix
aa6e9b6 to
5d2c654
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5d2c654057
ℹ️ 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".
| - **Absent** → guide the user to install + connect in one step via the pairing-code command from Settings → Connect an Agent. | ||
| - **Decline** → record the opt-out (best-effort) and go to Path B. | ||
|
|
||
| Skip Path 0 entirely — straight to Path B — when the opt-out is already recorded, when running headless, or when no blocking-question tool is available. |
There was a problem hiding this comment.
Fall back to text prompts instead of skipping setup
In runtimes without a blocking question tool (for example Codex edit modes, where request_user_input may be unavailable), this tells the skill to skip Path 0 entirely, so the first-run Spiral setup offer is never shown and users go straight to non-personalized drafting. That conflicts with the plugin interaction guidance in plugins/compound-engineering/AGENTS.md, which requires falling back to numbered options in chat and waiting for a reply rather than silently skipping the question; it also contradicts the new reference file's own fallback instructions.
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.
5d2c654 to
b61cb89
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b61cb89813
ℹ️ 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".
| spiral auth status 2>/dev/null | ||
| ``` | ||
|
|
||
| Classify into one of three states. Spiral is **ready** only if the binary exists AND auth status shows an authed key (`spiral_sk_...`): |
There was a problem hiding this comment.
Detect authenticated Spiral from JSON status
For already-authenticated Spiral 1.8 users, the published agent flow reports readiness via spiral auth status --json returning authenticated: true / status: authenticated, while this check only treats output containing spiral_sk_... as ready. If the status command does not print a raw token, ready users are misclassified as unauthed and get the setup/opt-out prompt instead of Path A; use the JSON authenticated flag (or spiral login --json's already_authenticated) for readiness.
Useful? React with 👍 / 👎.
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-promotepulls 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
SKILL.md+ one reference) plus two README rows; no new dependencies.ce-promoteships 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
spiral write … --instant --json.spiral login --json(non-blocking), shares the returnedauth_url, the user approves in a browser, and the agent pollsspiral auth status --jsonuntilauthenticated: true. The API key is exchanged server→CLI and never touches the agent's transcript or logs. Returning users (already_authenticated) skip straight through. Requires@every-env/spiral-cli≥ 1.8.0; older CLIs degrade gracefully (suggest update, or the user signs in themselves).--num-drafts; single-channel variations need--num-draftsand must avoid cue words. Verified live.Testing
bun test(frontmatter + shell-safety) green;bun run release:validatein sync (39 skills).Open for review (draft)
@every-env/spiral-cli≥ 1.8.0 (agent-awarespiral login, shipping in EveryInc/spiral-next#1182). The skill degrades gracefully on older CLIs.@every-env/spiral-clipackage in an OSS plugin.