Code Review Checklist
shareAI-lab/learn-claude-code
Reviews code against a five-part checklist covering security, correctness, performance, maintainability and testing, and reports findings in a fixed format.
Maps the hunkdiff/extension API for building Hunk terminal diff viewer extensions: panes, file views, commands, dialogs, themes, VCS backends and lifecycle events.
$ npx skills add modem-dev/hunk --skill hunk-extensions -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install modem-dev/hunk hunk-extensions --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/modem-dev/hunk.git skills-src && mkdir -p .claude/skills && cp -r skills-src/packages/hunk/skills/hunk-extensions .claude/skills/hunk-extensions && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "hunk-extensions" agent skill from https://github.com/modem-dev/hunk/tree/main/packages/hunk/skills/hunk-extensions into .claude/skills/hunk-extensions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hunk-extensions", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/modem-dev/hunk/tree/main/packages/hunk/skills/hunk-extensionsType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add modem-dev/hunk --skill hunk-extensions -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install modem-dev/hunk hunk-extensions --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/modem-dev/hunk.git skills-src && mkdir -p .agents/skills && cp -r skills-src/packages/hunk/skills/hunk-extensions .agents/skills/hunk-extensions && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "hunk-extensions" agent skill from https://github.com/modem-dev/hunk/tree/main/packages/hunk/skills/hunk-extensions into .agents/skills/hunk-extensions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hunk-extensions", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add modem-dev/hunk --skill hunk-extensions -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install modem-dev/hunk hunk-extensions --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/modem-dev/hunk.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/packages/hunk/skills/hunk-extensions .cursor/skills/hunk-extensions && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "hunk-extensions" agent skill from https://github.com/modem-dev/hunk/tree/main/packages/hunk/skills/hunk-extensions into .cursor/skills/hunk-extensions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hunk-extensions", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/modem-dev/hunk.git --path packages/hunk/skills/hunk-extensions--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add modem-dev/hunk --skill hunk-extensions -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install modem-dev/hunk hunk-extensions --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/modem-dev/hunk.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/packages/hunk/skills/hunk-extensions .gemini/skills/hunk-extensions && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "hunk-extensions" agent skill from https://github.com/modem-dev/hunk/tree/main/packages/hunk/skills/hunk-extensions into .gemini/skills/hunk-extensions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hunk-extensions", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install modem-dev/hunk hunk-extensionsInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add modem-dev/hunk --skill hunk-extensions -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/modem-dev/hunk.git skills-src && mkdir -p .github/skills && cp -r skills-src/packages/hunk/skills/hunk-extensions .github/skills/hunk-extensions && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "hunk-extensions" agent skill from https://github.com/modem-dev/hunk/tree/main/packages/hunk/skills/hunk-extensions into .github/skills/hunk-extensions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hunk-extensions", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add modem-dev/hunk --skill hunk-extensions -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install modem-dev/hunk hunk-extensions --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/modem-dev/hunk.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/packages/hunk/skills/hunk-extensions .opencode/skills/hunk-extensions && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "hunk-extensions" agent skill from https://github.com/modem-dev/hunk/tree/main/packages/hunk/skills/hunk-extensions into .opencode/skills/hunk-extensions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hunk-extensions", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
hunk-extensionsMaps the hunkdiff/extension API for building Hunk terminal diff viewer extensions: panes, file views, commands, dialogs, themes, VCS backends and lifecycle events.
A Hunk extension is one TypeScript, JSX or JavaScript file that default-exports a factory; Hunk imports it at startup and passes in an API object, with no build step or manifest. The skill is a map of touchpoints rather than a recipe: hiding or reordering reviewed files, docked panes, alternate file views, commands and key bindings, dialogs, workspace writes, themes, syntax languages, VCS backends and lifecycle events.
It lists the sources of truth to read before writing code: the extensions authoring guide, the type contract in `packages/hunk/src/extension-api/types.ts`, and working examples in `examples/extensions/`, with the online docs and the shipped `index.d.ts` as substitutes outside a checkout. Examples cover a review-triage pane with commands and dialogs, an inline-edit file view, rendered Markdown, code-document syntax painting and experimental JSX file views. Reviewing a diff in a live session is handled by `hunk-review`.
5 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 252f59d. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
buntscFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
hunk.devgithub.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Hunk Extension Authoring Map loads about 5.8k tokens when it runs. Until then it costs about 118 tokens; SKILL.md has 2,739 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from modem-dev/hunk at commit 252f59d, republished under its MIT licence (© modem-dev). 2,739 words, ~5,761 tokens.
.claude/skills/hunk-extensions/SKILL.md (or your agent's skills folder).A Hunk extension is one TypeScript (or JSX/JS) file that default-exports a factory. Hunk imports it at startup and hands it an API object. No build step, no manifest required.
// ~/.config/hunk/extensions/hello.ts
import type { HunkExtensionAPI } from "hunkdiff/extension";
export default function (hunk: HunkExtensionAPI) {
hunk.on("startup", (_event, ctx) => ctx.notify("Hello"));
}This skill is a map of the touchpoints, not a recipe. Decide what to build from the user's request; use the table below to find the call, then read the linked material before writing code.
| Source | What it answers |
|---|---|
docs/extensions.md | The authoring guide. Every call, every rule. Start here. |
packages/hunk/src/extension-api/types.ts | The contract — exact field names, optionality, doc comments. |
examples/extensions/* | Working extensions. Copy these patterns rather than invent. |
docs/extension-architecture.md | Hunk's internals. Needed only when changing the host. |
docs/keybindings.md, docs/themes.md | Chord grammar and theme token rules that extensions inherit. |
Outside a Hunk checkout the guide is split across
https://hunk.dev/docs/extend/extensions/ (discovery, trust, config) and its
companion pages — extension-api, file-previews, vcs-adapters, custom-panes —
and the contract ships as node_modules/hunkdiff/dist/npm/extension/index.d.ts.
The examples, by what they demonstrate:
review-triage/ — pane + commands + all three dialog shapes + lifecycle
events + the extension event bus + a useSyncExternalStore bridge.inline-edit/ — an interactive file-view mode driving ctx.workspace writes;
its README explains the async lifetime rules better than anything else in tree.rendered-markdown/ — a file view producing host-rendered rows from parsed
Markdown, and a folder extension with an npm dependency.code-document-file-view/ — API-v28 host-owned syntax paint over complete old/new
code documents, including semantic gutters and partial UTF-16 ranges.jsx-file-view/, jsx-file-view-gallery/ — the experimental fixed-height JSX
row component contract.| Source | Trust |
|---|---|
--extension <path> (repeatable) | runs immediately |
[extensions] paths in user config | runs immediately |
~/.config/hunk/extensions/ (XDG-aware) | runs immediately |
.hunk/extensions/ or repo-config paths | trust prompt |
Only the repo-local group is gated. Everything else — including --extension,
even when its path points inside the repository under review — is read as
explicit user intent and executes with full user permissions, no prompt. Never
pass or suggest a path you have not read, including one copied from a
repository's own README.
A directory matches *.ts/*.tsx/*.js/*.jsx/*.mjs at its top level, plus
one level of folder extensions. A folder is an extension if it has a
package.json with {"hunk": {"extensions": ["./index.ts"]}}, or an
index.{ts,tsx,js,jsx,mjs}. Reach for a folder only when you need npm
dependencies, helper modules, or a README; a single file keeps the install to one
cp. A .hunk/extensions/ folder extension's node_modules has to exist on
every machine that loads it — keep a repo-shared extension dependency-free.
Shared extensions install from git with hunk extension install <source>
(owner/repo[@ref], git:host/path[@ref], a git URL, or a local path) into
~/.config/hunk/extensions/installed/<repo-name>/, where they load with global
origin; list, update, and remove manage them. Declared dependencies are
bun installed at install time. The manifest may state
{"hunk": {"apiVersion": N}} — the minimum extension API version — and an older
Hunk refuses the extension with a startup notice instead of failing mid-factory.
To publish, push the folder-extension layout to a git repository's root with
real name/version/description, tag releases for @ref pins, and add the
hunk-extension GitHub topic so it appears at
https://github.com/topics/hunk-extension.
The id is the file stem, or the folder name for a folder extension — unless
its manifest declares several entries, in which case each entry is its own
extension named by its own stem (numeric suffix on collision). The id is the
namespace it owns: commands are <id>.<commandId>, panes and keyboard modes
are <id>:<localId>, config [extension.<id>]. Ids match
/^[A-Za-z0-9][A-Za-z0-9_-]*$/; hunk, git, jj, and sl are reserved. A
bad or duplicate id is skipped with a startup notice. [extensions] disabled = ["<id>"]
filters a user extension before import or trust prompting. --disable-extension <id> and
--enable-extension <id> are ordered one-run overrides; --no-extensions remains the hard switch
for all user extensions. Bundled capabilities use separate host-owned selection ids such as
hunk.gh, even when their public registrations remain under the hunk namespace.
| To do this | Call |
|---|---|
| Keep demo/training view settings temporary | hunk.configureSession(options) |
| Add a selectable color theme | hunk.registerTheme(theme) |
| Highlight an extension, exact filename, or filename glob | hunk.registerFileLanguage(matcher, lang) |
Support another VCS (git/jj/sl are reserved) | hunk.registerVcsAdapter(adapter) |
| Add a navigation/list/status pane beside the review | hunk.registerPane(pane) |
| Present a file as something other than a raw diff | hunk.registerFileView(view) (experimental) |
| Mark character ranges inside diff lines | hunk.registerLineHighlighter(highlighter) |
| Interpret review keys as a temporary global mode | hunk.registerKeyboardMode(mode) |
| Add a generic top-level CLI command tree | hunk.registerCliCommand(command, handler) |
| Bind a key / add an Extensions-menu entry | hunk.registerCommand(command, handler) |
| Show persistent text on the bottom status row | ctx.statusLine.set(item) in a handler |
Ask for one line of text inline, less-style | ctx.prompts.line(options) in a command |
| Hide, reorder, retitle files before review | hunk.transformChangeset(fn) |
| React to loads, selection, view movement, notes, reloads | hunk.on(event, handler) |
| Coordinate with another loaded extension | hunk.events.emit / hunk.events.on |
| Reload after an external agent changes reviewed inputs | ctx.review.requestReload() in an event |
| Read user-supplied settings | hunk.config ([extension.<id>] table) |
| Snapshot stable files and every saved review note | ctx.review.snapshot() in a command |
Branch on the API generation (currently 28) | hunk.apiVersion |
Registration is only valid while the factory runs — Hunk seals the API object afterwards.
Promise-returning VCS watchSignature hooks and watch cancellation require API
version 25. Declare {"hunk": {"apiVersion": 25}} in the manifest, or branch on
hunk.apiVersion and return signatures synchronously on older hosts. Use async
I/O and honor ctx.signal on API 25; existing synchronous hooks remain supported.
Register one lowercase-kebab top-level token; the handler owns every raw token below it. Built-ins and aliases cannot be shadowed, and discovery order makes the first extension claim win. During development, place the explicit path before the extension command:
hunk --extension ./my-ext.ts my-command sync --helpThe handler receives frozen args plus ctx.cwd, ctx.signal, streaming
ctx.stdin, and leased ctx.stdout/ctx.stderr writers. summary and
usage are listed when a token reaches discovery unclaimed, so write them as
one short line each. Return { kind: "exit", code? } or { kind: "delegate", argv: ["diff", ...] }. Delegation is
built-in-only and one-time: do not write stdout or read stdin before delegating;
use stderr for progress. Reading stdin is an exit-only workflow. Respect cancellation promptly.
Repo-local providers remain trust-gated; --no-extensions performs no discovery
or import, while a leading explicit --extension path is immediate consent.
Use packages/hunk-gh/src/ as the reference for a complete bundled CLI preprocessor: direct
authenticated HTTP with cancellation, temporary artifacts with platform-accurate permission claims
retained through delegated startup, cleanup on shutdown, and a one-time handoff to built-in
patch without touching stdin or stdout.
Every event, bus, command, and file-view mode handler — plus every changeset
transform — gets ctx.cwd and ctx.notify(message, type?). A file view's
matches and layout get no context at all. Beyond that:
ctx.panes (open/close/toggle/isOpen on
any pane), live ctx.navigation, attributed ctx.dialogs, ctx.statusLine
(set/clear this extension's status-row items), review reloads through
ctx.review.requestReload(), and
ctx.events.emit. ctx.sidebars is a deprecated alias for ctx.panes.ctx.panes, ctx.fileViews (select/toggle/isActive/
refresh/enterMode/exitMode), ctx.highlights (refresh prepared line marks,
whole or { fileId }-scoped), ctx.selection (a snapshot of file, hunk index,
nullable current { side, line } source address, and files, the visible files
in review order), ctx.navigation (live,
guarded selectFile/selectHunk/revealLine, the
last landing one exact (side, line) near the viewport top), ctx.commands
(isEnabled/execute for public semantic hunk.* commands),
ctx.keyboardModes (enter/exit/probe this extension's session modes), ctx.review
(deeply immutable snapshots of stable files and complete saved store notes),
ctx.dialogs (confirm/select/input, queued and attributed),
ctx.statusLine (set/clear persistent status-row items), ctx.prompts
(line: an inline status-row input resolving the text or null, queued and
attributed like dialogs), and
ctx.workspace (readDocument, canWriteDocument, writeDocument with consent).files, selection, placement, exact dimensions,
nullable immutable delegated-source review metadata, optional currentLine paint
(with { side, line } when opted in), semantic theme, resolved keybindings, and
guarded navigation/notification actions. Availability callbacks receive the same
review value, so a pane can consume no geometry for ordinary reviews.layout gets file, width, signal, changes, and a lazy
readDocument(side).mode handlers get ctx.file and ctx.fileViews. onKey,
onEnter, and onExit must answer synchronously — onKey's return value
("handled"/"pass"/"exit") is the routing decision, so kick off async work
and report it later through notify or refresh. A passed key reaches any
active session keyboard mode before ordinary Hunk routing. Escape is host-owned
and never reaches onKey.ctx.commands, ctx.highlights,
ctx.statusLine, and activation-scoped ctx.keyboardModes beyond the standard
context. A prompt-shaped interaction is a command plus ctx.prompts.line(),
not a mode. Those controls become inert on
exit, and lifecycle callbacks cannot change keyboard ownership. Keys are frozen
snapshots; dialogs, focused inputs, and file-view modes outrank them. When the
session mode owns input, Escape exits it; the status badge and Extensions menu
are unconditional host-owned exits.Event payloads, pane props, and a command's selection all hand you frozen
ExtensionDiffFile / ExtensionDiffHunk views. A changeset transform is the
exception: it receives the live changeset and is expected to return a new one.
metadata is unfrozen either way — it is the renderer's parsed diff, so pass it
through untouched.
Most extension bugs are one of these:
defaultOpen,
replaces: "hunk:files", or a command that opens them. File views remain raw
until selected from the View menu.hunkRows needs one
in-bounds, inclusive entry per parsed hunk at the same array index, and
sourceRanges may not overlap on a side; invalid, oversized, cancelled, and
throwing layouts warn once and fall back.codeDocuments and
map exact symbolic spans with syntax; Hunk owns tokenization, theme colors,
visible-window demand, resource limits, and plain fallback. Keep gutters and
separators in non-syntax spans, and use sourceRanges separately for notes/navigation.react and @opentui/*
to extension files; a second copy means a second hooks dispatcher and the
component fails to render. Import them normally. OpenTUI intrinsics (box,
text, scrollbox) need no import.layout is a pure derivation of (file, width). A stateful view keeps
painting its first answer until ctx.fileViews.refresh(viewId) — scope it with
{ fileId } when the state belongs to one file.useSyncExternalStore and immutable
snapshots (review-triage/index.tsx is the working version).ctx.review.snapshot() for complete saved-note state. note_created and
note_edited are incremental UI events, not an authoritative collection. Snapshots
include stale and orphaned saved notes, exclude drafts and static sidecar annotations,
and should be re-read before irreversible async work; compare both generation and revision.
review-note-navigator shows how to join stable note ids and file keys back to guarded
navigation after awaiting a selector; file filters can still refuse hidden targets.null/unavailable. A
consented write already in progress reports its real outcome, holds graceful
exit until it settles, and reconciles the active review on success. shutdown
runs after revocation, so use it only
to release extension-owned resources.id encodes its position in the changeset, so a reload that adds or drops a
file renumbers the rest. Key durable per-file state by path, or reconcile it
on changeset_loaded. Pick one deliberately.metadata (spreading a file does), keep ids
unique, and return a real changeset — otherwise the transform is skipped with a
warning and the previous changeset carries forward.[keybindings]; built-ins
win conflicts, refused one chord at a time. Bind the character shift produces
("!", not "shift+1").ctx.commands.execute
after resolving an action. vim-navigation demonstrates counts, Ctrl chords,
and a : key passed to a registered command whose host input dialog temporarily
outranks the still-active mode.ctx.commands invokes Hunk, not other extensions. Probe with
isEnabled("hunk.review.nextHunk"), then call execute(id, { count }) for an
explicitly public built-in. Counts are positive whole numbers up to 10,000,
applied atomically to movement; one-shot actions run once. Unknown, disabled,
private, extension-owned, or stale commands return false.[extension.<id>] for a globally installed extension.
Treat hunk.config as untrusted for anything exec-adjacent (binary paths,
shell commands, module loading).ctx.workspace writes only apply to reloadable, unstaged working-tree
reviews, by reviewed file id, inside the review root, with consent. Everything
else returns { ok: false, reason } — check canWriteDocument first.ctx.workspace — an extension is ordinary code, so shell
out for the rest. Never write to stdout: the renderer owns it. For the same
reason hunk.log is collected as diagnostics and printed nowhere; ctx.notify
is how a user hears from you.HunkExtensionUserError (detected structurally by name) buys the full
treatment — message plus suggestions, no stack trace — only from a VCS adapter
operation, which is where Hunk formats it for the CLI. From a command or event
handler only the message survives, as a warning toast.Hunk's TUI needs a real terminal, and the review UI is the user's — do not
launch hunk diff/hunk show to test, and do not reach for a pipe. No
invocation applies extensions headlessly: hunk diff … | cat still starts the
app and still takes the keyboard, so it hangs holding the user's terminal.
Practical checks, in order of cost:
bun run typecheck covers
examples/extensions/** via the hunkdiff/extension path mapping. Standalone,
add hunkdiff as a dev dependency and run tsc --noEmit; for a .tsx
extension also add react, @types/react (React ships no declarations of its
own), @opentui/core, and @opentui/react as dev dependencies and set
"jsx": "react-jsx" with
"jsxImportSource": "@opentui/react", or every <box> and <text> is an
untyped intrinsic. Types only — shipping those packages is the second-React bug.bun test coverage.test/pty/extensions-integration.test.ts
launches Hunk over a PTY with --extension <path> and asserts on rendered
snapshots; extend it via test/pty/harness.ts and run bun run test:integration.hunk diff --extension ./my-ext. --extension
loads immediately with no trust prompt, so it is the iteration path. Ask them
what the footer notices and toasts said.--no-extensions to confirm a symptom belongs to an extension
(bundled VCS backends, the built-in files pane, and the / content search stay loaded
either way).package.json hunk.extensions paths.~/.config/hunk/state.json.defaultOpen, no
command), matches returned false, or the layout was rejected.<id>.<commandId>.Only when the work is in the hunk repo rather than in a user extension:
hunk gh, the built-in files pane, and the / content search are
bundled extensions, registering through the same public API. That dogfooding is deliberate —
if the public contract cannot express something, that is a real gap, not a reason for a private
path. default/vcs/ loads from VCS adapter resolution and must stay renderer-free;
default/core/ loads session-owned CLI capabilities from private workspaces such as
packages/hunk-gh; and default/ui/ holds process-cached rendering registrations.packages/hunk/src/extension-api/types.ts must stay import-free; declaration emission
publishes whatever it reaches, and scripts/packaging/check-pack.ts fails the pack
otherwise. Shapes shared with internal code are declared there and re-exported
inward.docs/extensions.md (its examples are
typechecked as consumer code), the matching hand-written page under
website/src/content/docs/docs/extend/ (only cli.md and config.md are
generated), docs/extension-architecture.md if ownership moves, and a changeset.AGENTS.md and docs/extension-architecture.md own the rest of these rules.© modem-dev, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in packages/hunk/skills/hunk-extensions of modem-dev/hunk.
Open the folder on GitHubat commit 252f59d
Hunk Extension Authoring Map next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Hunk Extension Authoring Map this skillmodem-dev/hunk | 9.5k | — | ~5.8k | Automated safety check: Pass | MIT | |
| Code Review ChecklistshareAI-lab/learn-claude-code | 78k | 5 repos | ~1.1k | Automated safety check: Pass | MIT | |
| Liveagent Code ReviewStack-Cairn/LiveAgent | 2.2k | — | ~2k | Automated safety check: Pass | MIT | |
| Tbdjlevy/strif | 131 | — | ~3.5k | Automated safety check: Pass | MIT | |
| Codexqa Rootcause Analyzeropenqa-cn/codexqa | 152 | — | ~2.6k | Automated safety check: Pass | Apache-2.0 | |
| Code Revieweralirezarezvani/claude-code-tresor | 777 | — | ~1.8k | Automated safety check: Pass | MIT |
shareAI-lab/learn-claude-code
Reviews code against a five-part checklist covering security, correctness, performance, maintainability and testing, and reports findings in a fixed format.
Stack-Cairn/LiveAgent
Review an open GitHub pull request or the current local branch and working tree with parallel, independent reviewers and evidence-based validation.
jlevy/strif
Git-native issue tracking (beads), coding guidelines, knowledge injection, and spec-driven planning for AI agents.
openqa-cn/codexqa
Diagnoses exception root causes from stack traces, logs, call-chain dumps, and debug output using the CodexQA CLI for structured repo analysis.
alirezarezvani/claude-code-tresor
Automatic code quality and best practices analysis. An agent skill from alirezarezvani/claude-code-tresor.
logseq/logseq
Build, debug, or review Logseq plugins with the @logseq/libs SDK (TypeScript/JavaScript, iframe/shadow sandboxed).
modem-dev/hunk
Maintainer workflow for preparing, publishing, verifying and curating Hunk releases, with confirmation gates before tags, publishes and public edits.
modem-dev/hunk
Interacts with live Hunk diff review sessions via CLI. Inspects review focus, navigates files, hunks, and exact lines, reloads session contents, adds inline…
modem-dev/hunk
Produces captioned 1080p product videos of the Hunk terminal diff viewer by driving the real TUI headlessly and compositing frames in Chromium.
Works with
Categories
Maps the hunkdiff/extension API for building Hunk terminal diff viewer extensions: panes, file views, commands, dialogs, themes, VCS backends and lifecycle events. A Hunk extension is one TypeScript, JSX or JavaScript file that default-exports a factory; Hunk imports it at startup and passes in an API object, with no build step or manifest. The skill is a map of touchpoints rather than a recipe: hiding or reordering reviewed files, docked panes, alternate file views, commands and key bindings, dialogs, workspace writes, themes, syntax languages, VCS backends and lifecycle events.
Hunk Extension Authoring Map fits situations like: writing a Hunk extension that adds a pane, command or key binding; debugging or installing an existing Hunk extension; customizing how Hunk renders or filters files under review.
Run `npx skills add modem-dev/hunk --skill hunk-extensions -a claude-code`. Or copy the skill folder (packages/hunk/skills/hunk-extensions in modem-dev/hunk) into .claude/skills/hunk-extensions in your project. Claude Code loads it when a task matches its description.
Run `npx skills add modem-dev/hunk --skill hunk-extensions -a codex`. Or copy the skill folder (packages/hunk/skills/hunk-extensions in modem-dev/hunk) into .agents/skills/hunk-extensions in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add modem-dev/hunk --skill hunk-extensions -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/hunk-extensions, .gemini/skills/hunk-extensions, .github/skills/hunk-extensions and .opencode/skills/hunk-extensions in your project.
Going by SKILL.md and its folder, Hunk Extension Authoring Map needs the command-line tools its instructions call (bun and tsc). Our summary lists: Hunk, the terminal diff viewer (the `hunkdiff` package).
SKILL.md names 2 domains. As links in the text: hunk.dev and github.com. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Hunk Extension Authoring Map is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 5.8k tokens (SKILL.md is roughly 23k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Hunk Extension Authoring Map: Code Review Checklist (shareAI-lab/learn-claude-code, 78k stars), Liveagent Code Review (Stack-Cairn/LiveAgent, 2.2k stars), Tbd (jlevy/strif, 131 stars) and Codexqa Rootcause Analyzer (openqa-cn/codexqa, 152 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
modem-dev (a GitHub organization) maintains it in modem-dev/hunk, which has 9,521 GitHub stars. The repository holds 4 skills in this directory. The repository was last updated on October 6, 2026.
Source: modem-dev/hunk on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.