Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/SKILL_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ name: example-skill
description: >-
One or two sentences: what the skill does, plus when_to_use cues
(e.g. "Use when asked to …, or for …"). Keep the full description
within 1,536 characters.
within 1,024 characters.
maturity: stable
---

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ Your `skill.md` should include YAML frontmatter plus body content:
```yaml
---
name: <slash-command-name>
description: <≤1,536 chars including when_to_use cues>
description: <≤1,024 chars including when_to_use cues>
maturity: stable # experimental | stable | deprecated
---
```
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ domains/<area>/
```yaml
---
name: <slash-command-name>
description: <≤1,536 chars including when_to_use cues>
description: <≤1,024 chars including when_to_use cues>
maturity: stable # experimental | stable | deprecated (default stable)
---
```
Expand All @@ -393,7 +393,9 @@ base bypass, so `--maturity stable` drops a `base: true` experimental skill.
A skill with a `repos/` directory and no overlay for `--repo` is skipped
(this `analytics` skill installs for Mobile and is skipped for Extension).

The 1,536-character ceiling is a repo budget rather than an operator limit — the
The 1,024-character ceiling tracks the strictest operator rather than an opinion
about ideal length — descriptions well over 1,024 install and load in Claude Code,
but the pi coding agent warns about any description over 1,024 characters at startup. The
description is always-on context for every installed skill, so it is capped
deliberately. It is enforced by `yarn audit:skills` from
[`tools/skill-schema.mjs`](tools/skill-schema.mjs), which is the source of truth.
Expand Down
2 changes: 1 addition & 1 deletion domains/performance/skills/performance/skill.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
name: performance
description: Use for any performance question about the MetaMask Mobile React Native app, at any stage. Trigger when: a screen, list, or interaction feels slow, laggy, or janky (account/network switching, scrolling, typing, FPS drops); planning a feature with real-time/websocket data, frequent updates, or large lists and wanting to avoid perf pitfalls before building; reviewing or auditing PRs/code for excessive re-renders, broken selector memoization, Context providers, hook deps, or bundle bloat; making the app faster for power users with many accounts/assets; measuring time-to-interactive, render counts, or FPS and surfacing them in Sentry; analyzing a captured `.cpuprofile` / React Native Release Profiler trace (e.g. a `sampling-profiler-trace*.cpuprofile`) to find why a flow is slow; or adding render-regression tests so CI catches slowdowns. Covers re-renders, reselect memoization, FlashList, Reanimated, TTI, bundle size, trace() instrumentation, and Release Profiler CPU-profile analysis. Not for correctness bugs, styling/spacing, Solidity gas, or the browser extension.
description: Use for any performance question about the MetaMask Mobile React Native app. Trigger when: a screen, list, or interaction feels slow, laggy, or janky (account/network switching, scrolling, typing, FPS drops); planning a feature with real-time/websocket data, frequent updates, or large lists; reviewing or auditing PRs/code for excessive re-renders, broken selector memoization, Context providers, hook deps, or bundle bloat; making the app faster for power users with many accounts/assets; measuring time-to-interactive, render counts, or FPS and surfacing them in Sentry; analyzing a captured `.cpuprofile` / React Native Release Profiler trace to find why a flow is slow; or adding render-regression tests so CI catches slowdowns. Covers re-renders, reselect memoization, FlashList, Reanimated, TTI, bundle size, trace() instrumentation, and CPU-profile analysis. Not for correctness bugs, styling/spacing, Solidity gas, or the browser extension.
base: true
---
31 changes: 12 additions & 19 deletions domains/swaps/skills/swaps-cpu-profile-audit/skill.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,18 @@
name: swaps-cpu-profile-audit
description: >-
Parse an already-recorded Hermes / React Native Release Profiler
`.cpuprofile` (ideally symbolicated with source maps) and audit it for slow
frames on the swaps/bridge screen and the modals or subpages it opens —
quote select screen, post-trade modal, batch sell, asset picker/token
selector. Use when a user hands you a `.cpuprofile` file (e.g. a
`sampling-profiler-trace*.cpuprofile`, or its already-converted
`*-converted.json`) recorded per `docs/readme/release-build-profiler.md` and
asks to audit, analyze, explain, or find why the swaps/bridge flow is slow
based on that trace. This is an offline, file-based analysis — no simulator,
device, Metro, or `mm` session is required, unlike `swaps-perf-audit` (which
measures live render counts on a running simulator). The audit accounts for
ALL time in the capture, not just swaps-owned code: non-swaps frames that
ran while the user sat on a swaps screen (navigation, redux, design system,
polling controllers, React internals) are reported too, each labelled with
whether the swaps team owns it and how it relates to the swaps call stacks.
The report always leads with a timing table (capture metrics + by-area self
time with an ownership column) and a short outcome line, and only adds a
probable-cause/fix table when there is an actual issue — deep fixes are
proposed for swaps-owned rows, while non-owned rows are named and routed.
MetaMask Mobile only.
`.cpuprofile` and audit it for slow frames on the swaps/bridge screen and
its modals (quote select, post-trade, batch sell, asset picker). Use when a
user hands you a `.cpuprofile` (e.g. `sampling-profiler-trace*.cpuprofile`)
and asks to audit, analyze, or explain why the swaps/bridge flow is slow.
Offline, file-based analysis — no simulator, device, Metro, or `mm` session
required, unlike `swaps-perf-audit` (live render counts on a running
simulator). Accounts for ALL time in the capture, not just swaps-owned code:
non-swaps frames (navigation, redux, design system, polling controllers,
React internals) are reported with swaps ownership and relation to the swaps
call stacks. The report leads with a timing table and a short outcome line;
a probable-cause/fix table appears only for actual issues. MetaMask Mobile
only.
maturity: stable
---

