Turn on Loom's ponytail skill for every session, with level switching.

<img src="assets/loom-logo.svg" width="160" height="160" alt="Loom's woven purple logo">
Loom sets up coding agents with shared skills, pinned tools, Pi packages, and project instructions. Its skills cover the path from an early idea to a tested pull request.
Use Loom with Pi (recommended), Claude Code, Codex, OpenCode, Cursor, Grok, or any agent that reads an Agent Skills folder.
Prefer to set things up yourself? Follow the manual installation guide for skills, tools, MCP servers, and agent-specific packages.
macOS or Linux:
curl -fsSL https://raw.githubusercontent.com/Yassimba/loom/main/install.sh | sh
Windows:
powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://raw.githubusercontent.com/Yassimba/loom/main/install.ps1 | iex"
The installer adds mise, Node.js, and the loom command. It then opens a menu for skills, tools, and Pi packages. Choose Everything or select only what you need. Loom shows the full plan before it changes your machine.
Native Windows is supported. Use WSL2 for Linux-only tools such as Herdr:
wsl --install -d Ubuntu
Run the macOS or Linux install command inside Ubuntu.
loom status
cd your-project
loom init
pi. Use the implement skill to build the CSV export ticket.
loom init can create agent instructions, issue tracking, domain notes, coding standards, and editor links. When Codebase Memory is installed, it also creates a fast initial graph index and adds a short code-intelligence section to AGENTS.md. Run loom init --yes to accept the detected defaults.
Interactive setup can enable ADHD-friendly Pi responses. It installs i-have-adhd and writes the Pi flag under ~/.pi/agent or PI_CODING_AGENT_DIR. Run /reload in Pi after enabling it.
When Pi is installed or selected, Loom automatically installs pi-loom for its Loom header and startup update notice.
Start with the skill that matches the current state of the work.
| You have | Start with |
|---|---|
| An early idea | brainstorming |
| Unresolved design decisions | grill-me |
| A codebase that is hard to change | improve-codebase-architecture |
| An agreed plan | to-spec or to-tickets |
| A bug | diagnosing-bugs |
| Unnecessary complexity in a ticket | cleanup |
| Completed tickets that need a structural pass | refactor |
| A completed change that needs a real-world check | e2e-test |
<a href="assets/loom-workflow.png"> <img src="assets/loom-workflow.png" width="1200" alt="Loom workflow from brainstorming and architecture through the per-ticket implementation, review, and cleanup loop, then refactoring, end-to-end testing, and release"> </a>
Repeat implement -> code-review -> cleanup for each ticket. When all tickets are complete, continue with refactor -> e2e-test -> release.
implement finds the next actionable ticket when you do not name one. It uses ponytail, blueprint, tdd, and code-review as needed. release runs the repository checks, asks before committing remaining changes, pushes the branch, and opens a pull or merge request.
Browse every skill in skills.sh.json or the loom add menu. If a skill is missing, install it with its dependencies:
loom add --skill implement --yes
Run loom add to browse, or select items directly:
loom add --skill tdd --yes
loom add --tool gh --tool gitleaks --yes
loom add --pi-package add-dir --yes
loom add --skill tdd --agent codex --yes
loom add --skill tdd --agent claude --scope project --yes
Loom installs skills in the global folders of detected agents by default. Use --agent to choose an agent or --scope project to install in the current repository. Add --dry-run to preview changes.
loom update
loom update refreshes only the items you selected. It does not add new capabilities.
loom uninstall
loom uninstall --skill tdd --pi-package add-dir --yes
loom uninstall --all --yes
loom uninstall --dry-run --all
Loom keeps modified files by default. Interactive runs ask before deleting them; scripts require --force-modified.
Uninstall removes Loom's tool selection, not shared runtimes. It preserves mise, runtime binaries, PATH entries, and shell activation.
Install Pi packages through loom add, or install one directly:
pi install npm:@yassimba/pi-fast
pi install npm:@yassimba/pi-guardrails
pi install npm:@yassimba/pi-skill-autocomplete
pi install npm:@yassimba/pi-loom-mermaid
| Package | What it adds |
|---|---|
pi-fast | /fast priority requests for OpenAI, Codex, and xAI |
pi-guardrails | Safety checks plus /add-dir trusted workspace roots |
skill-autocomplete | $ skill completion in the editor |
pi-loom-mermaid | Colored Mermaid diagrams with cleaner routing |
pi-loom-mermaid adds class colors, visible hops where lines cross, and shorter routes around complex graphs. The same flowchart shows the difference:
| Pi built-in | pi-loom-mermaid |
|---|---|
![]() | ![]() |
| One gray style and stacked outer routes | Class colors, crossing hops, and shorter routes |
Open either image for the full-size comparison. See the pi-loom-mermaid guide for setup, usage, and more examples.
Loom installs Pi's standalone skills in .agents/skills. Start Pi from the project root so its .pi/settings.json applies. manifest/pi-packages.json lists the current package names and versions.
MCP connects Pi to extra tools. Loom offers two reviewed servers:
| Server | What it adds |
|---|---|
| Codebase Memory | Local repository graph and change-impact analysis |
| Context7 | Hosted library documentation and code examples |
loom add --mcp-server codebase-memory-mcp --agent pi
Loom installs the selected local binaries, shared Pi MCP adapter, and a non-blocking routing extension that nudges agents toward Codebase Memory after repeated native searches. Add --scope project for project-only server configuration; binaries, Pi, and packages remain machine-wide. All tools use gateway-only exposure. Loom restricts Codebase Memory to its read-only analysis profile. Run loom init in each repository, then restart Pi and open /mcp to check the connections.
Context7 queries leave the machine. Codebase Memory runs as a local stdio server.
Run loom wiki to create a Vault or adopt an existing Obsidian directory. Each Vault gets a named QMD search index and project-local wiki skills.
loom wiki
loom wiki status
loom wiki repair /path/to/Vault
loom wiki unregister /path/to/Vault
The index is a snapshot, so run repair after editing notes. unregister removes Loom's machine record without deleting notes. If you enable Confluence export, CME stores its credentials as owner-only plaintext.
loom wiki sessions /path/to/Vault copies your Claude Code, pi, OpenCode and Amp sessions into the Vault as Markdown, below the Git-ignored .raw/agent-sessions/, and adds them to the Vault's QMD search as the agent-sessions collection. Each file keeps prompts, answers and one line per tool call. Tool output and thinking are dropped, token-shaped strings are redacted, and subagent sessions are skipped. Amp threads are fetched with the amp CLI.
After that first run, loom wiki sessions syncs every Vault that has sessions on, converting only sessions that changed. Pi (through pi-loom) and Claude Code (through the loom-sessions plugin) run it in the background at session start, so a session reaches the Vault when your next session starts.
loom wiki sessions ~/notes
claude plugin install loom-sessions@loom
Session copies can contain secrets that redaction misses. Keep the Vault on your own machine.
Use the Vercel skills CLI to install Loom skills directly into OpenCode, Claude Code, Codex, Cursor, or another supported agent:
npx skills add Yassimba/loom
The command lets you choose the agent, skills, and global or project scope. For a non-interactive OpenCode install:
# All public Loom skills, for your user account
npx skills add Yassimba/loom --agent opencode --skill '*' --global --yes
# One skill, in the current project
npx skills add Yassimba/loom --agent opencode --skill tdd --yes
Use --agent '*' to install for every detected agent. Run npx skills update --global to update global installs.
Claude Code users can install Loom as a plugin instead:
/plugin marketplace add Yassimba/loom
/plugin install loom@loom
These methods install skills, not Loom's pinned command-line tools or Pi packages. Follow the manual installation guide to add command-line tools, MCP servers, and agent-specific packages.
| Path | Contents |
|---|---|
skills/<name>/SKILL.md | Reviewed public skills |
plugins/<name>/ | Pi packages |
manifest/ | Pinned tools and setup metadata |
cli/loom/ | Rust CLI |
drafts/ | Unreviewed, unpublished skills |
personal/ | Machine-specific skills that are never published |
npm install.drafts/ and machine-specific skills in personal/.npm run catalog:generate after changing a public skill or package entry.npm run check. After code changes, also run npm run audit.Run npm run check:js or npm run check:rust for a narrower check. See AGENTS.md for sync rules and repository conventions.
Skills in this repository draw from work by Matt Pocock, DataDog/pup, pbakaus/impeccable, ayghri/i-have-adhd, DietrichGebert/ponytail, and cathrynlavery/diagram-design. The modularity skills and Balanced Coupling reference are adapted from Vlad Khononov's modularity project. Licenses and pinned source versions for imported skills are recorded in their deps.yml files.
Pi subagents, web access, and rewind draw from nicobailon's Pi packages. Anthropic sign-in draws from gotgenes/pi-anthropic-auth. pi-loom-mermaid draws from pi-lovely-mermaid.
hooks/register.ts 65 lines1import type { PromptSubmitInput, Register } from "claude-code";
2import { atom, read, update } from "claude-code";
3import type { Level } from "../types";
4
5const LEVELS: readonly Level[] = ["lite", "full", "ultra", "off"];
6const STOP = /\b(stop ponytail|normal mode)\b/i;
7
8const level = atom({ plugin: "ponytail-mode", key: "level" } as const, "full" as Level);
9
10// The rules stay in the ponytail skill. This section only points at it, so the
11// skill is the one copy of the rules: the mod cannot read loom's skills/ folder
12// once the marketplace installs the mod folder alone.
13function section(current: Level): string {
14 return [
15 `Ponytail mode is on, level: ${current}.`,
16 "Before your first reply to a coding task, load the `ponytail` skill with the Skill tool,",
17 "and apply it to every reply for the rest of the session.",
18 'Switch the level with `/ponytail lite|full|ultra`. "stop ponytail" or "normal mode" turns it off.',
19 "A later message that sets a new level or turns ponytail off overrides this section.",
20 ].join("\n");
21}
22
23// The engine composes the system prompt once per session (again only after a
24// compaction or a resume), so a switch cannot reach the model through the
25// section. The switch goes beside the prompt that made it, and the transcript
26// keeps it for the rest of the session.
27function note(chosen: Level): string {
28 return chosen === "off"
29 ? "Ponytail mode is now off. Ignore the ponytail section of the system prompt from this reply on."
30 : `Ponytail mode is now on, level: ${chosen}. Load the \`ponytail\` skill if it is not loaded, and apply that level from this reply on.`;
31}
32
33function chosenLevel(e: PromptSubmitInput): Level | undefined {
34 if (e.command) {
35 const word = e.command.args.trim().split(/\s+/)[0]?.toLowerCase();
36 return e.command.name === "ponytail" ? LEVELS.find((name) => name === word) : undefined;
37 }
38 return STOP.test(e.text) ? "off" : undefined;
39}
40
41export const register: Register = (on) => {
42 on("prompt.submit", async ($, e, next) => {
43 const chosen = chosenLevel(e);
44 if (!chosen) {
45 return next(e);
46 }
47 await update($, level, () => chosen);
48 return next({ ...e, context: [...(e.context ?? []), note(chosen)] });
49 });
50
51 on("prompt.compose", async ($, e, next) => {
52 const result = await next(e);
53 const current = await read($, level);
54 if (current === "off") {
55 return result;
56 }
57 return {
58 sections: [
59 ...result.sections,
60 { id: "ponytail-mode:rules", text: section(current), scope: "session" as const },
61 ],
62 };
63 });
64};
65types/index.d.ts 9 lines1/** How hard the ponytail skill pushes for less code; `off` sends no ponytail section. */
2export type Level = "lite" | "full" | "ultra" | "off";
3
4declare module "claude-code" {
5 interface PluginState {
6 "ponytail-mode": { level: Level };
7 }
8}
9