Skip to content

Latest commit

 

History

History
367 lines (315 loc) · 28.4 KB

File metadata and controls

367 lines (315 loc) · 28.4 KB

Contributing to han

This page is for contributors: anyone adding, editing, or restructuring skills, agents, or documentation in the han plugin. If you only want to use the plugin, start with the Plugin landing page or the Quickstart.

See also: Plugin landing page · Concepts · Sizing · YAGNI · Evidence · Readability

TL;DR

Before you start

Read these once:

Setting up your environment

Han's dev tooling is managed as npm devDependencies, so a single npm install sets everything up at pinned versions with nothing installed globally. It installs prek (the git-hook runner), Prettier (formatting), and Bats (shell tests).

One-time setup, from the repo root:

  1. Install Node.js (the current LTS is fine).
  2. Run npm install. It installs the pinned tools into node_modules/. Nothing lands on your global PATH, so tool versions never clash with your other projects.
  3. If you want pre-commit hooks, run npx prek install.

Everyday use:

  • npm run lint runs every hook over the whole repo (prek run --all-files).
  • npm test runs the shell tests (every *.bats file in the repo outside node_modules).
  • If installed, every commit runs the lint hooks (Prettier, ShellCheck, and file hygiene) on your staged files.

CI runs the same lint hooks and the tests on every pull request.

How Prettier treats your files:

  • It formats Markdown, JSON, YAML, and JavaScript. Prose reflows to 120 columns and ordered lists keep their 1., 2., 3. numbering (configured in .prettierrc.json).
  • PR and issue templates under .github/ are unwrapped rather than wrapped, because GitHub renders every newline in a PR or issue body as a line break.
  • The static archives under docs/plans/ and docs/research/, and the vendored assets under han-reporting/skills/html-summary/assets/, are left untouched (.prettierignore).

Shell scripts are linted with ShellCheck. A script's tests sit next to it as a *.bats file in the same directory (for example han-coding/skills/code-review/scripts/detect-review-context.sh is covered by detect-review-context.bats in that same directory); harness-level checks that aren't tied to one script live in test/. npm test discovers every *.bats file in the repo outside node_modules. Tests run in CI rather than on commit; run them locally with npm test.

Which plugin does the change belong in?

Han ships as a family of plugins. Most carry components; the han meta-plugin bundles the others. Decide where your change goes before you scaffold anything. (For the user-facing version of this map, see Choosing a Han plugin.)

  • han-communication is the foundational plugin beneath every other. It owns the canonical readability standard, the writing-voice profile, and the explanation standard for talking to a reader who will not implement the work, plus the readability-guidance and explanation-guidance skills that surface them, the edit-for-readability skill, and the readability-editor agent, and the Han Readability and Han Concise output styles in han-communication/output-styles/. It depends on nothing; the plugins that produce prose output depend on it. A component goes here only when it is part of a shared communication capability: how output reads, or how a run talks to a person.
  • han-core carries the shared specialist agent roster — every agent in the suite except the readability-editor (which lives in han-communication), the research-analyst (which lives in han-research), and the discussion-facilitator (which lives in han-planning) — plus the project-discovery skill and the canonical evidence and YAGNI rule files. New agents go here by default. A skill goes here only when it is shared infrastructure the whole suite leans on, like project discovery. han-core depends on no other Han plugin.
  • han-documentation carries the documentation skills (project-documentation, architectural-decision-record, runbook). A skill goes here when its job is writing down what the team built and decided: feature and system docs, decision records, or operational knowledge. It depends on han-communication and han-core and is bundled by the han meta-plugin.
  • han-research carries the pre-planning knowledge-work skills (research, gap-analysis, issue-triage) plus the research-analyst agent. A skill goes here when its job is understanding a problem before anyone commits to a plan. It depends on han-communication and han-core and is bundled by the han meta-plugin.
  • han-planning carries the planning skills (plan-a-feature, plan-implementation, plan-a-phased-build, plan-work-items, iterative-plan-review). A skill goes here when its job is specifying what a feature does, planning how to build it, sequencing the build, breaking it into work, or stress-testing a plan before implementation. It depends on han-communication and han-core and is bundled by the han meta-plugin.
  • han-coding carries the coding skills (tdd, refactor, code-review, code-overview, architectural-analysis, automated-test-planning, manual-test-planning, investigate, coding-standard). A skill goes here when its job is working directly in code: writing it, reviewing it, analyzing it, testing it, investigating it, or standardizing it. It depends on han-communication and han-core and is bundled by the han meta-plugin.
  • han-github carries the GitHub-facing skills (post-code-review-to-pr, update-pr-description, work-items-to-issues). A skill goes here when it reads from or writes to GitHub through the gh CLI.
  • han-reporting carries the stakeholder-reporting skills (stakeholder-summary, html-summary). A skill goes here when its output is a report for a non-technical or executive audience rather than an engineering artifact.
  • han-feedback carries the single han-feedback skill. A skill goes here only when it captures feedback on the Han suite itself.
  • han-atlassian carries the Atlassian-facing skills (markdown-to-confluence, project-documentation-to-confluence, investigate-to-confluence, code-overview-to-confluence, plan-a-feature-to-confluence, work-items-to-jira). A skill goes here when it publishes a Han artifact to Confluence or Jira through the Atlassian MCP server. It is opt-in, requires a configured Atlassian MCP server, and depends on han-core, han-documentation, han-planning, and han-coding because its wrapper skills run skills from each, plus han-communication because those wrapped prose-producing skills source the shared readability standard.
  • han-linear carries the single work-items-to-linear skill. A skill goes here when it publishes Han work items to Linear through the Linear MCP server. It is opt-in, requires a configured Linear MCP server, and depends on no other Han plugin.
  • han-plugin-builder carries the contributor authoring guidance (the guidance skill and its reference set, plus the interview-driven skill-builder and agent-builder skills). It is opt-in and depends on nothing. Edit it when you change how skills, agents, or plugins are built; it is not where product-facing skills go.
  • han is the meta-plugin. It has no components of its own; it depends on han-communication, han-core, han-documentation, han-research, han-planning, han-coding, han-github, and han-reporting so one install pulls them all in. han-feedback, han-atlassian, han-linear, and han-plugin-builder are deliberately left out so they stay opt-in. You add a component to han only by adding it to one of the child plugins; you never put a skill or agent directly in han.