Expand Down
9 changes: 5 additions & 4 deletions test/lint-skill-entry.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,11 @@ describe('schema tracks the installer', () => {
// The workflow invokes the linter WITH changed-file arguments. Every test above runs the
// no-argument full-audit branch, so the branch CI actually depends on had no coverage —
// which is how malformed paths reached main. These mirror the CI invocation.
// 1,536 is a repo budget, not an operator limit — no observed operator rejects or
// truncates a longer description, and several over 1,024 install and load today. The
// check exists to bound always-on context, so what matters is that the number the docs
// state and the number enforced are the same one.
// 1,024 tracks the strictest operator observed so far: descriptions well over 1,024
// install and load in Claude Code, and the pi coding agent loads longer ones too but
// warns about them at startup. The check exists to bound always-on context, so what
// matters is that the
// number the docs state and the number enforced are the same one.
describe('description budget', () => {
test('the enforced ceiling is the one the docs state', () => {
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
Expand Down
14 changes: 8 additions & 6 deletions tools/skill-schema.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@ export const KNOWN_REPOS = ['metamask-extension', 'metamask-mobile', 'core'];
// per-skill always-on cost, and the only part of a skill that carries its own trigger
// cues — cutting it makes the skill less likely to be selected when it is relevant.
//
// This is a REPO BUDGET, not an operator limit. No operator observed here rejects or
// truncates a longer one: `tools/install` emits the value verbatim, and descriptions
// well over 1024 characters install and load in Claude Code today. Treat a lower number
// as a deliberate budget decision, and cite the operator and version before claiming any
// figure is externally imposed.
export const DESCRIPTION_MAX = 1536;
// This number tracks the strictest operator observed so far, not a judgement about the
// ideal length: `tools/install` emits the value verbatim, and descriptions well over
// 1024 characters install and load in Claude Code today. The pi coding agent (v0.85.1,
// docs/skills.md) also loads longer descriptions but flags any over 1024 characters
// with a "[Skill conflicts]" warning at startup — so 1024 is the largest value that
// trips no operator's validation. Raise it only with evidence that no operator warns
// below it.
export const DESCRIPTION_MAX = 1024;

// A base skill installs for every engineer, so its description is always-on
// context — and a description too thin to match anything is the failure mode
Expand Down
Loading