@imfusion/web-ui 0.6.1-dev.12.ge86ac0a1 → 0.6.1-dev.14.g8fac1dfb

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.
Files changed (40) hide show
  1. package/README.md +102 -170
  2. package/dist/{code-Blo48PGr.js → code-C_56u-Vk.js} +2 -2
  3. package/dist/{icons-wBmF0U2x.js → icons-Cy1HAosO.js} +1 -1
  4. package/dist/icons.js +1 -1
  5. package/dist/index.js +31 -31
  6. package/dist/integrations/code-highlight.js +2 -2
  7. package/dist/integrations/image-display-options.js +1 -1
  8. package/package.json +1 -1
  9. package/src/llms/install-templates/AGENTS.md +15 -18
  10. package/src/llms/llms.gen.txt +33 -33
  11. package/src/llms/skills/imf-web-ui/SKILL.md +29 -39
  12. package/src/llms/skills/imf-web-ui-audit/SKILL.md +50 -102
  13. package/src/llms/skills/imf-web-ui-components/SKILL.md +47 -104
  14. package/src/llms/skills/imf-web-ui-conventions/SKILL.md +39 -52
  15. package/src/llms/skills/imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md +1 -0
  16. package/src/llms/skills/imf-web-ui-conventions/topics/agent-tooling.md +40 -62
  17. package/src/llms/skills/imf-web-ui-conventions/topics/assets.md +11 -12
  18. package/src/llms/skills/imf-web-ui-conventions/topics/authentication.md +31 -46
  19. package/src/llms/skills/imf-web-ui-conventions/topics/class-names.md +18 -23
  20. package/src/llms/skills/imf-web-ui-conventions/topics/components.md +20 -69
  21. package/src/llms/skills/imf-web-ui-conventions/topics/data.md +50 -146
  22. package/src/llms/skills/imf-web-ui-conventions/topics/docs-structure.md +17 -23
  23. package/src/llms/skills/imf-web-ui-conventions/topics/git.md +15 -20
  24. package/src/llms/skills/imf-web-ui-conventions/topics/library-boundary.md +28 -19
  25. package/src/llms/skills/imf-web-ui-conventions/topics/library-setup.md +20 -16
  26. package/src/llms/skills/imf-web-ui-conventions/topics/npm-project.md +28 -42
  27. package/src/llms/skills/imf-web-ui-conventions/topics/project-structure.md +28 -30
  28. package/src/llms/skills/imf-web-ui-conventions/topics/react.md +28 -74
  29. package/src/llms/skills/imf-web-ui-conventions/topics/styling.md +65 -62
  30. package/src/llms/skills/imf-web-ui-conventions/topics/testing.md +12 -14
  31. package/src/llms/skills/imf-web-ui-conventions/topics/tokens.md +9 -4
  32. package/src/llms/skills/imf-web-ui-conventions/topics/tooling.md +40 -68
  33. package/src/llms/skills/imf-web-ui-conventions/topics/typescript.md +26 -50
  34. package/src/llms/skills/imf-web-ui-conventions/topics/validation.md +19 -25
  35. package/src/llms/skills/imf-web-ui-setup/SKILL.md +43 -64
  36. package/src/llms/skills/imf-web-ui-update/SKILL.md +48 -114
  37. package/src/llms/skills/imf-web-ui-ux/SKILL.md +64 -92
  38. package/src/llms/skills/imf-web-ui-ux/references/forms.md +16 -36
  39. package/src/llms/skills/imf-web-ui-ux/references/usability-heuristics.md +14 -27
  40. package/src/llms/skills/imf-web-ui-ux/references/visual-design.md +22 -38
@@ -1,73 +1,49 @@
1
- # TypeScript & code style
1
+ # TypeScript and code style
2
2
 
3
- Functional by default: pure functions over stateful classes, immutable data over in-place mutation, expressions over
4
- statements, side effects at the edges (network, DOM, store).
3
+ Prefer pure functions, immutable values, and side effects at the edges.
5
4
 
