The method every session can draw on: how to look at work before building it, the method skills for design, testing, debugging, refactoring, modelling…

The core method for an agent working beside a senior programmer: ten skills and four agents for design, testing, debugging, delegation and more.
Without a shared method, every session relearns how this person works: it builds before it understands, settles design by default, forgets what an earlier session decided, and either does everything itself or hands everything away. qsm-essentials is that method: the thinking of a senior programmer about a real problem, written as skills and bounded agents an agent applies, not as a summary a plain model already knows. It takes the stance that a skill earns its place only when the agent works measurably better with it than without. It refuses to hold anything specific to a language, a framework, a project or a machine, and refuses to restate what a plain model does well. When the harness ships this method itself, or a plain model matches it, this plugin has no reason to exist.
| Kind | Name | What it does |
|---|---|---|
| Skill | debugging | Finds the root cause of a bug or a flaky test before any fix is tried |
| Skill | distributed-systems | Service boundaries, sync or async, data ownership, failure across a network |
| Skill | domain-modeling | Entities, values, aggregates and where a business rule lives |
| Skill | refactoring | Changes structure without changing behaviour, in steps that each stay working |
| Skill | run-and-verify | Starts the project and proves a change works before anyone says it does |
| Skill | software-architecture | Picks an architecture style, weighs trade-offs, records the decision |
| Skill | software-design | Cuts modules, shapes interfaces and types, decides where complexity lives |
| Skill | software-testing | Decides if a change needs a test and picks the cheapest one that runs the real path |
| Skill | subagents | Writes the task for an agent, splits work, accepts what comes back |
| Skill | writing | Commit messages, tickets, review replies, READMEs, error messages |
| Agent | researcher | Answers where, what and how over a code tree, with file and line citations |
| Agent | runner | Runs one noisy command, keeps the log, returns a short briefing |
| Agent | implementer | Builds one bounded task in its own worktree and proves it end to end |
| Agent | web-research | Answers one question from the web in at most five rounds, with sources |
claude plugin install qsm-essentials@qsm-marketplace
Install adds the skills and agents only. It has no binary and no dependency.
The web-research agent is the default for the web-research role. A plug-in that ships its own agent of that name replaces it, and the role is that agent's; the core one is the one to use when no plug-in does.
Skills fire on the kind of ask, so there is nothing to call.
debugging.distributed-systems.writing.subagents, which then picks implementer, researcher or runner for each.[sonnet] researcher: …), and draws the tier in colour before the Agent row in the transcript.hooks/register.tsx 41 lines1// qsm-essentials' function-hooks module: every agent names its model, and the transcript shows it.
2// The rules are lib/agent-model.ts; the hooks only refuse, tag and draw.
3import type { On } from "claude-code";
4import { NO_MODEL, TIER_COLOR, tagged, tierOf } from "../lib/agent-model.ts";
5
6export function register(on: On): void {
7 on("agent.spawn", (_$, e, next) => {
8 if (e.fork) {
9 return next(e);
10 }
11 if (e.model === undefined || e.model === "") {
12 return { deny: NO_MODEL };
13 }
14 // A workflow agent's content cannot be rewritten; the engine would log the attempt.
15 return e.workflow === undefined
16 ? next({ ...e, description: tagged(e.description, e.model) })
17 : next(e);
18 });
19
20 on("ui.render", { component: "ToolUse" }, async ($, e, next) => {
21 const { input } = e.props;
22 const model =
23 e.props.tool === "Agent" && typeof input === "object" && input !== null && "model" in input
24 ? input.model
25 : undefined;
26 if (typeof model !== "string") {
27 return next(e);
28 }
29 const tier = tierOf(model);
30 const { Box, Text } = $.ui.resolve(e);
31 return (
32 <Box flexDirection="row">
33 <Text color={TIER_COLOR[tier] ?? "gray"} bold>
34 {tier}{" "}
35 </Text>
36 {await next(e)}
37 </Box>
38 );
39 });
40}
41lib/agent-model.ts 25 lines1// Every agent names its model: the tier of a model alias or id, the refusal for a spawn that names
2// none, and the colour the transcript draws each tier in.
3
4const TIERS = ["haiku", "sonnet", "opus", "fable"] as const;
5
6export const TIER_COLOR: Readonly<Record<string, string>> = {
7 haiku: "green",
8 sonnet: "cyan",
9 opus: "magenta",
10 fable: "yellow",
11};
12
13export const NO_MODEL =
14 "Name the model on every agent (haiku, sonnet, opus or fable): an agent left without one inherits the session's model.";
15
16/** The tier word of a model alias or id (`claude-sonnet-5-5` is sonnet), else the model itself. */
17export function tierOf(model: string): string {
18 return TIERS.find((tier) => model.includes(tier)) ?? model;
19}
20
21/** The description with the tier in front, unless it already opens with a bracket. */
22export function tagged(description: string, model: string): string {
23 return description.startsWith("[") ? description : `[${tierOf(model)}] ${description}`;
24}
25