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
137 changes: 137 additions & 0 deletions .agents/skills/repo-skill-authoring/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
name: repo-skill-authoring
description: Create and update repo-local skills that follow the MetaMask Mobile standard. Use for new repo-local skills, skill entrypoints, or harness shims in this repository.
---

# Repo Skill Authoring

Canonical guidance for creating and updating repo-local skills in MetaMask Mobile.

## Purpose

Use this standard when the repo needs a reusable agent workflow with stable instructions, validation, or harness shims.

Do not create a skill when one of these is enough:

- `AGENTS.md` or a narrow `tests/AGENTS.md` pointer
- Existing product or engineering docs in `docs/`
- A one-off prompt that does not need to be reused

Create a skill when the work is repeated, fragile, or benefits from a shared workflow across agents.

## When To Use This vs Native Skill Creator

Use the native or harness-provided `skill-creator` guidance for general skill design principles or when creating a skill outside this repository.

Use `repo-skill-authoring` for any MetaMask Mobile repo-local skill that should live in `.agents/skills/`, `.claude/`, or other repo-owned harness folders.

If both apply, use native `skill-creator` for general design guidance, and use this skill as the source of truth for repository-specific structure, naming, and entrypoints.

## Harness Entrypoints

Use these entrypoints:

- Codex skill entrypoint: `.agents/skills/repo-skill-authoring/SKILL.md` (`$repo-skill-authoring`)
- Claude skill entrypoint: `.claude/skills/repo-skill-authoring/SKILL.md`

## Repo Skill Shape

Required shape for a repo-local skill:

```text
.agents/skills/<skill-name>/SKILL.md
.agents/skills/<skill-name>/agents/openai.yaml
```

Optional shape, when the workflow needs it:

```text
.agents/skills/<skill-name>/scripts/
.agents/skills/<skill-name>/references/
.agents/skills/<skill-name>/assets/
.claude/skills/<skill-name>/SKILL.md
```

Keep `.agents/skills/<name>/SKILL.md` as the single source of truth. Any harness-specific shim should point directly to it.

## Naming And Trigger Rules

- Skill folder names use lowercase letters, digits, and hyphens only.
- The folder name and `SKILL.md` frontmatter `name` must match exactly.
- The Codex `description` must say what the skill does and when to use it.
- Prefer names that describe the reusable workflow, not the implementation detail.
- Keep the skill focused on repo-local conventions that are not already handled by generic guidance.

## Agent Execution Standard

For agent implementation and review tasks, follow this workflow:

1. Define the user/problem shape.
- Write down the jobs the skill should handle.
- Prefer concrete trigger phrases and in-scope task examples.
2. Split the content deliberately.
- Put the canonical workflow, conventions, and examples in this `SKILL.md`.
- Add `scripts/` only when deterministic validation or repeated logic is worth the maintenance cost.
- Add `references/` only when detailed content should be loaded on demand instead of sitting in the skill body.
3. Add the skill entrypoint.
- Include frontmatter `name` and `description`.
- Keep this file readable by both agents and humans.
4. Add the minimum harness shims required.
- Add `.claude/skills/<name>/SKILL.md` when Claude needs a pointer.
- Point every shim directly back to `.agents/skills/<name>/SKILL.md`.
5. Sanity check the result.
- Confirm the skill and any shims all point to the same workflow.

Authoring principle:

- Keep the repo skill as the canonical artifact. Avoid extra pointer layers unless they materially improve discovery or ergonomics.

Required agent response sections:

1. `Implementation Checklist`
2. `Files To Add Or Modify`
3. `Validation`
4. `Assumptions`

## Minimal Examples

### Canonical Repo Skill

````md
---
name: topic
description: Create and update the repo-local topic workflow. Use for new skill content or harness shims in this repository.
---

# Topic

## Purpose

Explain when this repo-local skill is needed and when existing repo docs are enough.

## Agent Execution Standard

1. Discover current implementation.
2. Apply repo-specific workflow.
3. Confirm any shims stay aligned.
````

### Claude Skill Shim

```md
---
name: topic
summary: Create or update the repo-local topic workflow.
---

Follow `.agents/skills/topic/SKILL.md`.
```

### agents/openai.yaml

```yaml
interface:
display_name: "Topic"
short_description: "Create and validate the repo-local topic workflow."
default_prompt: "Use $topic to create or update the canonical repo-local topic workflow."
```
4 changes: 4 additions & 0 deletions .agents/skills/repo-skill-authoring/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "Repo Skill Authoring"
short_description: "Create and validate repo-local skills."
default_prompt: "Use $repo-skill-authoring to create or update the canonical repo-local skill and any necessary harness shims."
6 changes: 6 additions & 0 deletions .claude/skills/repo-skill-authoring/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
name: repo-skill-authoring
summary: Create or update repo-local skills using the repository standard.
---

