@hiver/skills 1.0.8 → 1.0.9
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/README.md +1 -1
- package/collections/extension/agents/build-feature.md +2 -1
- package/collections/extension/agents/build-milestone.md +2 -1
- package/collections/extension/skills/build-component/SKILL.md +75 -1
- package/collections/extension/skills/build-component/palette/colors.md +76 -0
- package/collections/extension/skills/build-component/references/v2-components.md +100 -0
- package/collections/extension/skills/build-component/references/v2-usage-examples.md +23 -0
- package/collections/extension/skills/build-component/typography/variants.md +27 -14
- package/collections/mobile/skills/version-bump-up/SKILL.md +66 -0
- package/collections/qa-skills/README.md +103 -0
- package/collections/qa-skills/qa-suite-guide.html +760 -0
- package/collections/qa-skills/skills/hiver-explore/SKILL.md +413 -0
- package/collections/qa-skills/skills/hiver-explore/references/spec-template.md +204 -0
- package/collections/qa-skills/skills/playwright-gen/SKILL.md +280 -0
- package/collections/qa-skills/skills/playwright-gen/references/codegen-conventions.md +100 -0
- package/collections/qa-skills/skills/playwright-gen/references/step-mapping.md +137 -0
- package/collections/qa-skills/skills/qa-api-author/SKILL.md +204 -0
- package/collections/qa-skills/skills/qa-api-author/references/api-areas.md +112 -0
- package/collections/qa-skills/skills/qa-api-run/SKILL.md +178 -0
- package/collections/qa-skills/skills/qa-bugs/SKILL.md +82 -0
- package/collections/qa-skills/skills/qa-eval/SKILL.md +123 -0
- package/collections/qa-skills/skills/qa-eval/references/deterministic-checks.md +89 -0
- package/collections/qa-skills/skills/qa-kit/SKILL.md +228 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/INDEX.md +31 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/INDEX.md +90 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/account-security.md +44 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/apps-integrations.md +43 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/automate-workflows.md +65 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/collaborate.md +36 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/customer-relationships.md +20 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/getting-started.md +31 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/hiver-ai.md +79 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/multichannel-support.md +82 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/reporting-analytics.md +35 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/self-service.md +23 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/sla-policies.md +30 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/hig/troubleshooting.md +27 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/INDEX.md +45 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/account-security.md +13 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/apps-integrations.md +15 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/automate-workflows.md +26 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/collaborate.md +11 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/customer-relationships.md +9 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/getting-started.md +21 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/hiver-ai.md +13 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/identity-access.md +23 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/multichannel-support.md +47 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/reporting-analytics.md +13 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/self-service.md +11 -0
- package/collections/qa-skills/skills/qa-kit/knowledge-base/hiver/omni/sla-policies.md +12 -0
- package/collections/qa-skills/skills/qa-kit/references/clickup-ticket.md +163 -0
- package/collections/qa-skills/skills/qa-kit/references/eval.md +117 -0
- package/collections/qa-skills/skills/qa-kit/references/flow-capture.md +147 -0
- package/collections/qa-skills/skills/qa-kit/references/handoff-contract.md +159 -0
- package/collections/qa-skills/skills/qa-kit/references/hiver-context.md +99 -0
- package/collections/qa-skills/skills/qa-kit/references/tracker-format.md +123 -0
- package/collections/qa-skills/skills/qa-kit/references/triage-guide.md +105 -0
- package/collections/qa-skills/skills/qa-ui-author/SKILL.md +208 -0
- package/collections/qa-skills/skills/qa-ui-author/references/test-areas.md +132 -0
- package/collections/qa-skills/skills/qa-ui-run/SKILL.md +183 -0
- package/collections/web/agents/build-feature.md +2 -2
- package/collections/web/agents/build-milestone.md +2 -2
- package/collections/web/skills/build-component/SKILL.md +54 -13
- package/collections/web/skills/build-component/palette/colors.md +76 -0
- package/collections/web/skills/build-component/references/v2-components.md +100 -0
- package/collections/web/skills/build-component/references/v2-usage-examples.md +23 -0
- package/collections/web/skills/build-component/typography/variants.md +27 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ npx @hiver/skills add
|
|
|
16
16
|
|
|
17
17
|
This walks you through:
|
|
18
18
|
1. **Pick your IDE** — Claude Code, Cursor, or Windsurf
|
|
19
|
-
2. **Pick a collection** — `common` (generic)
|
|
19
|
+
2. **Pick a collection** — `common` (generic), `web` (React/Hiver-specific), `extension`, or `qa-skills` (QA→release pipeline; start with `qa-kit`)
|
|
20
20
|
3. **Pick type** — Skills or Agents (only shown if both exist)
|
|
21
21
|
4. **Pick items** — Select which skills/agents to install
|
|
22
22
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: build-feature
|
|
3
|
-
model:
|
|
3
|
+
model: inherit
|
|
4
4
|
description: Senior Manager owning a PRD to build the feature from end to end
|
|
5
|
+
tools: Agent, Bash, Edit, Glob, Grep, Read, SendMessage, Write
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
You are a Senior Manager who has owned a PRD to develop the feature or issue mentioned inside it from end to end.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: build-milestone
|
|
3
|
-
model:
|
|
3
|
+
model: inherit
|
|
4
4
|
description: Senior Frontend specialist helping to complete a milestone from the PRD document.
|
|
5
|
+
tools: Write, Bash, Edit, Glob, Grep, Read, SendMessage, Skill
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
You are a Senior frontend developer with years of experience in frontend development, debugging issues and developing features from end to end.
|
|
@@ -11,6 +11,77 @@ description: Build UI React components following Hiver design system and pattern
|
|
|
11
11
|
|
|
12
12
|
When building UI React components, use the currently selected Figma node as the design reference and follow the Hiver design system. Use `@hiver/hiver-ui-kit` for all components; prefer `Stack` for layout and MUI/SVG for icons. Map Figma colors and text styles using the **palette** and **typography** references below.
|
|
13
13
|
|
|
14
|
+
## Two component tracks
|
|
15
|
+
|
|
16
|
+
The Hiver UI kit exposes both **v1** and **v2** components:
|
|
17
|
+
|
|
18
|
+
- v1 → `import { … } from '@hiver/hiver-ui-kit'` — see `references/ui-kit-and-styling.md`
|
|
19
|
+
- v2 → `import { … } from '@hiver/hiver-ui-kit/v2'` — see `references/v2-components.md`
|
|
20
|
+
|
|
21
|
+
Palette (`palette/colors.md`) and Typography (`typography/variants.md`) list v1 and v2 tokens together — the theme merges both onto `theme.palette` and `Typography` variants when the provider has `v2` enabled. Match Figma against those lists; the matched token/variant name tells you which world the design lives in.
|
|
22
|
+
|
|
23
|
+
Do not mix v1 and v2 components in the same composition unless the design explicitly calls for it (composing v1 chrome like `Popover` / `Modal` / `Stack` around v2 content IS expected — see `references/v2-usage-examples.md`). Never reference `theme.v2.primitives.*` or `theme.v2.tokens.*` for **colour** in application code — always go through `theme.palette.*`. Non-colour primitives (spacing, radius, border-width, iconSize, font-family/size/weight, line-height) DO go through `theme.v2.primitives.*` in v2 code.
|
|
24
|
+
|
|
25
|
+
### v2 detection rules
|
|
26
|
+
|
|
27
|
+
Use these clues to decide v2 vs v1 before loading any component detail. Any single clue is sufficient — they're deterministic against the Figma design-token pipeline:
|
|
28
|
+
|
|
29
|
+
- Text uses font family **Inter** → v2. (v1 is Open Sans.)
|
|
30
|
+
- Text style resolves to a variant named `body_<sz>_<w>`, `heading_<sz>_<w>`, `display_<sz>_<w>`, `caption_<w>`, or `overline_<w>` → v2. (v1 uses `h2_medium`, `body1_regular`, `caption1_regular`, etc.)
|
|
31
|
+
- Fill / stroke / text token resolves to `theme.palette.<group>.<slot>` where `<group>` is one of `text`, `background`, `foreground`, `border`, `effect`, `charts`, and `<slot>` is one of `neutral`, `brand`, `success`, `warning`, `error`, `info`, `royal`, `accents.<tone>`, `on.<tone>`, or a semantic step (`subtle` / `soft` / `default` / `strong` / `intense`) → v2. (v1 shape: `palette.gray.gray4`, `palette.blue.primary`.)
|
|
32
|
+
- Fill / stroke token resolves to a primitive ramp `theme.palette.<ramp>[<shade>]` where `<ramp>` is one of `gray`, `royal`, `blue`, `red`, `green`, `orange`, `yellow`, `teal`, `cyan`, `violet`, `pink`, `indigo`, `lime`, `amber`, `sky`, `fuchsia`, and `<shade>` ∈ `25, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950` (or `alpha-*`) → v2.
|
|
33
|
+
- The Figma frame's component name matches an entry in `references/v2-components.md` (`Button`, `Badge`, `Tag`, `Checkbox`, `Radio`, `Switch`, `Avatar`, `IconButton`, `InlineSelectLabel`, `Breadcrumbs`, `Dropdown`, `Input.*`, `Tab.Item`, `Table.*`, `Toast`) → v2.
|
|
34
|
+
|
|
35
|
+
If a Figma design surfaces multiple worlds, treat the dominant *content* surface (the piece you're actually building) as authoritative and do not import v1 and v2 versions of the same component into one composition.
|
|
36
|
+
|
|
37
|
+
### Cross-repo pointer to `hiver-ui-kit`
|
|
38
|
+
|
|
39
|
+
v2 component detail (variants, prop matrix, slot list, Figma-variable → `theme.palette.*` reconciliation, caveats) lives in per-component `.figma-spec.md` files inside `hiver-ui-kit`, at `../hiver-ui-kit/src/v2/components/<Name>/.figma-spec.md` (relative to the extension repo root). Read the spec **on demand**, only when you're about to write JSX for that component. If `hiver-ui-kit` is not checked out at that path, `references/v2-components.md` still carries import paths and one-line purposes; you lose only the full token reconciliation. Ensure `hiver-ui-kit` is on the same git ref as the Figma source of truth before consuming a spec.
|
|
40
|
+
|
|
41
|
+
## Mandatory Rules (always apply)
|
|
42
|
+
|
|
43
|
+
### UI Kit and Styling
|
|
44
|
+
|
|
45
|
+
- **Use `@hiver/hiver-ui-kit`** for all UI components and styling. The package uses Material-UI (MUI) internally, so follow MUI patterns.
|
|
46
|
+
- **Pick the track based on the Figma design** (see "v2 detection rules" above):
|
|
47
|
+
- v1 → `import { Stack, Button, Typography, TextField, Select, Modal } from '@hiver/hiver-ui-kit';`
|
|
48
|
+
- v2 → `import { Button, IconButton, Input, Dropdown, Avatar, Tag, Badge, Typography } from '@hiver/hiver-ui-kit/v2';` — requires a v2-enabled provider (see `references/v2-components.md`).
|
|
49
|
+
- Chrome / layout primitives (`Modal`, `Popover`, `Popper`, `Tooltip`, `Stack`, `Box`, `Grid`) always come from v1 — wrap them around v2 content when needed (see `references/v2-usage-examples.md`).
|
|
50
|
+
- **Map Figma to design tokens**: use [palette/README.md](palette/README.md) for colors and [typography/README.md](typography/README.md) for text styles. The matched token/variant name tells you the track: v1 names (`body1_regular`, `palette.gray.gray4`) → v1 components; v2 names (`body_md_regular`, `theme.palette.text.neutral.strong`, primitive ramps) → v2 components.
|
|
51
|
+
- **Analyze the Figma selection** to identify all required components:
|
|
52
|
+
- **v1 designs**:
|
|
53
|
+
- Form inputs: `TextField`, `Select`, `Checkbox`, `Radio`.
|
|
54
|
+
- Typography: `<Typography variant="body1_regular">`, `"h2_medium"`, `"caption1_medium"`, etc.
|
|
55
|
+
- Buttons: `Button` with `contained` / `outlined` / `text`.
|
|
56
|
+
- Modals: `Modal`.
|
|
57
|
+
- Other: `Tooltip`, `CircularProgress`, `IconButton`.
|
|
58
|
+
- **v2 designs** (full index in `references/v2-components.md`):
|
|
59
|
+
- Form inputs: `Input.Text` / `Input.TextArea` / `Input.Search` / `Input.Tags`, `Checkbox`, `Radio`, `Switch`.
|
|
60
|
+
- Typography: `<Typography variant="body_md_regular">`, `"heading_lg_semiBold"`, `"caption_medium"`, etc.
|
|
61
|
+
- Buttons: `Button` (variant × tone × size) and `IconButton` for icon-only actions.
|
|
62
|
+
- Menus / dropdowns: `Dropdown.Menu` + `Dropdown.ListItem` inside a v1 `Popover` (v2 provides only the visible surface — anchoring / open state is your job).
|
|
63
|
+
- Chips / labels / status: `Tag`, `Badge`, `Avatar`, `InlineSelectLabel`, `Toast`, `Breadcrumbs`, `Tab.Item`, `Table.*`.
|
|
64
|
+
- Modals: v1 `Modal` shell around v2 content (v2 `Button` + v2 `IconButton` for the close X).
|
|
65
|
+
|
|
66
|
+
### Layout and Structure
|
|
67
|
+
|
|
68
|
+
- **Prefer `Stack` component** for flex layouts instead of raw flexbox CSS
|
|
69
|
+
- Use `Stack` with `direction="row"` or `direction="column"`
|
|
70
|
+
- Use `gap` prop for spacing between items
|
|
71
|
+
- Example: `<Stack direction="row" gap={2} alignItems="center">`
|
|
72
|
+
- **Use `Box`** for simple container elements or when you need custom styling
|
|
73
|
+
- Use `sx` prop for component-specific styling
|
|
74
|
+
|
|
75
|
+
### Component Organization
|
|
76
|
+
|
|
77
|
+
- **Small sub-components** (less than ~50 lines, simple logic):
|
|
78
|
+
- Define them in the same file, outside the main component
|
|
79
|
+
- Place them above the main component export
|
|
80
|
+
- **Large sub-components** (complex logic, reusable, >50 lines):
|
|
81
|
+
- Extract to separate files in the same directory or `components/` subdirectory
|
|
82
|
+
- Follow the pattern: `ComponentName/index.js` for main component, `ComponentName/SubComponent.js` for sub-components
|
|
83
|
+
- **File naming**: Use PascalCase for component files (e.g., `TagItem.js`, `ModifyTagDialog.js`)
|
|
84
|
+
|
|
14
85
|
## Reference files
|
|
15
86
|
|
|
16
87
|
**Load lazily — only read a reference file when you are about to perform that specific task. Do NOT read all files upfront.**
|
|
@@ -18,7 +89,10 @@ When building UI React components, use the currently selected Figma node as the
|
|
|
18
89
|
| Topic | File | When to load |
|
|
19
90
|
|-------|------|--------------|
|
|
20
91
|
| Figma integration | [references/figma-integration.md](references/figma-integration.md) | Only when a Figma link is present |
|
|
21
|
-
| UI Kit and styling | [references/ui-kit-and-styling.md](references/ui-kit-and-styling.md) | Before writing component JSX/styles |
|
|
92
|
+
| UI Kit and styling (v1) | [references/ui-kit-and-styling.md](references/ui-kit-and-styling.md) | Before writing v1 component JSX/styles |
|
|
93
|
+
| v2 components (index) | [references/v2-components.md](references/v2-components.md) | First lookup when the design is v2 — find the component name and its ui-kit spec path |
|
|
94
|
+
| v2 component detail (per component) | `../hiver-ui-kit/src/v2/components/<Name>/.figma-spec.md` | On demand, after the v2 index points at a specific `<Name>` |
|
|
95
|
+
| v2 usage examples (compositions) | [references/v2-usage-examples.md](references/v2-usage-examples.md) | Before composing v2 patterns (dropdown-in-popover, inline-field trigger, modal, toolbar) |
|
|
22
96
|
| Layout and structure | [references/layout-and-structure.md](references/layout-and-structure.md) | Only when laying out a new screen/panel |
|
|
23
97
|
| Icons | [references/icons.md](references/icons.md) | Only when adding icons |
|
|
24
98
|
| Component organization | [references/component-organization.md](references/component-organization.md) | Only when splitting into sub-components |
|
|
@@ -85,3 +85,79 @@ Use these when wiring to MUI theme (e.g. `color="primary"`, `color="text.seconda
|
|
|
85
85
|
- **Info**: blue
|
|
86
86
|
- **Warning**: orange
|
|
87
87
|
- **Divider**: `gray.gray6`
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Additional tokens
|
|
92
|
+
|
|
93
|
+
More tokens available on the same `theme.palette` object (in addition to the tables above). Reference these paths — not `theme.v2.primitives.*` or `theme.v2.tokens.*` (raw layers, not for application code).
|
|
94
|
+
|
|
95
|
+
### Primitive ramps (accessed as `theme.palette.<name>.<shade>`)
|
|
96
|
+
|
|
97
|
+
The following ramps land directly on `theme.palette`:
|
|
98
|
+
|
|
99
|
+
- **Neutral**: `white`, `black`, `gray`
|
|
100
|
+
- **Brand/status**: `yellow`, `red`, `green`, `orange`, `blue`
|
|
101
|
+
- **Accents**: `royal`, `teal`, `cyan`, `violet`, `pink`, `indigo`, `lime`, `amber`, `sky`, `fuchsia`
|
|
102
|
+
|
|
103
|
+
Each ramp has shades `25`, `50`, `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`, `950`, plus `alpha-*` variants (e.g. `alpha-10`, `alpha-20`, `alpha-30`).
|
|
104
|
+
|
|
105
|
+
Example: `theme.palette.royal[500]`, `theme.palette.gray[950]`, `theme.palette.blue['alpha-18']`.
|
|
106
|
+
|
|
107
|
+
### Semantic groups (accessed as `theme.palette.<group>.*`)
|
|
108
|
+
|
|
109
|
+
Values differ between light and dark modes — the same path resolves to the right hex for the active mode.
|
|
110
|
+
|
|
111
|
+
**`theme.palette.text.*`** — extends MUI's built-in `primary` / `secondary` / `disabled` with:
|
|
112
|
+
- `text.primary` → strong neutral text (light: `gray.900`)
|
|
113
|
+
- `text.secondary` → soft neutral text (light: `gray.500`)
|
|
114
|
+
- `text.disabled` → `gray.400`
|
|
115
|
+
- `text.inverse` → `gray.25`
|
|
116
|
+
- `text.neutral.{subtle,soft,default,strong,intense}`
|
|
117
|
+
- `text.brand.{subtle,soft,default,strong,intense}`
|
|
118
|
+
- `text.royal.{...}` / `text.success.{...}` / `text.warning.{...}` / `text.error.{...}` / `text.info.{...}`
|
|
119
|
+
- `text.accents.<tone>.{subtle,soft,default,strong,intense}` where `<tone>` is one of `teal`, `cyan`, `violet`, `pink`, `indigo`, `lime`, `amber`, `sky`, `fuchsia`, `green`, `blue`, `orange`, `red`, `gray`
|
|
120
|
+
- `text.on.{brand,success,warning,error,info,royal}` — foreground when placed on a solid tone-fill
|
|
121
|
+
- `text.on.accents.<tone>` — same, for accent surfaces
|
|
122
|
+
|
|
123
|
+
**`theme.palette.background.*`** — extends MUI's built-in `default` / `paper` with:
|
|
124
|
+
- `background.default` → `background.neutral.subtle` (light: `gray.25`)
|
|
125
|
+
- `background.paper` → `background.neutral.default` (light: `gray.100`)
|
|
126
|
+
- `background.disabled` / `background.inverse` / `background.overlay` / `background['selected-hover']`
|
|
127
|
+
- `background.alpha.{5}` / `background.static.{white,black}`
|
|
128
|
+
- `background.neutral.{white,subtle,soft,default,strong,intense,extreme,maximum}`
|
|
129
|
+
- `background['neutral-bold'].{soft,default,strong,intense,black}`
|
|
130
|
+
- `background.brand.{subtle,soft,default,strong,intense}`
|
|
131
|
+
- `background.royal.{...}` / `background.success.{...}` / `background.warning.{...}` / `background.error.{...}` / `background.info.{...}`
|
|
132
|
+
- `background.accents.<tone>.{subtle,soft,default,strong,intense}`
|
|
133
|
+
|
|
134
|
+
**`theme.palette.foreground.*`** — icon/glyph foreground colors:
|
|
135
|
+
- `foreground.inverse` / `foreground.disabled`
|
|
136
|
+
- `foreground.static.{white,black}` / `foreground.alpha.{30,40}`
|
|
137
|
+
- `foreground.neutral.{subtle,soft,default,strong,intense}`
|
|
138
|
+
- `foreground['neutral-bold'].{subtle,soft,default,strong,intense}`
|
|
139
|
+
- `foreground.brand.{...}` / `foreground.royal.{...}` / `foreground.success.{...}` / `foreground.warning.{...}` / `foreground.error.{...}` / `foreground.info.{...}`
|
|
140
|
+
- `foreground.accents.<tone>.{subtle,soft,default,strong,intense}`
|
|
141
|
+
- `foreground.on.{brand,success,warning,error,info,royal}` / `foreground.on.accents.<tone>`
|
|
142
|
+
|
|
143
|
+
**`theme.palette.border.*`** — stroke colors:
|
|
144
|
+
- `border.disabled`
|
|
145
|
+
- `border.neutral.{subtle,soft,default,strong,intense,extreme,maximum}`
|
|
146
|
+
- `border['neutral-bold'].{subtle,soft,default,strong,intense}`
|
|
147
|
+
- `border.brand.{subtle,soft,default,strong,intense,solid}`
|
|
148
|
+
- `border.royal.{subtle,soft,default,strong,intense,solid}`
|
|
149
|
+
- `border.success.{subtle,soft,default,strong,intense}` / `border.warning.{...}` / `border.error.{...}` / `border.info.{subtle,soft,default,strong,intense,solid}`
|
|
150
|
+
- `border.accents.<tone>.{subtle,soft,default,strong,intense}`
|
|
151
|
+
|
|
152
|
+
**`theme.palette.charts.*`** — chart series palette:
|
|
153
|
+
- `charts['1']` through `charts['8']`
|
|
154
|
+
- `1` blue, `2` teal, `3` orange, `4` violet, `5` pink, `6` green, `7` red, `8` cyan
|
|
155
|
+
|
|
156
|
+
**`theme.palette.effect.*`** — focus-ring / effect layers:
|
|
157
|
+
- `effect.focus.{brand,neutral,royal,error}`
|
|
158
|
+
|
|
159
|
+
### Access rules
|
|
160
|
+
|
|
161
|
+
- Reference tokens as `theme.palette.<group>.<slot>` (e.g. `theme.palette.text.neutral.strong`, `theme.palette.royal[500]`) — same shape across light/dark, resolved by the provider.
|
|
162
|
+
- Do **not** reference `theme.v2.primitives.*` or `theme.v2.tokens.*` in application code. Those are raw/escape layers, kept for cases like module-scope style composition without theme access.
|
|
163
|
+
- Do **not** hard-code hex values — always go through `theme.palette.*`.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# v2 components (`@hiver/hiver-ui-kit/v2`)
|
|
2
|
+
|
|
3
|
+
Load this only after the design has been identified as v2 (see `SKILL.md` → "v2 detection rules"). This file is an **index**. Per-component detail — variants, prop matrix, slot list, Figma-variable → `theme.palette.*` reconciliation, caveats — lives in each component's `.figma-spec.md` inside the `hiver-ui-kit` repo. Read the spec on demand; do not read all of them up front.
|
|
4
|
+
|
|
5
|
+
## Consumption
|
|
6
|
+
|
|
7
|
+
- **Import**: `import { <Component> } from '@hiver/hiver-ui-kit/v2';`
|
|
8
|
+
- **Provider**: v2 requires a v2-enabled theme. In existing code that already uses `HiverThemeProvider`, pass `v2` (and optionally `mode="light" | "dark"`) to enable v2 on top of v1. In v2-only trees use `HiverThemeProviderV2` (also exported from `/v2`).
|
|
9
|
+
- **Colours**: reference `theme.palette.*` (see `palette/colors.md` v2 section). **Never** reference `theme.v2.primitives.*` or `theme.v2.tokens.*` for colour tokens in application code.
|
|
10
|
+
- **Non-colour primitives** (spacing, radius, border-width, iconSize, font-family/size/weight, line-height): `theme.v2.primitives.*` is the correct access path — do **not** try to route these through `theme.palette`.
|
|
11
|
+
- **Typography**: v2 variants (`body_<sz>_<w>`, `heading_<sz>_<w>`, `display_<sz>_<w>`, `caption_<w>`, `overline_<w>`) via the same `<Typography>` component (see `typography/variants.md` v2 section).
|
|
12
|
+
- **Do not mix** v1 and v2 components in the same visual composition unless the design explicitly calls for it. It IS common to compose a v1 chrome primitive (`Popover`, `Modal`, `Popper`, `Tooltip`, `Stack`, `Box`) around v2 content — see `references/v2-usage-examples.md`.
|
|
13
|
+
|
|
14
|
+
## Component index
|
|
15
|
+
|
|
16
|
+
Cross-repo pointer format: `../hiver-ui-kit/src/v2/components/<Name>/.figma-spec.md` (relative to the extension repo root). If `hiver-ui-kit` is not checked out at that path, the index below still gives import paths and one-line purposes — the token reconciliation is what's lost.
|
|
17
|
+
|
|
18
|
+
| Component | Import | Ui-kit spec (full detail) | Purpose |
|
|
19
|
+
|---|---|---|---|
|
|
20
|
+
| `Avatar` | `Avatar` | `../hiver-ui-kit/src/v2/components/Avatar/.figma-spec.md` | User/entity avatar — `type="picture" \| "initials" \| "icon"`, sizes, status ring |
|
|
21
|
+
| `Badge` | `Badge` | `../hiver-ui-kit/src/v2/components/Badge/.figma-spec.md` | Status/tone chips (`variant` × `tone` × `size` × `shape`) |
|
|
22
|
+
| `Breadcrumbs` | `Breadcrumbs` | (spec pending — see inline block below) | Root → leaf breadcrumb list |
|
|
23
|
+
| `Button` | `Button` | `../hiver-ui-kit/src/v2/components/Button/.figma-spec.md` | Filled / outlined / link buttons; 9+ variants × 5 sizes × 5 states |
|
|
24
|
+
| `Checkbox` | `Checkbox` | `../hiver-ui-kit/src/v2/components/Checkbox/.figma-spec.md` | Tri-state (`-1 / 0 / 1`) with label + description |
|
|
25
|
+
| `Dropdown` (compound: `Dropdown.Menu`, `Dropdown.ListItem`) | `Dropdown` | (spec pending — see inline block below) | Visual container only — anchoring / open state is caller's job (compose inside MUI `Popover` / `Popper`) |
|
|
26
|
+
| `IconButton` | `IconButton` | `../hiver-ui-kit/src/v2/components/IconButton/.figma-spec.md` | Icon-only button; sizes, tones, variants aligned with `Button` |
|
|
27
|
+
| `InlineSelectLabel` | `InlineSelectLabel` | `../hiver-ui-kit/src/v2/components/InlineSelectLabel/.figma-spec.md` | Inline selection summary — icon/status/avatar + label + trailing `+N` badge |
|
|
28
|
+
| `Input.Text` | `Input` (namespace) | (spec pending — inline block below) | Single-line text input |
|
|
29
|
+
| `Input.TextArea` | `Input` | `../hiver-ui-kit/src/v2/components/Input/TextArea/.figma-spec.md` | Multi-line text input |
|
|
30
|
+
| `Input.Search` | `Input` | `../hiver-ui-kit/src/v2/components/Input/Search/.figma-spec.md` | Search-styled input |
|
|
31
|
+
| `Input.Tags` | `Input` | `../hiver-ui-kit/src/v2/components/Input/Tags/.figma-spec.md` | Tag-entry input |
|
|
32
|
+
| `Radio` | `Radio` | `../hiver-ui-kit/src/v2/components/Radio/.figma-spec.md` | Radio with label + description |
|
|
33
|
+
| `Switch` | `Switch` | `../hiver-ui-kit/src/v2/components/Switch/.figma-spec.md` | Toggle switch, `xs` / `sm` / `md` |
|
|
34
|
+
| `Tab.Item` | `Tab` | `../hiver-ui-kit/src/v2/components/Tab/Item/.figma-spec.md` | Tab item |
|
|
35
|
+
| `Table.Header` / `HeaderCell` / `HeaderLabel` / `BodyCell` | `Table` | `../hiver-ui-kit/src/v2/components/Table/{Header,HeaderCell,HeaderLabel,BodyCell}/.figma-spec.md` | Table primitives (compose your own row layout) |
|
|
36
|
+
| `Tag` | `Tag` | `../hiver-ui-kit/src/v2/components/Tag/.figma-spec.md` | Removable label with tone options |
|
|
37
|
+
| `Toast` | `Toast` | `../hiver-ui-kit/src/v2/components/Toast/.figma-spec.md` | Toast notification |
|
|
38
|
+
|
|
39
|
+
## General patterns
|
|
40
|
+
|
|
41
|
+
- All v2 components accept a `slotProps` prop for fine-grained overrides on internal DOM regions. Prefer top-level props first; fall back to `slotProps` for edge cases.
|
|
42
|
+
- v2 components generally accept `sx` on the root (either explicitly or via extended MUI props).
|
|
43
|
+
- Icon glyphs are consumer-supplied ReactNodes (usually MUI icons or SVG). Icon slots typically expect the glyph to inherit `currentColor`.
|
|
44
|
+
- Every v2 component is designed to render under a v2-enabled theme provider — behaviour outside a v2 theme is not defined.
|
|
45
|
+
- When a design needs anchoring, portalling, or click-away (Dropdown, tooltip-like overlays), wrap the v2 content inside an MUI `Popover` / `Popper` / `Modal`. See `references/v2-usage-examples.md`.
|
|
46
|
+
|
|
47
|
+
## Inline detail (spec pending)
|
|
48
|
+
|
|
49
|
+
The following v2 components don't yet have a `.figma-spec.md` in `hiver-ui-kit`. The blocks below carry just enough prop / slot detail to compose them. When the spec ships, replace the block with the cross-repo pointer.
|
|
50
|
+
|
|
51
|
+
### `Dropdown` (container + compound sub-exports)
|
|
52
|
+
|
|
53
|
+
Visual container only — does **not** manage open/close state, anchoring, portalling, or focus. Wire it inside an MUI `<Popover>` / `<Popper>` and drive open state yourself.
|
|
54
|
+
|
|
55
|
+
`Dropdown` (or `Dropdown.Menu`) — the paper surface:
|
|
56
|
+
- `title?: ReactNode` — header title (mutually exclusive with `showSearch`; `showSearch` wins).
|
|
57
|
+
- `endAction?: ReactNode` — trailing icon in the title row (ignored when `showSearch` is set).
|
|
58
|
+
- `showSearch?: boolean` — replaces title with an internal v2 `<Input size="sm">` search field; configure via `slotProps.search`.
|
|
59
|
+
- `children: ReactNode` — body slot (typically a stack of `<Dropdown.ListItem>`).
|
|
60
|
+
- `showFooter?: boolean` — footer with internally-mounted Cancel + Confirm buttons; configure via `slotProps.cancelButton` / `slotProps.confirmButton`.
|
|
61
|
+
- `elevation?: 'md' | 'none'` — default `'md'`.
|
|
62
|
+
- `minWidth?: number | string` — floor for container width.
|
|
63
|
+
- `maxHeight?: number | string` — caps the body slot; header + footer stay fixed.
|
|
64
|
+
- `sx?: SxProps<Theme>` — escape hatch on the root paper.
|
|
65
|
+
- `slotProps?: { header, title, search, slot, footer, cancelButton, confirmButton }`.
|
|
66
|
+
|
|
67
|
+
`Dropdown.ListItem` — single clickable row with up to 8 optional slots + a label:
|
|
68
|
+
- DOM order (fixed, left → right): `startCheckbox` · `startRadio` · `startAppsIcon` · `startAvatar` · `startIcon` · label · `endStatusIcon` · `endIcon` · `endCheckbox`.
|
|
69
|
+
- Boolean toggles: `startCheckbox?`, `startRadio?`, `startAppsIcon?`, `startAvatar?`, `startIcon?`, `endStatusIcon?`, `endIcon?`, `endCheckbox?`.
|
|
70
|
+
- `children: ReactNode` — label rendered inside `<Typography variant="body_sm_medium">` (single-line ellipsis).
|
|
71
|
+
- `slotProps?: { root, startCheckbox, startRadio, startAppsIcon, startAvatar, startIcon, label, endStatusIcon, endIcon, endCheckbox }`.
|
|
72
|
+
- Checkbox / Radio slots mount v2 `<Checkbox size="sm">` / `<Radio size="sm">` internally — pass `{ checked, onChange }` via the corresponding `slotProps.*Checkbox` / `slotProps.startRadio`.
|
|
73
|
+
- Icon-hosting slots (`startAppsIcon`, `startIcon`, `endStatusIcon`, `endIcon`) render a 20 × 20 wrapper — pass the glyph via `slotProps.<slot>.icon`.
|
|
74
|
+
|
|
75
|
+
### `Breadcrumbs`
|
|
76
|
+
|
|
77
|
+
- `items: BreadcrumbItem[]` — ordered root → leaf; last entry rendered as "current" (`aria-current="page"`, semibold, `text.neutral.strong`).
|
|
78
|
+
- `BreadcrumbItem = { label: ReactNode; href?: string; onClick?: (e) => void; key?: string | number }` — `href` → `<a>`, `onClick` (no `href`) → `<button>`, neither → static `<span>`.
|
|
79
|
+
- `maxItems?: number` — collapse middle items into an overflow indicator when `items.length > maxItems`.
|
|
80
|
+
- `itemsBeforeCollapse?: number` — default `1`.
|
|
81
|
+
- `itemsAfterCollapse?: number` — default `2`.
|
|
82
|
+
- `onOverflowClick?: (e: MouseEvent<HTMLButtonElement>) => void` — when set, overflow renders as a focusable `<button>`.
|
|
83
|
+
- `separator?: ReactNode` — default 14px slash SVG in `foreground['neutral-bold'].strong`.
|
|
84
|
+
- `slotProps?: { root, list, item, currentItem, separator, overflow }`.
|
|
85
|
+
|
|
86
|
+
### `Input.Text`
|
|
87
|
+
|
|
88
|
+
- `size?: 'sm' | 'md' | 'lg'`.
|
|
89
|
+
- `label?: ReactNode` — sibling above the field (not a notched legend).
|
|
90
|
+
- `helperText?: ReactNode` — bottom-row left side.
|
|
91
|
+
- `error?: boolean`, `required?: boolean`.
|
|
92
|
+
- `prefix?: ReactNode` — left adornment; string values render Inter Regular 14/20 in `text.neutral.soft`, ReactNode renders as-is.
|
|
93
|
+
- `suffix?: ReactNode` — right adornment; same rendering rules as `prefix`.
|
|
94
|
+
- `showCounter?: boolean` / `counterText?: string` — bottom-row right side (e.g. `"0/100"`).
|
|
95
|
+
- `slotProps?: { root, label, field, input, prefix, suffix, helper, counter }`.
|
|
96
|
+
- Single-line only — `multiline`, `rows`, `select` are stripped from the v2 API.
|
|
97
|
+
|
|
98
|
+
## Missing a spec? Extract one.
|
|
99
|
+
|
|
100
|
+
If you're implementing a v2 design against a component whose spec is marked "pending" above, run the `v2-figma-extract` skill inside the `hiver-ui-kit` repo on the corresponding Figma selection. That produces the `.figma-spec.md` and lets you delete the inline block.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# v2 usage examples (from `react-extn/src/RightPanelV2`)
|
|
2
|
+
|
|
3
|
+
Load this before composing common v2 shapes. Each row names a real file that already implements the pattern with v2 components + v1 chrome (Popover / Modal / Tooltip / Stack). Read the file when you're about to build the same shape.
|
|
4
|
+
|
|
5
|
+
Paths are relative to the extension repo root.
|
|
6
|
+
|
|
7
|
+
| Shape | Reference file | What to lift |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| Dropdown inside a Popover | `react-extn/src/RightPanelV2/pages/ThreadDetails/ThreadInfo/components/StatusField/StatusPopover.js` | v1 `Popover` (from `@hiver/hiver-ui-kit`) + v2 `Dropdown.Menu` + v2 `Dropdown.ListItem`. `PaperProps` on `Popover` is neutered (transparent, no shadow, `overflow: visible`) so the v2 Dropdown's own elevation is the only visible surface. |
|
|
10
|
+
| Inline field trigger + Popover | `react-extn/src/RightPanelV2/pages/ThreadDetails/ThreadInfo/components/AssigneeField/index.js` | v2 `InlineSelectLabel` as the trigger (icon / avatar + label + `+N`). Renders v2 `Avatar` (`type="picture" \| "initials" \| "icon"`, `size="2xs"`) for each user row. Opens a searchable popover with v2 `Dropdown`. |
|
|
11
|
+
| Modal | `react-extn/src/RightPanelV2/pages/ActivityAndNotes/common/components/DeleteNoteModal/index.js` | v1 `Modal` shell around v2 `Button` (destructive) + v2 `IconButton` (close X). v1 `Stack` / `Typography` / `icons` handle layout + copy. Backdrop click / X / Esc all route through `onCancel`. |
|
|
12
|
+
| Toolbar / composer row | `react-extn/src/RightPanelV2/pages/ActivityAndNotes/common/components/Composer/ComposerToolbar.js` | Horizontal toolbar: v1 `Stack` + `Tooltip` + `Box` around v2 `IconButton` (SVG glyph passed as child `<img>`) + v2 `Button` for the primary CTA. Left cluster stays enabled; right primary reflects a disabled gate. |
|
|
13
|
+
|
|
14
|
+
## Patterns to internalise
|
|
15
|
+
|
|
16
|
+
- **v1 chrome, v2 content.** For modals, popovers, portalled surfaces — v1 primitives (`Modal`, `Popover`, `Popper`, `Tooltip`, `Stack`, `Box`) provide behaviour (anchoring, focus trap, click-away, layout). v2 provides the visible surface + interactive content (`Dropdown`, `Button`, `IconButton`, `InlineSelectLabel`, `Avatar`, `Input`, `Tag`).
|
|
17
|
+
- **Neutralise v1 `Popover` chrome when placing a v2 Dropdown inside it.** Pass `PaperProps={{ elevation: 0, sx: { backgroundColor: 'transparent', boxShadow: 'none', overflow: 'visible' } }}` so the v2 Dropdown's shadow is the only surface. See `StatusPopover.js`.
|
|
18
|
+
- **Icon inputs to v2 components.** v2 icon-hosting components (`IconButton`, `Dropdown.ListItem`'s icon slots, `Avatar type="icon"`) accept raw SVG components, MUI icons, or `<img>` tags as children / `slotProps.<slot>.icon`. See `ComposerToolbar.js` for the SVG-as-`<img>` pattern.
|
|
19
|
+
- **Disabled / loading gate.** Composers gate the primary CTA via `disabled`; secondary controls stay interactive. See `ComposerToolbar.js`.
|
|
20
|
+
|
|
21
|
+
## Discoverable but not indexed
|
|
22
|
+
|
|
23
|
+
`react-extn/src/RightPanelV2/` has many more v2 consumers. Search with `grep -l "@hiver/hiver-ui-kit/v2" react-extn/src/RightPanelV2` when the four canonical files above don't cover your shape.
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Map Figma text styles to `<Typography variant="...">`. Match by fontSize + fontWeight (regular 400, medium 500, semiBold 600, bold 700).
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
5
|
+
Two variant sets live in the theme:
|
|
6
|
+
- **v1 variants** (below) — font family **Open Sans**, names like `h2_medium`, `body1_regular`.
|
|
7
|
+
- **v2 variants** (bottom of file) — font family **Inter**, names like `heading_md_semiBold`, `body_md_regular`.
|
|
8
|
+
|
|
9
|
+
Match the Figma text style against both sets; use the variant whose fontSize/weight matches. When the match lands on a v2 variant, the design is v2 — pair it with v2 components (`@hiver/hiver-ui-kit/v2`).
|
|
8
10
|
|
|
9
11
|
## Heading variants
|
|
10
12
|
|
|
@@ -72,9 +74,21 @@ Map Figma text styles to `<Typography variant="...">`. Match by fontSize + fontW
|
|
|
72
74
|
| `buttonSmall` | 12 | 500 | 20px | 0.4px |
|
|
73
75
|
| `chip` | 12 | 500 | 12px | 0.4px |
|
|
74
76
|
|
|
75
|
-
##
|
|
77
|
+
## Usage
|
|
78
|
+
|
|
79
|
+
```jsx
|
|
80
|
+
<Typography variant="h2_medium">Section title</Typography>
|
|
81
|
+
<Typography variant="body1_regular">Body text</Typography>
|
|
82
|
+
<Typography variant="caption1_medium" color="text.secondary">Caption</Typography>
|
|
83
|
+
```
|
|
76
84
|
|
|
77
|
-
|
|
85
|
+
**Figma → variant:** Compare Figma text style fontSize and weight (Regular/Medium/Semi Bold/Bold) to the tables above and pick the closest match.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## v2 variants
|
|
90
|
+
|
|
91
|
+
Font family **Inter**. Naming: `body_<size>_<weight>`, `heading_<size>_<weight>`, `display_<size>_<weight>`, `caption_<weight>`, `overline_<weight>`. Weight suffix → numeric weight: `regular` = 400, `medium` = 500, `semiBold` = 600, `bold` = 700.
|
|
78
92
|
|
|
79
93
|
### Display
|
|
80
94
|
|
|
@@ -113,27 +127,26 @@ Canonical 2026 design tokens. Use these for new UI built against the 2026 design
|
|
|
113
127
|
| `body_xs_medium` | 12 | 500 | 18px | -0.005em |
|
|
114
128
|
| `body_xs_semiBold` | 12 | 600 | 18px | -0.005em |
|
|
115
129
|
|
|
116
|
-
### Caption & overline
|
|
130
|
+
### Caption & overline
|
|
117
131
|
|
|
118
132
|
| Variant | fontSize | fontWeight | lineHeight | letterSpacing | Notes |
|
|
119
133
|
|---------|----------|------------|------------|---------------|-------|
|
|
120
134
|
| `caption_regular` | 12 | 400 | 14px | 0.01em | |
|
|
121
135
|
| `caption_medium` | 12 | 500 | 14px | 0.01em | |
|
|
122
136
|
| `overline_regular` | 12 | 400 | 14px | 0.01em | UPPERCASE |
|
|
137
|
+
| `overline_medium` | 12 | 500 | 14px | 0.01em | UPPERCASE |
|
|
123
138
|
|
|
124
139
|
> Note: a 2026 `overline_medium` token also exists in the theme (Inter, 12 / 500 / 14px / 0.01em / UPPERCASE) and shares its name with the legacy Open Sans `overline_medium` (11 / 500 / 18px). The 2026 spread is applied after the legacy block, so the Inter version wins at runtime — use accordingly.
|
|
125
140
|
|
|
126
|
-
|
|
141
|
+
### Usage (v2)
|
|
127
142
|
|
|
128
143
|
```jsx
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
<Typography variant="caption1_medium" color="text.secondary">Caption</Typography>
|
|
144
|
+
// Consumer must import v2 components from '@hiver/hiver-ui-kit/v2' and mount under a v2-enabled provider.
|
|
145
|
+
import { Typography } from '@hiver/hiver-ui-kit/v2';
|
|
132
146
|
|
|
133
|
-
|
|
134
|
-
<Typography variant="heading_lg_semiBold">Page title</Typography>
|
|
147
|
+
<Typography variant="heading_md_semiBold">Section title</Typography>
|
|
135
148
|
<Typography variant="body_md_regular">Body text</Typography>
|
|
136
|
-
<Typography variant="
|
|
149
|
+
<Typography variant="caption_medium" color="text.neutral.soft">Caption</Typography>
|
|
137
150
|
```
|
|
138
151
|
|
|
139
|
-
**Figma → variant:**
|
|
152
|
+
**Figma → variant (v2):** Match Figma text style fontSize and weight to the tables above. Prefer the exact match; if fontSize matches but weight doesn't, pick the closest weight variant in the same row group.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: version-bump-up
|
|
3
|
+
description: Bump the Android and iOS build numbers and the marketing (user-visible) version across all files that hold them. Use when the user explicitly asks to bump the app version, cut a new release version, or increase versionCode/versionName/build number/marketing version.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Version bump up
|
|
7
|
+
|
|
8
|
+
Bumps the mobile app's version fields in one coordinated pass across Android, iOS, and the RN `package.json`. Supports either fully-automatic increment or a user-supplied target version.
|
|
9
|
+
|
|
10
|
+
## When to use
|
|
11
|
+
|
|
12
|
+
- User asks to "bump the version", "increase the version", "cut version X.Y.Z", "bump build number", or similar.
|
|
13
|
+
- Use before shipping a release build, after a rejected upload (e.g. Play Store "version code already used"), or when preparing a new marketing version.
|
|
14
|
+
|
|
15
|
+
## Files this skill edits
|
|
16
|
+
|
|
17
|
+
Do NOT touch any files other than these. All paths are relative to the repo root.
|
|
18
|
+
|
|
19
|
+
| # | File | Field |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| 1 | `packages/app/android/app/build.gradle` | `versionCode <int>` (build number) |
|
|
22
|
+
| 2 | `packages/app/android/app/build.gradle` | `versionName "<X.Y.Z>"` (marketing) |
|
|
23
|
+
| 3 | `packages/app/ios/Hiver.xcodeproj/project.pbxproj` | `CURRENT_PROJECT_VERSION = <int>;` (build number — appears in BOTH Debug and Release configs, update every occurrence) |
|
|
24
|
+
| 4 | `packages/app/ios/Hiver.xcodeproj/project.pbxproj` | `MARKETING_VERSION = <X.Y.Z>;` (marketing — appears in BOTH Debug and Release configs, update every occurrence) |
|
|
25
|
+
| 5 | `packages/app/package.json` | `"version": "<X.Y.Z>"` (marketing, top-level) |
|
|
26
|
+
|
|
27
|
+
Do NOT edit `app.json` unless it also carries a version field — check first, only edit if present.
|
|
28
|
+
|
|
29
|
+
## Bump modes
|
|
30
|
+
|
|
31
|
+
Ask the user upfront which mode they want:
|
|
32
|
+
|
|
33
|
+
### Mode A — Auto increment (default when user says "just bump" / "auto")
|
|
34
|
+
- **Android `versionCode`**: current value + 1.
|
|
35
|
+
- **iOS `CURRENT_PROJECT_VERSION`**: current value + 1. (Android and iOS build numbers are tracked independently; do NOT try to align them.)
|
|
36
|
+
- **Marketing version** (`versionName`, `MARKETING_VERSION`, `package.json` `version`): increment the LAST segment by 1. Example: `2.8.8` → `2.8.9`. This mirrors the team's observed convention. If the user wants a minor bump (`2.8.8` → `2.9.0`) or major bump (`2.8.8` → `3.0.0`), they must use Mode B instead.
|
|
37
|
+
- Both platforms share the same marketing version — read one, verify the others match; if they diverge, surface the divergence to the user before bumping.
|
|
38
|
+
|
|
39
|
+
### Mode B — Specific version (user provides target)
|
|
40
|
+
Ask for either or both:
|
|
41
|
+
- **Target marketing version** (e.g. `2.9.0`, `3.0.0`) — must be a valid X.Y.Z string.
|
|
42
|
+
- **Target build numbers** — either a single value applied to both platforms, or separate values for Android/iOS.
|
|
43
|
+
|
|
44
|
+
If the user only gives marketing version, still auto-increment build numbers by +1. If the user only gives build numbers, leave marketing as-is.
|
|
45
|
+
|
|
46
|
+
## Instructions
|
|
47
|
+
|
|
48
|
+
1. **Ask which mode** (auto vs. specific). If the user's initial message already answered this, skip.
|
|
49
|
+
2. **Read the current values** from the five locations above. Confirm nothing is diverged unexpectedly (e.g. Android and iOS marketing versions differ). If they diverge, surface it and let the user decide before proceeding.
|
|
50
|
+
3. **Compute the new values** per the mode chosen.
|
|
51
|
+
4. **Show the plan** — a small table of "field: old → new" — and ask for one confirmation before editing. Skip this step only if the user explicitly said "just do it".
|
|
52
|
+
5. **Apply edits** using the `Edit` tool. For the pbxproj file the same field appears twice (Debug + Release) — update BOTH; use `replace_all: true` only when you have verified both occurrences carry the same old value; otherwise do two targeted edits.
|
|
53
|
+
6. **Verify** each edit landed by re-reading the surrounding line, and confirm all five bumps are consistent (marketing version identical across Android/iOS/package.json).
|
|
54
|
+
7. **Report** the final result to the user as a short table. Do NOT commit, do NOT run any build, do NOT push. Leave the working tree dirty for the user to review and commit.
|
|
55
|
+
|
|
56
|
+
## Guardrails
|
|
57
|
+
|
|
58
|
+
- Never skip iOS just because "Android is the one failing" (or vice versa). Bumping only one platform silently drifts marketing versions apart — always bump both marketing fields together.
|
|
59
|
+
- Never lower a version. If the user provides a target lower than current, stop and confirm — they may have a reason (e.g. rollback), but it is dangerous by default.
|
|
60
|
+
- Never commit changes; the user reviews and commits.
|
|
61
|
+
- Never edit unrelated version fields (dependency versions in package.json, Gradle plugin versions, Pods versions, etc.).
|
|
62
|
+
- If the pbxproj has more than two occurrences of `CURRENT_PROJECT_VERSION` or `MARKETING_VERSION` (e.g. test target or extensions), ask the user which targets to bump before proceeding — do NOT blindly `replace_all`.
|
|
63
|
+
|
|
64
|
+
## Common follow-up
|
|
65
|
+
|
|
66
|
+
After bumping, the user typically wants to commit with a message like `version bumped up to X.Y.Z (android <code>, ios <code>)`. Offer this as a suggestion but do not commit unless asked.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# qa-skills — take a Hiver feature from QA to release in one conversation
|
|
2
|
+
|
|
3
|
+
A collection of QA agents that hand work to each other inside a **single Claude Code chat**. You open
|
|
4
|
+
with one command; the spec, the test plan, the browser run, the bug tickets, the release gate, and
|
|
5
|
+
the automation PR all happen in that same thread.
|
|
6
|
+
|
|
7
|
+
> **One command to remember: `/qa-kit`.** It gathers your inputs, triages the change, and routes to
|
|
8
|
+
> the right track. Everything else chains automatically.
|
|
9
|
+
|
|
10
|
+
## Install (via the `@hiver/skills` CLI)
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npx @hiver/skills add
|
|
14
|
+
# → pick your IDE → pick the "qa-skills" collection → pick "qa-kit"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Picking **`qa-kit`** pulls in the whole suite automatically (it declares the rest as dependencies).
|
|
18
|
+
Then start any QA pass with `/qa-kit`.
|
|
19
|
+
|
|
20
|
+
Prefer a one-liner?
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx @hiver/skills add qa-kit # installs qa-kit + all its dependencies
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Why one conversation works
|
|
27
|
+
|
|
28
|
+
Handoffs are **files, not chat messages**. The first agent mints a *run directory* and writes a
|
|
29
|
+
pointer to `qa-output/.current-run`; every agent after that reads it, picks up the shared
|
|
30
|
+
`handoff.json`, does its job, writes its output back, and advances the baton. The chat is the
|
|
31
|
+
conversation; the run directory is the memory — so no agent ever re-asks you what an earlier one
|
|
32
|
+
already knows, and you can hand the thread to a teammate mid-run.
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
qa-output/<feature>/<run-id>/
|
|
36
|
+
handoff.json the baton: who → whom + all context so far
|
|
37
|
+
tracker.xlsx source of truth for cases & pass/fail (strict column ownership)
|
|
38
|
+
steps/ logs/ what each agent produced + a forensic trace of what it did
|
|
39
|
+
screenshots/ evidence from the browser run
|
|
40
|
+
trace/report.md qa-eval's quality verdict, written at the end
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## The pipeline
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
you type ► /qa-kit (orchestrator)
|
|
47
|
+
0 intake → 1 triage → 2 effort + route
|
|
48
|
+
no spec? ──► hiver-explore ────┤
|
|
49
|
+
(build a spec) │
|
|
50
|
+
UI / mixed ▼ ▼ API / new-API / mixed
|
|
51
|
+
┌───────────────────┐ ┌───────────────────┐
|
|
52
|
+
│ qa-ui-author │ │ qa-api-author │
|
|
53
|
+
│ → qa-ui-run │ │ → qa-api-run │
|
|
54
|
+
│ → qa-bugs │ │ → qa-bugs │
|
|
55
|
+
└─────────┬─────────┘ └───────────────────┘
|
|
56
|
+
▼ passing cases
|
|
57
|
+
┌───────────────────┐
|
|
58
|
+
│ playwright-gen │ specs → run → PR
|
|
59
|
+
└───────────────────┘
|
|
60
|
+
qa-eval grades every agent's output at the end → trace/report.md
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
| Skill | Role | Who calls it |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| **qa-kit** | Orchestrator / front door — triages (UI · API · new-API · mixed) and routes | **You** (`/qa-kit`) |
|
|
66
|
+
| **hiver-explore** | Builds a Confluence-style spec from help docs + the live UI when there's no PRD | qa-kit, or you |
|
|
67
|
+
| **qa-ui-author** | UI test plan (Word) + Excel tracker — no browser | qa-kit |
|
|
68
|
+
| **qa-ui-run** | Browser first pass — runs the tracker via Claude in Chrome, records ✅/❌/⚠️/⏭️ + screenshots | qa-ui-author |
|
|
69
|
+
| **qa-api-author** | API cases (endpoint, payload, expected) — no live calls | qa-kit |
|
|
70
|
+
| **qa-api-run** | Executes API cases against staging (opt-in, safety-gated) | qa-api-author / flow-capture |
|
|
71
|
+
| **qa-bugs** | Confirmed failures → ClickUp tickets with evidence | qa-ui-run / qa-api-run / you |
|
|
72
|
+
| **playwright-gen** | Passing cases → runnable `.spec.ts`, runs them, opens the automation PR | qa-ui-run, or you |
|
|
73
|
+
| **qa-eval** | Independent judge — grades each agent PASS/DEGRADED/FAIL | auto, at the end |
|
|
74
|
+
|
|
75
|
+
## Round 1 is Claude's. Round 2 is yours.
|
|
76
|
+
|
|
77
|
+
The browser first pass clears the repetitive coverage. Two things are handed back to you:
|
|
78
|
+
|
|
79
|
+
- **⏭️ Skipped cases** — anything needing a typed credential, two accounts at once, a simulated
|
|
80
|
+
backend failure, or an OAuth handshake. You run these into the tracker's *Testing 2* column (yours alone).
|
|
81
|
+
- **Exploratory testing** — go off-script and find the behaviours no written case predicted.
|
|
82
|
+
|
|
83
|
+
## The release gate (roadmap)
|
|
84
|
+
|
|
85
|
+
After manual sign-off, control the LaunchDarkly rollout **in the same chat** — connect the
|
|
86
|
+
LaunchDarkly MCP, or paste the flag JSON and apply the updated enrolment list yourself. This is a
|
|
87
|
+
workflow you run today (bring-your-own MCP), not yet a packaged skill.
|
|
88
|
+
|
|
89
|
+
## Connectors (all optional — there's always a paste-in fallback)
|
|
90
|
+
|
|
91
|
+
- **Claude in Chrome** — driving the live, logged-in Hiver tab (required for the browser pass).
|
|
92
|
+
- **ClickUp** — filing bugs · **Atlassian** — pulling the PRD/Confluence spec · **Figma** — UI states the spec misses.
|
|
93
|
+
|
|
94
|
+
## One prerequisite for the automation step
|
|
95
|
+
|
|
96
|
+
`playwright-gen` writes and runs real specs inside the **`poc-playwright`** (a.k.a.
|
|
97
|
+
`playwright-hig-automation`) repo, so that repo needs its one-time setup done (`npm install`,
|
|
98
|
+
`npx playwright install chromium`, `npm run auth:all`). Everything before automation runs without it.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
*A richer, illustrated version of this guide lives in [`qa-suite-guide.html`](./qa-suite-guide.html)
|
|
103
|
+
— open it locally, or host it on GitHub Pages for a shareable link.*
|