日本語版: README.ja.md
kamae-ts
Kamae (構え) — a stance of readiness.
An extensible harness of skill plugins for designing and implementing robust server-side TypeScript applications. Each skill encodes a kamae — a practiced stance for a specific design concern — that coding agents apply when generating or reviewing code.
The current stances focus on functional domain modeling; more will be added over time.
Overview of Principles
- Represent domain state with Discriminated Unions, avoiding classes
- Define state transitions with pure functions, making invalid transitions compile errors
- Handle errors as values with Result types (neverthrow / byethrow / fp-ts / option-t), avoiding thrown exceptions
- Validate external boundaries with schema validation (Zod / Valibot / ArkType), trusting types inside the domain
- Protect PII at runtime with the Sensitive type
Installation
Via gh skill (the GitHub CLI's agent skills extension):
# Install a single skill (interactive prompt for agent/scope)
gh skill install iwasa-kosui/kamae-ts kamae
# Install non-interactively for Claude Code at user scope
gh skill install iwasa-kosui/kamae-ts kamae \
--agent claude-code --scope user
# Pin to a specific release
gh skill install iwasa-kosui/kamae-ts [email protected]
Or via skills CLI:
npx skills add iwasa-kosui/kamae-ts
Provided Skills
kamae
Triggered when writing server-side TypeScript code (domain models, use cases, repositories, state transitions, error handling, boundary validation, PII protection). Guides code generation through a thin dispatcher SKILL.md that lazy-loads topic sub-files (domain-modeling.md, state-modeling.md, error-handling.md, boundary-defense.md, declarative-style.md, test-data.md) and library-specific guides only when relevant.
kamae-review
Triggered during code review. Walks a checklist of severity-tagged review items (split across checklist/*.md sub-files) and reports findings citing the canonical principle in kamae. Depends on kamae being installed for the knowledge base — install both together.
Customization via Rules
Both skills load applicable rules at the start of each invocation, in priority order:
.claude/rules/*.md(project)~/.claude/rules/*.md(user-global)- The plugin's own
rules/defaults/*.md
A rule applies to kamae-ts when its frontmatter declares applies-to: kamae, applies-to: kamae-review, or applies-to: "*". Four rule types are supported:
library-preference— pin a specific Result or validation library (overrides auto-detection)check-toggle— disable a named review check (e.g., PII protection for projects with no personal data)convention— declare project-specific conventions (e.g., "Branded Types live insrc/types/brand.ts")override— replace specific guidance from a topic sub-file
See rules/README.md for the rule format and concrete examples.
For full skill replacement, use Claude Code's standard skill path-shadowing (.claude/skills/kamae/SKILL.md overrides the installed plugin's).
Evaluation
Skill quality is continuously evaluated with microsoft/waza.
- Suites live under
evals/kamae/andevals/kamae-review/. .github/workflows/eval.ymlruns both suites on everypull_requestthat touchesskills/**,evals/**,rules/**, or.waza.yaml, using thecopilot-sdkexecutor.- See ADR 0001 for adoption rationale and preconditions.
Documentation
A reading version of the principles is published at https://iwasa-kosui.github.io/kamae-ts/, in both English (/en/) and Japanese (/ja/).
Community
Join the official Discord server to discuss server-side TypeScript, ask questions, and share what you are working on: https://discord.gg/Z9HVbqEWzd
- See the community page for channel layout and what kind of conversation happens there.
- Both this GitHub repository and the Discord server are governed by the Code of Conduct (Contributor Covenant v2.1).
Reference Articles
These principles are based on the following articles:
- Complex state transitions: Expressing state definitions and transitions with functions and Discriminated Unions instead of classes
- Implementing the State pattern with Discriminated Unions
- Designing TypeScript code for easy domain event recording
- Why you should avoid method notation in TypeScript
- Why I prefer type over interface in TypeScript
- Preventing PII leaks in logs: TypeScript type inference and runtime boundaries
- How to teach server-side TypeScript's type system
- as const satisfies is useful for TypeScript tests
- Declarative array operations in TypeScript
- TypeScript class pitfalls for developers from other languages
License
MIT
No comments yet
Be the first to share your take.