6
5
  ## Types
7
6
 
8
- - No `any`. `unknown` at a boundary you can't type, narrowed before use.
9
- - Infer locals; annotate contracts. Exported functions get an explicit return type.
10
- - No temporal coupling — model the states instead of initialising `null` and filling in later.
11
- - Avoid `as`. Fix the type. The honest exception: an untyped third-party boundary, kept at the boundary.
12
- - Derive, don't duplicate:
7
+ - Do not use `any`. Accept `unknown` at an untrusted boundary and narrow it.
8
+ - Infer local values; give exported functions explicit return types.
9
+ - Model states directly instead of filling a nullable value later.
10
+ - Derive types from their source. Use `z.infer` for schemas and `React.ComponentProps` for Web UI components.
11
+ - Avoid `as`. Keep an assertion only at an untyped third-party boundary where it is the honest boundary.
12
+ - Use one or two positional arguments. At three or more, pass a named object.
13
13
 
14
14
  ```ts
15
15
  const sizes = ["sm", "md", "lg"] as const;
16
16
  type Size = (typeof sizes)[number];
17
17
 
18
- const labels: Record<Size, string> = { sm: "S", md: "M", lg: "L" }; // compiler breaks if `sizes` changes
18
+ const labels: Record<Size, string> = {
19
+ sm: "S",
20
+ md: "M",
21
+ lg: "L"
22
+ };
19
23
  ```
20
24
 
21
- - Same rule across boundaries: library props via `React.ComponentProps<typeof Button>`
22
- ([library-boundary.md](library-boundary.md)), untrusted data via a runtime schema and `z.infer`
23
- ([validation.md](validation.md)).
24
- - Function signatures: 1–2 positional arguments; at 3+, one destructured object.
25
+ ## Immutability and expressions
25
26
 
26
- ## Immutability & expressions
27
+ Use `map`, `filter`, `find`, `some`, and `flatMap` for ordinary collection work. Create new values instead of mutating the
28
+ input. Use `toSorted` and `toReversed` instead of their mutating counterparts.
27
29
 
28
- - Array methods before loops — `map`, `filter`, `find`, `some`, `flatMap` name what they do:
29
-
30
- ```ts
31
- const activeNames = users.filter(u => u.isActive).map(u => u.name);
32
- ```
33
-
34
- - Produce new values: spreads and `structuredClone` over in-place edits, `toSorted`/`toReversed` over `sort`/`reverse` (which
35
- mutate their receiver).
36
- - Allowed exceptions: a genuine early exit (`for` + `break`), a measured hot loop.
37
- - Keep chains flat: 3–4 steps read well; longer wants named intermediates, and a `reduce` doing four things wants to be a
38
- loop.
30
+ A loop is fine when it has a real early exit or measured hot-path benefit. A long chain or a `reduce` with several jobs wants
31
+ named intermediate values.
39
32
 
40
33
  ## Naming
41
34
 
42
- - Say what it is, not what it's made of: `useUserQuery`, not `useUserHook`; `retryDelay`, not `num`.
43
- - Booleans read as assertions: `isOpen`, `hasAccess`, `canSubmit`.
44
- - Handlers: `onX` as props, `handleX` as implementations.
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:
35
+ Name what a value is, not how it is built. Booleans read as assertions (`isOpen`, `hasAccess`, `canSubmit`). Props use `onX`;
36
+ component implementations use `handleX`.
37
+
38
+ Keep a hook or query result as a namespace and name the local after its domain:
48
39
 
49
40
  ```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());
41
+ const search = Route.useSearch();
42
+ const user = useSuspenseQuery(context.api.user.getDetails());
53
43
 
54
44
  search.page;
55
45
  user.data.name;
56
- updateUser.mutate(values);
57
- updateUser.isPending;
58
46
  ```