Two rules keep the dependency direction clean:

  • Every plugin whose skills dispatch shared agents depends on han-core, so a skill in han-documentation, han-research, han-planning, han-coding, or han-github may dispatch any han-core agent freely. That is why nearly all agents live in han-core — the exceptions are the readability-editor, which lives in the foundational han-communication plugin alongside the readability skills and which every prose-producing plugin reaches by declaring a direct dependency on han-communication; the research-analyst, which lives in han-research because only the research skill dispatches it; and the discussion-facilitator, which lives in han-planning because only plan-implementation dispatches it. han-reporting, han-feedback, and han-linear dispatch no shared agents and so carry no han-core dependency.
  • han-core depends on no other Han plugin. It reaches nothing in the plugins above it; a han-core skill that needs a capability from one of those means the capability belongs in han-core. Nothing in han-core sources the readability standard either, so it carries no edge to han-communication. Both plugins are foundations the layers above them draw on independently.

When a change adds, removes, or moves a skill between plugins, update the marketplace registry at .claude-plugin/marketplace.json so the plugin's component set stays accurate. Long-form docs always live under docs/ regardless of which plugin the entity ships in.

Adding a skill

  1. Decide the plugin using Which plugin does the change belong in? above, then scaffold the folder under that plugin's skills/{name}/ directory (han-communication, han-core, han-documentation, han-research, han-planning, han-coding, han-github, han-reporting, han-feedback, han-atlassian, han-linear, or han-plugin-builder) and add a SKILL.md.
  2. Write the SKILL.md:
    • Frontmatter with name, description, allowed-tools. See skill-description-frontmatter.md.
    • Body: numbered steps, ${CLAUDE_SKILL_DIR} paths for script references, extracted references under references/.
    • If the skill reads .han/config.md, copy the personal config directory probe and its matching Bash(bash "${CLAUDE_PLUGIN_ROOT}/scripts/han-config-dir.sh") grant from any existing skill. The probe must run that script rather than name an environment variable, or the loader refuses it and the skill never runs. See context-injection-commands.md.
  3. Copy the skill template into {plugin}/docs/skills/{name}.md and fill it in. Every skill gets a long-form doc. If the skill runs inline in a calling skill's context and returns no artifact, follow the inline-guidance variant in the coverage rule instead.
  4. Add a scent line to the plugin's README.md and one alphabetized entry to the skills index, both reusing the long-form doc's own summary line as the canonical scent so the three do not drift.
  5. Add the skill to the catalog in Root CLAUDE.md. The indexes and concept docs list skills without a running total, so there is no count to bump. If the skill belongs to a new category, add it to the category lists too.
  6. If the skill classifies its work as small / medium / large, add it to the sizing-aware list and the at-a-glance table in Sizing, to the sizing-aware list in Concepts, and give its long-form doc a ## Sizing section. A sizing-aware skill that never lands in those catalogs is invisible to anyone reading them to learn which skills scale.
  7. If the skill chains with others, add the chain to Workflows, in both the prose and the mermaid diagram for that workflow.
  8. Update the marketplace registry at .claude-plugin/marketplace.json if the new skill ships in a different plugin's component set.

