@imfusion/web-ui 0.6.1-dev.9.g317bd6f2 → 0.6.2-dev.1.gf73fc5d3
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/LICENSE.txt +30 -0
- package/README.md +99 -173
- package/THIRD_PARTY_NOTICES.md +34 -0
- package/bin/install.js +28 -10
- package/dist/code-BFMQnmu9.js +147 -0
- package/dist/codegen/gen-code-highlight-theme.d.ts +1 -0
- package/dist/components/code/code.d.ts +5 -4
- package/dist/components/stack/stack.d.ts +1 -1
- package/dist/components/toast/index.d.ts +2 -0
- package/dist/components/toast/toast.d.ts +200 -0
- package/dist/components/toast/toast.meta.d.ts +2 -0
- package/dist/components/typo/typo.d.ts +23 -22
- package/dist/icons/icon-config.d.ts +12 -0
- package/dist/{icons-wBmF0U2x.js → icons-Cy1HAosO.js} +1 -1
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1278 -1069
- package/dist/integrations/code-highlight/highlighter.d.ts +24 -0
- package/dist/integrations/code-highlight.js +80 -47
- package/dist/integrations/image-display-options.js +2 -2
- package/dist/provider/web-ui-provider.d.ts +3 -3
- package/dist/style.css +1 -1
- package/dist/{tabs-CMKvMF4E.js → tabs-DIe1Utiy.js} +2 -0
- package/docs/assets/imfusion-banner.svg +16 -0
- package/package.json +10 -8
- package/src/docgen/doc.gen.json +515 -1
- package/src/llms/install-templates/AGENTS.md +15 -18
- package/src/llms/llms.gen.txt +39 -33
- package/src/llms/skills/imf-web-ui/SKILL.md +30 -39
- package/src/llms/skills/imf-web-ui-audit/SKILL.md +50 -102
- package/src/llms/skills/imf-web-ui-components/SKILL.md +47 -104
- package/src/llms/skills/imf-web-ui-conventions/SKILL.md +44 -52
- package/src/llms/skills/imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md +1 -0
- package/src/llms/skills/imf-web-ui-conventions/topics/agent-tooling.md +40 -62
- package/src/llms/skills/imf-web-ui-conventions/topics/assets.md +11 -12
- package/src/llms/skills/imf-web-ui-conventions/topics/authentication.md +31 -46
- package/src/llms/skills/imf-web-ui-conventions/topics/class-names.md +18 -23
- package/src/llms/skills/imf-web-ui-conventions/topics/components.md +20 -69
- package/src/llms/skills/imf-web-ui-conventions/topics/data.md +50 -146
- package/src/llms/skills/imf-web-ui-conventions/topics/docs-structure.md +17 -23
- package/src/llms/skills/imf-web-ui-conventions/topics/git.md +15 -20
- package/src/llms/skills/imf-web-ui-conventions/topics/library-boundary.md +28 -19
- package/src/llms/skills/imf-web-ui-conventions/topics/library-setup.md +20 -16
- package/src/llms/skills/imf-web-ui-conventions/topics/npm-project.md +28 -42
- package/src/llms/skills/imf-web-ui-conventions/topics/project-structure.md +28 -30
- package/src/llms/skills/imf-web-ui-conventions/topics/react.md +28 -74
- package/src/llms/skills/imf-web-ui-conventions/topics/styling.md +65 -62
- package/src/llms/skills/imf-web-ui-conventions/topics/testing.md +12 -14
- package/src/llms/skills/imf-web-ui-conventions/topics/tokens.md +9 -4
- package/src/llms/skills/imf-web-ui-conventions/topics/tooling.md +40 -68
- package/src/llms/skills/imf-web-ui-conventions/topics/typescript.md +26 -50
- package/src/llms/skills/imf-web-ui-conventions/topics/validation.md +19 -25
- package/src/llms/skills/imf-web-ui-setup/SKILL.md +45 -64
- package/src/llms/skills/imf-web-ui-update/SKILL.md +48 -114
- package/src/llms/skills/imf-web-ui-ux/SKILL.md +64 -92
- package/src/llms/skills/imf-web-ui-ux/references/forms.md +16 -36
- package/src/llms/skills/imf-web-ui-ux/references/usability-heuristics.md +14 -27
- package/src/llms/skills/imf-web-ui-ux/references/visual-design.md +22 -38
- package/src/llms/tokens.gen.json +5 -5
- package/bin/install.test.ts +0 -329
- package/dist/code-Blo48PGr.js +0 -136
- package/dist/icons/icon-config-provider.d.ts +0 -8
- package/dist/icons/icon-context.d.ts +0 -4
|
@@ -1,113 +1,62 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: imf-web-ui-components
|
|
3
3
|
description:
|
|
4
|
-
"Look up @imfusion/web-ui component APIs and icon glyphs without reading source.
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
"Look up @imfusion/web-ui component APIs, compound parts, defaults, and icon glyphs without reading source. Use this
|
|
5
|
+
whenever a consumer task names a Web UI component or icon and you need to choose a prop, part, default, or glyph. Do not
|
|
6
|
+
use it to choose between components or bootstrap a project."
|
|
7
7
|
allowed-tools: Bash
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
#
|
|
10
|
+
# Look up components
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
reading source or checking out the library's repo:
|
|
12
|
+
Use the generated package indexes. They are smaller and more reliable than reading the library source.
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
and a one-sentence description of what it's for and what else it's called.
|
|
17
|
-
- **`node_modules/@imfusion/web-ui/src/docgen/doc.gen.json`** — full prop tables (name, type, default, description) for every
|
|
18
|
-
component, keyed by kebab-case folder name.
|
|
19
|
-
- **`node_modules/@imfusion/web-ui/src/llms/icon-catalog.gen.json`** — searchable icon names, styles, categories, and tags.
|
|
20
|
-
Read it only when the task needs an icon.
|
|
14
|
+
## Component lookup
|
|
21
15
|
|
|
22
|
-
|
|
23
|
-
`@imfusion/web-ui/docgen.json`) — those are Node module-resolution aliases, meaningless to `cat`/`jq`/`grep` reading files
|
|
24
|
-
off disk. Use the `node_modules/...` paths above directly.
|
|
16
|
+
1. Read the identity index:
|
|
25
17
|
|
|
26
|
-
|
|
18
|
+
```sh
|
|
19
|
+
cat node_modules/@imfusion/web-ui/src/llms/llms.gen.txt
|
|
20
|
+
```
|
|
27
21
|
|
|
28
|
-
|
|
22
|
+
It lists each component's name, category, status, purpose, and docgen entry.
|
|
29
23
|
|
|
30
|
-
|
|
31
|
-
cat node_modules/@imfusion/web-ui/src/llms/llms.gen.txt
|
|
32
|
-
```
|
|
24
|
+
2. Read only the matching entry from docgen:
|
|
33
25
|
|
|
34
|
-
|
|
26
|
+
```sh
|
|
27
|
+
jq '.button' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json
|
|
28
|
+
```
|
|
35
29
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- category: Buttons, status: stable
|
|
39
|
-
Triggers an action — submit, confirm, cancel, navigate, or destructive operations. Six semantic variants ...
|
|
40
|
-
- props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .button (jq: jq '.button' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
|
|
41
|
-
- further reading (usage/anatomy, not props): https://base-ui.com/react/components/button.md
|
|
42
|
-
```
|
|
30
|
+
Replace `.button` with the kebab-case key from the identity index. The result contains `root` and `subComponents`, with
|
|
31
|
+
each prop's type, default, and description.
|
|
43
32
|
|
|
44
|
-
|
|
45
|
-
one entry with the exact command the index gave you:
|
|
33
|
+
If `jq` is unavailable, use Node without loading the whole file into the conversation:
|
|
46
34
|
|
|
47
|
-
```sh
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
That returns `{ root: { name, description, props: [...] }, subComponents: [...] }`. `root` is the primary export (`Button`);
|
|
52
|
-
`subComponents` holds compound parts (e.g. `Drawer.Root`, `Drawer.Trigger`, `Drawer.Content` all live under the `drawer`
|
|
53
|
-
key). Match the sub-component you need by its dotted `name`.
|
|
54
|
-
|
|
55
|
-
**`jq` may not be installed.** Check with `which jq` before relying on it. If it's missing, do **not** fall back to reading
|
|
56
|
-
the whole `doc.gen.json` file — that defeats the entire point of the two-hop design (~500KB across all components vs. one
|
|
57
|
-
~9KB entry) and will burn your context budget for no reason. Use whatever's actually available instead:
|
|
58
|
-
|
|
59
|
-
```sh
|
|
60
|
-
node -e "console.log(JSON.stringify(JSON.parse(require('fs').readFileSync('node_modules/@imfusion/web-ui/src/docgen/doc.gen.json','utf8')).button, null, 2))"
|
|
61
|
-
```
|
|
35
|
+
```sh
|
|
36
|
+
node -e "console.log(JSON.stringify(JSON.parse(require('fs').readFileSync('node_modules/@imfusion/web-ui/src/docgen/doc.gen.json','utf8')).button, null, 2))"
|
|
37
|
+
```
|
|
62
38
|
|
|
63
|
-
|
|
64
|
-
|
|
39
|
+
Use `doc.gen.json` for Web UI props. A linked upstream page is useful for behavior, composition, and accessibility, but its
|
|
40
|
+
prop table is not authoritative for this package.
|
|
65
41
|
|
|
66
|
-
|
|
67
|
-
documentation for composition, anatomy, keyboard/focus behavior, and accessibility notes docgen can't express. Props always
|
|
68
|
-
come from `doc.gen.json` — never treat the linked page's prop table as authoritative for a web-ui component; web-ui may add,
|
|
69
|
-
remove, or default differently.
|
|
42
|
+
## If the component is missing
|
|
70
43
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
The index is regenerated on every `@imfusion/web-ui` release; it should be exhaustive. If a component you expect is missing,
|
|
74
|
-
don't guess at an API — that's a real gap to report, not something to work around by inventing props. Tell the web-ui
|
|
75
|
-
maintainer, or file it in the [WEBSDK Jira project](https://imfusion.atlassian.net/browse/WEBSDK) if you have access. If the
|
|
76
|
-
gap is about _which_ component to use rather than a missing one, that's a design question: open `imf-web-ui-ux`.
|
|
44
|
+
Treat a missing identity-index entry as a real gap. Do not invent an API or silently import the upstream component. Report
|
|
45
|
+
the gap to the Web UI maintainer. If the question is which existing component fits, use `imf-web-ui-ux` instead.
|
|
77
46
|
|
|
78
47
|
## Icons
|
|
79
48
|
|
|
80
|
-
When the task
|
|
81
|
-
not load it for ordinary component work.
|
|
82
|
-
|
|
83
|
-
Search one relevant term at a time, then read only the matching records:
|
|
49
|
+
When the task needs an icon, search the generated catalog before choosing a name:
|
|
84
50
|
|
|
85
51
|
```sh
|
|
86
52
|
node -e '
|
|
87
53
|
const q = process.argv[1].toLowerCase();
|
|
88
|
-
const icons = JSON.parse(
|
|
89
|
-
|
|
90
|
-
"node_modules/@imfusion/web-ui/src/llms/icon-catalog.gen.json",
|
|
91
|
-
"utf8"
|
|
92
|
-
)
|
|
93
|
-
);
|
|
94
|
-
console.log(
|
|
95
|
-
JSON.stringify(
|
|
96
|
-
icons
|
|
97
|
-
.filter(icon => [icon.name, icon.category, ...icon.tags]
|
|
98
|
-
.join(" ")
|
|
99
|
-
.toLowerCase()
|
|
100
|
-
.includes(q))
|
|
101
|
-
.slice(0, 20),
|
|
102
|
-
null,
|
|
103
|
-
2
|
|
104
|
-
)
|
|
105
|
-
);
|
|
54
|
+
const icons = JSON.parse(require("fs").readFileSync("node_modules/@imfusion/web-ui/src/llms/icon-catalog.gen.json", "utf8"));
|
|
55
|
+
console.log(JSON.stringify(icons.filter(icon => [icon.name, icon.category, ...icon.tags].join(" ").toLowerCase().includes(q)).slice(0, 20), null, 2));
|
|
106
56
|
' "add"
|
|
107
57
|
```
|
|
108
58
|
|
|
109
|
-
Import the
|
|
110
|
-
surrounding color:
|
|
59
|
+
Import the glyph and `Icon` from the Web UI icons entry. Always render the glyph through `Icon`:
|
|
111
60
|
|
|
112
61
|
```tsx
|
|
113
62
|
import { ArrowRight, Icon } from "@imfusion/web-ui/icons";
|
|
@@ -115,39 +64,33 @@ import { ArrowRight, Icon } from "@imfusion/web-ui/icons";
|
|
|
115
64
|
<Icon glyph={ArrowRight} aria-hidden />;
|
|
116
65
|
```
|
|
117
66
|
|
|
118
|
-
|
|
67
|
+
Do not import `iconoir-react` or another icon package directly.
|
|
119
68
|
|
|
120
|
-
|
|
121
|
-
import { ArrowRight, Icon } from "@imfusion/web-ui/icons";
|
|
69
|
+
## Compound components
|
|
122
70
|
|
|
123
|
-
|
|
124
|
-
```
|
|
71
|
+
A non-empty `subComponents` array means the component is a namespace:
|
|
125
72
|
|
|
126
|
-
|
|
73
|
+
```tsx
|
|
74
|
+
import { Drawer } from "@imfusion/web-ui";
|
|
127
75
|
|
|
128
|
-
|
|
76
|
+
<Drawer.Root>
|
|
77
|
+
<Drawer.Trigger>Open</Drawer.Trigger>
|
|
78
|
+
<Drawer.Content>…</Drawer.Content>
|
|
79
|
+
</Drawer.Root>;
|
|
80
|
+
```
|
|
129
81
|
|
|
130
|
-
|
|
131
|
-
`import { Drawer } from "@imfusion/web-ui"` then `<Drawer.Root>`, `<Drawer.Trigger>`, `<Drawer.Content>`. The index's
|
|
132
|
-
category/description covers the whole family; look at `subComponents` in the docgen entry to see which parts exist and what
|
|
133
|
-
each one's own props are.
|
|
82
|
+
Use the identity index for the family description and the docgen entry for each part's props.
|
|
134
83
|
|
|
135
|
-
## Integrations
|
|
84
|
+
## Integrations
|
|
136
85
|
|
|
137
|
-
A
|
|
138
|
-
|
|
86
|
+
A component whose identity entry says it comes from `@imfusion/web-ui/integrations/*` is not in the main import. Install the
|
|
87
|
+
listed optional peer explicitly, then import from that path:
|
|
139
88
|
|
|
140
89
|
```tsx
|
|
141
90
|
import { Code } from "@imfusion/web-ui/integrations/code-highlight";
|
|
142
91
|
```
|
|
143
92
|
|
|
144
|
-
|
|
145
|
-
that most consumers shouldn't be forced to install. Check the component's description for which peer to add, and add it
|
|
146
|
-
explicitly to your own `package.json` — web-ui does not install it for you.
|
|
147
|
-
|
|
148
|
-
## Data grids (Table + a headless library)
|
|
93
|
+
## Data grids
|
|
149
94
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
/ `Table.Cell`, and use `Table.SortableHeaderCell` for sortable columns — it carries the `aria-sort` state and the sort
|
|
153
|
-
indicator. See the Table primitive's Storybook docs for the pairing.
|
|
95
|
+
`Table` supplies styled table parts, not sorting or pagination. Pair them with a headless table library installed by the
|
|
96
|
+
consumer. TanStack Table is the recommended choice. Use `Table.SortableHeaderCell` for sortable columns.
|
|
@@ -1,57 +1,49 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: imf-web-ui-conventions
|
|
3
3
|
description:
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
assets, and docs structure. Load when writing wrapper components, custom UI, styling beyond the defaults, validating
|
|
8
|
-
external data, adding new files to a consumer app, writing repo docs, touching tool config, choosing any dependency, or
|
|
9
|
-
installing the vendored skills and lifecycle hooks."
|
|
4
|
+
"Apply the ImFusion frontend conventions to consumer code. Use this whenever a task writes a wrapper or custom UI, CSS,
|
|
5
|
+
TypeScript, data fetching, validation, tests, project files, configuration, documentation, dependencies, or agent tooling
|
|
6
|
+
in a project that uses @imfusion/web-ui. Read only the topic references that match the task."
|
|
10
7
|
---
|
|
11
8
|
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
| [
|
|
30
|
-
| [
|
|
31
|
-
| [
|
|
32
|
-
| [
|
|
33
|
-
| [
|
|
34
|
-
| [
|
|
35
|
-
| [
|
|
36
|
-
| [
|
|
37
|
-
| [
|
|
38
|
-
| [
|
|
39
|
-
| [
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
##
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Each topic's `##` sections map 1:1 to its block in [templates/AUDIT_CHECKLIST.md](templates/AUDIT_CHECKLIST.md) — add,
|
|
54
|
-
remove, or rename a section and the checklist follows in the same change.
|
|
55
|
-
|
|
56
|
-
`imf-web-ui-setup` proposes approved bootstrap changes, while `imf-web-ui-audit` reports the current state against this
|
|
57
|
-
baseline.
|
|
9
|
+
# Frontend conventions
|
|
10
|
+
|
|
11
|
+
These are ImFusion defaults, not claims about every frontend. A host project's working choice wins. Use these topics to fill
|
|
12
|
+
a gap or to make a deliberate deviation visible; do not refactor a project just to match the baseline.
|
|
13
|
+
|
|
14
|
+
## Choose a topic
|
|
15
|
+
|
|
16
|
+
| Topic | Read when |
|
|
17
|
+
| ------------------------------------------------ | --------------------------------------------------------------- |
|
|
18
|
+
| [library-setup](topics/library-setup.md) | Installing or repairing stylesheet and provider wiring. |
|
|
19
|
+
| [library-boundary](topics/library-boundary.md) | Rendering Web UI components, wrapping them, or choosing a peer. |
|
|
20
|
+
| [authentication](topics/authentication.md) | Protecting routes or defining login and logout. |
|
|
21
|
+
| [react](topics/react.md) | Designing component roles, state ownership, or effects. |
|
|
22
|
+
| [components](topics/components.md) | Adding files or deciding component anatomy. |
|
|
23
|
+
| [typescript](topics/typescript.md) | Writing TypeScript or naming values. |
|
|
24
|
+
| [styling](topics/styling.md) | Writing CSS or customizing Web UI. |
|
|
25
|
+
| [tokens](topics/tokens.md) | Choosing an exact token name. |
|
|
26
|
+
| [class-names](topics/class-names.md) | Mapping variants and `className` to CSS. |
|
|
27
|
+
| [validation](topics/validation.md) | Accepting data from outside the frontend. |
|
|
28
|
+
| [data](topics/data.md) | Adding API queries, mutations, or invalidation. |
|
|
29
|
+
| [project-structure](topics/project-structure.md) | Adding files or routes. |
|
|
30
|
+
| [testing](topics/testing.md) | Deciding what to test. |
|
|
31
|
+
| [tooling](topics/tooling.md) | Adding a dependency or configuring a tool. |
|
|
32
|
+
| [npm-project](topics/npm-project.md) | Changing `package.json`, scripts, pins, or Node. |
|
|
33
|
+
| [git](topics/git.md) | Configuring hooks or choosing verification scope. |
|
|
34
|
+
| [agent-tooling](topics/agent-tooling.md) | Installing skills or lifecycle hooks. |
|
|
35
|
+
| [assets](topics/assets.md) | Adding images, icons, or other static files. |
|
|
36
|
+
| [docs-structure](topics/docs-structure.md) | Writing or reorganizing repository docs. |
|
|
37
|
+
|
|
38
|
+
## How to use the topics
|
|
39
|
+
|
|
40
|
+
Read the relevant file instead of loading the whole set. Each topic is a short checklist: follow its rules, use its examples
|
|
41
|
+
as patterns, and keep any exception explicit in the host project.
|
|
42
|
+
|
|
43
|
+
`imf-web-ui-setup` uses these topics to plan approved project changes. `imf-web-ui-audit` uses them to report the current
|
|
44
|
+
state without changing files.
|
|
45
|
+
|
|
46
|
+
## Documentation
|
|
47
|
+
|
|
48
|
+
Invoke `/documentation-writer` for new or updated documentation. Use the `docs-structure` topic for repository-specific
|
|
49
|
+
boundaries and conventions; it supplies context for the writer and does not replace the writer's workflow.
|
|
@@ -58,6 +58,7 @@ sections one to one — change a topic's sections and this file follows in the s
|
|
|
58
58
|
- [ ] Build custom UI from tokens
|
|
59
59
|
- [ ] Override through the sanctioned seams
|
|
60
60
|
- [ ] The color system
|
|
61
|
+
- [ ] Browser floor
|
|
61
62
|
- [ ] Responsive styling
|
|
62
63
|
|
|
63
64
|
## Tokens — `tokens`
|
|
@@ -1,82 +1,60 @@
|
|
|
1
1
|
# Agent tooling
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
`npx web-ui-install` manages the Web UI skills and optional lifecycle hooks in a consumer project. This topic explains the
|
|
4
|
+
choices around that installer.
|
|
5
5
|
|
|
6
6
|
## The skill bundle
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
Run:
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
npx web-ui-install
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
It installs or refreshes the `imf-web-ui-*` skills, updates the managed `AGENTS.md` fence, and removes skills that the
|
|
15
|
+
package no longer ships. The installer remembers `.claude/skills/`, `.agents/skills/`, or both. Use `--target claude|agents`
|
|
16
|
+
to choose explicitly and `--reconfigure` to choose again.
|
|
17
|
+
|
|
18
|
+
Skill version markers (`.imf-web-ui-skill-version.json`) show which package version installed each skill. Refresh them with
|
|
19
|
+
the installer; do not hand-edit the vendored files.
|
|
14
20
|
|
|
15
21
|
## The hooks
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
entries the installer didn't write.
|
|
22
|
-
|
|
23
|
-
- **SessionStart** — once per session: points the agent at the `imf-web-ui` skills router.
|
|
24
|
-
- **SubagentStart** — the same line, byte for byte, for each spawned subagent; subagents don't reliably inherit the parent
|
|
25
|
-
session's context.
|
|
26
|
-
- **UserPromptSubmit** — one line per prompt naming the companion skills to consult.
|
|
27
|
-
- **Stop** — the verify gate: when the turn edited source files, it blocks the agent from finishing once, with the
|
|
28
|
-
instruction to run the project's verification and fix what it reports. Re-entry is detected from the payload, so the gate
|
|
29
|
-
can never loop; a turn that edited nothing passes untouched.
|
|
30
|
-
|
|
31
|
-
```mermaid
|
|
32
|
-
flowchart LR
|
|
33
|
-
SS(["SessionStart<br/>once per session"]) --> ss["session-start.sh"]
|
|
34
|
-
SA(["SubagentStart<br/>per spawned subagent"]) --> sa["subagent-start.sh"]
|
|
35
|
-
UP(["UserPromptSubmit<br/>every prompt"]) --> up["user-prompt-submit.sh"]
|
|
36
|
-
ST(["Stop<br/>turn ends after edits"]) --> st["stop.sh"]
|
|
37
|
-
ss --> router["injects the router pointer:<br/>start at imf-web-ui"]
|
|
38
|
-
sa --> router
|
|
39
|
-
up --> hints["injects the per-task hints:<br/>components · conventions · ux"]
|
|
40
|
-
st --> gate["blocks once:<br/>run verification first"]
|
|
41
|
-
router --> agent["agent routes to the right<br/>companion skill"]
|
|
42
|
-
hints --> agent
|
|
43
|
-
gate --> agent2["agent verifies,<br/>then finishes"]
|
|
23
|
+
Install the optional lifecycle hooks with:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
npx web-ui-install --hooks
|
|
44
27
|
```
|
|
45
28
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
-
|
|
55
|
-
|
|
56
|
-
|
|
29
|
+
The installer owns the scripts under `.agents/hooks/imf-web-ui/` and merges its registrations into Claude Code and Codex
|
|
30
|
+
settings. It refreshes scripts and removes retired registrations without replacing unrelated entries.
|
|
31
|
+
|
|
32
|
+
The shipped events are:
|
|
33
|
+
|
|
34
|
+
- `SessionStart`: point the agent at the Web UI router once per session.
|
|
35
|
+
- `SubagentStart`: provide the same pointer to spawned agents.
|
|
36
|
+
- `UserPromptSubmit`: name the companion skills relevant to the prompt.
|
|
37
|
+
- `Stop`: ask for project verification after a turn edits source files.
|
|
38
|
+
|
|
39
|
+
Read existing registrations first. If the project already covers an event, do not stack a second hook; adapt the existing
|
|
40
|
+
registration and keep the missing behavior.
|
|
41
|
+
|
|
42
|
+
`baseline-staleness.sh` is a pre-commit check, not an agent hook. It compares installed skill markers with the installed
|
|
43
|
+
package version.
|
|
57
44
|
|
|
58
45
|
## Codex trust
|
|
59
46
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
- Until then hooks are skipped, and skipped silently — from outside, a skipped hook and a hook that ran and said nothing look
|
|
63
|
-
identical.
|
|
64
|
-
- After installing or updating hooks, tell the user to trust the project and review `/hooks` in Codex, and again after any
|
|
65
|
-
hook script changes.
|
|
66
|
-
- When a hint doesn't show up, check trust before debugging the script.
|
|
67
|
-
- Claude Code has no trust gate for project hooks.
|
|
47
|
+
Codex runs project hooks only after the project is trusted and each script is approved through `/hooks`. Revisit that review
|
|
48
|
+
after a hook script changes. Claude Code has no equivalent project-hook trust gate.
|
|
68
49
|
|
|
69
50
|
## Dependency-shipped skills
|
|
70
51
|
|
|
71
|
-
|
|
72
|
-
allowlist.
|
|
52
|
+
Dependencies can ship their own skills. TanStack is one example; its docs and allowlist determine how it is used.
|
|
73
53
|
|
|
74
54
|
## Hook docs
|
|
75
55
|
|
|
76
|
-
|
|
77
|
-
host and per event.
|
|
56
|
+
Read the current host documentation before adding or adapting a hook:
|
|
78
57
|
|
|
79
|
-
- [Claude Code
|
|
80
|
-
|
|
81
|
-
- [Codex
|
|
82
|
-
- [Codex: config reference](https://learn.chatgpt.com/docs/config-file/config-reference) — `[features]` and `[hooks.state]`
|
|
58
|
+
- [Claude Code hooks](https://code.claude.com/docs/en/hooks)
|
|
59
|
+
- [Codex hooks](https://learn.chatgpt.com/docs/hooks)
|
|
60
|
+
- [Codex configuration](https://learn.chatgpt.com/docs/config-file/config-reference)
|
|
@@ -2,26 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
## Importing
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
Import files from `src/assets/` so the bundler fingerprints and includes them. Do not reference an asset through a
|
|
6
|
+
public-path string.
|
|
7
7
|
|
|
8
|
-
## Photographs
|
|
8
|
+
## Photographs: WebP
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Convert photographs to WebP before adding them:
|
|
11
|
+
|
|
12
|
+
```sh
|
|
11
13
|
magick source.png -resize 2000x -quality 80 -define webp:method=6 src/assets/name.webp
|
|
12
14
|
```
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
- `method=6` — densest encoding; a one-off cost at conversion time, so take the smaller file.
|
|
16
|
-
- Long edge ≤ 2000px — nothing on the market resolves more in a content image.
|
|
17
|
-
- No `<picture>` fallback — WebP is supported everywhere since 2020.
|
|
16
|
+
Keep the long edge at 2000px or less. WebP is supported by the browser floor.
|
|
18
17
|
|
|
19
18
|
## Other formats
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
Use PNG when the image needs alpha or exact pixels. Use an inline SVG component for icons, logos, and line art so it inherits
|
|
21
|
+
`currentColor` and follows the theme.
|
|
23
22
|
|
|
24
23
|
## Scope
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
Apply these rules to assets you add or touch. Existing files do not need a format migration just because they use another
|
|
26
|
+
format.
|
|
@@ -1,65 +1,50 @@
|
|
|
1
1
|
# Authentication
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Use one route boundary for authentication. The provider, session mechanism, endpoint paths, and login/logout transport stay
|
|
4
|
+
owned by the application.
|
|
5
5
|
|
|
6
6
|
## Starter shape
|
|
7
7
|
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
lib/auth/
|
|
16
|
-
login-url.ts # pure login navigation helper; not an API topic file
|
|
17
|
-
login-url.test.ts # focused helper tests
|
|
18
|
-
routes/
|
|
19
|
-
__root.tsx # global Outlet and error/not-found boundaries; no auth guard
|
|
20
|
-
_public/route.tsx # anonymous route group
|
|
21
|
-
_app/route.tsx # authenticated route group
|
|
22
|
-
```
|
|
8
|
+
- Keep public routes under a pathless `_public/` group.
|
|
9
|
+
- Keep authenticated routes under a pathless `_app/` group.
|
|
10
|
+
- Guard `_app/` before its children render.
|
|
11
|
+
- Keep the root route neutral: it owns the outlet and global error/not-found boundaries.
|
|
12
|
+
- A greenfield app starts `_app/` with a minimal `AppShell` unless it has no persistent authenticated navigation.
|
|
13
|
+
|
|
14
|
+
The file layout is in [project-structure.md](project-structure.md).
|
|
23
15
|
|
|
24
16
|
## One current-user query
|
|
25
17
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
- `
|
|
31
|
-
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
18
|
+
Use one server-backed current-user query as the identity source:
|
|
19
|
+
|
|
20
|
+
- Put it in `api/auth/queries.ts` and define its key and schema with the [data.md](data.md) pattern.
|
|
21
|
+
- Expose query options as `context.api.auth.getUser()`.
|
|
22
|
+
- Call `ensureQueryData` in a loader or a query hook in a component.
|
|
23
|
+
- Keep credentials and access tokens out of React state.
|
|
24
|
+
- Do not infer authentication from local storage, decoded tokens, route flags, or permission-gated UI.
|
|
25
|
+
|
|
26
|
+
The server response, parsed at the network boundary, is the source of truth.
|
|
35
27
|
|
|
36
28
|
## The two route groups
|
|
37
29
|
|
|
38
|
-
Both resolve the current-user query in `beforeLoad
|
|
30
|
+
Both groups may resolve the current-user query in `beforeLoad`. They handle a 401 differently:
|
|
39
31
|
|
|
40
|
-
| Group | 401
|
|
41
|
-
| ---------- |
|
|
42
|
-
| `_app/` |
|
|
43
|
-
| `_public/` |
|
|
32
|
+
| Group | 401 result |
|
|
33
|
+
| ---------- | -------------------------------------------- |
|
|
34
|
+
| `_app/` | Navigate to the server-owned login endpoint. |
|
|
35
|
+
| `_public/` | Continue as an anonymous user. |
|
|
44
36
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
- The root route stays neutral: global `Outlet` and error/not-found boundaries, no public/authenticated decision.
|
|
37
|
+
The `_app/` guard should navigate only for the authentication 401. Rethrow redirects, server failures, connection failures,
|
|
38
|
+
and schema errors so the normal error boundary can handle them. A public route may redirect an already-authenticated user
|
|
39
|
+
into `_app/`.
|
|
49
40
|
|
|
50
41
|
## Login and logout
|
|
51
42
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
- Never hard-code an endpoint shape or provider into shared frontend conventions.
|
|
56
|
-
- No intermediate login route when the server owns the flow.
|
|
57
|
-
- A failed API request is an auth failure only when its typed error is specifically a 401.
|
|
43
|
+
Follow the application's documented server flow. Login is a browser navigation when the server owns the session; it is not a
|
|
44
|
+
Query fetch. Logout uses the server's documented state-changing action. Preserve a validated same-origin return path when the
|
|
45
|
+
server supports one. Do not invent an endpoint shape in this shared baseline.
|
|
58
46
|
|
|
59
47
|
## App shell
|
|
60
48
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
`_app/` outlet.
|
|
64
|
-
- An explicit no-persistent-navigation decision may omit the shell; the `_app/` guard stays.
|
|
65
|
-
- An established project keeps its working choice; public pages may use a small branded header.
|
|
49
|
+
`AppShell` is authenticated chrome, not the authentication mechanism. It can hold the logo, navigation, and session action
|
|
50
|
+
around the `_app/` outlet. An established project keeps its working shell or header choice.
|