@kensaurus/skills 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +2 -2
- package/.cursor-plugin/plugin.json +2 -2
- package/CHANGELOG.md +29 -0
- package/LICENSE-APACHE +62 -0
- package/README.md +16 -15
- package/install.sh +0 -0
- package/llms.txt +3 -3
- package/package.json +5 -4
- package/skills/audit-bundle-size/SKILL.md +1 -2
- package/skills/audit-resilience/SKILL.md +1 -2
- package/skills/audit-ux/SKILL.md +4 -2
- package/skills/enhance-onboarding/SKILL.md +2 -2
- package/skills/enhance-pwa/SKILL.md +1 -2
- package/skills/enhance-ux-laws/SKILL.md +409 -0
- package/skills/enhance-web-ux/HEURISTICS.md +10 -4
- package/skills/mobile-capacitor-platform/SKILL.md +1 -2
- package/skills/test-red-team/SKILL.md +2 -3
- package/skills.sh.json +1 -0
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Playbooks your coding agent runs from a plain-English request.",
|
|
9
|
-
"version": "2.
|
|
9
|
+
"version": "2.1.0"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "kenji",
|
|
14
14
|
"source": ".",
|
|
15
|
-
"description": "
|
|
15
|
+
"description": "159 agent skills, 63 slash commands, 6 subagents for Claude Code, effort-routed for Opus 5.5. Install: /plugin install kenji@kenji",
|
|
16
16
|
"homepage": "https://github.com/kensaurus/skills#readme",
|
|
17
17
|
"repository": "https://github.com/kensaurus/skills",
|
|
18
18
|
"license": "MIT",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kenji",
|
|
3
3
|
"displayName": "kenji skills",
|
|
4
|
-
"description": "You say the job; the playbook runs.
|
|
5
|
-
"version": "2.
|
|
4
|
+
"description": "You say the job; the playbook runs. 159 agent skills, 63 slash commands, 6 subagents, and MCP templates for Claude Code, Cursor, Codex CLI, and Gemini CLI. Tuned for React / Next.js / Supabase; works on most stacks. Effort-routed for Claude Opus 5.5.",
|
|
5
|
+
"version": "2.1.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "kensaurus",
|
|
8
8
|
"email": "kensaurus@gmail.com"
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kenji",
|
|
3
3
|
"displayName": "kenji skills",
|
|
4
|
-
"version": "2.
|
|
5
|
-
"description": "You say the job; the playbook runs.
|
|
4
|
+
"version": "2.1.0",
|
|
5
|
+
"description": "You say the job; the playbook runs. 159 agent skills, 63 slash commands, 6 subagents, and MCP templates for Claude Code, Cursor, Codex CLI, and Gemini CLI. Tuned for React / Next.js / Supabase; works on most stacks.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "kensaurus"
|
|
8
8
|
},
|
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,35 @@ All notable additions and changes to kenji (`kensaurus/skills`, named `cursor-ke
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [2.1.0] — 2026-10-01
|
|
10
|
+
|
|
11
|
+
UX laws as a measured fix pass, and the Miller misreading removed from the
|
|
12
|
+
pack.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **`enhance-ux-laws`.** Measure-then-fix pass on one screen or flow against
|
|
17
|
+
seven Laws of UX: Fitts, Hick, Miller, Jakob, Zeigarnik, Goal-Gradient and
|
|
18
|
+
Von Restorff. A browser probe measures tap targets, competing accents,
|
|
19
|
+
choice sets, unlabeled fields and progress cues at phone and desktop widths;
|
|
20
|
+
an eight-check flow walk covers what the DOM cannot show (resume after
|
|
21
|
+
reload, dead controls, pasted codes). Each law states its precondition and
|
|
22
|
+
what it does not say. Progress and resume cues must read real state, and
|
|
23
|
+
drafts never store card numbers or one-time codes.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **Miller and Hick read correctly.** `audit-ux` and `enhance-web-ux` no
|
|
28
|
+
longer cap menus or navigation at seven items: Miller is about what the user
|
|
29
|
+
must hold in mind, and Hick applies only when options must be weighed, not to
|
|
30
|
+
known-item lookups. `audit-ux` gains Von Restorff and
|
|
31
|
+
Goal-Gradient/Zeigarnik rows.
|
|
32
|
+
- **Releases are staged.** `npm-publish.yml` runs `npm stage publish
|
|
33
|
+
--provenance`; a version goes live only when the maintainer approves it with
|
|
34
|
+
2FA. CI actions moved to v5 (Node 24).
|
|
35
|
+
- Six skill descriptions dropped duplicate trigger phrases so the listing stays
|
|
36
|
+
under its 39,000-character ratchet with the new skill (ADR-0010).
|
|
37
|
+
|
|
9
38
|
## [2.0.0] — 2026-10-01
|
|
10
39
|
|
|
11
40
|
**cursor-kenji is now kenji: `kensaurus/skills` on GitHub, `@kensaurus/skills`
|
package/LICENSE-APACHE
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Work" shall mean the work of authorship made available under the
|
|
27
|
+
License, as indicated by a copyright notice included in or attached
|
|
28
|
+
to the work.
|
|
29
|
+
|
|
30
|
+
"Derivative Works" shall mean any work based on (or derived from)
|
|
31
|
+
the Work for which the editorial revisions represent, as a whole,
|
|
32
|
+
an original work of authorship.
|
|
33
|
+
|
|
34
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
35
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
36
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
37
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
38
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
39
|
+
Work and such Derivative Works in Source or Object form.
|
|
40
|
+
|
|
41
|
+
3. Redistribution. You may reproduce and distribute copies of the
|
|
42
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
43
|
+
modifications, in Source or Object form, provided that You meet the
|
|
44
|
+
following conditions:
|
|
45
|
+
|
|
46
|
+
(a) You must give any other recipients a copy of this License; and
|
|
47
|
+
(b) You must cause any modified files to carry prominent notices
|
|
48
|
+
stating that You changed the files; and
|
|
49
|
+
(c) You must retain all copyright, patent, trademark, and attribution
|
|
50
|
+
notices from the Source form of the Work; and
|
|
51
|
+
(d) If the Work includes a NOTICE file, any Derivative Works must
|
|
52
|
+
include a readable copy of those attribution notices.
|
|
53
|
+
|
|
54
|
+
[Full license text: http://www.apache.org/licenses/LICENSE-2.0]
|
|
55
|
+
|
|
56
|
+
Copyright 2025 Anthropic, PBC.
|
|
57
|
+
|
|
58
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
59
|
+
you may not use this file except in compliance with the License.
|
|
60
|
+
You may obtain a copy of the License at
|
|
61
|
+
|
|
62
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
**You say the job. The playbook runs.** Agent skills, slash commands, and subagents for **Claude Code, Cursor, Codex CLI, and Gemini CLI**.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
159 agent skills · 63 slash commands · 15 MCP servers · 12 Cursor skills · 6 subagents — for React / Next.js / Supabase, usable on almost any stack.
|
|
10
10
|
|
|
11
11
|
<p>
|
|
12
12
|
<a href="https://www.npmjs.com/package/@kensaurus/skills"><img src="https://img.shields.io/npm/v/@kensaurus/skills?style=flat-square&color=cb3837&logo=npm" alt="npm version" /></a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
**Who it’s for** — People shipping in Cursor, Claude Code, Codex CLI, or Gemini CLI. Tuned for React / Next.js / Supabase. Works on other stacks.
|
|
32
32
|
|
|
33
|
-
**What it’s not** — A Cursor replacement, a prompt paste-bin, or
|
|
33
|
+
**What it’s not** — A Cursor replacement, a prompt paste-bin, or 171 names to memorize. Install once. Talk like a teammate.
|
|
34
34
|
|
|
35
35
|
## Install (30 seconds)
|
|
36
36
|
|
|
@@ -114,7 +114,7 @@ Four rooms. Same rule: you talk, a named playbook runs.
|
|
|
114
114
|
| **Rule** | A house rule the AI always obeys | Drop a `.mdc` into your project |
|
|
115
115
|
| **MCP server** | A connection to your database / GitHub / browser | Copy a template + set env vars |
|
|
116
116
|
|
|
117
|
-
Everything follows the [Agent Skills spec](https://agentskills.io/specification) and is checked on every commit (`npm test` covers all **
|
|
117
|
+
Everything follows the [Agent Skills spec](https://agentskills.io/specification) and is checked on every commit (`npm test` covers all **171** installable skills). MCP templates pin exact versions against [package-hallucination attacks](https://labs.cloudsecurityalliance.org/research/csa-research-note-slopsquatting-ai-supply-chain-20260419-csa/).
|
|
118
118
|
|
|
119
119
|
## How it works
|
|
120
120
|
|
|
@@ -142,13 +142,13 @@ The 23 `plan-*` skills audit first and wait for your approval. See [docs/PLAN-LO
|
|
|
142
142
|
|
|
143
143
|
| | Count | What it does |
|
|
144
144
|
|:--|------:|:-------------|
|
|
145
|
-
| **Skills** |
|
|
145
|
+
| **Skills** | 159 | Auto-triggering playbooks (audit, enhance, debug, test, build, plan) |
|
|
146
146
|
| **Cursor Skills** | 12 | IDE tools (canvas, hooks, rules, PR splitter) |
|
|
147
147
|
| **Commands** | 63 | Slash shortcuts (`/commit`, `/pr`, `/burndown-full`, …) |
|
|
148
148
|
| **Subagents** | 6 | Background helpers (code-reviewer, debugger, db-migrator…) |
|
|
149
149
|
| **Completion hook** | 1 | Opt-in stop gate: continues only unfinished durable closure state |
|
|
150
|
-
| **MCP Servers** |
|
|
151
|
-
| **Project Rules** | 7 | Drop-in `.mdc` for `.cursor/rules/` (plus
|
|
150
|
+
| **MCP Servers** | 15 | Full template: Supabase · GitHub · Playwright · AWS · Slack (essential is 3) |
|
|
151
|
+
| **Project Rules** | 7 | Drop-in `.mdc` for `.cursor/rules/` (plus 6 global, 5 RN bundle optional) |
|
|
152
152
|
| **Notepads** | 2 | Context templates (architecture, design tokens) |
|
|
153
153
|
| **Shell Aliases** | 8 | `newskill`, `cursor-sync`, `gc`, `gp` |
|
|
154
154
|
|
|
@@ -269,7 +269,7 @@ You don't memorize names — describe the job in chat. Exact trigger phrases →
|
|
|
269
269
|
|
|
270
270
|
<!-- SKILL-INDEX:START -->
|
|
271
271
|
|
|
272
|
-
_Auto-generated from each skill's `SKILL.md` — run `npm run gen:skill-index` after adding a skill. **
|
|
272
|
+
_Auto-generated from each skill's `SKILL.md` — run `npm run gen:skill-index` after adding a skill. **171 skills** listed below._
|
|
273
273
|
|
|
274
274
|
_Skills marked `/name only` are user-invoked rituals; `reference only` skills are loaded by other skills; every other skill auto-routes from a plain request._
|
|
275
275
|
|
|
@@ -279,7 +279,7 @@ _Skills marked `/name only` are user-invoked rituals; `reference only` skills ar
|
|
|
279
279
|
|:-------|------:|:----------------|
|
|
280
280
|
| Audit — inspect; some then fix | **32** | Check the codebase — security, UX, analytics, IAP, the skill pack… |
|
|
281
281
|
| Plan — audit first, change only after you approve | **23** | Write a fix plan you approve before any code changes |
|
|
282
|
-
| Enhance — improve what already exists | **
|
|
282
|
+
| Enhance — improve what already exists | **22** | Polish UI, forms, motion, SEO, PWA, email deliverability |
|
|
283
283
|
| Design — build something new | **10** | Create new UI, APIs, emails, themes from scratch |
|
|
284
284
|
| Backend — server & data patterns | **5** | Auth, caching, queues, realtime, observability |
|
|
285
285
|
| Mobile — React Native / Capacitor | **5** | RN screens, emulators, Capacitor, App Store prep |
|
|
@@ -297,7 +297,7 @@ _Skills marked `/name only` are user-invoked rituals; `reference only` skills ar
|
|
|
297
297
|
| Third-party (upstream-maintained) | **3** | Vendored upstream skills (Emil, UI/UX Pro Max, Vercel WIG) |
|
|
298
298
|
| Core & cross-cutting | **4** | Close everything, burndown, research, handoff |
|
|
299
299
|
| Cursor IDE skills | **12** | Canvas, hooks, rules, PR splitter, CLI helpers |
|
|
300
|
-
| **Total** | **
|
|
300
|
+
| **Total** | **171** | |
|
|
301
301
|
|
|
302
302
|
#### Full list (every skill)
|
|
303
303
|
|
|
@@ -366,7 +366,7 @@ _Skills marked `/name only` are user-invoked rituals; `reference only` skills ar
|
|
|
366
366
|
| `plan-test-coverage` | Plan-only, user-story-driven test coverage audit |
|
|
367
367
|
| `plan-uiux-unification` | Plan-only UI/UX and design-system audit that emits a unification burndown; no code until a phase is approved |
|
|
368
368
|
|
|
369
|
-
### Enhance — improve what already exists (
|
|
369
|
+
### Enhance — improve what already exists (22)
|
|
370
370
|
|
|
371
371
|
| Skill | What it does |
|
|
372
372
|
|:------|:-------------|
|
|
@@ -382,6 +382,7 @@ _Skills marked `/name only` are user-invoked rituals; `reference only` skills ar
|
|
|
382
382
|
| `enhance-readability` | Audit and fix how easily content is understood: line length (CPL), reading level, grouping, deadspace, icons or tables that cut verbosity |
|
|
383
383
|
| `enhance-readme` | Enhance an existing README: theme-aware hero, feature tour, screenshots or GIF, accurate badges, synced content |
|
|
384
384
|
| `enhance-skill-prompts` | Upgrade how an existing SKILL.md instructs, not what it does: freedom, a classification contract, one worked example, an evidence rubric,… |
|
|
385
|
+
| `enhance-ux-laws` | Measured fix pass on one screen or flow against seven Laws of UX: Fitts, Hick, Miller, Jakob, Zeigarnik, Goal-Gradient, Von Restorff |
|
|
385
386
|
| `enhance-web-conversion` | Conversion pass for landing, pricing, and upgrade paths: positioned hero, one CTA, real proof, anchored tiers, upgrade prompts at value… |
|
|
386
387
|
| `enhance-web-forms` | Build or upgrade web forms: accessible structure, schema-driven validation, client↔server parity |
|
|
387
388
|
| `enhance-web-instant-nav` | Instant in-site navigation: Speculation Rules, View Transitions, bfcache, 103 Early Hints |
|
|
@@ -654,11 +655,11 @@ Type `/` in chat to see them all.
|
|
|
654
655
|
|
|
655
656
|
---
|
|
656
657
|
|
|
657
|
-
## MCP servers (
|
|
658
|
+
## MCP servers (15)
|
|
658
659
|
|
|
659
660
|
```bash
|
|
660
661
|
cp ~/skills/mcp/mcp.json.template ~/.cursor/mcp.json # essential 3
|
|
661
|
-
cp ~/skills/mcp/mcp-full.json.template ~/.cursor/mcp.json # all
|
|
662
|
+
cp ~/skills/mcp/mcp-full.json.template ~/.cursor/mcp.json # all 15
|
|
662
663
|
```
|
|
663
664
|
|
|
664
665
|
Set `FIRECRAWL_API_KEY`, `CONTEXT7_API_KEY`, `SUPABASE_ACCESS_TOKEN`, and `SUPABASE_PROJECT_REF` in the environment. Slack/Notion in the full template still use `YOUR_*`. Setup → **[mcp/README.md](mcp/README.md)**
|
|
@@ -721,7 +722,7 @@ Full definitions in [shell-aliases/cursor-helpers.sh](shell-aliases/cursor-helpe
|
|
|
721
722
|
|
|
722
723
|
```
|
|
723
724
|
skills/
|
|
724
|
-
├── skills/ #
|
|
725
|
+
├── skills/ # 159 Agent Skills (SKILL.md each)
|
|
725
726
|
├── skills-cursor/ # 12 Cursor-specific skills
|
|
726
727
|
├── commands/ # 63 slash commands
|
|
727
728
|
├── agents/ # 6 subagents
|
|
@@ -770,7 +771,7 @@ You say the job in chat; a playbook runs. [Agent Skills](https://agentskills.io)
|
|
|
770
771
|
`npx @kensaurus/skills --all` for skills **and** slash commands. `npx skills add kensaurus/skills` installs skills only. Claude Code as a plugin: `/plugin marketplace add kensaurus/skills`. Restart Cursor after install. Re-check with `npx @kensaurus/skills --verify --all`.
|
|
771
772
|
|
|
772
773
|
**How many skills?**
|
|
773
|
-
**
|
|
774
|
+
**159** agent skills in `skills/` plus **12** Cursor-specific skills in `skills-cursor/` (**171** total). Counts come from the filesystem via `npm run check:skills`. See the [family counts table](#skill-families-at-a-glance).
|
|
774
775
|
|
|
775
776
|
**How do skills trigger?**
|
|
776
777
|
You talk normally. Cursor matches your words to each skill's YAML `description`. To force one: *"use \`audit-security\` on this repo"*. Full trigger list: [docs/CATALOG.md](docs/CATALOG.md).
|
|
@@ -790,7 +791,7 @@ Yes — [llms.txt](llms.txt) at the repo root.
|
|
|
790
791
|
|
|
791
792
|
- [awesome-cursorrules](https://github.com/PatrickJS/awesome-cursorrules) — curated rules collections
|
|
792
793
|
- [skills.sh](https://www.skills.sh/kensaurus/skills) — this pack’s live skills page
|
|
793
|
-
- [SkillsMP](https://skillsmp.com/creators/kensaurus/
|
|
794
|
+
- [SkillsMP](https://skillsmp.com/creators/kensaurus/cursor-kenji) — aggregator crawl of this repo
|
|
794
795
|
- [agentskills.io](https://agentskills.io) — Agent Skills spec (not a skill catalog)
|
|
795
796
|
|
|
796
797
|
kenji ships executable skills, MCP configs, commands, and subagents in one installable package — not static rules alone. What is actually listed vs submitted → **[docs/DISTRIBUTION.md](docs/DISTRIBUTION.md)**.
|
package/install.sh
CHANGED
|
File without changes
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# kenji
|
|
2
2
|
|
|
3
|
-
> You say the job; the playbook runs. Installable workflows for Cursor, Claude Code, Codex CLI, and Gemini CLI:
|
|
3
|
+
> You say the job; the playbook runs. Installable workflows for Cursor, Claude Code, Codex CLI, and Gemini CLI: 159 agent skills, 63 slash commands, 6 subagents, and MCP templates for React / Next.js / Supabase.
|
|
4
4
|
>
|
|
5
5
|
> Full pack: `npx @kensaurus/skills --all` (skills + commands; kenji `--all` = four tools). Skills only: `npx skills add kensaurus/skills` (that CLI's `--all` means every skill to every agent). Claude Code plugin: `/plugin marketplace add kensaurus/skills`. Re-check: `npx @kensaurus/skills --verify --all`.
|
|
6
6
|
|
|
@@ -31,8 +31,8 @@ Runs on Claude Opus 5.5 — the Claude Code default since 2.1.280 and a Cursor a
|
|
|
31
31
|
|
|
32
32
|
- [docs/DISTRIBUTION.md](https://github.com/kensaurus/skills/blob/main/docs/DISTRIBUTION.md): Install channels, directory listings, discovery status
|
|
33
33
|
- [skills.sh listing](https://www.skills.sh/kensaurus/skills): Live installable catalog page (`npx skills add kensaurus/skills`)
|
|
34
|
-
- [SkillsMP pack page](https://skillsmp.com/creators/kensaurus/
|
|
35
|
-
- [docs/PUBLISHING.md](https://github.com/kensaurus/skills/blob/main/docs/PUBLISHING.md): Maintainer release guide (GitHub Release → OIDC npm)
|
|
34
|
+
- [SkillsMP pack page](https://skillsmp.com/creators/kensaurus/cursor-kenji): Aggregator crawl of this repo’s `SKILL.md` files (their count can lag)
|
|
35
|
+
- [docs/PUBLISHING.md](https://github.com/kensaurus/skills/blob/main/docs/PUBLISHING.md): Maintainer release guide (GitHub Release → OIDC-staged npm publish → owner approves with 2FA)
|
|
36
36
|
- [docs/PROMOTION.md](https://github.com/kensaurus/skills/blob/main/docs/PROMOTION.md): Listing copy for skills.sh, cursor.directory, marketplace, Claude plugin
|
|
37
37
|
- [Claude Code plugin](https://github.com/kensaurus/skills/blob/main/.claude-plugin/marketplace.json): `/plugin marketplace add kensaurus/skills` (community catalog is a separate submit)
|
|
38
38
|
- [docs/examples/plan-audits/](https://github.com/kensaurus/skills/tree/main/docs/examples/plan-audits): Sample `plan-*.md` audit outputs
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kensaurus/skills",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "You say the job; the playbook runs.
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "You say the job; the playbook runs. 159 agent skills, 63 slash commands, 6 subagents, and MCP templates for Claude Code, Cursor, Codex CLI, and Gemini CLI. Tuned for React / Next.js / Supabase; works on most stacks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"kenji": "bin/kenji.js"
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"check:skill-refs": "node scripts/check-skill-refs.mjs --self-test && node scripts/check-skill-refs.mjs",
|
|
30
30
|
"check:docs-facts": "node scripts/check-docs-facts.mjs",
|
|
31
31
|
"check:md-structure": "node scripts/check-md-structure.mjs --self-test && node scripts/check-md-structure.mjs",
|
|
32
|
-
"check:dead-code": "npx -y knip@6.
|
|
33
|
-
"check:dead-code:prod": "npx -y knip@6.
|
|
32
|
+
"check:dead-code": "npx -y knip@6.38.0 --max-issues 0 --treat-config-hints-as-errors",
|
|
33
|
+
"check:dead-code:prod": "npx -y knip@6.38.0 --production --max-issues 0",
|
|
34
34
|
"test:install": "node scripts/test-install.mjs",
|
|
35
35
|
"test:completion-gate": "node scripts/test-completion-gate.mjs",
|
|
36
36
|
"test": "node scripts/validate-skills.mjs && node scripts/check-skill-count.mjs && node scripts/generate-skill-index.mjs --check && node scripts/scan-secrets.mjs --self-test && node scripts/check-mcp-pins.mjs && node scripts/check-docs-facts.mjs && node scripts/check-skill-refs.mjs --self-test && node scripts/check-skill-refs.mjs && node scripts/check-md-structure.mjs --self-test && node scripts/check-md-structure.mjs && node scripts/test-completion-gate.mjs && node scripts/test-install.mjs && npm run -s check:dead-code && npm run -s check:dead-code:prod"
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"README.md",
|
|
67
67
|
"CHANGELOG.md",
|
|
68
68
|
"LICENSE",
|
|
69
|
+
"LICENSE-APACHE",
|
|
69
70
|
"NOTICE",
|
|
70
71
|
"llms.txt",
|
|
71
72
|
"docs/screenshots/",
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
name: audit-bundle-size
|
|
3
3
|
description: >
|
|
4
4
|
Analyse and shrink a web app's JavaScript bundle. Use when "reduce bundle
|
|
5
|
-
size", "
|
|
6
|
-
load", "chunk size", "LCP caused by JS", or "why is the bundle so big".
|
|
5
|
+
size", "code splitting", "slow initial load", or "why is the bundle so big".
|
|
7
6
|
Runtime → audit-performance.
|
|
8
7
|
license: MIT
|
|
9
8
|
effort: high
|
|
@@ -3,8 +3,7 @@ name: audit-resilience
|
|
|
3
3
|
description: >
|
|
4
4
|
Read-only production-resilience audit: timeouts, bounded retries, circuit
|
|
5
5
|
breakers, idempotency, rate limits, graceful degradation, PII in logs. Use
|
|
6
|
-
when "resilience audit"
|
|
7
|
-
retries/timeouts/idempotency".
|
|
6
|
+
when "resilience audit" or "will this survive real traffic?".
|
|
8
7
|
license: MIT
|
|
9
8
|
effort: high
|
|
10
9
|
---
|
package/skills/audit-ux/SKILL.md
CHANGED
|
@@ -302,8 +302,10 @@ Search `*.tsx` for in-app help: `Tooltip|tooltip|HelpCircle|InfoIcon|help.*text|
|
|
|
302
302
|
|-----|-----------|---------------|----------------------|
|
|
303
303
|
| **Jakob's Law** | Users expect your site to work like other sites | Navigation, form patterns, checkout flows follow platform conventions | Research 3 competitors via Firecrawl, adopt their common patterns |
|
|
304
304
|
| **Fitts's Law** | Larger, closer targets are faster to click | Primary CTAs large enough, not in corners. Touch targets ≥44px | Increase CTA size, move primary actions to natural thumb zones on mobile |
|
|
305
|
-
| **Hick's Law** | More
|
|
306
|
-
| **Miller's Law** | Working memory holds ~7
|
|
305
|
+
| **Hick's Law** | More options to *weigh* = longer decisions | Choice sets the user must evaluate (plans, actions, filters) are grouped, staged, or have a default. Not known-item lookups (countries, prefectures): that is search | Group options, preselect one with a true reason, hide the long tail behind "More", typeahead for lookups |
|
|
306
|
+
| **Miller's Law** | Working memory holds ~4–7 chunks | Nothing must be carried in memory between screens; codes shown grouped with Copy; fields keep visible labels. Not a cap on visible menu items: a visible menu is read, not memorised | Persistent labels, summaries of earlier choices, chunked codes, labelled field groups |
|
|
307
|
+
| **Von Restorff** | The item that differs is noticed | One filled accent action per view | Demote competing CTAs to outline/ghost variants |
|
|
308
|
+
| **Goal-Gradient / Zeigarnik** | Visible progress and unfinished work pull users to finish | Multi-step flows show honest position and total; input survives reload and Back | "Step 2 of 3" from real state, autosave drafts (never card numbers or codes) |
|
|
307
309
|
| **Cognitive Load** | Minimize mental effort | No unnecessary fields, no memory burden between steps | Remove optional fields from default view, show only what's needed now |
|
|
308
310
|
| **Aesthetic-Usability** | Beautiful = perceived as easier | First impression inspires confidence | Visual polish on landing + key flows. Personality, not just correctness |
|
|
309
311
|
| **Tesler's Law** | Complexity can't be eliminated, only moved | Complex tasks simplified for the user, not pushed to them | Smart defaults, auto-detection, progressive disclosure of complexity |
|
|
@@ -3,8 +3,8 @@ name: enhance-onboarding
|
|
|
3
3
|
description: >
|
|
4
4
|
Activation pass: define the activation event, cut steps to first value, add
|
|
5
5
|
templates, sample data, a short checklist, and signup → activated events.
|
|
6
|
-
Use when "improve onboarding", "users sign up and leave",
|
|
7
|
-
|
|
6
|
+
Use when "improve onboarding", "users sign up and leave", or "activation
|
|
7
|
+
rate".
|
|
8
8
|
license: MIT
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -3,8 +3,7 @@ name: enhance-pwa
|
|
|
3
3
|
description: >
|
|
4
4
|
Add or upgrade PWA features: manifest, service worker, offline mode, install
|
|
5
5
|
prompt, push, background sync. Use when "make it a PWA", "offline support",
|
|
6
|
-
"install prompt"
|
|
7
|
-
mobile-capacitor-platform.
|
|
6
|
+
or "install prompt". Native → mobile-capacitor-platform.
|
|
8
7
|
license: MIT
|
|
9
8
|
---
|
|
10
9
|
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: enhance-ux-laws
|
|
3
|
+
description: >
|
|
4
|
+
Measured fix pass on one screen or flow against seven Laws of UX: Fitts,
|
|
5
|
+
Hick, Miller, Jakob, Zeigarnik, Goal-Gradient, Von Restorff. Use when "too
|
|
6
|
+
many choices", "hard to tap", or "users drop off mid-flow". NN/g pass →
|
|
7
|
+
enhance-web-ux.
|
|
8
|
+
license: MIT
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Enhance UX with the Laws of UX
|
|
12
|
+
|
|
13
|
+
**Degree of freedom: MIXED.** Probe run, thresholds, and re-measure
|
|
14
|
+
`[LOW freedom — run exactly]`; scoping, diagnosis, law conflicts, and fix
|
|
15
|
+
design `[HIGH freedom]`.
|
|
16
|
+
|
|
17
|
+
Takes one screen or flow and improves it against seven behavioural laws, using
|
|
18
|
+
measured values in place of impressions. Each law answers one question about
|
|
19
|
+
the person using the screen:
|
|
20
|
+
|
|
21
|
+
| Question | Law | Lever |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| Can they hit it? | Fitts | target size and travel distance |
|
|
24
|
+
| Can they decide? | Hick | number and weight of simultaneous choices |
|
|
25
|
+
| Do they see what matters? | Von Restorff | one distinct element per view |
|
|
26
|
+
| Can they hold it in mind? | Miller | chunking; nothing carried between screens |
|
|
27
|
+
| Does it work the way they expect? | Jakob | conventions from products they already use |
|
|
28
|
+
| Will they come back and finish? | Zeigarnik | visible, resumable unfinished work |
|
|
29
|
+
| Will they push through to the end? | Goal-Gradient | visible, honest progress |
|
|
30
|
+
|
|
31
|
+
Fix by default. When the request is for a review only, stop after the
|
|
32
|
+
findings table.
|
|
33
|
+
|
|
34
|
+
## How to reason
|
|
35
|
+
|
|
36
|
+
1. **Scope** — one screen or flow, its primary task, who uses it (first-time or daily), pointer type per layout
|
|
37
|
+
2. **Measure** — probe at phone and desktop widths, then the flow walk for what the DOM cannot show
|
|
38
|
+
3. **Diagnose** — each finding = law + measured value + threshold + why the law's precondition holds here
|
|
39
|
+
4. **Resolve** — where two laws pull apart, pick by the conflict table and say so
|
|
40
|
+
5. **Fix** — repair a broken flow first, then the smallest change at the shared component or token, driven by real product state
|
|
41
|
+
6. **Verify** — re-run the probe and the flow walk; report before → after per metric
|
|
42
|
+
|
|
43
|
+
## Worked example
|
|
44
|
+
|
|
45
|
+
Illustrative. Probe values are from a real run against a test booking page.
|
|
46
|
+
|
|
47
|
+
> **Scope:** `/book`, phone (touch) and desktop. Primary task: pick a site type and pay. First-time visitors.
|
|
48
|
+
> **Measure @390×844:** `under24` 17 of 38 targets; Edit/Delete 23×14 and 39×14, 2px apart; `accentsInFold` 8 filled blue; `repeatedActions` Choose ×6; nav 14 flat links; form 11 fields, 0 groups, 8 `placeholderOnly`, 3 `unlabeled`; `longCodes` one 16-digit reference; `stepButtons` Back/Next with 0 `indicators`; `fakeControls` `div:Pay now`; `homeLink` false. Flow walk: reload at step 2 empties the form; Next does nothing; a pasted card number with spaces is cut short.
|
|
49
|
+
> **Diagnose:** Jakob — "Pay now" is a `div` that submits nothing and the keyboard cannot reach (blocker). Zeigarnik — reload wipes the form (blocker). Fitts — Delete is 14px tall, 2px from Edit: destructive mis-tap (blocker). Von Restorff + Hick — 8 equal accents, six equally weighted plans (major). Miller — labels vanish on typing; reference must be retyped by hand (major). Goal-Gradient — no position in a 3-step flow (major).
|
|
50
|
+
> **Not a finding:** the prefecture select has 21 options, but people look up a known answer in a conventional order, so Hick does not apply. Left as is.
|
|
51
|
+
> **Resolve:** hiding three plans under "More site types" adds a tap (Hick vs Fitts); accepted because those three are 8% of bookings.
|
|
52
|
+
> **Fix:** `<button type="submit">` and working steps first; `Button` primitive gets a 44px min height and 8px gap; Delete moves away from Edit, behind a confirm; three plans visible, one preselected "Most booked"; one filled CTA per view, the rest outline; persistent labels in three fieldsets; reference rendered `8842 0193 7745 1206` with Copy; "Step 2 of 3" from the real step index; draft saved per field, card number excluded.
|
|
53
|
+
> **Verify:** `under24` 17 → 0, `accentsInFold` 8 → 1, `placeholderOnly` 8 → 0, `fakeControls` 1 → 0, `indicators` 0 → 1; reload at step 2 restores input; the pasted card number is kept whole.
|
|
54
|
+
> **Contract change:** `/book` now receives a `plan` field; the plan was never submitted before.
|
|
55
|
+
|
|
56
|
+
## Self-critique before reporting
|
|
57
|
+
|
|
58
|
+
- **Measured** — every finding carries a probe value or a flow-walk observation, and its after-value from a re-run
|
|
59
|
+
- **Precondition stated** — each finding says why the law applies here (Hick: the options need evaluating; Miller: the user must hold the item in memory)
|
|
60
|
+
- **Real state** — every progress, draft, or completeness cue reads product data; the report names the field
|
|
61
|
+
- **Nothing sensitive stored** — drafts exclude card numbers, security codes, passwords, and one-time codes; the report lists what is persisted and for how long
|
|
62
|
+
- **One accent** — `accentsInFold` shows one filled accent action per view at both widths
|
|
63
|
+
- **Primitive-first** — a finding that repeats is fixed in the shared component or token, with the call sites listed
|
|
64
|
+
- **Conflicts named** — where two laws disagreed, the report says which won and why
|
|
65
|
+
- **Right owner** — full WCAG sweep → `audit-accessibility`; breakpoints → `audit-responsive`; NN/g page pass → `enhance-web-ux`
|
|
66
|
+
|
|
67
|
+
## What each law claims, and what it does not
|
|
68
|
+
|
|
69
|
+
Most damage done in the name of these laws comes from applying one outside its
|
|
70
|
+
precondition. Check the middle column before writing a finding.
|
|
71
|
+
|
|
72
|
+
| Law | Claim | Applies when | It does not say |
|
|
73
|
+
|---|---|---|---|
|
|
74
|
+
| **Fitts** (1954) | Time to acquire a target grows with distance and shrinks with size: `T = a + b·log₂(D/W + 1)` | The user points at something: tap, click, drag | "Bigger is always better" — the gain is logarithmic, and size should track frequency and importance |
|
|
75
|
+
| **Hick–Hyman** (1952) | Decision time grows with the log of the number of equally likely options | Options must be read and weighed: plans, actions, filters, unfamiliar categories | Anything about looking up a known item in an ordered list (countries, prefectures) — that is search, so give it typeahead |
|
|
76
|
+
| **Miller** (1956) | Working memory holds about 7 ± 2 chunks; later work puts it nearer 4 (Cowan, 2001) | The user must hold something in mind: a code, a value from another screen, instructions | "Menus may have at most 7 items" — a visible menu is read, not memorised |
|
|
77
|
+
| **Jakob** (Nielsen, 2000) | People spend most of their time in other products and expect yours to work the same | A convention exists for this pattern on this platform and in this locale | "Copy the market leader" — a convention is what users already do, including name order, address order, and date format for the locale |
|
|
78
|
+
| **Zeigarnik** (1927) | Unfinished tasks stay on the mind more than finished ones; replications are mixed, so treat it as a design heuristic | Work spans interruptions or sessions | "Create open loops" — invented incompleteness is a dark pattern |
|
|
79
|
+
| **Goal-Gradient** (Hull, 1932; Kivetz et al., 2006) | Effort rises as the goal gets closer; a head start raises completion (Nunes & Drèze, 2006: 34% vs 19%) | A multi-step goal with a visible end | "Any progress bar helps" — slow early progress raises abandonment (Conrad et al., 2010) |
|
|
80
|
+
| **Von Restorff** (1933) | The item that differs from its neighbours is noticed and remembered | One item should win attention in this view | "Highlight the important things" — distinctiveness is a budget of one; a second accent spends it |
|
|
81
|
+
|
|
82
|
+
## Step 1 — Scope [HIGH freedom]
|
|
83
|
+
|
|
84
|
+
Read the route file and its top-level components. Record:
|
|
85
|
+
|
|
86
|
+
- **Primary task** — the one thing a person comes to this screen to do, and the action that completes it
|
|
87
|
+
- **Users** — first-time, occasional, or daily. Daily users tolerate density and want speed; first-time users need conventions and guidance
|
|
88
|
+
- **Pointer** — touch, mouse, or both per layout. Touch thresholds apply to every layout a phone or tablet will see
|
|
89
|
+
- **Flow** — steps before and after this screen, and whether the task can span sessions
|
|
90
|
+
- **Primitives and tokens** — the shared `Button`, `Input`, `Field`, `Badge`, progress component, colour tokens
|
|
91
|
+
- **Real state available** — step index, completion flags, timestamps, draft storage, usage counts per option. Progress and resume cues are built from these
|
|
92
|
+
|
|
93
|
+
## Step 2 — Measure [LOW freedom — run exactly]
|
|
94
|
+
|
|
95
|
+
### 2a. Probe
|
|
96
|
+
|
|
97
|
+
Save the probe as `ux-laws-probe.js` in a scratch directory outside the repo
|
|
98
|
+
and work from there: the CLI writes its `.playwright-cli/` folder, the JSON,
|
|
99
|
+
and the screenshots into the current directory. Evaluate the probe in the
|
|
100
|
+
live page at a phone width and a desktop width. Resize before navigating so
|
|
101
|
+
the page lays out at the target width from first paint. With the pack
|
|
102
|
+
installed, follow `protocol-browser-anti-stall` for browser sessions.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
PW="npx --yes @playwright/cli@latest"; S="-s=ux-laws"
|
|
106
|
+
$PW $S open "<app-url>"
|
|
107
|
+
for wh in "390 844" "1440 900"; do
|
|
108
|
+
$PW $S resize $wh && $PW $S goto "<route>"
|
|
109
|
+
$PW $S eval "$(cat ux-laws-probe.js)" --filename "before-${wh// /x}.json" > /dev/null
|
|
110
|
+
$PW $S screenshot --filename "before-${wh// /x}.png" --full-page
|
|
111
|
+
done
|
|
112
|
+
$PW $S close
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Read the JSON files. The probe measures the state the page is in, so repeat
|
|
116
|
+
it for each state that matters — filled, error, menu open, every step of a
|
|
117
|
+
flow — by driving the same session there (`fill`, `click`) and evaluating
|
|
118
|
+
again to a new file. Any driver that evaluates JavaScript in the page works
|
|
119
|
+
as well: Playwright `page.evaluate`, a DevTools or browser-automation script
|
|
120
|
+
tool, or pasting `(<probe>)()` into the console.
|
|
121
|
+
|
|
122
|
+
```js
|
|
123
|
+
() => {
|
|
124
|
+
const vw = innerWidth, vh = innerHeight, cap = a => a.slice(0, 12);
|
|
125
|
+
const R = el => el.getBoundingClientRect(), CS = el => getComputedStyle(el);
|
|
126
|
+
const vis = el => { const r = R(el), s = CS(el); // checkVisibility also catches closed <details> and hidden ancestors
|
|
127
|
+
return r.width > 0 && r.height > 0 && s.visibility !== 'hidden' && +s.opacity > 0.05 &&
|
|
128
|
+
(!el.checkVisibility || el.checkVisibility()); };
|
|
129
|
+
const label = el => (el.getAttribute('aria-label') || (el.tagName === 'SELECT' ? el.name : el.innerText) ||
|
|
130
|
+
el.value || el.placeholder || el.name || el.tagName).trim().replace(/\s+/g, ' ').slice(0, 32);
|
|
131
|
+
const SEL = 'a[href],button,input:not([type=hidden]),select,textarea,summary,[role=button],' +
|
|
132
|
+
'[role=link],[role=tab],[role=menuitem],[role=checkbox],[role=switch],[role=radio]';
|
|
133
|
+
const targets = [...document.querySelectorAll(SEL)].filter(vis);
|
|
134
|
+
const inFold = el => { const r = R(el); return r.top < vh && r.bottom > 0 && r.left < vw && r.right > 0; };
|
|
135
|
+
// Hit area = element box, extended by its <label> when it has one.
|
|
136
|
+
const hit = el => { let r = R(el), b = { l: r.left, t: r.top, r: r.right, b: r.bottom };
|
|
137
|
+
for (const lb of el.labels || []) { const q = R(lb);
|
|
138
|
+
b = { l: Math.min(b.l, q.left), t: Math.min(b.t, q.top), r: Math.max(b.r, q.right), b: Math.max(b.b, q.bottom) }; }
|
|
139
|
+
return { ...b, w: Math.round(b.r - b.l), h: Math.round(b.b - b.t) }; };
|
|
140
|
+
// Links inside a sentence are exempt from WCAG 2.5.8: their size follows the line of text.
|
|
141
|
+
const inline = el => el.tagName === 'A' && CS(el).display === 'inline' && !!el.closest('p,li,dd,td,blockquote,figcaption') &&
|
|
142
|
+
[...el.parentElement.childNodes].some(n => n.nodeType === 3 && n.textContent.trim().length > 12);
|
|
143
|
+
const gap = (a, b) => Math.round(Math.max(a.l - b.r, b.l - a.r, a.t - b.b, b.t - a.b, 0));
|
|
144
|
+
const hits = targets.filter(el => !inline(el)).map(el => ({ el, ...hit(el) }));
|
|
145
|
+
|
|
146
|
+
// FITTS — size, spacing, position of the main action
|
|
147
|
+
const small = hits.filter(t => Math.min(t.w, t.h) < 44);
|
|
148
|
+
const tiny = small.filter(t => Math.min(t.w, t.h) < 24);
|
|
149
|
+
const sized = t => ({ name: label(t.el), w: t.w, h: t.h });
|
|
150
|
+
const crowded = [];
|
|
151
|
+
hits.forEach((a, i) => hits.slice(i + 1).forEach(b => {
|
|
152
|
+
if (Math.min(a.w, a.h, b.w, b.h) >= 44 || a.el.contains(b.el) || b.el.contains(a.el)) return;
|
|
153
|
+
const g = gap(a, b); if (g < 8) crowded.push({ a: label(a.el), b: label(b.el), gapPx: g }); }));
|
|
154
|
+
crowded.sort((p, q) => p.gapPx - q.gapPx);
|
|
155
|
+
|
|
156
|
+
// VON RESTORFF — filled, saturated controls competing in the first fold
|
|
157
|
+
const rgb = c => (c.match(/[\d.]+/g) || []).map(Number);
|
|
158
|
+
const filled = el => { const [r, g, b, a = 1] = rgb(CS(el).backgroundColor);
|
|
159
|
+
return a > 0.5 && (Math.max(r, g, b) - Math.min(r, g, b)) > 60; };
|
|
160
|
+
const pointerRoots = [...document.querySelectorAll('body *')].filter(el => vis(el) &&
|
|
161
|
+
CS(el).cursor === 'pointer' && CS(el.parentElement).cursor !== 'pointer' &&
|
|
162
|
+
!el.matches(SEL + ',label') && !el.closest(SEL + ',label'));
|
|
163
|
+
const accents = {};
|
|
164
|
+
[...targets, ...pointerRoots].filter(el => inFold(el) && filled(el)).forEach(el => {
|
|
165
|
+
const k = CS(el).backgroundColor; (accents[k] = accents[k] || []).push(label(el)); });
|
|
166
|
+
|
|
167
|
+
// HICK — sets of options offered at once
|
|
168
|
+
const choiceSets = [];
|
|
169
|
+
document.querySelectorAll('nav,[role=navigation],[role=tablist],[role=toolbar],[role=menu],[role=radiogroup]')
|
|
170
|
+
.forEach(c => { const n = [...c.querySelectorAll(SEL)].filter(vis).length;
|
|
171
|
+
if (n) choiceSets.push({ set: c.getAttribute('aria-label') || c.tagName.toLowerCase(), options: n,
|
|
172
|
+
grouped: !!c.querySelector('h2,h3,h4,h5,[role=group],hr,ul ul,details') }); });
|
|
173
|
+
document.querySelectorAll('select').forEach(s => { if (vis(s)) choiceSets.push({ set: 'select:' + label(s),
|
|
174
|
+
options: s.options.length, grouped: !!s.querySelector('optgroup') }); });
|
|
175
|
+
const radios = {};
|
|
176
|
+
document.querySelectorAll('input[type=radio][name]').forEach(r => {
|
|
177
|
+
if (vis(r) || [...(r.labels || [])].some(vis)) (radios[r.name] = radios[r.name] || []).push(r); });
|
|
178
|
+
Object.entries(radios).forEach(([name, rs]) => choiceSets.push({ set: 'radio:' + name, options: rs.length,
|
|
179
|
+
preselected: rs.some(r => r.checked) }));
|
|
180
|
+
const byLabel = {};
|
|
181
|
+
targets.filter(el => /^(BUTTON|A)$/.test(el.tagName) || el.getAttribute('role') === 'button')
|
|
182
|
+
.forEach(el => { const k = label(el); byLabel[k] = (byLabel[k] || 0) + 1; });
|
|
183
|
+
const repeatedActions = Object.entries(byLabel).filter(([, n]) => n >= 3).map(([name, count]) => ({ name, count }));
|
|
184
|
+
|
|
185
|
+
// MILLER — things the user has to hold in their head
|
|
186
|
+
const inputs = targets.filter(el => /^(INPUT|TEXTAREA|SELECT)$/.test(el.tagName) && !/^(submit|button|reset|image)$/.test(el.type));
|
|
187
|
+
const named = el => (el.labels && el.labels.length) || el.getAttribute('aria-label') || el.getAttribute('aria-labelledby') || el.title;
|
|
188
|
+
const forms = [...document.forms].map(f => { const fs = inputs.filter(el => f.contains(el));
|
|
189
|
+
return { form: f.getAttribute('aria-label') || f.getAttribute('name') || f.getAttribute('action') || 'form',
|
|
190
|
+
fields: fs.filter(el => el.type !== 'radio').length + new Set(fs.filter(el => el.type === 'radio').map(el => el.name)).size,
|
|
191
|
+
groups: [...f.querySelectorAll('fieldset,[role=group],h2,h3,h4')].filter(vis).length,
|
|
192
|
+
required: fs.filter(el => el.required).length }; });
|
|
193
|
+
const longNumericInputs = inputs.filter(el => el.tagName === 'INPUT' && (el.inputMode === 'numeric' || el.type === 'tel' ||
|
|
194
|
+
/cc-number|one-time-code/.test(el.autocomplete) || /card|otp|code|iban|account/i.test(el.name + el.id)))
|
|
195
|
+
.map(el => ({ name: label(el), maxLength: el.maxLength }));
|
|
196
|
+
const longCodes = cap([...new Set((document.body.innerText.match(/\b(?=[A-Z0-9]*\d{4})[A-Z0-9]{10,}\b/g) || []))]);
|
|
197
|
+
|
|
198
|
+
// GOAL-GRADIENT + ZEIGARNIK — is progress visible, and is this a multi-step flow?
|
|
199
|
+
const stepWords = /^(next|continue|back|previous)\b|^(次へ|戻る|進む|続ける)/i;
|
|
200
|
+
const progressText = (document.body.innerText.match(
|
|
201
|
+
/(step|ステップ)\s*\d+\s*(of|\/|/)\s*\d+|\d+\s*(of|\/|/)\s*\d+\s*(steps?|complete|done|完了)|\d{1,3}\s*%\s*(complete|done|完了)/gi) || []);
|
|
202
|
+
const progress = { indicators: document.querySelectorAll('progress,meter,[role=progressbar],[aria-current=step]').length,
|
|
203
|
+
text: cap(progressText), stepButtons: targets.filter(el => stepWords.test(label(el))).map(label) };
|
|
204
|
+
|
|
205
|
+
// JAKOB — conventions users bring from every other product
|
|
206
|
+
const isHome = a => { try { const u = new URL(a.href); return u.origin === location.origin && u.pathname === '/'; } catch { return false; } };
|
|
207
|
+
const jakob = {
|
|
208
|
+
homeLink: [...document.querySelectorAll('header a[href],[role=banner] a[href]')].some(isHome),
|
|
209
|
+
search: !!document.querySelector('input[type=search],[role=search],[role=searchbox]'),
|
|
210
|
+
fakeControls: cap(pointerRoots.map(el => el.tagName.toLowerCase() + ':' + label(el))),
|
|
211
|
+
inlineLinksNoUnderline: cap(targets.filter(el => inline(el) && CS(el).textDecorationLine === 'none').map(label)),
|
|
212
|
+
inputsUnder16px: inputs.filter(el => !/^(radio|checkbox|range|color|file)$/.test(el.type) && parseFloat(CS(el).fontSize) < 16).length,
|
|
213
|
+
noAutocomplete: inputs.filter(el => el.tagName === 'INPUT' && !el.autocomplete &&
|
|
214
|
+
(/^(email|tel|password)$/.test(el.type) || /name|mail|phone|tel|postal|zip|addr|card/i.test(el.name + el.id))).map(label),
|
|
215
|
+
};
|
|
216
|
+
const primary = hits.filter(t => inFold(t.el) && filled(t.el)).sort((a, b) => b.w * b.h - a.w * a.h)[0];
|
|
217
|
+
|
|
218
|
+
return {
|
|
219
|
+
viewport: { vw, vh, touch: matchMedia('(pointer: coarse)').matches },
|
|
220
|
+
fitts: { targets: hits.length, under24: tiny.length, under44: small.length,
|
|
221
|
+
smallest: cap(small.sort((a, b) => Math.min(a.w, a.h) - Math.min(b.w, b.h)).map(sized)),
|
|
222
|
+
crowdedPairs: crowded.length, tightest: cap(crowded),
|
|
223
|
+
primaryGuess: primary ? { ...sized(primary), xPct: Math.round(100 * (primary.l + primary.w / 2) / vw),
|
|
224
|
+
yPct: Math.round(100 * (primary.t + primary.h / 2) / vh) } : null },
|
|
225
|
+
hick: { targetsInFold: targets.filter(inFold).length, choiceSets: choiceSets.filter(c => c.options > 4), repeatedActions },
|
|
226
|
+
vonRestorff: { accentsInFold: Object.entries(accents).map(([bg, names]) => ({ bg, count: names.length, names: cap(names) })),
|
|
227
|
+
loopingAnimations: cap([...document.querySelectorAll('body *')].filter(el => vis(el) &&
|
|
228
|
+
CS(el).animationName !== 'none' && CS(el).animationIterationCount === 'infinite').map(label)) },
|
|
229
|
+
miller: { forms, placeholderOnly: cap(inputs.filter(el => !named(el) && el.placeholder).map(label)),
|
|
230
|
+
unlabeled: cap(inputs.filter(el => !named(el) && !el.placeholder).map(label)), longNumericInputs, longCodes },
|
|
231
|
+
progress, jakob,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
The probe reports candidates. Confirm each one against the page before it
|
|
237
|
+
becomes a finding:
|
|
238
|
+
|
|
239
|
+
- It measures element boxes. A hit area extended by a pseudo-element or a padded parent handler reads smaller than it is
|
|
240
|
+
- `touch` reflects the device running the probe, not the resized width. Decide touch from the product
|
|
241
|
+
- `primaryGuess` is the largest filled control in the fold. When `accentsInFold` holds several, the guess is arbitrary — which is the Von Restorff finding. `null` means no filled action is visible before scrolling
|
|
242
|
+
- `fakeControls` relies on `cursor: pointer`. Click handlers without it need a code search (`onClick` on `div`/`span`). A real `<button>` that does nothing passes; flow walk 7 catches it
|
|
243
|
+
- `choiceSets` and `repeatedActions` count options (the same label on three or more buttons is usually a picker). Whether they need evaluating is the Hick precondition, judged in Step 3
|
|
244
|
+
- `longNumericInputs` lists fields to try by hand in flow walk 8; the DOM does not show how a field formats what is typed
|
|
245
|
+
- `longCodes` reads text content, so a code grouped only by CSS spacing still appears. Confirm by eye
|
|
246
|
+
|
|
247
|
+
### 2b. Flow walk
|
|
248
|
+
|
|
249
|
+
Eight checks the DOM cannot answer. Record one line each.
|
|
250
|
+
|
|
251
|
+
1. **Leave and return** — fill half the flow, reload, press Back, close and reopen. What survives? Is there a cue on return that work is waiting?
|
|
252
|
+
2. **Promise vs delivery** — count the steps the flow announces and the steps it takes. Note any step that appears after the announced last one
|
|
253
|
+
3. **Carry-over** — at each step, list what the user needs from an earlier screen: a code, a price, an instruction, a selection
|
|
254
|
+
4. **Travel** — trace the pointer or thumb through the primary task. Note long jumps between consecutive actions (last field bottom-left, submit top-right)
|
|
255
|
+
5. **Keyboard** — Tab through. Every target reachable, in visual order, with Enter and Esc doing what they do elsewhere
|
|
256
|
+
6. **Evaluate or look up** — for each choice set over 4, does the user weigh options or find a known one?
|
|
257
|
+
7. **Dead controls** — press every button and link on the primary path. Note any that does nothing, and any choice that never reaches the submitted data
|
|
258
|
+
8. **Type and paste** — in each long numeric field, type a value and paste one with spaces (`4242 4242 4242 4242`). Is it kept whole and grouped?
|
|
259
|
+
|
|
260
|
+
## Step 3 — Diagnose [LOW freedom thresholds, HIGH freedom judgment]
|
|
261
|
+
|
|
262
|
+
One row per finding: law, evidence, threshold, why the precondition holds,
|
|
263
|
+
severity. Thresholds marked *house* are working targets, adjustable for a
|
|
264
|
+
dense professional tool with a stated reason.
|
|
265
|
+
|
|
266
|
+
| Law | Evidence | Threshold | Basis |
|
|
267
|
+
|---|---|---|---|
|
|
268
|
+
| Fitts | `under24`, `smallest` | 0 targets under 24×24 CSS px, unless a 24px circle around each stays clear, the link sits in a sentence, or the control is an unstyled native default | WCAG 2.2 SC 2.5.8 (AA) |
|
|
269
|
+
| Fitts | `under44` on touch layouts | primary and frequent targets ≥ 44×44 CSS px (48 on Android) | Apple HIG 44pt, Material 48dp, WCAG 2.5.5 (AAA) |
|
|
270
|
+
| Fitts | `tightest` | ≥ 8px between targets when either is under 44; a destructive action never within 8px of a frequent one | Material spacing; *house* |
|
|
271
|
+
| Fitts | flow walk 4, `primaryGuess.yPct` | the completing action sits directly after the last input; on phones, within thumb reach or in a sticky bottom bar | *house* |
|
|
272
|
+
| Hick | `choiceSets`, flow walk 6 | choice sets over 7 that need evaluating are grouped, staged, or given a default | *house* |
|
|
273
|
+
| Hick | `repeatedActions`, `radio:` sets | pickers show ≤ 4 options with one recommended and preselected, when usage data supports the choice | *house* |
|
|
274
|
+
| Von Restorff | `accentsInFold` | one filled accent action per view | *house* |
|
|
275
|
+
| Von Restorff | `loopingAnimations` | nothing loops past 5s without a pause control; `prefers-reduced-motion` honoured | WCAG 2.2.2 (A) |
|
|
276
|
+
| Von Restorff | emphasis channels | emphasis uses colour plus size, weight, icon, or position, at ≥ 3:1 against neighbours | WCAG 1.4.1, 1.4.11 |
|
|
277
|
+
| Miller | `placeholderOnly`, `unlabeled` | 0 — every field keeps a visible label while filled | WCAG 3.3.2; *house* |
|
|
278
|
+
| Miller | `longCodes`, flow walk 8 | strings of 7+ characters shown in groups of 3–4 with Copy; inputs accept spaces and dashes | *house* |
|
|
279
|
+
| Miller | `forms[].fields` vs `groups` | forms over 7 fields split into labelled groups of 3–5 | *house* |
|
|
280
|
+
| Miller | flow walk 3 | nothing must be remembered from an earlier screen; entered data is reused | WCAG 3.3.7 (A) |
|
|
281
|
+
| Jakob | `fakeControls`, flow walk 5 and 7 | 0 — every control is a native element, or carries role, name, and keyboard support, and does something | WCAG 4.1.2, 2.1.1 |
|
|
282
|
+
| Jakob | `homeLink`, `search`, `inlineLinksNoUnderline`, `noAutocomplete` | logo links home; sentence links differ by more than colour; standard `autocomplete` tokens set | WCAG 1.4.1, 1.3.5 |
|
|
283
|
+
| Jakob | `inputsUnder16px` on phone layouts | 0 — iOS zooms the page when a focused field's text is under 16px | platform behaviour |
|
|
284
|
+
| Goal-Gradient | `progress`, flow walk 2 | flows of 3+ steps show position and total; the indicator never moves backward; the total never grows after start | *house* |
|
|
285
|
+
| Zeigarnik | flow walk 1 | input survives reload and Back; the return screen offers a way to resume | *house* |
|
|
286
|
+
|
|
287
|
+
**Severity.** *Blocker*: the task fails or work is lost (a primary target
|
|
288
|
+
under 24px, a control that does nothing or that the keyboard cannot reach,
|
|
289
|
+
input wiped on Back or reload). *Major*: the primary task is measurably
|
|
290
|
+
slower or misleading (several equal accents, placeholder-only labels on a
|
|
291
|
+
long form, a 5-step flow with no position). *Minor*: secondary paths and
|
|
292
|
+
polish.
|
|
293
|
+
|
|
294
|
+
## Step 4 — Resolve conflicts [HIGH freedom]
|
|
295
|
+
|
|
296
|
+
The laws optimise different things, so a fix for one can break another.
|
|
297
|
+
|
|
298
|
+
| Conflict | Resolution |
|
|
299
|
+
|---|---|
|
|
300
|
+
| Hick vs Fitts — hiding options adds taps and travel | Keep the top 3–5 options by real usage visible; hide only the long tail. One extra tap costs more than two extra options |
|
|
301
|
+
| Hick vs Jakob — trimming an item users expect to find | Conventional items stay (search, cart, account, back). Trim what is specific to this product |
|
|
302
|
+
| Von Restorff vs Jakob — a distinct control that no longer reads as a control | Differ in colour, size, or position; keep the conventional shape and behaviour |
|
|
303
|
+
| Fitts vs density — larger targets push content off screen and into memory | On dense desktop tools, enlarge the hit area with padding or a pseudo-element while the visible control stays compact |
|
|
304
|
+
| Miller vs Goal-Gradient — more, smaller steps lengthen the road | Split until each step holds one decision or 3–5 fields, then show position and total |
|
|
305
|
+
| Zeigarnik and Goal-Gradient vs calm — every cue is a demand on attention | One open-loop cue per surface, tied to real state, with a way to finish it or dismiss it |
|
|
306
|
+
|
|
307
|
+
When no row applies, order by what fails hardest: can't hit or can't operate
|
|
308
|
+
→ breaks an expectation → too many choices → weak emphasis → weak motivation.
|
|
309
|
+
The first two stop the task; the rest slow it.
|
|
310
|
+
|
|
311
|
+
## Step 5 — Fix [HIGH freedom]
|
|
312
|
+
|
|
313
|
+
Repair a broken flow before tuning it: no law helps a task that cannot
|
|
314
|
+
complete. Dead controls get behaviour or get removed, and a choice the user
|
|
315
|
+
makes has to reach the submitted data. Record every resulting change to what
|
|
316
|
+
the backend receives.
|
|
317
|
+
|
|
318
|
+
Then fix in the shared component or token when a finding repeats, and use the
|
|
319
|
+
design system's existing variants. Progress, drafts, and completeness cues
|
|
320
|
+
read real state; when the state does not exist, add the smallest persistence
|
|
321
|
+
that makes the cue true, or propose it.
|
|
322
|
+
|
|
323
|
+
**Fitts**
|
|
324
|
+
- Raise the minimum height and padding on the `Button`, `IconButton`, and row-action primitives; add gap tokens between adjacent targets
|
|
325
|
+
- Extend hit areas without enlarging chrome: padding, a wrapping `<label>`, or an inset pseudo-element
|
|
326
|
+
- Shorten travel: submit directly under the last field, row actions on the row, the next step where the last one ended. On phones, a sticky bottom action bar clear of the safe area
|
|
327
|
+
- Screen edges are effectively infinite targets for a mouse only when the control touches the edge with no margin; touch gets no such benefit
|
|
328
|
+
- Separate destructive from frequent actions by distance. Offer undo where the server can reverse the action; otherwise confirm
|
|
329
|
+
|
|
330
|
+
**Hick**
|
|
331
|
+
- Recommend one option: preselected, labelled with a reason that is true ("Most booked")
|
|
332
|
+
- Disclose progressively: frequent options visible, the rest behind "More" or an advanced section
|
|
333
|
+
- Stage decisions one per step when each depends on the last
|
|
334
|
+
- Group related options under headings; replace long known-item lists with typeahead
|
|
335
|
+
- Fill defaults from real data: last used, locale, the account's plan
|
|
336
|
+
- Without usage data, keep every option visible, group them, preselect nothing, and list the missing data as an open item. A recommendation needs a true reason
|
|
337
|
+
|
|
338
|
+
**Von Restorff**
|
|
339
|
+
- Give one action per view the filled accent variant; move the others to outline, ghost, or text variants
|
|
340
|
+
- Isolate with whitespace and position as well as colour
|
|
341
|
+
- Spend the accent on the user's task, not on promotion; emphasis styled like an advert gets ignored
|
|
342
|
+
- Stop looping animation after the first cycle or on interaction
|
|
343
|
+
|
|
344
|
+
**Miller**
|
|
345
|
+
- Add persistent labels; move help text beside the field it explains; show errors inline at the field
|
|
346
|
+
- Format long strings in groups and add Copy; accept any spacing on input
|
|
347
|
+
- Keep earlier choices in view: a summary panel, selected filters as chips, a review step before commit
|
|
348
|
+
- Put compared items in one view, side by side
|
|
349
|
+
- Group long forms into labelled fieldsets of 3–5 fields
|
|
350
|
+
|
|
351
|
+
**Jakob**
|
|
352
|
+
- Replace `div`/`span` controls with `<button>`, `<a>`, `<select>`, `<label>`
|
|
353
|
+
- Put the logo, navigation, search, account, and cart where the platform puts them; use the words users already know ("Sign in", "Cart", "Settings")
|
|
354
|
+
- Keep Enter, Esc, Back, and swipe-back doing what they do everywhere else; Back preserves input
|
|
355
|
+
- Set `autocomplete` tokens so the browser fills what it knows
|
|
356
|
+
- Compare against two or three products the target users open daily, in their locale. When a deviation is worth it, make one and teach it
|
|
357
|
+
- For a redesign of a product people already use, their expectations come from the old version: stage the change or offer a preview
|
|
358
|
+
|
|
359
|
+
**Zeigarnik**
|
|
360
|
+
- Autosave drafts per field or per step; restore on return
|
|
361
|
+
- Add a resume entry where returning users land: "Continue your booking"
|
|
362
|
+
- Show what remains as a short checklist built from real completion flags
|
|
363
|
+
- Every cue offers a way to finish and a way to dismiss
|
|
364
|
+
- Drafts never hold card numbers, security codes, passwords, or one-time codes; they expire; and the draft and its cue are cleared when the task completes
|
|
365
|
+
|
|
366
|
+
**Goal-Gradient**
|
|
367
|
+
- Show position and total ("Step 2 of 3"), or time remaining when length varies
|
|
368
|
+
- Count completed prerequisites as progress: an account already created is step 1 done
|
|
369
|
+
- Make the first step quick so progress is felt early; announce every step up front
|
|
370
|
+
- Break long goals into sub-goals so a finish line is always near; near the end, show what is left ("1 step left")
|
|
371
|
+
- Make steps behave like pages: each gets a history entry so Back moves one step, focus moves to the step heading, and validation runs per step
|
|
372
|
+
|
|
373
|
+
Cues with no state behind them are out of scope as fixes: unread badges for
|
|
374
|
+
nothing, a meter that cannot reach 100%, a bar driven by a timer, a head
|
|
375
|
+
start that was not earned. They work once and cost the product its
|
|
376
|
+
credibility.
|
|
377
|
+
|
|
378
|
+
## Step 6 — Verify [LOW freedom — run exactly]
|
|
379
|
+
|
|
380
|
+
1. Re-run the probe at the same widths and states; save `after-*.json` and `after-*.png`
|
|
381
|
+
2. Repeat the flow-walk checks that produced findings
|
|
382
|
+
3. Fill the before → after column for every finding. A metric still over threshold stays in the report with its reason
|
|
383
|
+
4. Run the repo's lint, typecheck, and tests for the touched components. Where none exist, script the flow walk and report that
|
|
384
|
+
|
|
385
|
+
## Output format
|
|
386
|
+
|
|
387
|
+
1. **Scope** — route, primary task, users, pointer types, widths and states measured
|
|
388
|
+
2. **Measurements** — law | metric | threshold | before (phone / desktop) | after (phone / desktop)
|
|
389
|
+
3. **Flow walk** — check | before | after
|
|
390
|
+
4. **Findings** — # | law | evidence | precondition | severity | fix | file
|
|
391
|
+
5. **Not findings** — probe candidates dismissed, with the precondition that failed
|
|
392
|
+
6. **Conflicts** — which laws disagreed, which won, why
|
|
393
|
+
7. **Changes** — files touched, primitive-level changes first; then contract changes: fields the backend now receives differently, new required or optional decisions, what is persisted and for how long
|
|
394
|
+
8. **Open items** — metrics still over threshold with the reason; state or data that must exist before a cue can be built; handoffs
|
|
395
|
+
|
|
396
|
+
## Other surfaces
|
|
397
|
+
|
|
398
|
+
- **Native (React Native, SwiftUI, Compose)** — the probe is web-only. Measure with layout callbacks or the inspector; thresholds are 44pt on iOS and 48dp on Android. With the pack installed, `mobile-rn-screen` owns the screen
|
|
399
|
+
- **Mockup or screenshot only** — run the same pass by estimating from the image, and mark every value "estimated"
|
|
400
|
+
|
|
401
|
+
## Related
|
|
402
|
+
|
|
403
|
+
- `enhance-web-ux` — NN/g heuristics and DOM forensics for one page
|
|
404
|
+
- `audit-ux` — heuristic report without fixes
|
|
405
|
+
- `audit-accessibility` — full WCAG sweep; this skill uses a few criteria as thresholds
|
|
406
|
+
- `enhance-web-forms` — validation, schema parity, form structure
|
|
407
|
+
- `enhance-onboarding` — activation event and steps to first value
|
|
408
|
+
- `enhance-web-conversion` — pricing and landing-page persuasion
|
|
409
|
+
- `audit-responsive` — breakpoint layout
|
|
@@ -160,7 +160,9 @@ where convention exists.
|
|
|
160
160
|
> Time to make a decision = log₂(N+1) of options.
|
|
161
161
|
|
|
162
162
|
**Implication:** group related actions; collapse rarely-used options under "More"; never
|
|
163
|
-
show all 12 filters at once if 3 cover 90% of use.
|
|
163
|
+
show all 12 filters at once if 3 cover 90% of use. Applies only when options must be
|
|
164
|
+
weighed; looking up a known item in an ordered list (a country, a prefecture) is search,
|
|
165
|
+
so give it typeahead instead of trimming it.
|
|
164
166
|
|
|
165
167
|
### Fitts's Law
|
|
166
168
|
|
|
@@ -172,10 +174,14 @@ NOT immediately adjacent to common ones.
|
|
|
172
174
|
|
|
173
175
|
### Miller's Law
|
|
174
176
|
|
|
175
|
-
> The average person can hold ~7 ± 2 items in working memory
|
|
177
|
+
> The average person can hold ~7 ± 2 items in working memory; later work puts it nearer 4
|
|
178
|
+
> (Cowan, 2001).
|
|
176
179
|
|
|
177
|
-
**Implication:**
|
|
178
|
-
|
|
180
|
+
**Implication:** it is about what the user must *hold in mind*, not how many items a screen
|
|
181
|
+
shows. A visible menu is read, not memorised, so this law sets no cap on menu length. Do:
|
|
182
|
+
keep labels visible while fields are filled, show earlier choices instead of making users
|
|
183
|
+
remember them, group long codes in 3–4s with Copy, split long forms into labelled groups of
|
|
184
|
+
3–5 fields, show running totals. For a measured pass on one flow, use `enhance-ux-laws`.
|
|
179
185
|
|
|
180
186
|
### Tesler's Law (Law of Conservation of Complexity)
|
|
181
187
|
|
|
@@ -3,8 +3,7 @@ name: mobile-capacitor-platform
|
|
|
3
3
|
description: >
|
|
4
4
|
Capacitor work beyond UI: plugins, OTA, deep links, push, offline, native
|
|
5
5
|
CI/CD, store submission, Cordova migration. Use for "add push
|
|
6
|
-
notifications", "deep linking", "OTA update",
|
|
7
|
-
rejection", or "migrate to Capacitor".
|
|
6
|
+
notifications", "deep linking", "OTA update", or "App Store rejection".
|
|
8
7
|
license: MIT
|
|
9
8
|
paths:
|
|
10
9
|
- "**/ios/**"
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
name: test-red-team
|
|
3
3
|
description: >
|
|
4
4
|
Red-team a running web, React Native, or Capacitor app. Use when "red team
|
|
5
|
-
this app", "attack my app", "break it", "
|
|
6
|
-
|
|
7
|
-
test → test-exploratory.
|
|
5
|
+
this app", "attack my app", "break it", "pentest the app", or "pre-launch
|
|
6
|
+
hardening". Monkey test → test-exploratory.
|
|
8
7
|
license: MIT
|
|
9
8
|
effort: high
|
|
10
9
|
---
|