59
47
 
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
- ```
48
+ Destructure a primitive only when a stable value is needed, such as an effect dependency. Match existing product and API
49
+ vocabulary instead of inventing synonyms.
@@ -1,20 +1,22 @@
1
1
  # Validation
2
2
 
3
- Validate where data crosses from untrusted representation into frontend-owned values; the schema is the single source of
4
- truth for runtime check and TypeScript type.
3
+ Validate data when it crosses into frontend-owned code. Use the schema as both the runtime check and the TypeScript source.
5
4
 
6
5
  ## Boundaries
7
6
 
8
- - Validate once, at the edge: network responses on entry; URL path and search params before business logic; persisted browser
9
- data on read; user input becoming a submitted domain or request value.
10
- - Inside the boundary: parsed values only, no repeated defensive shape checks.
11
- - Outgoing requests built from already parsed domain values are serialized, not re-validated.
12
- - A typed client's handwritten generic is not validation — it only asserts a type onto an untrusted response.
7
+ Validate once at the edge:
8
+
9
+ - network responses on entry;
10
+ - URL path and search values;
11
+ - persisted browser data when read;
12
+ - user input when it becomes a submitted domain or request value.
13
+
14
+ After the boundary, use parsed values. A generic on a typed client only tells TypeScript what you hope the response looks
15
+ like; it does not validate it.
13
16
 
14
17
  ## Schema first, type derived
15
18
 
16
- - Zod schema, type via `z.infer`; never a handwritten type beside its schema.
17
- - Same rule for request and response shapes the frontend owns or consumes at runtime.
19
+ Use a Zod schema and derive the type:
18
20
 
19
21
  ```ts
20
22
  import { z } from "zod";