Follow `.agents/skills/repo-skill-authoring/SKILL.md`.
60 changes: 60 additions & 0 deletions .cursor/rules/unit-testing-guidelines.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,66 @@ See [PR #25548](https://github.com/MetaMask/metamask-mobile/pull/25548) for refa
- **Mock all external dependencies** including APIs, services, hooks
- **Use realistic mock data** that reflects real usage

### Theme Mocking Rules

- **Prefer shared `mockTheme` from `app/util/theme`** instead of hard-coded color literals in tests.
- **Never hardcode design token hex values** in assertions or theme mocks (enforced by `@metamask/design-tokens/color-no-hex`).
- **Avoid local hex color objects** for `useTheme`, `useStyles`, or tailwind mock color functions.
- **If a test only needs a specific theme field**, derive it from `mockTheme` (or spread `mockTheme` and override minimally).

```ts
// ✅ CORRECT: use shared mockTheme for useTheme mocks
import { mockTheme } from '../../util/theme';

jest.mock('../../util/theme', () => ({
useTheme: () => mockTheme,
}));
```

```ts
// ✅ CORRECT: return { styles, theme } for useStyles mocks
import { mockTheme } from '../../util/theme';

jest.mock('../../../../../component-library/hooks', () => ({
useStyles: jest.fn((styleFn, vars) => ({
styles: styleFn({ theme: mockTheme, vars }),
theme: mockTheme,
})),
}));
```

```ts
// ✅ CORRECT: mock useTailwind with the right shape
jest.mock('@metamask/design-system-twrnc-preset', () => ({
useTailwind: () => ({
// Most components only need tw.style(...)
style: jest.fn(() => ({})),
}),
}));
```

```ts
// ✅ ALSO CORRECT: match real useTailwind() return type (callable function + helpers)
import { mockTheme } from '../../util/theme';

jest.mock('@metamask/design-system-twrnc-preset', () => ({
useTailwind: () => {
const tw = () => ({});
tw.style = jest.fn(() => ({}));
return tw;
},
}));
```

```ts
// ❌ AVOID: local hex color mocks
const mockColors = {
text: { default: '#000000' },
background: { default: '#FFFFFF' },
border: { muted: '#E5E7EB' },
};
```

```ts
// ✅ CORRECT
import { apiService } from '../services/api';
Expand Down
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ app/core/Engine/messengers/earn-controller-messenger @MetaMask/metamask-earn
app/selectors/earnController @MetaMask/metamask-earn
**/Earn/** @MetaMask/metamask-earn
**/earn/** @MetaMask/metamask-earn
**/Money/** @MetaMask/metamask-earn
**/money/** @MetaMask/metamask-earn

# Rewards Team
app/core/Engine/controllers/rewards-controller @MetaMask/rewards
Expand Down
1 change: 0 additions & 1 deletion .github/scripts/known-feature-flag-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const FILE_SOURCES: Array<{ key: string; file: string; exportName: string }> = [
{ key: 'TRON_REWARDS_FLAG_NAME', file: REWARDS_FILE, exportName: 'TRON_REWARDS_FLAG_NAME' },
{ key: 'SNAPSHOTS_REWARDS_FLAG_NAME', file: REWARDS_FILE, exportName: 'SNAPSHOTS_REWARDS_FLAG_NAME' },
{ key: 'MISSING_ENROLLED_ACCOUNTS_FLAG_NAME', file: REWARDS_FILE, exportName: 'MISSING_ENROLLED_ACCOUNTS_FLAG_NAME' },
{ key: 'CAMPAIGNS_REWARDS_FLAG_NAME', file: REWARDS_FILE, exportName: 'CAMPAIGNS_REWARDS_FLAG_NAME' },
{ key: 'ACCOUNT_MENU_FLAG_KEY', file: sel('accountMenu'), exportName: 'ACCOUNT_MENU_FLAG_KEY' },
{ key: 'NETWORK_MANAGEMENT_FLAG_KEY', file: sel('networkManagement'), exportName: 'NETWORK_MANAGEMENT_FLAG_KEY' },
// FEATURE_FLAG_NAME is omitted (non-unique across rwa / gasFeesSponsored); per-file fallback handles it.
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
contents: write
id-token: write
with:
base-branch: ${{ inputs.source_branch != '' && inputs.source_branch || github.ref_name }}
base-branch: ${{ inputs.source_branch || github.ref_name }}
secrets:
PR_TOKEN: ${{ secrets.PR_TOKEN }}

Expand All @@ -87,12 +87,12 @@ jobs:
signing_aws_role: ${{ steps.config.outputs.signing_aws_role }}
signing_aws_secret: ${{ steps.config.outputs.signing_aws_secret }}
signing_android_keystore_path: ${{ steps.config.outputs.signing_android_keystore_path }}
checkout_ref_for_setup: ${{ !inputs.skip_version_bump && needs.update-build-version.outputs.commit-hash || (inputs.source_branch != '' && inputs.source_branch || github.ref_name) }}
checkout_ref_for_setup: ${{ !inputs.skip_version_bump && needs.update-build-version.outputs.commit-hash || (inputs.source_branch || github.ref_name) }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ !inputs.skip_version_bump && needs.update-build-version.outputs.commit-hash || (inputs.source_branch != '' && inputs.source_branch || github.ref_name) }}
ref: ${{ !inputs.skip_version_bump && needs.update-build-version.outputs.commit-hash || (inputs.source_branch || github.ref_name) }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
Expand Down
Loading
Loading