SLOPSHOPPER

discuss-first

Adds a 'Discuss first' choice to every Q&A question: talk it through in chat, then Claude re-asks it with the agreed answer.

newguard
v0.1.0no licenseupdated 2026-10-25pnshad/claude-code-mods/discuss-first
A shopper browsing a rack in a slop shop
README

claude-mods

Claude Code mods (plugins), as one local marketplace: cc-mods.

ModWhat it does
discuss-firstAdds a "Discuss first" choice to every Q&A (AskUserQuestion) question. Pick it, talk the question through in chat, and Claude re-asks it with the agreed answer as option 1 "(Agreed)". With 4 options already, type discuss under Other.
harness-coachTeaches Claude Code while you work: one small toast every 3 turns (💡, 9 s) with a tip about keys, slash commands, skills or the harness, chosen by what the turn did (shell, edits, subagents, a long turn, a full context). First-time situations get a one-time nudge at once. Every tip is shown once before any repeats, across sessions. /coach = a tip now · list · off / on · reset · every <n> · find <word>.
checklistA checklist band above the prompt for what waits on you: decisions, approvals, answers, steps. Claude adds items with its add tool whenever a reply hands you something, grouped ("Change requests waiting for your approval"), each with an Open button to the sub-session where you work on it; it ticks them when you answer. Click an item to tick it. /checklist = full list · add <text> · clear. One list per session, kept across restarts.

Install on a machine

git clone https://github.com/pnshad/claude-code-mods.git ~/claude-code-mods
claude plugin marketplace add ~/claude-code-mods
claude plugin install discuss-first@cc-mods --scope user
claude plugin install harness-coach@cc-mods --scope user
claude plugin install checklist@cc-mods --scope user

The plugin is read from this folder: after editing, run /reload-plugins in a session.

Test

claude plugin test discuss-first
claude plugin test harness-coach
claude plugin test checklist
Source 1 files
hooks/register.ts 53 lines
1import type { Register } from 'claude-code'
2
3export const DISCUSS = 'Discuss first'
4const DISCUSS_OPTION = {
5  label: DISCUSS,
6  description: 'Talk it through in chat; Claude re-asks this one with the agreed answer.',
7}
8
9// "Discuss first" picked, or "discuss ..." typed under Other (for questions that already had 4 options).
10export const wantsDiscussion = (answer: unknown): string | undefined => {
11  if (typeof answer !== 'string') return undefined
12  const a = answer.trim()
13  if (a.split(',').map(s => s.trim()).includes(DISCUSS)) return ''
14  const m = /^discuss\b[:\s-]*(.*)$/is.exec(a)
15  return m ? m[1].trim() : undefined
16}
17
18export const register: Register = on => {
19  on('tool.call', { tool: 'AskUserQuestion' }, async ($, e, next) => {
20    const questions = e.questions.map(q =>
21      q.options.length < 4 && !q.options.some(o => o.label === DISCUSS)
22        ? { ...q, options: [...q.options, DISCUSS_OPTION] }
23        : q,
24    )
25    const ran = await next({ ...e, questions })
26    if (ran.deny !== undefined || ran.isError) return ran
27
28    const answers = (ran.result as { answers?: Record<string, unknown> }).answers ?? {}
29    const discuss = questions.flatMap(q => {
30      const note = wantsDiscussion(answers[q.question])
31      return note === undefined ? [] : [{ q, note }]
32    })
33    if (discuss.length === 0) return ran
34
35    const list = discuss
36      .map(({ q, note }, i) => `${i + 1}. "${q.question}"${note ? ` — his first thought: ${note}` : ''}`)
37      .join('\n')
38    return {
39      ...ran,
40      context: [
41        ...(ran.context ?? []),
42        `discuss-first: the user chose "Discuss first" on ${discuss.length} question(s):\n${list}\n\n` +
43          'Every other answer in this result stands; record it, but do not act yet on anything that depends on a discussed question. ' +
44          'Take the discussed questions one at a time, in order. For each: give the background he needs (assume he remembers nothing), ' +
45          'the options and trade-offs, and your recommendation with why; then talk it through in normal chat, with no AskUserQuestion, until he reaches an answer. ' +
46          'When he has one, call AskUserQuestion with only that question, the agreed answer as option 1 labelled "<answer> (Agreed)", ' +
47          'its description summing up what was decided, so he confirms it with one pick. Then move to the next discussed question, ' +
48          'and when all are settled, continue the work.',
49      ],
50    }
51  }).catch(($, e, next) => next(e)) // never break the Q&A: on a failure, plain answers go through
52}
53