Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"owner": { "name": "bully911210", "url": "https://github.com/bully911210" },
"metadata": { "description": "Function-hook mods for Claude Code: a limits telemetry row, multi-select question and next-step panes, and README updates after every commit." },
"plugins": [
{ "name": "token-ledger", "source": "./token-ledger", "description": "5-hour, weekly, context and cache-hit figures in one row above the prompt, a ? button for Haiku questions, and a /ledger pane." },
{ "name": "token-ledger", "source": "./token-ledger", "description": "5-hour, weekly, context and cache-hit figures in one row above the prompt, a ? button for Haiku questions that learns your project and feedback, a /brief pane to see and correct it, and a /ledger pane." },
{ "name": "next-steps", "source": "./next-steps", "description": "1-3 suggested next prompts after each real turn, tick any number and insert them together." },
{ "name": "auto-docs", "source": "./auto-docs", "description": "After each commit, updates README.md (or the docs you list) in a follow-up docs commit." }
]
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

Each mod is versioned on its own (the `version` in its `.claude-plugin/plugin.json`). Dates are UTC.

## 2026-10-17

- **token-ledger 0.6.0**: `?` now learns from your project and from you.
- After each turn you type, Haiku folds the exchange into a short per-project brief and a profile of you that carries across projects.
- Your corrections and frustration, and which suggestions you inserted or skipped, are logged as feedback.
- `?` reads that memory plus only the latest messages. Until a brief exists it still gets the full chat.
- New `/brief` command shows what the mod knows and lets you fix it: `/brief brief <text>`, `/brief profile <text>`, `/brief forget`, `/brief reset`.
- South African ID numbers and phone numbers, emails, card numbers, bank accounts and passport numbers are redacted before anything is stored or sent to Haiku. Names and non-South-African phone or ID formats are not detected. Only prompts a person typed are learned from, never notifications or schedules.
- The `?` prompt no longer assumes you are a developer.

## 2026-10-13

- **auto-docs:** tests now pass on Linux and macOS as well as Windows.
Expand Down
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Every picture below was rendered from the element trees these mods really return