@@ -27,17 +29,13 @@ export const userSchema = z.object({
27
29
  export type User = z.infer<typeof userSchema>;
28
30
  ```
29
31
 
32
+ Apply the same rule to request and response shapes the frontend owns at runtime.
33
+
30
34
  ## TanStack Router search params
31
35
 
32
- - `validateSearch` takes a Zod v4 schema directly (TanStack Router v1) — no adapter or parsing wrapper.
33
- - `Route.useSearch()` infers its type from `validateSearch`.
34
- - `.catch()`: malformed URL input falls back without interrupting navigation.
35
- - `.default()`: only for missing values; malformed values still follow the route's validation error path.
36
+ Pass a Zod v4 schema to `validateSearch`. Route search types then come from that schema:
36
37
 
37
38
  ```tsx
38
- import { createFileRoute } from "@tanstack/react-router";
39
- import { z } from "zod";
40
-
41
39
  const searchSchema = z.object({
42
40
  page: z.number().int().positive().catch(1),
43
41
  filter: z.string().catch("")
@@ -47,16 +45,12 @@ export const Route = createFileRoute("/users")({
47
45
  validateSearch: searchSchema,
48
46
  component: Users
49
47
  });
50
-
51
- function Users() {
52
- const search = Route.useSearch(); // inferred: z.infer<typeof searchSchema>
53
- return <UserList page={search.page} filter={search.filter} />;
54
- }
55
48
  ```
56
49
 
50
+ Use `.catch()` for malformed values that can safely fall back. Use `.default()` only for missing values.
51
+
57
52
  ## Failure handling
58
53
 
59
- - `schema.parse`: invalid data is a contract failure on the normal error path (malformed backend response → route error
60
- boundary).
61
- - `schema.safeParse`: failure is expected and the caller handles the issues (submitted user input).
62
- - Transforms and coercion live in the boundary schema — never scatter trimming, number conversion, or defaulting downstream.
54
+ - Use `parse` when invalid data is a contract failure that should reach the normal error boundary.
55
+ - Use `safeParse` when failure is expected and the caller can show a validation message.
56
+ - Keep trimming, coercion, transforms, and defaults in the boundary schema.
@@ -1,87 +1,66 @@
1
1
  ---
2
2
  name: imf-web-ui-setup
3
3
  description:
4
- "Plan and, after explicit approval, bootstrap an ImFusion frontend against the conventions baseline: library setup,
5
- tooling, git, npm project, authentication, project structure, docs structure, data, testing, or agent tooling. Inspect
6
- statically first and write only the approved files. Use imf-web-ui-audit for read-only health checks or topics with no
7
- setup action."
4
+ "Plan and, after explicit approval, bootstrap a consumer project that uses @imfusion/web-ui. Use this whenever a project
5
+ needs library wiring, tooling, git, npm, authentication, structure, data, testing, docs, or agent tooling. Inspect first,
6
+ propose concrete files, and write only what the user approves. Use imf-web-ui-audit for read-only checks."
8
7
  argument-hint: "[full|library-setup|tooling|git|npm-project|authentication|project-structure|docs-structure|data|testing|agent-tooling]"
9
8
  allowed-tools: Read Glob Grep Write
10
9
  ---
11
10
 
12
- # imf-web-ui-setup
11
+ # Set up a consumer project
13
12
 
14
- You are the frontend bootstrap planner. Inspect the repository statically, read the applicable `imf-web-ui-conventions`
15
- topics, and prepare a complete proposal for every file you would create or change. The project wins where it already has a
16
- working convention. This skill is plan-first: enter the host's plan mode before presenting the proposal, and do not create a
17
- report file as a substitute for the host plan.
13
+ Plan the missing pieces of an ImFusion frontend. The existing project wins; this skill fills gaps instead of reshaping
14
+ working choices.
18
15
 
19
16
  ## Workflow
20
17
 
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.
27
- 2. Enter the host's plan mode. If it is not already active, use the host plan-mode control before inspecting and planning.
18
+ 1. Resolve the argument. Bare means `full`. A named topic limits the assessment to that topic. If the argument is unknown,
19
+ list the supported topics and point to `imf-web-ui-audit`.
20
+ 2. Enter the host's plan mode before inspecting or proposing changes.
28
21
  3. Read the selected convention topics and inspect the repository with `Read`, `Glob`, and `Grep` only.
29
- 4. Build the complete proposal in the host plan from the shared report contract at
30
- [`../imf-web-ui-conventions/templates/REPORT.md`](../imf-web-ui-conventions/templates/REPORT.md). Include the concrete
31
- content of every file the approved setup would create or change, with repository evidence for each decision.
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)).
22
+ 4. Put a complete proposal in the host plan, using [`templates/REPORT.md`](../imf-web-ui-conventions/templates/REPORT.md).
23
+ Name every file to create or change, include its intended content, and cite the repository evidence behind the choice.
24
+ 5. Wait for explicit approval. After approval, write only the listed files.
25
+ 6. Run `imf-web-ui-audit full` as a follow-up and review its findings before calling setup complete.
43
26
 
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.
27
+ ## Greenfield `full` setup
46
28
 
47
- 6. Keep the plan as the approval gate. After the host approves and exits plan mode, write only the listed files. Complete any
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.
29
+ Include these pieces unless the existing project already has them or the user removes them from the plan:
51
30
 
52
- Installer and hook runs stay with the human: an `agent-tooling` proposal lists the `npx web-ui-install` commands as human
53
- steps, applies the judgment from the topic (read existing registrations first, never stack a hook on a covered event), and
54
- includes the topic's Codex trust follow-up whenever hooks are part of the plan.
31
+ - `@tanstack/react-router` and its router devtools in `package.json`;
32
+ - pathless `_public/` and `_app/` route groups;
33
+ - one server-backed current-user query at the route boundary;
34
+ - a minimal `AppShell` in `_app/`, unless the user says the product has no persistent authenticated navigation;
35
+ - an API topic folder for data shown by the first screen;
36
+ - the root provider and library wiring.
55
37
 
56
- ## Checklist
38
+ The plan describes the exact starter files. It does not copy a generic starter project.
57
39
 
58
- The post-implementation audit uses the shared
59
- [convention audit checklist](../imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md) to verify the complete baseline, not
60
- only the setup topic selected at the start.
40
+ ## Installer steps
61
41
 
62
- ## Safety
42
+ For `agent-tooling`, list the `npx web-ui-install` commands as steps for the human. Read existing registrations first and do
43
+ not stack a hook on an event the project already covers. Include the Codex trust review when hooks are part of the plan.
63
44
 
64
- Use only static inspection: `Read`, `Glob`, and `Grep`. Do not use a shell or invoke Node, npm, npx, package scripts, hooks,
65
- config imports, linters, tests, builds, Git commands, project binaries, installers, or package managers. Read config as text
66
- and report runtime or machine-local state that cannot be established statically as unverified. After approval, `Write` is
67
- limited to the files listed in the approved report; anything needing execution goes in the plan for the human.
45
+ ## Safety
68
46
 
69
- ## Setup topics
47
+ During inspection use only `Read`, `Glob`, and `Grep`. Do not run shells, Git, Node, npm, npx, installers, builds, tests, or
48
+ local config. Report anything that needs runtime state as unverified. After approval, `Write` is limited to the approved file
49
+ list; put commands in the plan for the human to run.
70
50
 
71
- `full` covers every topic below. A one-topic run assesses only that topic.
51
+ ## Topics
72
52
 
73
- | Topic | Assess and plan |
74
- | ------------------- | ------------------------------------------------------------------------------ |
75
- | `library-setup` | styles import, `WebUIProvider`, and library package wiring |
76
- | `tooling` | dependency selection, devtools, Prettier, ESLint, TypeScript, and verification |
77
- | `git` | tracked hooks, verification scopes, and staleness wiring |
78
- | `npm-project` | package metadata, scripts, pins, npm, and Node configuration |
79
- | `authentication` | current-user query, public/app guards, login, and logout |
80
- | `project-structure` | source tree, route groups, optional app shell, naming, and placement |
81
- | `docs-structure` | README, AGENTS, docs index, and content boundaries |
82
- | `data` | transport, schemas, query/mutation options, keys, and invalidation |
83
- | `testing` | test boundaries and verification coverage |
84
- | `agent-tooling` | vendored skills, AGENTS fence, lifecycle hooks, registrations, and staleness |
53
+ | Topic | Covers |
54
+ | ------------------- | ------------------------------------------------------------------------ |
55
+ | `library-setup` | Stylesheet, `WebUIProvider`, and package wiring. |
56
+ | `tooling` | Dependencies, devtools, formatter, linter, TypeScript, and verification. |
57
+ | `git` | Hooks, verification scopes, and staleness checks. |
58
+ | `npm-project` | Manifest, scripts, pins, npm, and Node. |
59
+ | `authentication` | Current-user query, route groups, login, and logout. |
60
+ | `project-structure` | Source tree, route placement, naming, and imports. |
61
+ | `docs-structure` | README, AGENTS, docs index, and content boundaries. |
62
+ | `data` | Transport, schemas, query/mutation options, keys, and invalidation. |
63
+ | `testing` | Test boundaries and coverage. |
64
+ | `agent-tooling` | Vendored skills, hooks, registrations, and Codex trust. |
85
65
 
86
- Setup has no file-creation action for `react`, `typescript`, `class-names`, `validation`, `components`, `styling`, `assets`,
87
- `library-boundary`, or `tokens`; select those in `imf-web-ui-audit`.
66
+ The other convention topics are read by `imf-web-ui-audit` when a project needs assessment rather than setup.
@@ -1,157 +1,91 @@
1
1
  ---
2
2
  name: imf-web-ui-update
3
3
  description:
4
- "Update @imfusion/web-ui in a consumer repository: refresh the package, vendored skills, and lifecycle hooks, verify the
5
- base update, then audit and optionally migrate affected or custom consumer components in a separate approved commit."
4
+ "Update @imfusion/web-ui in a consumer repository. Use this whenever a consumer needs a newer package, installed skills, or
5
+ lifecycle hooks. Refresh the base first, verify it, then audit any consumer migration separately. Preserve user work and
6
+ get approval before each commit."
6
7
  argument-hint: "[--dry-run] [optional version or reason]"
7
8
  allowed-tools: Bash Read Grep
8
9
  ---
9
10
 
10
- # imf-web-ui-update
11
-
12
- Update a repository that consumes `@imfusion/web-ui`. Preserve existing project choices and user work. The workflow has two
13
- commits: the dependency/tooling update first, then an optional consumer migration. Never commit without a fresh explicit
14
- approval.
15
-
16
- ## Rules
17
-
18
- - Work from the frontend package root. In a monorepo, inspect package manifests and `git worktree list` first, then choose
19
- the frontend package in the active worktree that uses web-ui. Read repository and component instructions before changing
20
- files.
21
- - This workflow uses npm. `package-lock.json` is the expected lockfile. Another lockfile is a conflict: stop and ask.
22
- - A dry run is read-only. Do not install, run the installer, format, stage, commit, reset, or clean. Report what would run.
23
- - Record the initial `git status --short`. Existing changes are held back, never staged or overwritten.
24
- - A dirty file that the workflow needs to modify is a conflict. Stop and report it. This includes package files, installed
25
- skill directories, the `AGENTS.md` installer fence, hook files, and hook settings.
26
- - Do not hand-edit installer-owned skills, the `AGENTS.md` fenced block, or installer-owned hook files.
27
- - Keep the base update and consumer migration in separate commits. Do not begin the migration audit until the base update
28
- commit is complete.
29
- - Treat the installed package version before the update as the comparison baseline. There is no assumed changelog.
30
- - A migration candidate is a custom consumer implementation whose behavior overlaps with a current web-ui component, or an
31
- existing web-ui usage affected by changed types or documented API. Do not infer a replacement from a name alone; inspect
32
- the implementation and the current component documentation/types.
11
+ # Update Web UI
12
+
13
+ This workflow has two possible commits: the package/tooling update, then an optional consumer migration. Keep them separate.
14
+ Never overwrite user changes or commit without fresh approval.
33
15
 
34
16
  ## Preflight
35
17
 
36
- 1. Select the frontend package in the active worktree and read its instructions, `package.json`, and `package-lock.json`.
37
- 2. Check whether `@imfusion/web-ui` is already declared and record its installed/version-marker version.
38
- 3. Record the worktree status and identify files the update would touch.
39
- 4. Inspect `.agents/skills/`, `.claude/skills/`, the `AGENTS.md` fence, `.claude/settings.json`, and `.agents/hooks/`.
40
- 5. Check for another npm process. Stop on any conflict or ambiguous target.
18
+ 1. Work from the frontend package root. In a monorepo, find the package that owns the Web UI dependency.
19
+ 2. Read its `package.json`, lockfile, and repository instructions. npm with `package-lock.json` is the expected setup; stop
20
+ if another lockfile is the active one.
21
+ 3. Record `git status --short`, the installed Web UI version, the installed skill targets, hooks, registrations, and
22
+ `AGENTS.md` fence.
23
+ 4. Check for another npm process and stop on a conflict. A dirty file this workflow needs is also a conflict. Do not reset,
24
+ clean, restore, or hide it.
25
+ 5. With `--dry-run`, stop after reporting what would happen. Do not install, format, stage, commit, or ask for commit
26
+ approval.
41
27
 
42
- ## Base update
28
+ ## Update the base
43
29
 
44
- In a non-dry run, update the dependency:
30
+ Run from the consumer package root:
45
31
 
46
32
  ```sh
47
33
  npm install @imfusion/web-ui
48
- ```
49
-
50
- Pass an explicit version only when the user supplied one. Do not use `--force` or `--legacy-peer-deps` to make installation
51
- pass. Stop on install failure.
52
-
53
- Then refresh the existing web-ui skill target and lifecycle hooks:
54
-
55
- ```sh
56
34
  npx web-ui-install
57
35
  npx web-ui-install --hooks
58
36
  ```
59
37
 
60
- Run these from the consumer package root, the directory holding the `node_modules` that the dependency install just wrote.
61
- `npx` resolves `web-ui-install` from the installed `@imfusion/web-ui` there; from any other directory it cannot find the
62
- binary. Preserve the existing target (`.agents`, `.claude`, or both); do not silently choose a new one.
63
-
64
- Always run both installer commands after the package update. Skills and installer-owned hook scripts may have changed even
65
- when their existing registrations already cover session start, subagent start, prompt submit, and the stop gate. The hook
66
- installer refreshes those scripts wholesale, prunes retired scripts and their registrations, and merges registrations
67
- idempotently into both host files (`.claude/settings.json` and `.codex/hooks.json`). Stop on malformed settings or installer
68
- conflicts.
69
-
70
- ## Verification
71
-
72
- After each mutating command, compare `git status --short` with the preflight snapshot.
38
+ Use `npm install @imfusion/web-ui@<version>` when the user supplied an explicit version. Stop on install failure. Preserve
39
+ the installer's existing target. Do not use `--force` or `--legacy-peer-deps`.
73
40
 
74
- Classify paths as:
41
+ The installer owns the vendored skills, its `AGENTS.md` fence, and hook scripts. Run both installer commands after the
42
+ package update even when the existing registrations look complete: they refresh scripts, prune retired registrations, and
43
+ merge installer-owned entries idempotently into `.claude/settings.json` and `.codex/hooks.json`. Stop on malformed settings
44
+ or installer conflicts. Read existing host registrations first and do not stack an event the project already covers.
75
45
 
76
- - **Update-owned:** package files and installer-owned files changed by this workflow.
77
- - **Held back:** pre-existing user changes, excluded from the commit.
78
- - **Conflict:** an overlapping pre-existing change, ambiguous target, or unexpected changed path.
46
+ ## Verify the base update
79
47
 
80
- On conflict, stop. Never use `git restore`, `git reset`, `git clean`, or broad staging to hide it.
48
+ After every mutating command, compare the status with the preflight snapshot. Stop on an unexpected path or overlapping
49
+ change.
81
50
 
82
- Run the frontend package's documented full verification after the base update. Read its `package.json` scripts and choose
83
- commands that cover typechecking, linting, tests, and building. Prefer one documented aggregate `verify`/`check` script when
84
- it covers those responsibilities; otherwise run the documented non-watch scripts for the responsibilities that exist. Do not
85
- invent script names or run watch/dev scripts. A type or build failure is a base-update conflict to resolve before the base
86
- commit, not a migration finding to defer.
51
+ Run the consumer's documented full verification. Read its scripts first; prefer an aggregate check, otherwise run the
52
+ non-watch format, lint, typecheck, test, and build commands that exist.
87
53
 
88
- Verify the dependency/lockfile, current skill markers, the `AGENTS.md` fence, hook coverage, and the final path list. In
89
- dry-run mode, say that mutation-dependent checks were skipped.
54
+ Check the dependency and lockfile, skill markers, `AGENTS.md` fence, hook registrations, and final update-owned path list.
90
55
 
91
- ## Base update report and approval
92
-
93
- Before the base commit, show this concise report:
56
+ Report before the first commit:
94
57
 
95
58
  ```text
96
59
  @imfusion/web-ui update report
97
- Package : <old> -> <new> / would update
60
+ Package : <old> -> <new>
98
61
  Skills : <status>
99
62
  Hooks : <status>
100
63
  Verification : <status>
101
64
  Update files : <paths>
102
65
  Held back : <paths or none>
103
66
  Conflicts : <paths or none>
104
- Commit : <imperative message or not proposed>
67
+ Commit : <message or not proposed>
105
68
  ```
106
69
 
107
- Normal mode: ask exactly, **“Approve these update-owned changes and commit them?”** Do not commit without an affirmative
108
- answer. If denied, leave the changes uncommitted.
109
-
110
- Dry-run mode: state **“Dry run complete; no changes or commit were made.”** Do not mutate or ask for commit approval.
111
-
112
- ## Consumer migration audit
113
-
114
- Begin this phase only after the approved base update has been committed. Record the old and new package versions from the
115
- pre-update and current manifests/lockfile. Use the current package's exported types, generated documentation, and component
116
- examples as the source of truth. Use the old version's package metadata or repository history when available to identify what
117
- changed; do not pretend a changelog exists.
118
-
119
- Run the same documented full verification again after the base commit. Separate findings into:
120
-
121
- - **Compatibility fixes:** existing web-ui imports, props, or usage patterns that no longer typecheck, build, lint, or pass
122
- tests.
123
- - **Changed component usages:** existing components whose current API, behavior, or documented contract changed between the
124
- two versions and may need a consumer update, even when the typecheck passes.
125
- - **Replacement candidates:** custom consumer components, wrappers, or field implementations that overlap with a component
126
- now exported by `@imfusion/web-ui`. Inspect their code, styles, and call sites before suggesting a replacement. Include the
127
- current custom implementation, the proposed web-ui component, the relevant API/type evidence, and any behavior or styling
128
- that still needs to be preserved.
129
-
130
- Report these findings separately from the base update. Ask whether to apply the proposed migration. If the user declines,
131
- leave the consumer code unchanged. If accepted, make only the approved migration changes, run the documented full
132
- verification again, and show a second report with the migration paths, held-back paths, conflicts, and verification result.
133
-
134
- If no findings exist, report that the installed update has no detected compatibility fixes, changed usages, or replacement
135
- candidates. Do not create an empty migration commit.
70
+ Ask: **Approve these update-owned changes and commit them?** Stage only approved update paths and follow the repository's
71
+ commit workflow.
136
72
 
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 shows where the project now stands against it. Run it only on an
139
- explicit yes.
73
+ ## Audit the consumer migration
140
74
 
141
- ## Migration approval
75
+ Start this phase only after the base update commit exists. Use the pre-update package metadata as the comparison baseline;
76
+ don't assume a changelog exists. Compare the old and new package metadata, current generated docs, types, and examples. Run
77
+ the full verification again.
142
78
 
143
- Ask exactly, **“Approve these consumer migration changes and commit them separately?”** Do not commit without an affirmative
144
- answer. The migration approval is not implied by approval of the base update.
79
+ Report separately:
145
80
 
146
- ## Commit
81
+ - compatibility fixes required by changed imports or types;
82
+ - existing uses affected by a changed API or documented behavior;
83
+ - custom components that overlap with a current Web UI primitive, with evidence and any behavior to preserve.
147
84
 
148
- For the base update, after approval:
85
+ Do not infer a replacement from a name. Inspect the implementation, styles, and call sites. If there are no findings, say so
86
+ and do not make an empty migration commit.
149
87
 
150
- 1. Recheck status and exclude held-back paths.
151
- 2. Stage base update-owned paths selectively. Never use `git add .` or `git add -A`.
152
- 3. Run the repository's commit workflow if it has one, including its required verification and documentation audit. Otherwise
153
- run documented verification and follow the repository's commit convention.
154
- 4. Commit with a concise imperative message and confirm the commit and final status.
88
+ Ask whether to run `imf-web-ui-audit full`. Run it only after an explicit yes.
155
89
 
156
- For an approved migration, repeat the same selective staging and documented commit workflow with a separate imperative
157
- message. Never bypass hooks or amend an unrelated commit after a hook failure.
90
+ For approved migration work, ask: **Approve these consumer migration changes and commit them separately?** Then stage only
91
+ the approved paths, verify again, and use a separate imperative commit message.