A Claude Code plugin that makes Claude ask you questions in a card instead of burying them in a paragraph. One question at a time, with a recommended answer. Ships a skill and hooks, so the rules hold even when the model would rather not.
I read the scheduling code — the calendar lives in
schedule-rule.mjs, the allocator inschedule.mjs, and the gate runs insidebuild.mjs. There are a few ways to do this. A frontmatter flag would be simplest, though you could also track it in the ledger, or push the post to the next free day, which changes how the calendar reports it. Let me know which you prefer and I'll get started, or if you'd rather I just pick one, say the word.
You read 60 words to find out that a decision is waiting, and you still have to write a reply in prose.
☐ Skip shape
What should "skip" do to a post that's dated and waiting?
❯ 1. skip: in frontmatter (Recommended)
One line in the post itself. The calendar hands the day back.
2. Track it in the ledger
Keeps posts untouched, but the reason lives away from the post.
3. Push to the next free day
No new field, but it silently moves a date you chose.
One glance, one keypress.
/plugin marketplace add IndieCoreDev/ask-first
/plugin install ask-first@ask-first
Then restart Claude Code. /reload-plugins does not load skills — this catches everyone
once.
Requires Claude Code with plugin support, and Node (already present if you run Claude Code).
Updating and uninstalling
claude plugin marketplace update ask-first
claude plugin update ask-first@ask-first # then restart
claude plugin uninstall ask-first@ask-first # removes the skill and both hooksTwo costs, both paid on every single reply:
- Length. You read a long answer to find the one line that needs you.
- Difficulty. The words are harder than they need to be, which slows you down again — and most people using a coding agent are not reading their first language.
A reply holds three different things at the same weight: what was done, what was assumed, and what is actually needed from you. In plain text they look alike, so you read all of it to find the part that blocks progress. A card does not look like a paragraph. The part that needs you stops hiding.
| Rule | |
|---|---|
| 1 | Every question goes in a card, never in prose |
| 2 | Only questions — information stays as normal text |
| 3 | One question at a time, always |
| 4 | The first option is the recommendation, and it is marked |
| 5 | Get your final goal when the request does not say why, and judge every option against it |
| 6 | Show the difference with a preview when there is something to look at |
A skill is instruction: it puts rules in the model's context, and the model mostly follows them. This plugin also ships hooks, which run whether the model agrees or not.
| Rule | How |
|---|---|
| One question per card | Hook. The call is rejected before it is sent. |
| Recommendation first, marked | Hook. Rejected, naming where the recommendation actually was. |
| No question left in prose | Hook. The turn is blocked until it becomes a card. |
| Only questions in the card | Skill text only. |
| Name the goal, judge against it | Skill text only. |
That split is the honest one, and it came out of testing rather than design. Three rewrites of the skill text narrowed the one-question gap without closing it. One hook closed it on the first try, against a user actively asking for two questions at once. But a hook can only check a shape — whether a question named your real goal is a judgement, and the only lever there is the skill text.
.claude-plugin/marketplace.json the marketplace entry
plugins/ask-first/
.claude-plugin/plugin.json the plugin manifest
skills/ask-first/SKILL.md the rules, loaded into context
hooks/hooks.json wires both hooks
hooks/check-card.mjs PreToolUse on AskUserQuestion
hooks/check-prose.mjs Stop: catches a turn that ends waiting
tests/run.mjs 22 cases, run by CI on every push
Both hooks are short, unminified and dependency-free. They read the pending question and your session transcript, write nothing, and make no network calls — see SECURITY.md.
No. A skill is a folder — skills/<name>/SKILL.md — and a gist cannot hold folders, because
gist filenames are not allowed to contain /. A gist is a real git repo and clones fine, but
it can never carry the .claude-plugin/marketplace.json an install needs, so
claude plugin marketplace add fails on it.
A gist can still hold a single SKILL.md with a curl line in the description. That is
copy-and-paste, not an install, and it never updates.
Put it in a git repo shaped as a marketplace:
your-repo/
.claude-plugin/marketplace.json
plugins/<plugin>/.claude-plugin/plugin.json
plugins/<plugin>/skills/<skill>/SKILL.md
Then anyone runs /plugin marketplace add <owner>/<repo>. This repo is exactly that shape, so
clone it as a starting point.
A skill alone cannot. A skill is instruction — it puts rules in the model's context, and obedience gets weaker as a conversation grows longer. A hook is enforcement: the harness runs your code, so it does not depend on the model agreeing.
This plugin ships both, which is the point. Use skill text for judgement, hooks for anything with a checkable shape.
In order of how often it is the cause:
- You did not restart.
/reload-pluginsreports0 skillsand does not load them. Skills are read when a session starts. - Run
claude plugin validate <path>on both the plugin folder and the marketplace root. It names the problem, and almost nobody mentions it. - Check
enabledPluginsin~/.claude/settings.json. - Check the installed copy on disk under
~/.claude/plugins/cache/.
Nothing in a plain reply limits its size. A card has a fixed small shape — a short label, a line or two of description — so it cannot run long and cannot bury the choice inside a paragraph. The format does the work that asking for brevity does not.
No, and that matters — asking costs you time too. It does not ask for a small reversible fix with an obvious default, for anything the code already answers, or for a decision you already made. Those get done and reported in one line.
It is written not to. It ignores a question mark inside code, a turn that already used a card, and reports like "the profiler will tell me where the time goes". It never blocks on input it cannot parse. If it does nag you, that is the bug worth reporting most — open an issue with the exact text.
Bug reports and rule proposals are welcome — see CONTRIBUTING.md and the Code of Conduct. The most useful report is a false block: the hook stopping a reply that was not asking you anything.
Every rule here exists because a real session got past one, and every one has a test.
MIT — see LICENSE.