@imfusion/web-ui 0.10.1-dev.41.g467e0e1a → 0.10.1-dev.45.ga6a3c86a
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/CHANGELOG.md +4 -5
- package/README.md +4 -33
- package/dist/icons.js +1 -2
- package/dist/paths-B5Ht3ETc.js +26 -0
- package/dist/vite/local-web-ui-link.d.ts +15 -6
- package/dist/vite.js +33 -44
- package/dist/web-ui-cli.js +129 -161
- package/package.json +9 -7
- package/src/llms/install-templates/hooks/baseline-staleness.sh +2 -0
- package/src/llms/install-templates/hooks/stop.sh +5 -2
- package/src/llms/skills/imf-web-ui/SKILL.md +13 -15
- package/src/llms/skills/imf-web-ui-audit/SKILL.md +4 -1
- package/src/llms/skills/imf-web-ui-conventions/SKILL.md +23 -24
- package/src/llms/skills/imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md +1 -0
- package/src/llms/skills/imf-web-ui-conventions/topics/tooling.md +22 -23
- package/src/llms/skills/imf-web-ui-setup/SKILL.md +3 -2
- package/src/llms/skills/imf-web-ui-update/SKILL.md +7 -0
- package/dist/paths-CZtwNknt.js +0 -132
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
name: imf-web-ui-conventions
|
|
3
3
|
description:
|
|
4
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,
|
|
6
|
-
|
|
7
|
-
task."
|
|
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."
|
|
8
7
|
user-invocable: false
|
|
9
8
|
---
|
|
10
9
|
|
|
@@ -15,27 +14,27 @@ a gap or to make a deliberate deviation visible; do not refactor a project just
|
|
|
15
14
|
|
|
16
15
|
## Choose a topic
|
|
17
16
|
|
|
18
|
-
| Topic | Read when
|
|
19
|
-
| ------------------------------------------------ |
|
|
20
|
-
| [library-setup](topics/library-setup.md) | Installing or repairing stylesheet and provider wiring.
|
|
21
|
-
| [library-boundary](topics/library-boundary.md) | Rendering, locking, or wrapping components, or choosing a peer.
|
|
22
|
-
| [authentication](topics/authentication.md) | Protecting routes or defining login and logout.
|
|
23
|
-
| [react](topics/react.md) | Designing component roles, state ownership, or effects.
|
|
24
|
-
| [components](topics/components.md) | Adding files or deciding component anatomy.
|
|
25
|
-
| [typescript](topics/typescript.md) | Writing TypeScript or naming values.
|
|
26
|
-
| [styling](topics/styling.md) | Writing CSS or customizing Web UI.
|
|
27
|
-
| [tokens](topics/tokens.md) | Choosing an exact token name.
|
|
28
|
-
| [class-names](topics/class-names.md) | Mapping variants and `className` to CSS.
|
|
29
|
-
| [validation](topics/validation.md) | Accepting data from outside the frontend.
|
|
30
|
-
| [data](topics/data.md) | Adding API queries, mutations, or invalidation.
|
|
31
|
-
| [project-structure](topics/project-structure.md) | Adding files or routes.
|
|
32
|
-
| [testing](topics/testing.md) | Deciding what to test.
|
|
33
|
-
| [tooling](topics/tooling.md) | Adding a dependency
|
|
34
|
-
| [npm-project](topics/npm-project.md) | Changing `package.json`, scripts, pins, or Node.
|
|
35
|
-
| [git](topics/git.md) | Configuring hooks or choosing verification scope.
|
|
36
|
-
| [agent-tooling](topics/agent-tooling.md) | Installing skills or lifecycle hooks.
|
|
37
|
-
| [assets](topics/assets.md) | Adding images, icons, or other static files.
|
|
38
|
-
| [docs-structure](topics/docs-structure.md) | Writing or reorganizing repository docs.
|
|
17
|
+
| Topic | Read when |
|
|
18
|
+
| ------------------------------------------------ | --------------------------------------------------------------- |
|
|
19
|
+
| [library-setup](topics/library-setup.md) | Installing or repairing stylesheet and provider wiring. |
|
|
20
|
+
| [library-boundary](topics/library-boundary.md) | Rendering, locking, or wrapping components, or choosing a peer. |
|
|
21
|
+
| [authentication](topics/authentication.md) | Protecting routes or defining login and logout. |
|
|
22
|
+
| [react](topics/react.md) | Designing component roles, state ownership, or effects. |
|
|
23
|
+
| [components](topics/components.md) | Adding files or deciding component anatomy. |
|
|
24
|
+
| [typescript](topics/typescript.md) | Writing TypeScript or naming values. |
|
|
25
|
+
| [styling](topics/styling.md) | Writing CSS or customizing Web UI. |
|
|
26
|
+
| [tokens](topics/tokens.md) | Choosing an exact token name. |
|
|
27
|
+
| [class-names](topics/class-names.md) | Mapping variants and `className` to CSS. |
|
|
28
|
+
| [validation](topics/validation.md) | Accepting data from outside the frontend. |
|
|
29
|
+
| [data](topics/data.md) | Adding API queries, mutations, or invalidation. |
|
|
30
|
+
| [project-structure](topics/project-structure.md) | Adding files or routes. |
|
|
31
|
+
| [testing](topics/testing.md) | Deciding what to test. |
|
|
32
|
+
| [tooling](topics/tooling.md) | Adding a dependency or configuring a tool. |
|
|
33
|
+
| [npm-project](topics/npm-project.md) | Changing `package.json`, scripts, pins, or Node. |
|
|
34
|
+
| [git](topics/git.md) | Configuring hooks or choosing verification scope. |
|
|
35
|
+
| [agent-tooling](topics/agent-tooling.md) | Installing skills or lifecycle hooks. |
|
|
36
|
+
| [assets](topics/assets.md) | Adding images, icons, or other static files. |
|
|
37
|
+
| [docs-structure](topics/docs-structure.md) | Writing or reorganizing repository docs. |
|
|
39
38
|
|
|
40
39
|
## How to use the topics
|
|
41
40
|
|
|
@@ -110,6 +110,7 @@ sections one to one — change a topic's sections and this file follows in the s
|
|
|
110
110
|
- [ ] Oxlint and TypeScript
|
|
111
111
|
- [ ] Pre-commit checks
|
|
112
112
|
- [ ] Vite plugins, including `localWebUILink()`
|
|
113
|
+
- [ ] Aligned runtime packages
|
|
113
114
|
|
|
114
115
|
## npm project — `npm-project`
|
|
115
116
|
|
|
@@ -130,33 +130,32 @@ export default defineConfig({
|
|
|
130
130
|
Register `readableCssModuleNames` in every compiler that processes the app's CSS, including development, Storybook, and
|
|
131
131
|
production. A compiler left out produces different class names and styles that appear to work only in some environments.
|
|
132
132
|
|
|
133
|
-
|
|
134
|
-
`npx web-ui link <checkout>` it serves the linked build without pre-bundling it and reloads the page on each sync;
|
|
135
|
-
`npx web-ui unlink` restores the published package. Restart the dev server after either command, since the plugin reads the
|
|
136
|
-
link when Vite starts. The plugin does not cover server rendering.
|
|
133
|
+
## Aligned runtime packages
|
|
137
134
|
|
|
138
|
-
|
|
135
|
+
Web UI and the app run the same versions of these packages. The `peerDependencies` of
|
|
136
|
+
`node_modules/@imfusion/web-ui/package.json` give the accepted ranges, and its `devDependencies` give the version Web UI
|
|
137
|
+
builds and tests with. A matching major and minor is the rule; a patch difference is fine.
|
|
139
138
|
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
- `react`, `react-dom`
|
|
140
|
+
- `@types/react`, `@types/react-dom`
|
|
141
|
+
- `@base-ui/react`, which brings `@floating-ui/*` with it
|
|
142
|
+
- `vite-plus`
|
|
143
|
+
- `vite`, the `npm:@voidzero-dev/vite-plus-core` alias that `vite-plus` provides
|
|
142
144
|
|
|
143
|
-
|
|
145
|
+
## Version drift
|
|
144
146
|
|
|
145
|
-
|
|
146
|
-
2. Find the checkout path: use `WEB_UI_CHECKOUT` when it is set, and ask otherwise.
|
|
147
|
-
3. Start `npm run dev:lib` in the checkout as a background process. `web-ui link` refuses a checkout without `dist/`.
|
|
148
|
-
4. Start `npx web-ui link <checkout>` in the consumer as a background process. It keeps running and syncs on each rebuild.
|
|
149
|
-
5. Restart the consumer's dev server.
|
|
150
|
-
6. Verify the rebuild arrives: after a rebuild, `diff -rq <checkout>/dist node_modules/@imfusion/web-ui/dist` prints nothing.
|
|
147
|
+
Aligned versions are the primary fix. The plugin and the `paths` block below catch the drift that slips through.
|
|
151
148
|
|
|
152
|
-
|
|
149
|
+
`localWebUILink` stays registered for good. It does nothing for an installed package. When `@imfusion/web-ui` is a symlinked
|
|
150
|
+
checkout, it keeps one React in dev, build, and Vitest.
|
|
153
151
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
3. Restart the consumer's dev server.
|
|
152
|
+
Add this to `compilerOptions` in `tsconfig.json`, merged by hand into an existing `paths`. For a symlinked checkout it keeps
|
|
153
|
+
one set of React and Vite types for `tsc`, and it does nothing for an installed package:
|
|
157
154
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
155
|
+
```json
|
|
156
|
+
"paths": {
|
|
157
|
+
"react": ["./node_modules/@types/react"],
|
|
158
|
+
"react/*": ["./node_modules/@types/react/*"],
|
|
159
|
+
"vite": ["./node_modules/vite"]
|
|
160
|
+
}
|
|
161
|
+
```
|
|
@@ -53,8 +53,9 @@ The plan describes the exact starter files. It does not copy a generic starter p
|
|
|
53
53
|
## Vite plugins
|
|
54
54
|
|
|
55
55
|
Propose a `vite.config.ts` that registers `imfusionBrandAssets()`, `readableCssModuleNames()`, and `localWebUILink()` from
|
|
56
|
-
`@imfusion/web-ui/vite`, next to the plugins the project already has. Register `localWebUILink()` in every project:
|
|
57
|
-
|
|
56
|
+
`@imfusion/web-ui/vite`, next to the plugins the project already has. Register `localWebUILink()` in every project: without a
|
|
57
|
+
symlinked checkout it does nothing. Also propose the `tsconfig.json` `paths` block. Both keep one React and one set of types
|
|
58
|
+
when the package is a symlinked checkout. The `tooling` topic has the exact config.
|
|
58
59
|
|
|
59
60
|
## Installer steps
|
|
60
61
|
|
|
@@ -96,6 +96,13 @@ changed. A diff shows what moved, not the step order you continue under, so it d
|
|
|
96
96
|
the current step using the updated guidance, keeping the original baseline, user choices, and completed changes in mind.
|
|
97
97
|
Check for newly required steps without repeating completed mutations or expanding the approved scope.
|
|
98
98
|
|
|
99
|
+
## Align the runtime packages
|
|
100
|
+
|
|
101
|
+
After the install, compare the app's installed versions of the packages listed under Aligned runtime packages in the
|
|
102
|
+
`tooling` topic with Web UI's own `package.json` in `node_modules/@imfusion/web-ui`. Report every major or minor mismatch and
|
|
103
|
+
propose `npm install <package>@<Web UI's version>` for each. Make the change as its own commit, in this same update, after
|
|
104
|
+
the base commit and with its own approval.
|
|
105
|
+
|
|
99
106
|
## Verify the base update
|
|
100
107
|
|
|
101
108
|
After every mutating command, compare the status with the preflight snapshot. Stop on an unexpected path or overlapping
|
package/dist/paths-CZtwNknt.js
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { chmodSync as e, copyFileSync as t, cpSync as n, existsSync as r, mkdirSync as i, readFileSync as a, readdirSync as o, rmSync as s, watch as c, writeFileSync as l } from "node:fs";
|
|
2
|
-
import { dirname as u, join as d, relative as f, resolve as p } from "node:path";
|
|
3
|
-
import { fileURLToPath as m } from "node:url";
|
|
4
|
-
import { spawnSync as h } from "node:child_process";
|
|
5
|
-
//#region src/cli/link.ts
|
|
6
|
-
var g = "@imfusion/web-ui", _ = ".local-link.json", v = [
|
|
7
|
-
"exports",
|
|
8
|
-
"module",
|
|
9
|
-
"types",
|
|
10
|
-
"bin"
|
|
11
|
-
], y = class extends Error {};
|
|
12
|
-
function b(e) {
|
|
13
|
-
return p(e, "node_modules", "@imfusion", "web-ui");
|
|
14
|
-
}
|
|
15
|
-
function x(e) {
|
|
16
|
-
return r(d(e, _));
|
|
17
|
-
}
|
|
18
|
-
function S(e) {
|
|
19
|
-
return p(e, "node_modules", ".web-ui-link");
|
|
20
|
-
}
|
|
21
|
-
function C(e) {
|
|
22
|
-
let t = JSON.parse(a(e, "utf-8"));
|
|
23
|
-
if (typeof t != "object" || !t || Array.isArray(t)) throw new y(`${e} is not a JSON object.`);
|
|
24
|
-
return Object.fromEntries(Object.entries(t));
|
|
25
|
-
}
|
|
26
|
-
function w(e) {
|
|
27
|
-
if (!r(d(e, "package.json"))) throw new y(`${g} is not installed at ${e}. Run npm install in the consumer first.`);
|
|
28
|
-
}
|
|
29
|
-
function T(e) {
|
|
30
|
-
let t = d(e, "package.json");
|
|
31
|
-
if (!r(t) || C(t).name !== g) throw new y(`${e} is not a ${g} checkout.`);
|
|
32
|
-
if (!r(d(e, "dist", "index.js"))) throw new y(`${e} has no dist/ build. Run npm run dev:lib in that checkout first.`);
|
|
33
|
-
}
|
|
34
|
-
function E(e, t) {
|
|
35
|
-
i(t, { recursive: !0 }), n(e, t, {
|
|
36
|
-
recursive: !0,
|
|
37
|
-
force: !0
|
|
38
|
-
});
|
|
39
|
-
for (let n of o(t, {
|
|
40
|
-
recursive: !0,
|
|
41
|
-
withFileTypes: !0
|
|
42
|
-
})) {
|
|
43
|
-
let i = d(n.parentPath, n.name);
|
|
44
|
-
r(d(e, f(t, i))) || s(i, {
|
|
45
|
-
recursive: !0,
|
|
46
|
-
force: !0
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
function D(e, t) {
|
|
51
|
-
let n = { ...e };
|
|
52
|
-
for (let e of v) e in t && (n[e] = t[e]);
|
|
53
|
-
return n;
|
|
54
|
-
}
|
|
55
|
-
function O(t, n) {
|
|
56
|
-
let r = n.bin, i = typeof r == "string" ? [r] : typeof r == "object" && r ? Object.values(r) : [];
|
|
57
|
-
for (let n of i) typeof n == "string" && e(d(t, n), 493);
|
|
58
|
-
}
|
|
59
|
-
function k(e, t) {
|
|
60
|
-
let n = b(e), r = d(S(e), "backup");
|
|
61
|
-
if (!x(n)) return;
|
|
62
|
-
E(d(t, "dist"), d(n, "dist"));
|
|
63
|
-
let i = D(C(d(r, "package.json")), C(d(t, "package.json")));
|
|
64
|
-
l(d(n, "package.json"), `${JSON.stringify(i, null, 2)}\n`), O(n, i);
|
|
65
|
-
}
|
|
66
|
-
function A(e, n) {
|
|
67
|
-
let r = b(e);
|
|
68
|
-
if (w(r), T(n), !x(r)) {
|
|
69
|
-
let n = d(S(e), "backup");
|
|
70
|
-
s(n, {
|
|
71
|
-
recursive: !0,
|
|
72
|
-
force: !0
|
|
73
|
-
}), E(d(r, "dist"), d(n, "dist")), i(n, { recursive: !0 }), t(d(r, "package.json"), d(n, "package.json"));
|
|
74
|
-
}
|
|
75
|
-
return l(d(r, _), `${JSON.stringify({
|
|
76
|
-
checkout: n,
|
|
77
|
-
linkedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
78
|
-
}, null, 2)}\n`), k(e, n), r;
|
|
79
|
-
}
|
|
80
|
-
function j(e) {
|
|
81
|
-
let n = b(e);
|
|
82
|
-
if (!x(n)) return [`${n} is not linked. Nothing to restore.`];
|
|
83
|
-
let i = S(e), a = d(i, "backup");
|
|
84
|
-
if (!r(d(a, "dist")) || !r(d(a, "package.json"))) throw new y(`No backup at ${a}. Run npm install to restore the published package.`);
|
|
85
|
-
return E(d(a, "dist"), d(n, "dist")), t(d(a, "package.json"), d(n, "package.json")), s(d(n, _)), s(i, {
|
|
86
|
-
recursive: !0,
|
|
87
|
-
force: !0
|
|
88
|
-
}), [
|
|
89
|
-
"Restored dist/ from the published build.",
|
|
90
|
-
"Restored package.json.",
|
|
91
|
-
"Removed the link marker and the backup."
|
|
92
|
-
];
|
|
93
|
-
}
|
|
94
|
-
function M(e, t, n) {
|
|
95
|
-
let r = b(e), i, a = c(d(t, "dist"), { recursive: !0 }, () => {
|
|
96
|
-
clearTimeout(i), i = setTimeout(() => {
|
|
97
|
-
if (!x(r)) {
|
|
98
|
-
n("Package is no longer linked; stopped syncing."), a.close();
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
try {
|
|
102
|
-
k(e, t), n(`Synced at ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}`);
|
|
103
|
-
} catch (e) {
|
|
104
|
-
n(`Sync failed, retrying on the next change: ${e instanceof Error ? e.message : String(e)}`);
|
|
105
|
-
}
|
|
106
|
-
}, 150);
|
|
107
|
-
});
|
|
108
|
-
return a;
|
|
109
|
-
}
|
|
110
|
-
//#endregion
|
|
111
|
-
//#region src/cli/paths.ts
|
|
112
|
-
function N(e) {
|
|
113
|
-
let t = e;
|
|
114
|
-
for (; !r(p(t, "package.json"));) {
|
|
115
|
-
let n = u(t);
|
|
116
|
-
if (n === t) throw Error(`Could not find package.json above ${e}`);
|
|
117
|
-
t = n;
|
|
118
|
-
}
|
|
119
|
-
return t;
|
|
120
|
-
}
|
|
121
|
-
var P = N(u(m(import.meta.url))), F = process.cwd();
|
|
122
|
-
function I(e) {
|
|
123
|
-
let t = F;
|
|
124
|
-
for (; t !== u(t) && !r(p(t, "node_modules", ".bin"));) t = u(t);
|
|
125
|
-
let n = p(t, "node_modules", ".bin"), i = p(n, "vp"), [a, o] = r(i) ? [i, ["fmt", ...e]] : [p(n, "prettier"), ["--write", ...e]];
|
|
126
|
-
r(a) && h(a, o, {
|
|
127
|
-
cwd: F,
|
|
128
|
-
stdio: "ignore"
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
//#endregion
|
|
132
|
-
export { A as a, M as c, y as i, P as n, j as o, F as r, x as s, I as t };
|