Usage limits in the status line and a usage band above the prompt.

Repository-level instructions, coding standards, and role-specific workflows for Daniel's AI-assisted programming work.
This repository contains reusable guidance. It is intentionally general and should not contain assumptions from a single analysis project.
AGENTS.md is the repository instruction entry point.R Code Conventions.md is the canonical standard for R code.General Code Conventions.md covers Stata, Python, and Julia. Its R section routes back to the R standard.GIT_WORKFLOW.md documents the safe Git workflow for pulling, reviewing, committing, and publishing changes..agents/skills/ contains Codex skills and their optional UI metadata..claude/agents/ and .claude/skills/ contain Claude-specific agents and skills..github/ contains Copilot routing and cross-tool synchronization guidance..codex/instructions.md is retained as a compatibility copy; new Codex repository instructions belong in AGENTS.md.AGENTS.md states the working philosophy. The coding convention files match it.
The roles are:
r-coder for writing or substantially revising one R script;r-reviewer for auditing R scripts and producing a quality report;r-build-and-review for write-then-review orchestration;simplifier for overengineering review; anddocumentation-writer for methodology and technical documentation.Before changing code, read the applicable canonical standard and the relevant role-specific workflow. Keep project-specific assumptions in the project repository, not here. When changing a role that exists in both Claude and Codex formats, make the matching substantive change in both locations.
For R work, the repository includes configuration for lintr and styler. Use the review checklist in the R standard and run git diff --check before publishing.
Keep guidance concise, executable, and evidence-based. Prefer one canonical rule over duplicated conflicting rules. Update references when sections or paths move, and verify that examples follow the rules they describe.
hooks/register.tsx 73 lines1import type { Register } from 'claude-code'
2
3const WINDOW_NAMES: Record<string, string> = {
4 five_hour: '5-hour limit',
5 seven_day: '7-day limit',
6 spend_limit: 'Spend limit',
7}
8
9// Green under 60%, yellow under 85%, red above.
10const barColor = (percent: number) =>
11 percent < 60 ? 'green' : percent < 85 ? 'yellow' : 'red'
12
13const bar = (percent: number, cells = 10) => {
14 const filled = Math.round((Math.min(percent, 100) / 100) * cells)
15
16 return '█'.repeat(filled) + '░'.repeat(cells - filled)
17}
18
19export const register: Register = on => {
20 on('session.start', async ($, e, next) => {
21 let lastSignature = ''
22
23 const tick = async () => {
24 const now = await $.session.usage()
25 const got = {
26 windows: now.rateLimits,
27 contextPercent: now.context.percent,
28 }
29 const signature = JSON.stringify(got)
30
31 if (signature !== lastSignature) {
32 lastSignature = signature
33 await $.state.set({ plugin: 'cc-daniel', key: 'usage' } as const, got)
34 }
35
36 const five = got.windows.find((w: any) => w.kind === 'five_hour')
37 $.ui.status(five ? `5h ${five.percentUsed}%` : undefined)
38 }
39
40 await tick()
41 $.clock.every(5000, () => void tick())
42
43 return next(e)
44 })
45
46 on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
47 const { value: now } = await $.state.get({ plugin: 'cc-daniel', key: 'usage' } as const)
48
49 if (e.props.hasSurvey || !now) return next(e)
50
51 const { Box, Text } = $.ui.resolve(e)
52 const items = [
53 ...now.windows.map(w => ({
54 name: WINDOW_NAMES[w.kind] ?? w.kind,
55 percent: w.percentUsed,
56 })),
57 { name: 'Context', percent: now.contextPercent ?? 0 },
58 ]
59
60 return (
61 <Box gap={3}>
62 {items.map(item => (
63 <Box gap={1}>
64 <Text bold>{item.name}</Text>
65 <Text color={barColor(item.percent)}>{bar(item.percent)}</Text>
66 <Text bold>{`${item.percent}%`}</Text>
67 </Box>
68 ))}
69 </Box>
70 )
71 })
72}
73types/index.d.ts 14 lines1export type Window = { kind: string; percentUsed: number; resetsAt?: string }
2export type Usage = {
3 windows: Window[]
4 contextPercent?: number
5}
6
7declare module 'claude-code' {
8 interface PluginState {
9 'cc-daniel': {
10 usage: Usage | null
11 }
12 }
13}
14