Adding an agent

  1. Create han-core/agents/{name}.md with frontmatter (name, description, tools, model) and the agent body. New agents live in han-core by default; an agent moves out only when a single skill family in one plugin above han-core dispatches it exclusively. Today that is the readability-editor, living in han-communication with the readability skills it serves; the research-analyst, living in han-research with the research skill that dispatches it; and the discussion-facilitator, living in han-planning with plan-implementation. See agent-domain-focus.md for how narrow and named the domain vocabulary should be.
  2. Copy the agent template into {plugin}/docs/agents/{name}.md (usually han-core) and fill it in. Every agent gets a long-form doc.
  3. Add a scent line to the plugin's README.md and one alphabetized entry to the agents index, both reusing the long-form doc's own summary line as the canonical scent.

Splitting an existing agent

An agent that both produces an artifact and judges one violates the one-role rule in agent-domain-focus.md: the reasoning that creates a blind spot also grades it as correct. When you find one, split it in four steps.

  1. Apply the generate-or-evaluate test. An agent with two named modes is not automatically a split. Two modes that both evaluate (the junior-developer) or a skeptical posture toward someone else's findings followed by a recommendation (the two architects) are single roles. A split is warranted when one half authors the artifact and the other half grades an artifact.
  2. Place each half by its own callers, not the combined agent's. The combined agent's caller set says nothing about where each half belongs. Default to han-core, and move a half out only when a single skill family in one plugin dispatches it exclusively.
  3. Grep the whole repo for the old name and repoint everything. Call sites are the smallest part. Also repoint dead links to the deleted long-form doc, prose mentions in the skill long-form docs, plugin manifest descriptions, and any artifact field label that carried the old name.
  4. Run the four-surface coverage rule for each resulting agent. Agent definition, long-form doc, plugin README scent line, and agents-index entry, per the coverage rule.

Adding an output style

  1. Create han-communication/output-styles/{name}.md with frontmatter (name, description, keep-coding-instructions) and the instruction body. An output style is text Claude Code appends to the system prompt at session start, so write it as instructions to follow, not as documentation about itself. The directory is auto-discovered, so plugin.json needs no field for it.
  2. Copy the output-style variant of the skill template into han-communication/docs/output-styles/{name}.md and fill it in. Every output style gets a long-form doc.
  3. Add a scent line to the plugin's README.md, reusing the long-form doc's own summary line. There is no repo-root output-styles index; add one when a second plugin ships a style.
  4. A style derived from readability-rule.md or writing-voice.md says so in its long-form doc. Record any place it departs from the canonical file as deliberate in the CLAUDE.md doc map, so a later sync pass does not read the difference as drift.

Wiring the readability standard into a skill

A skill is reader-facing when its primary deliverable is human-facing prose that a non-author reads end to end to understand something: a finding, a summary, a plan of record, a document. If the skill you are adding fits that description, it applies the shared Readability standard. A structured specification, plan, phased build, work-item list, coding standard, or test plan counts too when a human reads it end to end. Skills whose output is code, or a structured artifact consumed only by downstream skills as machine input with no human reading it end to end, are out of scope and skip this section.

There is a second, narrower standard beside it. The explanation standard governs what a run says to a person in a turn: an escalation, a confirmation, a stop for a missing input. Readability governs the shape of a written deliverable. A skill that both drafts a document and stops to ask questions wires in both, sourcing readability at its drafting point and invoking han-communication:explanation-guidance at the point it talks to the operator. A skill that never asks a question needs only the readability wiring below.

