@imfusion/web-ui 0.5.1-dev.40.gfb5bc73e → 0.5.1-dev.44.g02fbbc52
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/package.json +1 -1
- package/src/llms/skills/imf-web-ui-audit/SKILL.md +54 -22
- package/src/llms/skills/imf-web-ui-conventions/topics/authentication.md +3 -3
- package/src/llms/skills/imf-web-ui-conventions/topics/data.md +16 -7
- package/src/llms/skills/imf-web-ui-conventions/topics/react.md +4 -2
- package/src/llms/skills/imf-web-ui-conventions/topics/typescript.md +28 -0
- package/src/llms/skills/imf-web-ui-setup/SKILL.md +24 -8
- package/src/llms/skills/imf-web-ui-update/SKILL.md +2 -2
package/README.md
CHANGED
|
@@ -69,7 +69,7 @@ skill.
|
|
|
69
69
|
| `/imf-web-ui-components` | Component reference — what exists and how it's meant to be used. |
|
|
70
70
|
| `/imf-web-ui-ux` | UX guidance for building interfaces with the library. |
|
|
71
71
|
| `/imf-web-ui-conventions` | The frontend conventions baseline, including the sanctioned styling seams. |
|
|
72
|
-
| `/imf-web-ui-audit` | Read-only health check for a consumer project,
|
|
72
|
+
| `/imf-web-ui-audit` | Read-only health check for a consumer project, ending in a plan you approve. |
|
|
73
73
|
| `/imf-web-ui-update` | Update the library, skills, and optional hooks, then verify before committing. |
|
|
74
74
|
|
|
75
75
|
Start at `/imf-web-ui` — it routes to the rest. Storybook's **User Guide → AI Agents** page covers the whole family.
|
package/package.json
CHANGED
|
@@ -4,49 +4,76 @@ description:
|
|
|
4
4
|
"Read-only health check for an ImFusion frontend against the conventions baseline. Audit the full project or any topic,
|
|
5
5
|
including library-setup, tooling, git, npm-project, authentication, project-structure, docs-structure, data, testing,
|
|
6
6
|
React, TypeScript, class names, validation, components, styling, assets, library-boundary, and tokens. Reports broken
|
|
7
|
-
pieces, missing pieces, working deviations, present evidence, and unverified state
|
|
7
|
+
pieces, missing pieces, working deviations, present evidence, and unverified state, then turns them into an actionable
|
|
8
|
+
plan."
|
|
8
9
|
argument-hint: "[full|<topic>]"
|
|
9
10
|
allowed-tools: Read Glob Grep
|
|
10
11
|
---
|
|
11
12
|
|
|
12
13
|
# imf-web-ui-audit
|
|
13
14
|
|
|
14
|
-
You are the frontend health-check auditor
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
You are the frontend health-check auditor, and you run as an orchestrator: one investigator per topic gathers the evidence,
|
|
16
|
+
you merge their findings and turn them into an actionable plan. Follow the applicable `imf-web-ui-conventions` topics, cite
|
|
17
|
+
repository evidence, distinguish defects from working deviations, and never present the baseline as universal best practice.
|
|
18
|
+
|
|
19
|
+
An audit belongs in plan mode: it ends in work to approve, not in files to write.
|
|
18
20
|
|
|
19
21
|
## Workflow
|
|
20
22
|
|
|
21
23
|
1. Resolve the argument. Bare means `full`; a topic selects one row below. If no topic matches, list every available topic
|
|
22
24
|
instead of guessing or widening the scope.
|
|
23
|
-
2.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
2. Enter the host's plan mode, unless one of the exceptions after step 5 applies. If plan mode is not already active, use the
|
|
26
|
+
host plan-mode control before dispatching anything.
|
|
27
|
+
3. Dispatch one investigator per in-scope topic, using the host's subagent mechanism, as concurrently as the host allows.
|
|
28
|
+
Investigators are cheap and narrow: each one gets a single topic and reports back. A host with no subagent mechanism is
|
|
29
|
+
not a blocker — work the topics inline in this session, in the same order, to the same contract.
|
|
30
|
+
4. Merge what comes back. Findings you did not gather yourself are the report; do not re-inspect files an investigator
|
|
31
|
+
covered. Reconcile conflicts by reading the cited evidence, and drop any finding whose citation does not hold.
|
|
32
|
+
5. Deliver the merged report and the plan in the host plan, from the shared report contract at
|
|
33
|
+
[`../imf-web-ui-conventions/templates/REPORT.md`](../imf-web-ui-conventions/templates/REPORT.md), with the mode label
|
|
34
|
+
`audit`. The plan's ordered steps are the `Next action` lines of the findings, grouped by topic and cheapest-first;
|
|
35
|
+
`Present` findings produce no steps.
|
|
36
|
+
|
|
37
|
+
Some runs take the report somewhere other than a plan. When the human asks for the durable file, or the host has no plan
|
|
38
|
+
mode, write the same content to `AUDIT_REPORT.md` and preserve everything under `## Reviewer notes` verbatim. When another
|
|
39
|
+
skill invokes the audit as its verification step, report the findings to that caller and stay out of plan mode — the caller
|
|
40
|
+
owns the flow, and the human has usually just left plan mode to let its work happen.
|
|
41
|
+
|
|
42
|
+
## Dispatching an investigator
|
|
43
|
+
|
|
44
|
+
Each investigator prompt carries, in full:
|
|
45
|
+
|
|
46
|
+
- the topic name and the path of its convention topic file;
|
|
47
|
+
- the topic's block from the shared [convention audit checklist](../imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md), and
|
|
48
|
+
the instruction to check every box in it;
|
|
49
|
+
- the safety constraint below, verbatim — an investigator that reaches for a shell breaks the audit's only guarantee;
|
|
50
|
+
- the report contract's entry format, so findings arrive mergeable: severity, reference, short title, `path:line` evidence,
|
|
51
|
+
impact, next action;
|
|
52
|
+
- the instruction to report findings back as its result and write no files.
|
|
53
|
+
|
|
54
|
+
An investigator reports on its topic alone. Anything it notices outside that topic goes back as a note for the orchestrator
|
|
55
|
+
to route, not as a finding it rules on.
|
|
34
56
|
|
|
35
57
|
## Checklist
|
|
36
58
|
|
|
37
|
-
|
|
38
|
-
|
|
59
|
+
The shared [convention audit checklist](../imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md) is the working checklist: a
|
|
60
|
+
full audit covers every block, a scoped audit covers the requested block plus its dependencies. The audit is not complete
|
|
61
|
+
until every in-scope box has been checked by the investigator that owns it and its evidence appears in the report. The
|
|
39
62
|
checklist itself is not edited during an audit.
|
|
40
63
|
|
|
41
64
|
## Safety
|
|
42
65
|
|
|
43
66
|
Use only static inspection: Read, Glob, Grep, and equivalent non-executing search tools. Do not use a shell or invoke Node,
|
|
44
67
|
npm, npx, package scripts, hooks, config imports, linters, tests, builds, Git commands, or project binaries. Read config as
|
|
45
|
-
text and report runtime or machine-local state that cannot be established statically as unverified.
|
|
68
|
+
text and report runtime or machine-local state that cannot be established statically as unverified. This binds every
|
|
69
|
+
investigator too — a dispatched agent inherits the audit's constraint, not the host's default freedom, so the prompt that
|
|
70
|
+
dispatches it repeats this paragraph verbatim.
|
|
46
71
|
|
|
47
|
-
|
|
48
|
-
host's
|
|
49
|
-
|
|
72
|
+
An audit writes at most one file: `AUDIT_REPORT.md`, in the two cases named in the workflow. Investigators write nothing.
|
|
73
|
+
Neither Write nor the host's dispatch tool is pre-approved in `allowed-tools` — `allowed-tools` names what an audit needs on
|
|
74
|
+
every run, and both of these follow the host's ordinary approval when a run needs them. Host-managed hooks may run after that
|
|
75
|
+
write; the skill neither invokes nor suppresses them, but it does report broken or unexpected hook behavior found during
|
|
76
|
+
static inspection.
|
|
50
77
|
|
|
51
78
|
## Topics
|
|
52
79
|
|
|
@@ -83,5 +110,10 @@ three injection hooks, the stop gate, plus `baseline-staleness.sh` — are drift
|
|
|
83
110
|
`baseline-staleness.sh`. Read files and settings as text—do not run installers, hooks, or local config queries during
|
|
84
111
|
assessment.
|
|
85
112
|
|
|
113
|
+
Version drift is part of this topic: compare the declared version in `package.json`, the installed
|
|
114
|
+
`node_modules/@imfusion/web-ui/package.json`, and every `.imf-web-ui-skill-version.json` marker, then report the drift and
|
|
115
|
+
point at `imf-web-ui-update`. The registry is unreachable from a static audit, so a line saying that a newer version may
|
|
116
|
+
exist is unverified.
|
|
117
|
+
|
|
86
118
|
Use the shared report template as the report contract. It defines the headings, ordering, empty-section marker, evidence
|
|
87
119
|
format, and reviewer-note preservation rules; do not duplicate that contract here.
|
|
@@ -11,7 +11,7 @@ project-owned — no provider is prescribed or named.
|
|
|
11
11
|
|
|
12
12
|
```text
|
|
13
13
|
src/
|
|
14
|
-
api/auth/ #
|
|
14
|
+
api/auth/ # getUser query options, keys.ts, types.ts, index.ts barrel
|
|
15
15
|
lib/auth/
|
|
16
16
|
login-url.ts # pure login navigation helper; not an API topic file
|
|
17
17
|
login-url.test.ts # focused helper tests
|
|
@@ -25,10 +25,10 @@ src/
|
|
|
25
25
|
|
|
26
26
|
- One identity source of truth: a server-backed current-user query; never copy session credentials or access tokens into
|
|
27
27
|
React state.
|
|
28
|
-
- The auth topic follows the default [data.md](data.md) shape: `
|
|
28
|
+
- The auth topic follows the default [data.md](data.md) shape: `getUser` in `api/auth/queries.ts`, key leading with the
|
|
29
29
|
`auth` topic, schema in `types.ts`.
|
|
30
30
|
- `lib/auth/login-url.ts`: project-owned navigation helper, not an options factory; tests colocated.
|
|
31
|
-
- Reached as `context.api.auth.
|
|
31
|
+
- Reached as `context.api.auth.getUser()`; returns query options, never a hook or a user value — callers pick
|
|
32
32
|
`ensureQueryData` or a query hook.
|
|
33
33
|
- Never infer authentication from local storage, a decoded token, a route flag, or permission-gated chrome — stale or
|
|
34
34
|
forgeable; the server response and its schema define the current user.
|
|
@@ -7,9 +7,11 @@ the boundary principles — validate at the edge, errors as values — not this
|
|
|
7
7
|
|
|
8
8
|
- One folder per API topic: options factories, key factory, Zod schemas together, so a query key is never spelled out at a
|
|
9
9
|
call site.
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
- Name a file for what it holds, never for the topic it sits in — the folder already says that: `keys.ts`, not `<topic>.ts`
|
|
11
|
+
or `query-key.ts` (it holds mutation keys too).
|
|
12
|
+
- A file appears only when the topic needs it: a topic with only queries has no `mutations.ts`, and vice versa.
|
|
13
|
+
- A GraphQL (or similarly document-based) transport may split `queries.ts`/`mutations.ts` further into
|
|
14
|
+
`queryFns.ts`/`mutationFns.ts`; that's an elaboration of the same options-vs-mutations split, not its origin.
|
|
13
15
|
- Transport code (base client, error normalisation): `http/` and nowhere else.
|
|
14
16
|
- Topic helpers: `lib/`, framework-free, tested beside themselves (`build-query-string.ts` + its test) — never inside the
|
|
15
17
|
topic folder.
|
|
@@ -19,8 +21,13 @@ src/
|
|
|
19
21
|
api/
|
|
20
22
|
topics.ts # one topic registry, reused by keys and namespaces
|
|
21
23
|
index.ts # topic barrels composed as api.<topic>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
<topic>/
|
|
25
|
+
index.ts # barrel: named re-exports of what other modules call
|
|
26
|
+
keys.ts # createApiKeys — query and mutation keys
|
|
27
|
+
queries.ts # query options factories — present when the topic has queries
|
|
28
|
+
mutations.ts # mutation options factories — present when the topic has mutations
|
|
29
|
+
types.ts # Zod schemas + z.infer types
|
|
30
|
+
types.test.ts # schema cases, when the schema encodes product behaviour
|
|
24
31
|
http/ # transport: client, error normalisation — the only transport-aware place
|
|
25
32
|
lib/ # framework-free helpers shared by API topics and other callers
|
|
26
33
|
```
|
|
@@ -94,6 +101,8 @@ export type API = typeof api;
|
|
|
94
101
|
- No topic prefix, no `Options` suffix: `context.api.<topic>.<fn>()` carries both.
|
|
95
102
|
- Queries `get*` (`getAll`, `getById`, `getBySlug`, `getDetails`, `getActive`, `getFiltered`); mutations bare verbs
|
|
96
103
|
(`update`, `login`, `addItem`, `deleteAddress`, `setShippingMethod`).
|
|
104
|
+
- Same suffix-free naming applies to the local binding a query or mutation resolves to —
|
|
105
|
+
[typescript.md](typescript.md#naming).
|
|
97
106
|
|
|
98
107
|
```ts
|
|
99
108
|
// api/user/queries.ts — returns options; keys come from the factory
|
|
@@ -166,13 +175,13 @@ export const Route = createFileRoute("/user")({
|
|
|
166
175
|
|
|
167
176
|
function UserPage() {
|
|
168
177
|
const context = Route.useRouteContext();
|
|
169
|
-
const
|
|
178
|
+
const user = useSuspenseQuery(context.api.user.getDetails());
|
|
170
179
|
const updateUser = useMutation(
|
|
171
180
|
context.api.user.update({
|
|
172
181
|
onSuccess: () => context.queryClient.invalidateQueries({ queryKey: context.api.orders.keys.topic })
|
|
173
182
|
})
|
|
174
183
|
);
|
|
175
|
-
return <input defaultValue={user.name} onBlur={e => updateUser.mutate({ name: e.target.value })} />;
|
|
184
|
+
return <input defaultValue={user.data.name} onBlur={e => updateUser.mutate({ name: e.target.value })} />;
|
|
176
185
|
}
|
|
177
186
|
```
|
|
178
187
|
|
|
@@ -44,9 +44,9 @@ function UserCard({ name, role, onEdit }: { name: string; role: string; onEdit:
|
|
|
44
44
|
```tsx
|
|
45
45
|
// Smart — knows where data comes from, renders the dumb component
|
|
46
46
|
function UserCardContainer({ userId }: { userId: string }) {
|
|
47
|
-
const
|
|
47
|
+
const user = useUserQuery(userId);
|
|
48
48
|
const openEditor = useEditorNavigation(userId);
|
|
49
|
-
return <UserCard name={data.name} role={data.role} onEdit={openEditor} />;
|
|
49
|
+
return <UserCard name={user.data.name} role={user.data.role} onEdit={openEditor} />;
|
|
50
50
|
}
|
|
51
51
|
```
|
|
52
52
|
|
|
@@ -95,6 +95,8 @@ useEffect(
|
|
|
95
95
|
);
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
+
- A dependency sourced from a hook or query return: destructure the primitive first — [typescript.md](typescript.md#naming).
|
|
99
|
+
|
|
98
100
|
## Reading list
|
|
99
101
|
|
|
100
102
|
Consult while building; each is the authority for its topic:
|
|
@@ -43,3 +43,31 @@ const activeNames = users.filter(u => u.isActive).map(u => u.name);
|
|
|
43
43
|
- Booleans read as assertions: `isOpen`, `hasAccess`, `canSubmit`.
|
|
44
44
|
- Handlers: `onX` as props, `handleX` as implementations.
|
|
45
45
|
- Match the vocabulary the product and the API already use — no synonyms for terms the backend named.
|
|
46
|
+
- Keep the object a hook or query returns as a namespace instead of destructuring it, and drop the `Query`/`Mutation` suffix
|
|
47
|
+
from the local binding — the binding reads as the domain name, and every field access shows where it came from:
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
const search = Route.useSearch(); // not const { page, filter } = ...
|
|
51
|
+
const user = useSuspenseQuery(context.api.user.getDetails()); // not const { data } = ...
|
|
52
|
+
const updateUser = useMutation(context.api.user.update());
|
|
53
|
+
|
|
54
|
+
search.page;
|
|
55
|
+
user.data.name;
|
|
56
|
+
updateUser.mutate(values);
|
|
57
|
+
updateUser.isPending;
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- Exception: a `useEffect` dependency array needs a stable primitive, since deps compare by identity — destructure the
|
|
61
|
+
primitive out first rather than listing the object or a deep path into it:
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
const user = useSuspenseQuery(context.api.auth.getUser());
|
|
65
|
+
const { name } = user.data; // destructure for the dep array
|
|
66
|
+
|
|
67
|
+
useEffect(
|
|
68
|
+
function syncDocumentTitle() {
|
|
69
|
+
document.title = name;
|
|
70
|
+
},
|
|
71
|
+
[name]
|
|
72
|
+
);
|
|
73
|
+
```
|
|
@@ -18,20 +18,36 @@ report file as a substitute for the host plan.
|
|
|
18
18
|
|
|
19
19
|
## Workflow
|
|
20
20
|
|
|
21
|
-
1. Resolve the argument. Bare means `full`; a topic selects one supported setup topic.
|
|
22
|
-
|
|
21
|
+
1. Resolve the argument, not the prose. Bare means `full`; a topic argument selects one supported setup topic. A prompt that
|
|
22
|
+
merely _mentions_ one area ("wire up the tooling", "get the project set up") is still a `full` run — the words describe a
|
|
23
|
+
starting point, not a scope that excludes the rest. For a greenfield `full` run the application boundary (router, route
|
|
24
|
+
groups, current-user query, AppShell) is part of the deliverable even when the prompt never names it; propose it and let
|
|
25
|
+
the human remove it, never silently defer it as "out of scope." For an unsupported topic argument, list the available
|
|
26
|
+
setup topics and point the human to `imf-web-ui-audit` for a read-only report.
|
|
23
27
|
2. Enter the host's plan mode. If it is not already active, use the host plan-mode control before inspecting and planning.
|
|
24
28
|
3. Read the selected convention topics and inspect the repository with `Read`, `Glob`, and `Grep` only.
|
|
25
29
|
4. Build the complete proposal in the host plan from the shared report contract at
|
|
26
30
|
[`../imf-web-ui-conventions/templates/REPORT.md`](../imf-web-ui-conventions/templates/REPORT.md). Include the concrete
|
|
27
31
|
content of every file the approved setup would create or change, with repository evidence for each decision.
|
|
28
|
-
5.
|
|
29
|
-
|
|
30
|
-
the
|
|
31
|
-
|
|
32
|
+
5. A greenfield `full` setup proposes the whole starter skeleton, not just tooling — tooling without the application boundary
|
|
33
|
+
is an unfinished setup. Include, as concrete files in the plan:
|
|
34
|
+
- the TanStack Router **package added to `package.json`** (with its router devtools as a dev dependency), not just
|
|
35
|
+
imported — code that imports an uninstalled package is an incomplete setup
|
|
36
|
+
([project-structure.md](../imf-web-ui-conventions/topics/project-structure.md));
|
|
37
|
+
- pathless `_public/` and `_app/` route groups behind one server-backed current-user boundary
|
|
38
|
+
([authentication.md](../imf-web-ui-conventions/topics/authentication.md));
|
|
39
|
+
- the minimal branded `AppShell` in `_app/` by default — omit the shell only when the human explicitly says the product
|
|
40
|
+
has no persistent authenticated navigation (ask first), but keep the `_app/` boundary either way;
|
|
41
|
+
- a per-topic `api/` folder for any data the first screen shows, never an inline fixture in the component
|
|
42
|
+
([data.md](../imf-web-ui-conventions/topics/data.md)).
|
|
43
|
+
|
|
44
|
+
The plan documents this starter shape as concrete file content; it does not copy a full external starter template.
|
|
45
|
+
Existing projects keep their working choices — propose only the gaps.
|
|
46
|
+
|
|
32
47
|
6. Keep the plan as the approval gate. After the host approves and exits plan mode, write only the listed files. Complete any
|
|
33
|
-
immediately requested bootstrap work covered by that approved plan, then invoke `imf-web-ui-audit full`
|
|
34
|
-
|
|
48
|
+
immediately requested bootstrap work covered by that approved plan, then invoke `imf-web-ui-audit full` as a verification
|
|
49
|
+
step and review the findings it reports back before declaring the setup complete. The audit stays out of plan mode here —
|
|
50
|
+
the human has just left it to let this work happen.
|
|
35
51
|
|
|
36
52
|
Installer and hook runs stay with the human: an `agent-tooling` proposal lists the `npx web-ui-install` commands as human
|
|
37
53
|
steps, applies the judgment from the topic (read existing registrations first, never stack a hook on a covered event), and
|
|
@@ -135,8 +135,8 @@ If no findings exist, report that the installed update has no detected compatibi
|
|
|
135
135
|
candidates. Do not create an empty migration commit.
|
|
136
136
|
|
|
137
137
|
Whatever the migration outcome, close the phase by asking whether to run `imf-web-ui-audit full`: an update can shift the
|
|
138
|
-
baseline (new components, hooks, conventions), and the audit
|
|
139
|
-
|
|
138
|
+
baseline (new components, hooks, conventions), and the audit shows where the project now stands against it. Run it only on an
|
|
139
|
+
explicit yes.
|
|
140
140
|
|
|
141
141
|
## Migration approval
|
|
142
142
|
|