| Mod | What you get | Commands |
| --- | --- | --- |
| [token-ledger](#token-ledger) | A telemetry row above the prompt (5-hour %, burn rate, reset, time left, weekly %, context %, cache hit %, model, effort). A `?` button for five Haiku questions. A `/ledger` pane. | `/ask`, `/ledger` |
| [token-ledger](#token-ledger) | A telemetry row above the prompt (5-hour %, burn rate, reset, time left, weekly %, context %, cache hit %, model, effort). A `?` button for five Haiku questions. A `/ledger` pane. A `/brief` pane for what it has learned about you and your project. | `/ask`, `/ledger`, `/brief` |
| [next-steps](#next-steps) | 1-3 suggested next prompts after each real turn, in a pane of their own. | `/next`, `/next off`, `/next on` |
| [auto-docs](#auto-docs) | After each commit, a follow-up `docs: sync with <sha>` commit that updates README.md, or the docs you list. | `/docs`, `/docs <commit>` |

Expand Down Expand Up @@ -59,6 +59,28 @@ Click `?` at the end of the row, or run `/ask`. Haiku 5.5 reads the project (fol

<img src="docs/img/questions-pane.svg" alt="Questions worth asking pane with two questions ticked and the Insert 2 questions button" width="560">

### `/brief`: what `?` has learned

`?` does not start cold. After each prompt you type, a small Haiku call folds the exchange into three things the mod keeps on your machine:

- **A project brief:** what the project is, the goal, what has been decided and what is still open. One per project folder.
- **A profile of you:** who you are, your business, how you like to be spoken to. Shared across projects.
- **Feedback:** things you corrected, moments you were frustrated, and which suggestions you inserted or skipped.

`?` then reads that memory plus the latest messages, so its questions fit your project and don't repeat what you have already decided or skipped. Until a brief exists, `?` still gets the full recent chat.

`/brief` shows what the mod believes so you can correct it:

| Command | What it does |
| --- | --- |
| `/brief` | Opens the pane. |
| `/brief brief <text>` | Replaces this project's brief. |
| `/brief profile <text>` | Replaces your profile. |
| `/brief forget` | Clears this project's feedback log. |
| `/brief reset` | Clears this project's brief and feedback. Your profile is kept. |

Privacy: South African ID numbers and phone numbers, email addresses, card numbers, bank accounts and passport numbers are replaced with stable tokens before anything is stored or sent to Haiku. People's names and phone or ID formats from other countries are **not** detected, so don't put those in prompts you don't want a model to see. Only prompts a person typed are learned from, never notifications, schedules or peer messages. Everything is stored locally in the plugin's own store. A manual `/brief brief` edit can be rewritten by a later turn's fold, so re-run it if a fact must stay.

### `/ledger`

<img src="docs/img/ledger-pane.svg" alt="Token ledger pane: limits, this session, subagents, last 7 days, cache rewrites after idle, recent turns" width="600">
Expand Down
4 changes: 2 additions & 2 deletions token-ledger/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "token-ledger",
"version": "0.5.0",
"description": "Your 5-hour, weekly, context and cache-hit figures as one line above the prompt, a ? button that asks Haiku 5.5 for questions to ask next, and a /ledger pane with subagent shares. Percentages only, no money.",
"version": "0.6.0",
"description": "Your 5-hour, weekly, context and cache-hit figures as one line above the prompt, a ? button that asks Haiku 5.5 for questions to ask next, drawn from a running brief of the project and what you've told it (see /brief), and a /ledger pane with subagent shares. Percentages only, no money.",
"author": {
"name": "claude-code-mods contributors",
"url": "https://github.com/bully911210/claude-code-mods"
Expand Down
32 changes: 22 additions & 10 deletions token-ledger/hooks/lib/insights.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export const QUESTION_COUNT = 5

/** Budgets keep the request small and fast; the newest context matters most. */
const MAX_MESSAGES = 40
/** With a memory block the history lives there, so only the freshest turns are needed. */
const MAX_MESSAGES_WITH_MEMORY = 6
const MAX_MESSAGE_CHARS = 1_500
const MAX_THINKING_CHARS = 4_000
const MAX_PROJECT_DOC_CHARS = 6_000
Expand All @@ -23,17 +25,25 @@ export type InsightContext = {
}
readonly messages: readonly { readonly role: 'user' | 'assistant'; readonly text: string; readonly tools: readonly string[] }[]
readonly thinking: readonly string[]
/** The rendered memory block (see memory.ts renderMemory); leads the prompt when present. */
readonly memory?: string
/** False when the memory holds no brief yet (only feedback): the chat then still carries the history. */
readonly memoryHasBrief?: boolean
}

export const SYSTEM = [
'You help a developer get more out of their current Claude Code conversation.',
`Write exactly ${QUESTION_COUNT} questions the developer could ask Claude next.`,
'Each question must uncover something the conversation has not adequately explored:',
'information or capabilities the system already has but has not surfaced; non-obvious technical opportunities;',
'critical assumptions nobody has verified; failure modes, edge cases and architectural weaknesses;',
'or a high-leverage experiment or investigation that would materially improve the outcome.',
'Tie every question to specifics in the context (files, tools, decisions, errors, names). No generic prompts.',
'Make the five meaningfully different from one another. Keep each question under 220 characters and actionable.',
'The user is a business owner and operator, not a developer. Do not assume the work is software, and do not use developer framing or jargon.',
'Work out from the context what the project actually is (for example marketing, ads, sales, lead generation, content, brand, operations, reporting, or software) and what outcome the user is chasing.',
`Then write exactly ${QUESTION_COUNT} questions the user could ask Claude next, as the sharpest domain expert for that exact project would: a senior marketer, strategist, operator or analyst, whichever fits.`,
'Each question must surface expert insight the conversation has not yet explored:',
'a lever or opportunity being missed; an assumption nobody has tested; the real risk, weakness or blind spot in the current approach;',
'something Claude or the connected tools could already do or find out but has not yet; or a high-leverage test, check or decision that would materially improve the result.',
'Tie every question to specifics in the context (the actual project, brand, numbers, files, tools, decisions, names). Never ask a generic question that could apply to any project.',
'The memory sections at the top of the context (About the user, The project so far, What the user has told us and how they react) are the authoritative picture of the user and the project; trust them over a thin or empty chat.',
'Signals in the memory: ignored, correction and frustration are things to AVOID repeating or contradicting, so never ask something the user has already decided, corrected or ignored.',
'Signals marked accepted show the style the user likes, so lean toward similar depth and angle, but do not repeat the same question.',
'Write for a business owner in plain language.',
'Make the five meaningfully different from one another. Keep each question under 220 characters, plain-spoken and actionable.',
'Use only what the context shows. Do not claim to have seen anything it does not contain.',
'Reply with JSON only: {"questions":[{"title":"2-5 word label","question":"the full question"}]}',
].join(' ')
Expand All @@ -53,11 +63,13 @@ export const buildPrompt = (c: InsightContext): string => {
const thinkingPart = thinking.length
? [`Claude's visible reasoning notes (most recent):\n${cut(thinking.slice(-3).join('\n---\n'), MAX_THINKING_CHARS)}`]
: ["Claude's reasoning is not visible for this conversation; do not guess at it."]
const convo = c.messages.slice(-MAX_MESSAGES).map(m => {
const memory = (c.memory ?? '').trim()
const recent = memory === '' || c.memoryHasBrief === false ? MAX_MESSAGES : MAX_MESSAGES_WITH_MEMORY
const convo = c.messages.slice(-recent).map(m => {
const tools = m.tools.length ? ` [tools: ${[...new Set(m.tools)].join(', ')}]` : ''
return `${m.role === 'user' ? 'USER' : 'CLAUDE'}${tools}: ${cut(m.text.trim(), MAX_MESSAGE_CHARS)}`
})
const head = ['## Project', ...project, '', '## Reasoning', ...thinkingPart, '', '## Conversation (oldest first)'].join('\n')
const head = [...(memory === '' ? [] : [memory, '']), '## Project', ...project, '', '## Reasoning', ...thinkingPart, '', '## Conversation (oldest first)'].join('\n')
// Drop the oldest messages until the whole prompt fits.
let body = convo
while (body.length > 1 && head.length + body.join('\n').length > MAX_TOTAL_CHARS) body = body.slice(1)
Expand Down
Loading
Loading