The inclusion test is the guide; the enumerated list in Readability is authoritative. When a new skill passes the test, add it to that list and wire the standard in:

  1. Declare the dependency on han-communication. The canonical rule and writing-voice profile live in han-communication/references/; no plugin vendors a copy. If the skill's plugin does not already depend on han-communication, add the direct dependency edge to its plugin.json so the capability resolves by qualified name. (han-linear and han-feedback host no prose-producing skill, so they carry no edge.)
  2. Embed the structural rules in the output template. The skill's output template carries main-point-first, descriptive front-loaded headings, one-idea-per-paragraph, numbered lists for steps and bullets for the rest, and progressive disclosure, so the draft is born structured.
  3. Source the standard and apply it, with an audience frame. The skill invokes han-communication:readability-guidance at its drafting point to surface the rule and writing-voice profile into its own context, then applies them while holding the audience frame: a capable reader who did not do the work. If the skill's real reader is a specific expert (an engineer, a pull-request reviewer, a non-technical stakeholder), name that reader instead of defaulting. Scope the frame per section so technical specifics the reader needs are not simplified away.
  4. Add the standardized self-check. Before presenting, the skill runs behaviorally-anchored yes/no criteria over the prose regions only: main point first, descriptive headings, one idea per paragraph, sentence length, common words with no blocklisted word and an explanation for every term the reader cannot look up, every fact preserved. It corrects any failure. Leave code fences, diagram bodies, rendered markup, and citation identifiers unevaluated and unchanged.
  5. Wire the rewrite pass only if the skill synthesizes. If the skill has a synthesis or editor step (a distinct pass, after the full draft exists, that reviews or consolidates the whole draft before presenting it), dispatch the readability-editor agent after the draft is written and before the self-check. It reads han-communication's own canonical rule, so pass no rule path; it rewrites the draft, preserving every fact. Where the skill already ran a readability pass of its own, the dedicated reviewer replaces it rather than stacking a second pass on top. A synthesis skill that cannot dispatch an agent today gains that capability as part of wiring the standard in.

Keep the applied set tight. The rule is applied in stages (template, then a discrete self-check, plus the rewrite pass for synthesis skills), never as one stacked instruction block.

Editing an existing long-form doc

The docs follow a strict template. Before changing a section's shape, check docs/templates/skill-long-form-template.md or docs/templates/agent-long-form-template.md so the change stays consistent across peers.

If you are adding a section that is not in the template but applies to several skills or agents, raise it as a template change first. Drift across peer docs is worse than a missing section.

Writing voice

All han documentation follows the writing voice profile in han-communication/references/writing-voice.md. The most load-bearing rules:

  • Em-dashes only in two positions: separating a label from its gloss in a scent line or definition bullet, and setting off a parenthetical or appositive aside. Anywhere else, use a period, colon, comma, or parentheses.
  • Direct second person ("you"), mentor-tone, plainspoken. No flattery, no hype words.
  • Avoid "leverage," "utilize," "showcase," "robust" (as a vague positive), "actually," "just," "It's worth noting," "Importantly," and similar AI-slop tells.
  • Open with context or history, not a thesis statement.

The full voice profile names the prohibited words, the preferred sentence rhythms, and the structural moves the docs use.

Documentation conventions

  • One canonical source per concept. The long-form doc is canonical. The Skills Index and Agents Index carry scent only. One sentence plus a link. The README never duplicates long-form content.
  • Every long-form doc links up. The Related Documentation section's first bullet points back to the doc's own plugin README, and the second to the repository root. A reader arriving cold via search must be able to get to the front door in one click.
  • Orientation frame on top. The first two lines of every long-form doc state what the page is, who it is for, and where the internal definition (SKILL.md or agent .md) lives.
  • TL;DR before anything else. Three lines: what / when / what-you-get-back. Scannable for readers doing reference lookup.
  • YAGNI applies to docs too. Doc sections that fail the YAGNI evidence test (speculative usage notes, for-future-flexibility warnings, examples for behavior the skill doesn't have yet) are not added. The same evidence rule that gates plan steps and code recommendations gates documentation.

Reviewing your own changes

Before opening the PR, run through this checklist:

  • Frontmatter is valid (no XML, no reserved prefixes, description under 1024 characters).
  • allowed-tools matches actual usage; Bash permissions are per-prefix, not wildcards.
  • Context injection commands (!`command`) are simple; complex operations live in scripts.
  • Long-form doc follows the template.
  • The skill or agent appears in the right index, at the right group, with accurate scent.
  • Internal links resolve.
  • Em-dashes appear only as a label-gloss separator or an appositive aside, never standing in for a sentence break.
  • No "actually," "just," "leverage," "utilize," "showcase," "robust" (vague), "It's worth noting," "Importantly," or other voice violations.
  • npm run lint passes.
  • npm run test passes.

Related Documentation