@imfusion/web-ui 0.5.1-dev.56.gcf89961f → 0.5.1-dev.6.ge1cebe1f
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 +31 -68
- package/bin/install-skill.js +180 -0
- package/dist/code-qBbqAHK-.js +190 -0
- package/dist/components/callout/callout.d.ts +1 -1
- package/dist/components/chip-link/chip-link.d.ts +1 -1
- package/dist/components/code/code.d.ts +18 -10
- package/dist/components/input/input.d.ts +1 -3
- package/dist/components/typo/typo.d.ts +2 -2
- package/dist/hooks/index.d.ts +0 -1
- package/dist/index.d.ts +1 -4
- package/dist/index.js +12206 -1789
- package/dist/integrations/code-highlight/code-highlight.d.ts +6 -8
- package/dist/integrations/code-highlight/highlighter.d.ts +3 -32
- package/dist/integrations/code-highlight.js +59 -198
- package/dist/integrations/image-display-options.js +69 -70
- package/dist/meta-B8C51eyL.js +74 -0
- package/dist/provider/web-ui-provider.d.ts +1 -4
- package/dist/style.css +1 -1
- package/dist/tabs-DqBFSqq6.js +3789 -0
- package/package.json +26 -48
- package/src/docgen/doc.gen.json +38 -381
- package/src/llms/llms.gen.txt +0 -17
- package/src/llms/skills/imf-web-ui/SKILL.md +12 -13
- package/src/llms/skills/imf-web-ui-components/SKILL.md +3 -56
- package/src/llms/skills/imf-web-ui-frontend-patterns/SKILL.md +93 -0
- package/src/llms/skills/imf-web-ui-frontend-patterns/references/code-conventions.md +133 -0
- package/src/llms/skills/imf-web-ui-frontend-patterns/references/react-patterns.md +94 -0
- package/src/llms/skills/imf-web-ui-imfusion-frontend-setup/SKILL.md +201 -0
- package/src/llms/skills/imf-web-ui-setup/SKILL.md +37 -67
- package/src/llms/skills/imf-web-ui-ux/SKILL.md +4 -4
- package/src/llms/skills/imf-web-ui-ux/references/forms.md +2 -2
- package/bin/install.js +0 -428
- package/bin/install.test.ts +0 -329
- package/dist/build/vite-css-module-names/index.d.ts +0 -20
- package/dist/build/vite-css-module-names.js +0 -17
- package/dist/chunk-DmhlhrBa.js +0 -11
- package/dist/code-Blo48PGr.js +0 -136
- package/dist/codegen/gen-icons.d.ts +0 -24
- package/dist/components/field/field.d.ts +0 -104
- package/dist/components/field/field.meta.d.ts +0 -2
- package/dist/components/field/index.d.ts +0 -2
- package/dist/components/fieldset/fieldset.d.ts +0 -29
- package/dist/components/fieldset/fieldset.meta.d.ts +0 -2
- package/dist/components/fieldset/index.d.ts +0 -2
- package/dist/components/icon/icon.d.ts +0 -16
- package/dist/components/icon/icon.meta.d.ts +0 -2
- package/dist/components/icon/index.d.ts +0 -4
- package/dist/components/icon/types.d.ts +0 -2
- package/dist/docgen/component-sources.d.ts +0 -7
- package/dist/hooks/use-resize-observer.d.ts +0 -2
- package/dist/icons/catalog.gen.d.ts +0 -8357
- package/dist/icons/icon-config-provider.d.ts +0 -8
- package/dist/icons/icon-context.d.ts +0 -4
- package/dist/icons/icons.gen.d.ts +0 -1672
- package/dist/icons/index.d.ts +0 -3
- package/dist/icons-wBmF0U2x.js +0 -78
- package/dist/icons.js +0 -2
- package/dist/integrations/code-highlight/language-patterns.d.ts +0 -7
- package/dist/integrations/code-highlight/languages/cmake.d.ts +0 -1
- package/dist/integrations/code-highlight/languages/cpp.d.ts +0 -1
- package/dist/integrations/code-highlight/languages/python.d.ts +0 -1
- package/dist/llms/gen-tokens.d.ts +0 -7
- package/dist/meta-CySnRuVp.js +0 -21
- package/dist/tabs-CMKvMF4E.js +0 -369
- package/src/llms/icon-catalog.gen.json +0 -11203
- package/src/llms/install-templates/AGENTS.md +0 -34
- package/src/llms/install-templates/codex-hooks.json +0 -44
- package/src/llms/install-templates/hooks/baseline-staleness.sh +0 -17
- package/src/llms/install-templates/hooks/session-start.sh +0 -5
- package/src/llms/install-templates/hooks/stop.sh +0 -18
- package/src/llms/install-templates/hooks/subagent-start.sh +0 -5
- package/src/llms/install-templates/hooks/user-prompt-submit.sh +0 -5
- package/src/llms/install-templates/settings.json +0 -45
- package/src/llms/skills/imf-web-ui-audit/SKILL.md +0 -119
- package/src/llms/skills/imf-web-ui-conventions/SKILL.md +0 -57
- package/src/llms/skills/imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md +0 -141
- package/src/llms/skills/imf-web-ui-conventions/templates/REPORT.md +0 -45
- package/src/llms/skills/imf-web-ui-conventions/topics/agent-tooling.md +0 -82
- package/src/llms/skills/imf-web-ui-conventions/topics/assets.md +0 -27
- package/src/llms/skills/imf-web-ui-conventions/topics/authentication.md +0 -65
- package/src/llms/skills/imf-web-ui-conventions/topics/class-names.md +0 -50
- package/src/llms/skills/imf-web-ui-conventions/topics/components.md +0 -101
- package/src/llms/skills/imf-web-ui-conventions/topics/data.md +0 -221
- package/src/llms/skills/imf-web-ui-conventions/topics/docs-structure.md +0 -40
- package/src/llms/skills/imf-web-ui-conventions/topics/git.md +0 -34
- package/src/llms/skills/imf-web-ui-conventions/topics/library-boundary.md +0 -35
- package/src/llms/skills/imf-web-ui-conventions/topics/library-setup.md +0 -26
- package/src/llms/skills/imf-web-ui-conventions/topics/npm-project.md +0 -53
- package/src/llms/skills/imf-web-ui-conventions/topics/project-structure.md +0 -44
- package/src/llms/skills/imf-web-ui-conventions/topics/react.md +0 -109
- package/src/llms/skills/imf-web-ui-conventions/topics/styling.md +0 -88
- package/src/llms/skills/imf-web-ui-conventions/topics/testing.md +0 -25
- package/src/llms/skills/imf-web-ui-conventions/topics/tokens.md +0 -7
- package/src/llms/skills/imf-web-ui-conventions/topics/tooling.md +0 -116
- package/src/llms/skills/imf-web-ui-conventions/topics/typescript.md +0 -73
- package/src/llms/skills/imf-web-ui-conventions/topics/validation.md +0 -62
- package/src/llms/skills/imf-web-ui-update/SKILL.md +0 -157
- package/src/llms/tokens.gen.json +0 -887
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# AGENTS.md
|
|
2
|
-
|
|
3
|
-
<Keep this file lean — target ~50 lines. Decision test for every line: would the agent make a costly mistake without it? If
|
|
4
|
-
it would just need to read a file first, cut it. Dev commands, path aliases, and tool config are discoverable from the files
|
|
5
|
-
themselves.>
|
|
6
|
-
|
|
7
|
-
<One paragraph: what the app is and the stack in one line.>
|
|
8
|
-
|
|
9
|
-
Scripts, deps, and setup: [`README.md`](./README.md) and [`package.json`](./package.json) are the source of truth. Check the
|
|
10
|
-
`package.json` scripts before running or suggesting a command — don't infer one exists by pattern-matching a sibling.
|
|
11
|
-
|
|
12
|
-
## Read before you write
|
|
13
|
-
|
|
14
|
-
<One bullet per doc in docs/, each with when to read it, e.g.:>
|
|
15
|
-
|
|
16
|
-
- [`docs/<topic>.md`](./docs/<topic>.md) — <what it covers>. Read before <the change it governs>.
|
|
17
|
-
|
|
18
|
-
[`docs/index.md`](./docs/index.md) registers all of them.
|
|
19
|
-
|
|
20
|
-
## Working here
|
|
21
|
-
|
|
22
|
-
<The fenced block below is the only part of this file `npx web-ui-install` touches: its content comes from this template and
|
|
23
|
-
is refreshed on every skills install. Everything else in the file is scaffolded once by the setup skill and then owned by the
|
|
24
|
-
repo.>
|
|
25
|
-
|
|
26
|
-
<!-- imf-web-ui:begin — managed by `npx web-ui-install`; edits inside the fence are overwritten -->
|
|
27
|
-
|
|
28
|
-
`.agents/skills/imf-web-ui-*` is vendored from `@imfusion/web-ui` and resynced with `npx web-ui-install`. Don't edit it and
|
|
29
|
-
don't put repo conventions there. Load the matching `imf-web-ui-*` skill before writing code, styles, data fetching, or docs;
|
|
30
|
-
repo docs hold only what is unique to this repo.
|
|
31
|
-
|
|
32
|
-
<!-- imf-web-ui:end -->
|
|
33
|
-
|
|
34
|
-
<Repo-specific agent guidance: generated files that are committed, tools to verify APIs against, things never to touch.>
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"hooks": {
|
|
3
|
-
"SessionStart": [
|
|
4
|
-
{
|
|
5
|
-
"hooks": [
|
|
6
|
-
{
|
|
7
|
-
"type": "command",
|
|
8
|
-
"command": "\"$(git rev-parse --show-toplevel)/.agents/hooks/imf-web-ui/session-start.sh\""
|
|
9
|
-
}
|
|
10
|
-
]
|
|
11
|
-
}
|
|
12
|
-
],
|
|
13
|
-
"Stop": [
|
|
14
|
-
{
|
|
15
|
-
"hooks": [
|
|
16
|
-
{
|
|
17
|
-
"type": "command",
|
|
18
|
-
"command": "\"$(git rev-parse --show-toplevel)/.agents/hooks/imf-web-ui/stop.sh\""
|
|
19
|
-
}
|
|
20
|
-
]
|
|
21
|
-
}
|
|
22
|
-
],
|
|
23
|
-
"SubagentStart": [
|
|
24
|
-
{
|
|
25
|
-
"hooks": [
|
|
26
|
-
{
|
|
27
|
-
"type": "command",
|
|
28
|
-
"command": "\"$(git rev-parse --show-toplevel)/.agents/hooks/imf-web-ui/subagent-start.sh\""
|
|
29
|
-
}
|
|
30
|
-
]
|
|
31
|
-
}
|
|
32
|
-
],
|
|
33
|
-
"UserPromptSubmit": [
|
|
34
|
-
{
|
|
35
|
-
"hooks": [
|
|
36
|
-
{
|
|
37
|
-
"type": "command",
|
|
38
|
-
"command": "\"$(git rev-parse --show-toplevel)/.agents/hooks/imf-web-ui/user-prompt-submit.sh\""
|
|
39
|
-
}
|
|
40
|
-
]
|
|
41
|
-
}
|
|
42
|
-
]
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env sh
|
|
2
|
-
# Advisory baseline-staleness check, meant to be called from the repo's pre-commit hook.
|
|
3
|
-
# Compares the installed imf-web-ui skill markers against the installed package version
|
|
4
|
-
# and warns on drift. Always exits 0 — staleness never blocks a commit.
|
|
5
|
-
PKG=node_modules/@imfusion/web-ui/package.json
|
|
6
|
-
[ -f "$PKG" ] || exit 0
|
|
7
|
-
CURRENT=$(node -p "require('./$PKG').version" 2>/dev/null) || exit 0
|
|
8
|
-
|
|
9
|
-
for marker in .agents/skills/imf-web-ui-*/.imf-web-ui-skill-version.json; do
|
|
10
|
-
[ -f "$marker" ] || continue
|
|
11
|
-
INSTALLED=$(node -p "require('./$marker').version" 2>/dev/null) || continue
|
|
12
|
-
if [ "$INSTALLED" != "$CURRENT" ]; then
|
|
13
|
-
echo "imf-web-ui skills are stale ($INSTALLED installed, package is $CURRENT) — run: npx web-ui-install"
|
|
14
|
-
break
|
|
15
|
-
fi
|
|
16
|
-
done
|
|
17
|
-
exit 0
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env sh
|
|
2
|
-
# SessionStart: inject the web-ui router pointer once per session. Fixed string — the
|
|
3
|
-
# hook-injection eval asserts on it verbatim.
|
|
4
|
-
echo "This project depends on @imfusion/web-ui. Start at the imf-web-ui skill: it decides whether guidance is needed and routes to the right companion. Repo docs carry only what is unique to this repo."
|
|
5
|
-
exit 0
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env sh
|
|
2
|
-
# Stop: the turn-end verify gate. When this turn edited source files, block the
|
|
3
|
-
# agent from finishing once, instructing it to run the project's verification.
|
|
4
|
-
# Both hosts send stop_hook_active=true when the turn continues because of a
|
|
5
|
-
# prior block, so the gate can never loop. Fails open everywhere else: no git,
|
|
6
|
-
# a clean tree, or no edit evidence in the transcript all pass silently.
|
|
7
|
-
PAYLOAD=$(cat)
|
|
8
|
-
printf '%s' "$PAYLOAD" | grep -q '"stop_hook_active"[[:space:]]*:[[:space:]]*true' && exit 0
|
|
9
|
-
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || exit 0
|
|
10
|
-
[ -n "$(git status --porcelain -- '*.ts' '*.tsx' '*.js' '*.jsx' '*.css' 2>/dev/null)" ] || exit 0
|
|
11
|
-
# Gate only turns that actually edited files — a tree left dirty by an earlier
|
|
12
|
-
# session must not block a question-answering turn. Edit evidence: Write/Edit
|
|
13
|
-
# tool calls (Claude transcript) or apply_patch calls (Codex rollout).
|
|
14
|
-
TRANSCRIPT=$(printf '%s' "$PAYLOAD" | sed -n 's/.*"transcript_path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -n 1)
|
|
15
|
-
[ -f "$TRANSCRIPT" ] || exit 0
|
|
16
|
-
grep -q '"name":"Write"\|"name":"Edit"\|"name":"MultiEdit"\|"name":"NotebookEdit"\|apply_patch' "$TRANSCRIPT" || exit 0
|
|
17
|
-
printf '{"decision":"block","reason":"web-ui stop gate: this turn changed source files. Run the project verification (verify:typecheck, verify:lint, and verify:format at minimum), fix what it reports, then finish. If it already ran after the last change, say so and finish."}\n'
|
|
18
|
-
exit 0
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env sh
|
|
2
|
-
# SubagentStart: subagents don't reliably inherit the parent session's SessionStart
|
|
3
|
-
# context, so they get the same router pointer. Text byte-identical to session-start.sh.
|
|
4
|
-
echo "This project depends on @imfusion/web-ui. Start at the imf-web-ui skill: it decides whether guidance is needed and routes to the right companion. Repo docs carry only what is unique to this repo."
|
|
5
|
-
exit 0
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env sh
|
|
2
|
-
# UserPromptSubmit: one-line per-prompt pointer to the companion skills. Fixed string —
|
|
3
|
-
# the hook-injection eval asserts on it verbatim.
|
|
4
|
-
echo "web-ui: check imf-web-ui-components before using a component API, imf-web-ui-conventions before writing code, styles or docs, and imf-web-ui-ux when shaping a screen or flow."
|
|
5
|
-
exit 0
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
|
3
|
-
"hooks": {
|
|
4
|
-
"SessionStart": [
|
|
5
|
-
{
|
|
6
|
-
"hooks": [
|
|
7
|
-
{
|
|
8
|
-
"type": "command",
|
|
9
|
-
"command": "\"$CLAUDE_PROJECT_DIR/.agents/hooks/imf-web-ui/session-start.sh\""
|
|
10
|
-
}
|
|
11
|
-
]
|
|
12
|
-
}
|
|
13
|
-
],
|
|
14
|
-
"Stop": [
|
|
15
|
-
{
|
|
16
|
-
"hooks": [
|
|
17
|
-
{
|
|
18
|
-
"type": "command",
|
|
19
|
-
"command": "\"$CLAUDE_PROJECT_DIR/.agents/hooks/imf-web-ui/stop.sh\""
|
|
20
|
-
}
|
|
21
|
-
]
|
|
22
|
-
}
|
|
23
|
-
],
|
|
24
|
-
"SubagentStart": [
|
|
25
|
-
{
|
|
26
|
-
"hooks": [
|
|
27
|
-
{
|
|
28
|
-
"type": "command",
|
|
29
|
-
"command": "\"$CLAUDE_PROJECT_DIR/.agents/hooks/imf-web-ui/subagent-start.sh\""
|
|
30
|
-
}
|
|
31
|
-
]
|
|
32
|
-
}
|
|
33
|
-
],
|
|
34
|
-
"UserPromptSubmit": [
|
|
35
|
-
{
|
|
36
|
-
"hooks": [
|
|
37
|
-
{
|
|
38
|
-
"type": "command",
|
|
39
|
-
"command": "\"$CLAUDE_PROJECT_DIR/.agents/hooks/imf-web-ui/user-prompt-submit.sh\""
|
|
40
|
-
}
|
|
41
|
-
]
|
|
42
|
-
}
|
|
43
|
-
]
|
|
44
|
-
}
|
|
45
|
-
}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: imf-web-ui-audit
|
|
3
|
-
description:
|
|
4
|
-
"Read-only health check for an ImFusion frontend against the conventions baseline. Audit the full project or any topic,
|
|
5
|
-
including library-setup, tooling, git, npm-project, authentication, project-structure, docs-structure, data, testing,
|
|
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, then turns them into an actionable
|
|
8
|
-
plan."
|
|
9
|
-
argument-hint: "[full|<topic>]"
|
|
10
|
-
allowed-tools: Read Glob Grep
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
# imf-web-ui-audit
|
|
14
|
-
|
|
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.
|
|
20
|
-
|
|
21
|
-
## Workflow
|
|
22
|
-
|
|
23
|
-
1. Resolve the argument. Bare means `full`; a topic selects one row below. If no topic matches, list every available topic
|
|
24
|
-
instead of guessing or widening the scope.
|
|
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.
|
|
56
|
-
|
|
57
|
-
## Checklist
|
|
58
|
-
|
|
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
|
|
62
|
-
checklist itself is not edited during an audit.
|
|
63
|
-
|
|
64
|
-
## Safety
|
|
65
|
-
|
|
66
|
-
Use only static inspection: Read, Glob, Grep, and equivalent non-executing search tools. Do not use a shell or invoke Node,
|
|
67
|
-
npm, npx, package scripts, hooks, config imports, linters, tests, builds, Git commands, or project binaries. Read config as
|
|
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.
|
|
71
|
-
|
|
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.
|
|
77
|
-
|
|
78
|
-
## Topics
|
|
79
|
-
|
|
80
|
-
| Topic | Assess |
|
|
81
|
-
| ------------------- | ------------------------------------------------------------------------------ |
|
|
82
|
-
| `library-setup` | styles import, `WebUIProvider`, and library package wiring |
|
|
83
|
-
| `library-boundary` | imports, wrappers, type derivation, and peer boundaries |
|
|
84
|
-
| `react` | component roles, state ownership, and effects discipline |
|
|
85
|
-
| `components` | component folders, anatomy, and colocation |
|
|
86
|
-
| `typescript` | functional style, types, and naming |
|
|
87
|
-
| `styling` | CSS Modules, tokens, and prohibited styling systems |
|
|
88
|
-
| `tokens` | names, authored default values, and families from the shipped token index |
|
|
89
|
-
| `class-names` | CVA variants, `cx`, and incoming `className` handling |
|
|
90
|
-
| `validation` | runtime schemas, boundary parsing, and derived types |
|
|
91
|
-
| `data` | transport, schemas, query/mutation options, keys, and invalidation |
|
|
92
|
-
| `authentication` | current-user query, public/app guards, login, and logout |
|
|
93
|
-
| `project-structure` | source tree, route groups, optional app shell, naming, and imports |
|
|
94
|
-
| `testing` | test boundaries and verification coverage |
|
|
95
|
-
| `npm-project` | package metadata, scripts, pins, npm, and Node configuration |
|
|
96
|
-
| `tooling` | dependency selection, devtools, Prettier, ESLint, TypeScript, and verification |
|
|
97
|
-
| `git` | tracked hooks, verification scopes, and staleness wiring |
|
|
98
|
-
| `assets` | image formats and static asset handling |
|
|
99
|
-
| `docs-structure` | README, AGENTS, docs index, and content boundaries |
|
|
100
|
-
| `agent-tooling` | installed skills, AGENTS fence, lifecycle hooks, registrations, staleness |
|
|
101
|
-
|
|
102
|
-
Report everything within the selected topic: defects and working deviations alike, with no severity-based filtering.
|
|
103
|
-
|
|
104
|
-
## Agent-tooling assessment reference
|
|
105
|
-
|
|
106
|
-
The baseline is the conventions [agent-tooling topic](../imf-web-ui-conventions/topics/agent-tooling.md): the complete bundle
|
|
107
|
-
with matching version markers, the AGENTS fence, and the lifecycle hooks installed and registered for both hosts
|
|
108
|
-
(`.claude/settings.json` and `.codex/hooks.json`) or consciously adapted. Hooks or registrations beyond the shipped set — the
|
|
109
|
-
three injection hooks, the stop gate, plus `baseline-staleness.sh` — are drift, and the tracked pre-commit path calls
|
|
110
|
-
`baseline-staleness.sh`. Read files and settings as text—do not run installers, hooks, or local config queries during
|
|
111
|
-
assessment.
|
|
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
|
-
|
|
118
|
-
Use the shared report template as the report contract. It defines the headings, ordering, empty-section marker, evidence
|
|
119
|
-
format, and reviewer-note preservation rules; do not duplicate that contract here.
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: imf-web-ui-conventions
|
|
3
|
-
description:
|
|
4
|
-
"The ImFusion frontend conventions baseline — in-house conventions, valid in every ImFusion frontend and usable by anyone
|
|
5
|
-
who likes them. A router over topic references: library setup, library boundary, React, components, TypeScript, styling,
|
|
6
|
-
tokens, validation, data layer, authentication, project structure, testing, tooling, npm project, git, agent tooling,
|
|
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."
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# imf-web-ui-conventions
|
|
13
|
-
|
|
14
|
-
The ImFusion frontend baseline. In-house conventions, not industry claims — they encode how ImFusion frontends are built, and
|
|
15
|
-
anyone else is welcome to them.
|
|
16
|
-
|
|
17
|
-
**The project wins.** These defaults fill vacuums: if the host project already has a convention — a styling system, a state
|
|
18
|
-
library, a folder shape — that stands. They are not a license to refactor a consumer codebase toward this document.
|
|
19
|
-
|
|
20
|
-
When a project has an established convention, it wins. The audit skill records a working difference as a deviation; the setup
|
|
21
|
-
skill proposes only the changes the project asks it to make.
|
|
22
|
-
|
|
23
|
-
## The topics
|
|
24
|
-
|
|
25
|
-
Each topic lives in one reference. Read the one whose moment you're in; starting a new feature usually wants several.
|
|
26
|
-
|
|
27
|
-
| Reference | Covers | Read when |
|
|
28
|
-
| --------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------- |
|
|
29
|
-
| [library-setup.md](topics/library-setup.md) | styles import, `WebUIProvider`, and broken library wiring | installing or repairing library wiring |
|
|
30
|
-
| [library-boundary.md](topics/library-boundary.md) | staying behind `@imfusion/web-ui`, wrappers, type derivation, peers | touching anything that renders library components |
|
|
31
|
-
| [authentication.md](topics/authentication.md) | current-user source, public/app guards, login and logout | setting up or reviewing route protection |
|
|
32
|
-
| [react.md](topics/react.md) | component roles, state kinds and owners, effects discipline | writing new screens, components, or wrappers |
|
|
33
|
-
| [components.md](topics/components.md) | component anatomy on disk: grouping, folders, colocation | adding a component file |
|
|
34
|
-
| [typescript.md](topics/typescript.md) | functional style, types, naming | writing any code |
|
|
35
|
-
| [styling.md](topics/styling.md) | native CSS Modules, tokens, the override contract | writing CSS or styling beyond the defaults |
|
|
36
|
-
| [tokens.md](topics/tokens.md) | shipped CSS-variable names grouped by family | choosing a design token |
|
|
37
|
-
| [class-names.md](topics/class-names.md) | CVA variants, `cx`, merging the incoming `className` | writing a component with variants or a `className` prop |
|
|
38
|
-
| [validation.md](topics/validation.md) | runtime schemas, boundary parsing, schema-derived types | accepting data the frontend does not own |
|
|
39
|
-
| [data.md](topics/data.md) | `api/`+`http/` shape, query/mutation patterns and invalidation | adding an API topic, a fetch, or a mutation |
|
|
40
|
-
| [project-structure.md](topics/project-structure.md) | the `src/` tree, route groups, file naming, imports | adding files rather than editing existing ones |
|
|
41
|
-
| [testing.md](topics/testing.md) | what's worth testing and what isn't | writing or reviewing tests |
|
|
42
|
-
| [tooling.md](topics/tooling.md) | the topic→tool map, tool configuration, and verification | choosing a dependency or touching tool config |
|
|
43
|
-
| [npm-project.md](topics/npm-project.md) | `package.json`, the `verify:*` script set, dependency pinning | running or adding a script, adding a dependency |
|
|
44
|
-
| [git.md](topics/git.md) | `git:config`, verify scopes, staleness at commit time | wiring hooks or the commit path |
|
|
45
|
-
| [agent-tooling.md](topics/agent-tooling.md) | vendored skills, lifecycle hooks, registrations, Codex trust | installing or reviewing the shipped agent tooling |
|
|
46
|
-
| [assets.md](topics/assets.md) | image formats, the WebP recipe | adding images or other static assets |
|
|
47
|
-
| [docs-structure.md](topics/docs-structure.md) | what a repo documents, where, how it's written | writing or restructuring repo docs |
|
|
48
|
-
|
|
49
|
-
## Topic format
|
|
50
|
-
|
|
51
|
-
Topics are manifests, not essays: `##` sections group rule bullets, and each section is one auditable unit. A rule is one
|
|
52
|
-
imperative bullet; only a pushback-prone rule carries a one-line why. Snippets illustrate rules, prose never replaces them.
|
|
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.
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
# Convention audit checklist
|
|
2
|
-
|
|
3
|
-
One block per topic, one box per topic section. Check a box only after checking that section's rules against the repo. A full
|
|
4
|
-
audit checks every box; a scoped audit names its topics first and checks only their blocks. Blocks mirror each topic's `##`
|
|
5
|
-
sections one to one — change a topic's sections and this file follows in the same commit.
|
|
6
|
-
|
|
7
|
-
## Library setup — `library-setup`
|
|
8
|
-
|
|
9
|
-
- [ ] Entry-point wiring
|
|
10
|
-
- [ ] Symptoms of broken setup
|
|
11
|
-
|
|
12
|
-
## Library boundary — `library-boundary`
|
|
13
|
-
|
|
14
|
-
- [ ] Stay behind the library
|
|
15
|
-
- [ ] Wrap primitives when the app has a reason to
|
|
16
|
-
- [ ] Derive types, don't import them
|
|
17
|
-
- [ ] Integrations own their peers
|
|
18
|
-
- [ ] Styling crosses the boundary through seams
|
|
19
|
-
|
|
20
|
-
## Authentication — `authentication`
|
|
21
|
-
|
|
22
|
-
- [ ] Starter shape
|
|
23
|
-
- [ ] One current-user query
|
|
24
|
-
- [ ] The two route groups
|
|
25
|
-
- [ ] Login and logout
|
|
26
|
-
- [ ] App shell
|
|
27
|
-
|
|
28
|
-
## Project structure — `project-structure`
|
|
29
|
-
|
|
30
|
-
- [ ] Layout
|
|
31
|
-
- [ ] Application boundary
|
|
32
|
-
- [ ] Imports
|
|
33
|
-
|
|
34
|
-
## React — `react`
|
|
35
|
-
|
|
36
|
-
- [ ] Composition: pages (smart containers), partials, dumb components
|
|
37
|
-
- [ ] Compose, don't configure
|
|
38
|
-
- [ ] Put state where its truth lives
|
|
39
|
-
- [ ] Effects: last resort, and named
|
|
40
|
-
- [ ] Reading list
|
|
41
|
-
|
|
42
|
-
## Components — `components`
|
|
43
|
-
|
|
44
|
-
- [ ] As dumb as possible
|
|
45
|
-
- [ ] Grouping
|
|
46
|
-
- [ ] One file or a folder
|
|
47
|
-
- [ ] Colocation
|
|
48
|
-
|
|
49
|
-
## TypeScript & code style — `typescript`
|
|
50
|
-
|
|
51
|
-
- [ ] Types
|
|
52
|
-
- [ ] Immutability & expressions
|
|
53
|
-
- [ ] Naming
|
|
54
|
-
|
|
55
|
-
## Styling — `styling`
|
|
56
|
-
|
|
57
|
-
- [ ] CSS authoring
|
|
58
|
-
- [ ] Build custom UI from tokens
|
|
59
|
-
- [ ] Override through the sanctioned seams
|
|
60
|
-
- [ ] The color system
|
|
61
|
-
- [ ] Responsive styling
|
|
62
|
-
|
|
63
|
-
## Tokens — `tokens`
|
|
64
|
-
|
|
65
|
-
- [ ] Token index
|
|
66
|
-
|
|
67
|
-
## Class names in components — `class-names`
|
|
68
|
-
|
|
69
|
-
- [ ] CVA is the only tool
|
|
70
|
-
- [ ] Merging `className`
|
|
71
|
-
- [ ] Shared CVA modules
|
|
72
|
-
|
|
73
|
-
## Validation — `validation`
|
|
74
|
-
|
|
75
|
-
- [ ] Boundaries
|
|
76
|
-
- [ ] Schema first, type derived
|
|
77
|
-
- [ ] TanStack Router search params
|
|
78
|
-
- [ ] Failure handling
|
|
79
|
-
|
|
80
|
-
## Data — `data`
|
|
81
|
-
|
|
82
|
-
- [ ] The shape
|
|
83
|
-
- [ ] The network boundary validates
|
|
84
|
-
- [ ] Errors are values
|
|
85
|
-
- [ ] Topic registry and key factory
|
|
86
|
-
- [ ] Options factories and naming
|
|
87
|
-
- [ ] Router context access
|
|
88
|
-
- [ ] Automatic invalidation
|
|
89
|
-
- [ ] Testing the data layer
|
|
90
|
-
|
|
91
|
-
## Testing — `testing`
|
|
92
|
-
|
|
93
|
-
- [ ] Naming
|
|
94
|
-
- [ ] What gets a test
|
|
95
|
-
- [ ] Layer-specific recipes
|
|
96
|
-
|
|
97
|
-
## Tooling — `tooling`
|
|
98
|
-
|
|
99
|
-
- [ ] Topic-to-tool map
|
|
100
|
-
- [ ] When a library owns a layer
|
|
101
|
-
- [ ] Devtools
|
|
102
|
-
- [ ] Docs over memory
|
|
103
|
-
- [ ] Prettier
|
|
104
|
-
- [ ] ESLint
|
|
105
|
-
- [ ] tsconfig
|
|
106
|
-
- [ ] Staged files
|
|
107
|
-
- [ ] CSS class names
|
|
108
|
-
|
|
109
|
-
## npm project — `npm-project`
|
|
110
|
-
|
|
111
|
-
- [ ] package.json
|
|
112
|
-
- [ ] Scripts
|
|
113
|
-
- [ ] Dependencies
|
|
114
|
-
|
|
115
|
-
## Git — `git`
|
|
116
|
-
|
|
117
|
-
- [ ] git:config
|
|
118
|
-
- [ ] Verify scopes
|
|
119
|
-
- [ ] Staleness at commit time
|
|
120
|
-
|
|
121
|
-
## Assets — `assets`
|
|
122
|
-
|
|
123
|
-
- [ ] Importing
|
|
124
|
-
- [ ] Photographs — WebP
|
|
125
|
-
- [ ] Other formats
|
|
126
|
-
- [ ] Scope
|
|
127
|
-
|
|
128
|
-
## Documentation structure — `docs-structure`
|
|
129
|
-
|
|
130
|
-
- [ ] The shape
|
|
131
|
-
- [ ] Repo docs hold only what is unique to the repo
|
|
132
|
-
- [ ] How docs are written
|
|
133
|
-
- [ ] Staleness at commit time
|
|
134
|
-
|
|
135
|
-
## Agent tooling — `agent-tooling`
|
|
136
|
-
|
|
137
|
-
- [ ] The skill bundle
|
|
138
|
-
- [ ] The hooks
|
|
139
|
-
- [ ] Codex trust
|
|
140
|
-
- [ ] Dependency-shipped skills
|
|
141
|
-
- [ ] Hook docs
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# Frontend Report
|
|
2
|
-
|
|
3
|
-
Mode: `<setup|audit>` Scope: `<all applicable topics or the resolved topic>`
|
|
4
|
-
|
|
5
|
-
<!--
|
|
6
|
-
This template is the report contract. Keep every H2 below once and in this order.
|
|
7
|
-
Use `None.` for an empty section.
|
|
8
|
-
|
|
9
|
-
Broken, Missing, Deviations, and Unverified entries use:
|
|
10
|
-
- **[high|medium|low] reference-or-agent-tooling — Short title**
|
|
11
|
-
- Evidence: `path:line`
|
|
12
|
-
- Impact: concrete consequence
|
|
13
|
-
- Next action: smallest selectable follow-up
|
|
14
|
-
|
|
15
|
-
Present entries name the topic and evidence path. Deviations are selectable follow-up work, not defects. Optional tools are not
|
|
16
|
-
missing findings.
|
|
17
|
-
-->
|
|
18
|
-
|
|
19
|
-
## Verdict
|
|
20
|
-
|
|
21
|
-
<One short assessment of the current frontend setup.>
|
|
22
|
-
|
|
23
|
-
## Broken
|
|
24
|
-
|
|
25
|
-
None.
|
|
26
|
-
|
|
27
|
-
## Missing
|
|
28
|
-
|
|
29
|
-
None.
|
|
30
|
-
|
|
31
|
-
## Deviations
|
|
32
|
-
|
|
33
|
-
None.
|
|
34
|
-
|
|
35
|
-
## Present
|
|
36
|
-
|
|
37
|
-
None.
|
|
38
|
-
|
|
39
|
-
## Unverified
|
|
40
|
-
|
|
41
|
-
None.
|
|
42
|
-
|
|
43
|
-
## Reviewer notes
|
|
44
|
-
|
|
45
|
-
<!-- Human-owned. Preserve everything under this heading verbatim when refreshing the report. -->
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# Agent tooling
|
|
2
|
-
|
|
3
|
-
How a consumer repo carries the `@imfusion/web-ui` agent tooling; `npx web-ui-install` does the mechanics, this topic carries
|
|
4
|
-
the judgment.
|
|
5
|
-
|
|
6
|
-
## The skill bundle
|
|
7
|
-
|
|
8
|
-
- `npx web-ui-install` installs or refreshes the vendored `imf-web-ui-*` skills, refreshes the
|
|
9
|
-
`<!-- imf-web-ui:begin/end -->` fence in an existing `AGENTS.md`, and removes skills dropped from the bundle.
|
|
10
|
-
- Target: remembered first-run choice — `.claude/skills/`, vendor-neutral `.agents/skills/`, or both (`.agents/` real copy,
|
|
11
|
-
`.claude/` symlink); `--reconfigure` re-opens it, `--target claude|agents` selects non-interactively.
|
|
12
|
-
- Staleness: per-skill `.imf-web-ui-skill-version.json`; a marker older than the installed package means re-run the binary —
|
|
13
|
-
never hand-diff or hand-edit vendored skill contents.
|
|
14
|
-
|
|
15
|
-
## The hooks
|
|
16
|
-
|
|
17
|
-
- `npx web-ui-install --hooks` adds three injection hooks and a turn-end gate.
|
|
18
|
-
- Scripts in `.agents/hooks/imf-web-ui/` are installer-owned: refreshed wholesale each run, retired scripts pruned with their
|
|
19
|
-
registrations.
|
|
20
|
-
- Registrations merge idempotently into `.claude/settings.json` (Claude Code) and `.codex/hooks.json` (Codex), never touching
|
|
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"]
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
- Each injection hook echoes one fixed line and exits 0; the router does the task-sorting a shell script can't — why a hint
|
|
47
|
-
on every prompt isn't noise.
|
|
48
|
-
- `baseline-staleness.sh` ships alongside but is not an agent hook; the repo's pre-commit calls it ([git.md](./git.md),
|
|
49
|
-
staleness at commit time).
|
|
50
|
-
- Never edit an installed script — the next install overwrites it; adapt in the repo's own hooks.
|
|
51
|
-
- Registration entries are yours: the installer matches by script name and keeps edited commands across re-runs. Monorepo:
|
|
52
|
-
the Codex commands anchor at `$(git rev-parse --show-toplevel)` — adjust their paths once after installing when the
|
|
53
|
-
frontend isn't the git toplevel.
|
|
54
|
-
- **Read the registration files before installing**; per event: nothing registered → install as shipped; already covered by
|
|
55
|
-
the repo (its own session reminder, say) → don't stack a second hook — fold the missing line into the repo's script, or
|
|
56
|
-
adapt the shipped one and register that; surface it and let the human pick.
|
|
57
|
-
|
|
58
|
-
## Codex trust
|
|
59
|
-
|
|
60
|
-
- Codex runs a project's hooks only when two trust gates hold: the project itself is trusted, and each hook script has been
|
|
61
|
-
trusted via the `/hooks` review, which keys trust to the script's hash.
|
|
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.
|
|
68
|
-
|
|
69
|
-
## Dependency-shipped skills
|
|
70
|
-
|
|
71
|
-
- npm packages can ship Agent Skills of their own; TanStack does — [tooling.md](./tooling.md) covers TanStack Intent and its
|
|
72
|
-
allowlist.
|
|
73
|
-
|
|
74
|
-
## Hook docs
|
|
75
|
-
|
|
76
|
-
Both hosts move fast; read the current references before adapting or adding a hook — payloads and stdout rules differ per
|
|
77
|
-
host and per event.
|
|
78
|
-
|
|
79
|
-
- [Claude Code: hooks reference](https://code.claude.com/docs/en/hooks) — event list, JSON input and output, exit codes,
|
|
80
|
-
`disableAllHooks`
|
|
81
|
-
- [Codex: hooks](https://learn.chatgpt.com/docs/hooks) — events, the `hooks.json` schema, trust, `/hooks`
|
|
82
|
-
- [Codex: config reference](https://learn.chatgpt.com/docs/config-file/config-reference) — `[features]` and `[hooks.state]`
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# Assets
|
|
2
|
-
|
|
3
|
-
## Importing
|
|
4
|
-
|
|
5
|
-
- Import everything from `src/assets/` so the bundler fingerprints and bundles it. Never reference an image by public-path
|
|
6
|
-
string.
|
|
7
|
-
|
|
8
|
-
## Photographs — WebP
|
|
9
|
-
|
|
10
|
-
```bash
|
|
11
|
-
magick source.png -resize 2000x -quality 80 -define webp:method=6 src/assets/name.webp
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
- Quality 80 — visually lossless on photos, routinely an order of magnitude smaller.
|
|
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.
|
|
18
|
-
|
|
19
|
-
## Other formats
|
|
20
|
-
|
|
21
|
-
- Alpha, or pixels that must stay exact → PNG, optimized with `oxipng` or `pngquant`.
|
|
22
|
-
- Icons, logos, line art → inline SVG component, so it inherits `currentColor` and follows the theme.
|
|
23
|
-
|
|
24
|
-
## Scope
|
|
25
|
-
|
|
26
|
-
- Rules apply to assets as they're added or touched. Existing assets in another format are not findings to sweep — convert
|
|
27
|
-
opportunistically.
|