@imfusion/web-ui 0.5.1-dev.48.g27701f90 → 0.5.1-dev.5.gb4de52d7

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 (69) hide show
  1. package/README.md +55 -156
  2. package/bin/install-skill.js +180 -0
  3. package/dist/index.d.ts +0 -2
  4. package/dist/index.js +4317 -4956
  5. package/dist/integrations/code-highlight/highlighter.d.ts +3 -32
  6. package/dist/integrations/code-highlight.js +48 -188
  7. package/dist/integrations/image-display-options.js +1 -1
  8. package/dist/style.css +1 -1
  9. package/dist/{tabs-CVp_SgBl.js → tabs-DqBFSqq6.js} +1 -1
  10. package/package.json +25 -39
  11. package/src/docgen/doc.gen.json +0 -327
  12. package/src/llms/llms.gen.txt +0 -12
  13. package/src/llms/skills/imf-web-ui/SKILL.md +12 -13
  14. package/src/llms/skills/imf-web-ui-components/SKILL.md +1 -2
  15. package/src/llms/skills/imf-web-ui-frontend-patterns/SKILL.md +93 -0
  16. package/src/llms/skills/imf-web-ui-frontend-patterns/references/code-conventions.md +133 -0
  17. package/src/llms/skills/imf-web-ui-frontend-patterns/references/react-patterns.md +94 -0
  18. package/src/llms/skills/imf-web-ui-imfusion-frontend-setup/SKILL.md +201 -0
  19. package/src/llms/skills/imf-web-ui-setup/SKILL.md +37 -67
  20. package/src/llms/skills/imf-web-ui-ux/SKILL.md +4 -4
  21. package/src/llms/skills/imf-web-ui-ux/references/forms.md +2 -2
  22. package/bin/install.js +0 -428
  23. package/bin/install.test.ts +0 -329
  24. package/dist/build/vite-css-module-names/index.d.ts +0 -20
  25. package/dist/build/vite-css-module-names.js +0 -17
  26. package/dist/components/field/field.d.ts +0 -104
  27. package/dist/components/field/field.meta.d.ts +0 -2
  28. package/dist/components/field/index.d.ts +0 -2
  29. package/dist/components/fieldset/fieldset.d.ts +0 -29
  30. package/dist/components/fieldset/fieldset.meta.d.ts +0 -2
  31. package/dist/components/fieldset/index.d.ts +0 -2
  32. package/dist/integrations/code-highlight/language-patterns.d.ts +0 -7
  33. package/dist/integrations/code-highlight/languages/cmake.d.ts +0 -1
  34. package/dist/integrations/code-highlight/languages/cpp.d.ts +0 -1
  35. package/dist/integrations/code-highlight/languages/python.d.ts +0 -1
  36. package/dist/llms/gen-tokens.d.ts +0 -7
  37. package/src/llms/install-templates/AGENTS.md +0 -34
  38. package/src/llms/install-templates/codex-hooks.json +0 -44
  39. package/src/llms/install-templates/hooks/baseline-staleness.sh +0 -17
  40. package/src/llms/install-templates/hooks/session-start.sh +0 -5
  41. package/src/llms/install-templates/hooks/stop.sh +0 -18
  42. package/src/llms/install-templates/hooks/subagent-start.sh +0 -5
  43. package/src/llms/install-templates/hooks/user-prompt-submit.sh +0 -5
  44. package/src/llms/install-templates/settings.json +0 -45
  45. package/src/llms/skills/imf-web-ui-audit/SKILL.md +0 -119
  46. package/src/llms/skills/imf-web-ui-conventions/SKILL.md +0 -57
  47. package/src/llms/skills/imf-web-ui-conventions/templates/AUDIT_CHECKLIST.md +0 -141
  48. package/src/llms/skills/imf-web-ui-conventions/templates/REPORT.md +0 -45
  49. package/src/llms/skills/imf-web-ui-conventions/topics/agent-tooling.md +0 -82
  50. package/src/llms/skills/imf-web-ui-conventions/topics/assets.md +0 -27
  51. package/src/llms/skills/imf-web-ui-conventions/topics/authentication.md +0 -65
  52. package/src/llms/skills/imf-web-ui-conventions/topics/class-names.md +0 -50
  53. package/src/llms/skills/imf-web-ui-conventions/topics/components.md +0 -101
  54. package/src/llms/skills/imf-web-ui-conventions/topics/data.md +0 -221
  55. package/src/llms/skills/imf-web-ui-conventions/topics/docs-structure.md +0 -40
  56. package/src/llms/skills/imf-web-ui-conventions/topics/git.md +0 -34
  57. package/src/llms/skills/imf-web-ui-conventions/topics/library-boundary.md +0 -33
  58. package/src/llms/skills/imf-web-ui-conventions/topics/library-setup.md +0 -26
  59. package/src/llms/skills/imf-web-ui-conventions/topics/npm-project.md +0 -53
  60. package/src/llms/skills/imf-web-ui-conventions/topics/project-structure.md +0 -44
  61. package/src/llms/skills/imf-web-ui-conventions/topics/react.md +0 -109
  62. package/src/llms/skills/imf-web-ui-conventions/topics/styling.md +0 -88
  63. package/src/llms/skills/imf-web-ui-conventions/topics/testing.md +0 -25
  64. package/src/llms/skills/imf-web-ui-conventions/topics/tokens.md +0 -7
  65. package/src/llms/skills/imf-web-ui-conventions/topics/tooling.md +0 -116
  66. package/src/llms/skills/imf-web-ui-conventions/topics/typescript.md +0 -73
  67. package/src/llms/skills/imf-web-ui-conventions/topics/validation.md +0 -62
  68. package/src/llms/skills/imf-web-ui-update/SKILL.md +0 -157
  69. package/src/llms/tokens.gen.json +0 -887
package/README.md CHANGED
@@ -2,11 +2,6 @@
2
2
 
3
3
  `@imfusion/web-ui` — the official shared Web UI library for ImFusion web apps, built on Base UI.
4
4
 
5
- - [Usage](#usage) — install, wire up, and keep the version current
6
- - [Documentation](#documentation) — Storybook and the developer docs
7
- - [Development](#development) — working on the library itself, including the Agent Skills
8
- - [Releasing](#releasing) — how versions are derived and how to cut one
9
-
10
5
  ## Usage
11
6
 
12
7
  The packages are private on npmjs.com.
@@ -38,74 +33,8 @@ import "@imfusion/web-ui/styles.css";
38
33
  import { WebUIProvider } from "@imfusion/web-ui";
39
34
  ```
40
35
 
41
- ### LLM integration
42
-
43
- The `web-ui` package does offer first-class support for LLMs, but it's not wired up by default.
44
-
45
- To install the skills, run this command after the package is installed:
46
-
47
- ```bash
48
- npx web-ui-install
49
- ```
50
-
51
- The binary asks which LLM client you use and installs everything it needs. Run it again after a version bump and it refreshes
52
- the directories it already installed into, without asking again — `--reconfigure` re-opens that choice.
53
-
54
- The optional `--hooks` flag also installs the agent lifecycle hooks and registers them for both hosts, in
55
- `.claude/settings.json` (Claude Code) and `.codex/hooks.json` (Codex). Three hooks inject one fixed line each: `SessionStart`
56
- and `SubagentStart` point the agent at the `imf-web-ui` skills router, and `UserPromptSubmit` names the companion skills to
57
- consult per task. A fourth, the `Stop` gate, blocks a turn that edited source files once, until the agent has addressed the
58
- project's verification. Re-running the installer refreshes the scripts and prunes retired ones along with their
59
- registrations. Without `--hooks`, the skills are still available but no lifecycle hook runs. The full flow is documented in
60
- the shipped [`agent-tooling` topic](./src/llms/skills/imf-web-ui-conventions/topics/agent-tooling.md) of the conventions
61
- skill.
62
-
63
- **Available consumer skills - `/imf-web-ui-*`**
64
-
65
- | Skill | What it does |
66
- | ------------------------- | ------------------------------------------------------------------------------ |
67
- | `/imf-web-ui` | The router: decides whether guidance is needed, then which companion to open. |
68
- | `/imf-web-ui-setup` | Plan and, after approval, bootstrap a consumer project by topic. |
69
- | `/imf-web-ui-components` | Component reference — what exists and how it's meant to be used. |
70
- | `/imf-web-ui-ux` | UX guidance for building interfaces with the library. |
71
- | `/imf-web-ui-conventions` | The frontend conventions baseline, including the sanctioned styling seams. |
72
- | `/imf-web-ui-audit` | Read-only health check for a consumer project, ending in a plan you approve. |
73
- | `/imf-web-ui-update` | Update the library, skills, and optional hooks, then verify before committing. |
74
-
75
- Start at `/imf-web-ui` — it routes to the rest. Storybook's **User Guide → AI Agents** page covers the whole family.
76
-
77
- ### Versions and updates
78
-
79
- Every merge to master publishes a new build under the `dev` dist-tag. Which spec you install decides how you pick those up:
80
-
81
- | Spec in `package.json` | Gets | Update with |
82
- | ---------------------------------- | -------------------------- | ------------------------------ |
83
- | `"@imfusion/web-ui": "^0.5.0"` | matching releases | `npm update @imfusion/web-ui` |
84
- | `"@imfusion/web-ui": "latest"` | the newest release | `npm update @imfusion/web-ui` |
85
- | `"@imfusion/web-ui": "dev"` | the newest build of master | `npm update @imfusion/web-ui` |
86
- | `"@imfusion/web-ui": "file:….tgz"` | a packed tarball, frozen | re-pack and re-install by hand |
87
-
88
- - **Two dist-tags.** `latest` moves when a release is tagged, `dev` on every build of master (and onto the release when one
89
- is cut).
90
- - **A range like `^0.5.0` is the usual choice.** It tracks releases and states which major you expect; bare `latest` follows
91
- releases across majors, breaking changes included.
92
- - **Dist-tag specs stay literal.** npm keeps `dev` or `latest` as-is in `package.json` and re-resolves on every `npm update`.
93
- The concrete version lands in `package-lock.json`, so builds stay reproducible until you update.
94
- - **Track `dev` while building against the library**, to get new components as they land. Use a release spec for anything you
95
- cut a production release from, since `dev` moves whenever someone merges.
96
- - **A `file:` tarball never updates.** npm copies the archive into `node_modules` and re-copies the same one on every
97
- install. Switch to `dev` or a version range to get updates.
98
-
99
- ## Documentation
100
-
101
- **[Storybook](https://storybook.js.org/)** is the documentation platform — the component catalog, every prop, and the setup
102
- guides. It isn't hosted yet, so run it locally:
103
-
104
- ```bash
105
- npm run dev # builds the library, then Storybook + a rebuild watcher
106
- ```
107
-
108
- See the [Developer Docs](./docs/README.md).
36
+ **There is also an AI skill to help you set up the Web UI library in your project:
37
+ [`/imf-web-ui-setup`](./src/llms/skills/imf-web-ui-setup/SKILL.md). **
109
38
 
110
39
  ## Development
111
40
 
@@ -118,92 +47,62 @@ npm run git:config # hooks path + rebase-only pull/merge
118
47
 
119
48
  **Try out **`/web-ui-dev-getting-started`** for an ai assisted start.**
120
49
 
121
- ### LLM integration
122
-
123
- These skills are shipped with a `/web-ui-dev-*` prefix, so to make their names identifiable and not pollute the skill
124
- namespace.
125
-
126
- | Skill | What it does |
127
- | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
128
- | `/web-ui-dev-getting-started` | Interactive intro — gauges your experience, works out your goal, routes you. |
129
- | `/web-ui-dev-start` | Starting ritual for any task: Jira context, `master` vs. a worktree, context summary. |
130
- | `/web-ui-dev-new-component` | Scaffolds an architecture-compliant primitive (adapted or absorbed). |
131
- | `/web-ui-dev-update-component` | Pointers to every file a prop, variant, or sub-component change touches. |
132
- | `/web-ui-dev-design-component` | Brand design pass for a component that works but isn't styled yet. |
133
- | `/web-ui-dev-story` | Author or update a Storybook story. |
134
- | `/web-ui-dev-commit` | Commit workflow: changelog skill, staged docs audit, CI-parity checks, house commit format. |
135
- | `/web-ui-dev-changelog` | Generate and validate the required one-line CHANGELOG.md entry for a web-ui change, including direct commits to master. |
136
- | `/web-ui-dev-audit-docs` | Audit docs against staged or recent changes for staleness, gaps, and drift. |
137
- | `/web-ui-dev-audit-pass-through-defaults` | Check `@default` annotations on pass-through props against Base UI upstream. |
138
- | `/web-ui-dev-teardown-worktree` | Tear down a worktree, wherever it lives — merging its branch first or dropping it. |
139
- | `/web-ui-dev-refresh-design-reference` | Refresh the committed brand snapshots in `design/` from the Figma styleguide. |
140
- | `/web-ui-dev-mcp` | Set up or recover Storybook, DevTools, Atlassian, or Figma MCP access. |
141
-
142
- ## Releasing
143
-
144
- Release-facing changes are recorded as one-line entries in [`CHANGELOG.md`](./CHANGELOG.md) under `## [Unreleased]`. The
145
- commit workflow requires an entry for pull-request commits and direct commits to `master`, with only narrow mechanical
146
- exceptions. Each entry ends with its author as ` — Name <email>`, taken from the committer's git config.
147
-
148
- The published version is derived from git tags, not from `package.json`.
149
-
150
- The `version` field stays at `0.0.0` in the repository and he CI computes the real number with
151
- [`scripts/version.ts`](./scripts/version.ts) and writes it into `package.json` on the build agent just before publishing.
152
-
153
- That working copy is thrown away, so nothing is committed back.
154
-
155
- `scripts/version.ts` reads `git describe` and applies two rules:
156
-
157
- Given the tag `web-ui/v0.5.0`:
158
-
159
- | Where HEAD sits | Published version | dist-tag |
160
- | -------------------------- | ----------------------- | -------- |
161
- | Exactly on `web-ui/v0.5.0` | `0.5.0` | `latest` |
162
- | 5 commits after that tag | `0.5.1-dev.5.gb4de52d7` | `dev` |
163
-
164
- The off-tag string breaks down as:
165
-
166
- ```
167
- 0.5.1-dev.5.gb4de52d7
168
- └─┬─┘ └┬┘ │ └───┬────┘
169
- │ │ │ └── commit hash, abbreviated; the leading g means "git"
170
- │ │ └──────── commits since the tag
171
- │ └─────────── pre-release marker, which is what puts it on the dev tag
172
- └──────────────── the tag's version, patch bumped
173
- ```
174
-
175
- Bumping the patch is what makes a dev build sort above the release it follows and below the next one.
176
-
177
- Every build of `master` publishes a `dev` version automatically. To check what the current checkout would publish:
178
-
179
- ```bash
180
- npx tsx scripts/version.ts # prints, changes nothing
181
- ```
182
-
183
- ### Cutting a release
50
+ ## Documentation
184
51
 
185
- Tag the commit you want to ship and push the tag:
52
+ **[Storybook](https://storybook.js.org/)** is the documentation platform — the component catalog, every prop, and the setup
53
+ guides. It isn't hosted yet, so run it locally:
186
54
 
187
55
  ```bash
188
- git tag -a web-ui/v0.5.1 -m "web-ui 0.5.1"
189
- git push origin web-ui/v0.5.1
56
+ npm run dev # builds the library, then Storybook + a rebuild watcher
190
57
  ```
191
58
 
192
- The tag triggers a build that publishes `0.5.1` as `latest` and repoints the `dev` dist-tag at the same version.
193
-
194
- **The tag must be annotated (`-a`).** `git describe` ignores lightweight tags, so a tag pushed without `-a` is invisible to
195
- the version script — the build reads through it to the previous release tag and publishes another `dev` version instead of
196
- the release.
197
-
198
- The tag name must match `web-ui/vX.Y.Z` exactly. Both the version script's `--match` and the TeamCity branch filter in
199
- [`.teamcity/settings.kts`](./.teamcity/settings.kts) key off that shape; a tag in any other form publishes nothing.
200
-
201
- ### Building locally with a real version
202
-
203
- A local `npm run build` stamps `dist` with `0.0.0`. When you need the true version in a local artifact:
59
+ See the [Developer Docs](./docs/README.md).
204
60
 
205
- ```bash
206
- npx tsx scripts/version.ts --write # writes it into package.json
207
- npm run build
208
- git checkout package.json # discard the write
209
- ```
61
+ ## AI agents
62
+
63
+ Two families of Agent Skills, told apart by their prefix:
64
+
65
+ | Prefix | For | Lives in | How to get it |
66
+ | -------------- | ----------------------------- | -------------------------- | --------------------------- |
67
+ | `imf-web-ui-*` | Apps consuming the library | shipped in the npm package | `npx web-ui-install-skills` |
68
+ | `web-ui-dev-*` | Developing the library itself | `.agents/skills/` | already there after cloning |
69
+
70
+ ### Development skills — `web-ui-dev-*`
71
+
72
+ **`web-ui-dev-*`** never ships; it's the workflow for working on this repo — scaffolding a component, authoring a story,
73
+ committing. Start with `/web-ui-dev-getting-started`, which routes you the same way.
74
+
75
+ | Skill | What it does |
76
+ | ----------------------------------------- | ------------------------------------------------------------------------------------- |
77
+ | `/web-ui-dev-getting-started` | Interactive intro — gauges your experience, works out your goal, routes you. |
78
+ | `/web-ui-dev-start` | Starting ritual for any task: Jira context, `master` vs. a worktree, context summary. |
79
+ | `/web-ui-dev-new-component` | Scaffolds an architecture-compliant primitive (adapted or absorbed). |
80
+ | `/web-ui-dev-update-component` | Pointers to every file a prop, variant, or sub-component change touches. |
81
+ | `/web-ui-dev-design-component` | Brand design pass for a component that works but isn't styled yet. |
82
+ | `/web-ui-dev-story` | Author or update a Storybook story. |
83
+ | `/web-ui-dev-commit` | Commit workflow: staged docs audit, CI-parity checks, house commit format. |
84
+ | `/web-ui-dev-audit-docs` | Audit docs against staged or recent changes for staleness, gaps, and drift. |
85
+ | `/web-ui-dev-audit-pass-through-defaults` | Check `@default` annotations on pass-through props against Base UI upstream. |
86
+ | `/web-ui-dev-manage-worktrees` | Create, close, or discard a worktree in `.workspaces/`. |
87
+ | `/web-ui-dev-refresh-design-reference` | Refresh the committed brand snapshots in `design/` from the Figma styleguide. |
88
+ | `/web-ui-dev-mcp` | Set up or recover Storybook, DevTools, Atlassian, or Figma MCP access. |
89
+
90
+ ### Consumer skills — `imf-web-ui-*`
91
+
92
+ **`imf-web-ui-*`** travels with the package, so an agent in a consumer app gets library guidance without reading this
93
+ library's source. ` imf-web-ui` — the bare name, no suffix — is the router: it costs little to load and decides which
94
+ companion applies, or that none does.
95
+
96
+ The companions cover library wiring (`-setup`), the component reference (`-components`), UX guidance (`-ux`), frontend
97
+ patterns (`-frontend-patterns`), and ImFusion project tooling (`-imfusion-frontend-setup`).
98
+
99
+ | Skill | What it does |
100
+ | ------------------------------------- | ------------------------------------------------------------------------------------ |
101
+ | `/imf-web-ui` | The router: decides whether guidance is needed, then which companion to open. |
102
+ | `/imf-web-ui-setup` | One-time wiring in a consumer project — the styles import and the provider. |
103
+ | `/imf-web-ui-components` | Component reference — what exists and how it's meant to be used. |
104
+ | `/imf-web-ui-ux` | UX guidance for building interfaces with the library. |
105
+ | `/imf-web-ui-frontend-patterns` | Frontend patterns, including the sanctioned styling seams (tokens, data attributes). |
106
+ | `/imf-web-ui-imfusion-frontend-setup` | Set up or audit an ImFusion frontend's tooling against the house baseline. |
107
+
108
+ Keep these tables current when a skill is added, renamed, or removed — `/web-ui-dev-audit-docs` checks them.
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Installs the consumer skill family (../src/llms/skills/imf-web-ui*/)
4
+ // into the consumer project's agent skill directories. Runs in the
5
+ // CONSUMER's environment, so it may only use this package's real runtime
6
+ // dependencies (@clack/prompts). Never wire this into a postinstall hook:
7
+ // ambient script execution on `npm install` is a live supply-chain attack
8
+ // vector — install stays an explicit, user-run command.
9
+ //
10
+ // The skills cross-reference each other, so they install as one bundle.
11
+ // When both targets are selected, .agents/skills/ holds the real copy and
12
+ // .claude/skills/ symlinks it (this repo's own convention) so the two
13
+ // can't drift apart.
14
+
15
+ import {
16
+ cpSync,
17
+ existsSync,
18
+ lstatSync,
19
+ mkdirSync,
20
+ readdirSync,
21
+ readFileSync,
22
+ rmSync,
23
+ symlinkSync,
24
+ writeFileSync
25
+ } from "node:fs";
26
+ import { dirname, relative, resolve } from "node:path";
27
+ import { fileURLToPath } from "node:url";
28
+ import * as p from "@clack/prompts";
29
+
30
+ const SKILL_PREFIX = "imf-web-ui";
31
+ const VERSION_MARKER = ".imf-web-ui-skill-version.json";
32
+
33
+ const here = dirname(fileURLToPath(import.meta.url));
34
+ // Source is relative to THIS SCRIPT's location (inside node_modules), not
35
+ // the consumer's cwd — the script is invoked from the consumer's project
36
+ // root, but the skills it copies ship alongside this file in the package.
37
+ const skillsRoot = resolve(here, "..", "src", "llms", "skills");
38
+ const packageJson = JSON.parse(readFileSync(resolve(here, "..", "package.json"), "utf-8"));
39
+ const currentVersion = packageJson.version;
40
+
41
+ // Destination is relative to the consumer's project root (cwd), since
42
+ // that's where their `.claude/` or `.agents/` directory lives.
43
+ const projectRoot = process.cwd();
44
+
45
+ const TARGETS = {
46
+ claude: { label: "Claude Code", root: resolve(projectRoot, ".claude", "skills") },
47
+ agents: { label: "Vendor-neutral (.agents/)", root: resolve(projectRoot, ".agents", "skills") }
48
+ };
49
+
50
+ function discoverSkills() {
51
+ if (!existsSync(skillsRoot)) return [];
52
+ return readdirSync(skillsRoot, { withFileTypes: true })
53
+ .filter(entry => entry.isDirectory() && entry.name.startsWith(SKILL_PREFIX))
54
+ .map(entry => entry.name)
55
+ .sort();
56
+ }
57
+
58
+ function displayPath(absPath) {
59
+ return `./${relative(projectRoot, absPath)}`;
60
+ }
61
+
62
+ function readInstalledVersion(dir) {
63
+ const markerPath = resolve(dir, VERSION_MARKER);
64
+ if (!existsSync(markerPath)) return null;
65
+ try {
66
+ return JSON.parse(readFileSync(markerPath, "utf-8")).version ?? null;
67
+ } catch {
68
+ return null;
69
+ }
70
+ }
71
+
72
+ function writeRealCopy(sourceDir, destDir) {
73
+ mkdirSync(dirname(destDir), { recursive: true });
74
+ // force: true makes re-running after a version bump overwrite cleanly.
75
+ cpSync(sourceDir, destDir, { recursive: true, force: true });
76
+ writeFileSync(resolve(destDir, VERSION_MARKER), JSON.stringify({ version: currentVersion }, null, 2) + "\n");
77
+ }
78
+
79
+ function writeSymlink(linkPath, targetPath) {
80
+ mkdirSync(dirname(linkPath), { recursive: true });
81
+ // lstat (not existsSync, which follows symlinks) catches a broken/stale
82
+ // symlink left over from a prior run, not just a real file or directory.
83
+ if (lstatSync(linkPath, { throwIfNoEntry: false })) {
84
+ rmSync(linkPath, { recursive: true, force: true });
85
+ }
86
+ symlinkSync(relative(dirname(linkPath), targetPath), linkPath);
87
+ }
88
+
89
+ // --target claude|agents (repeatable) selects targets without the
90
+ // interactive prompt — for CI and scripted installs.
91
+ function parseTargetFlags(argv) {
92
+ const targets = [];
93
+ for (let i = 0; i < argv.length; i++) {
94
+ if (argv[i] !== "--target") continue;
95
+ const value = argv[i + 1];
96
+ if (!value || !(value in TARGETS)) {
97
+ console.error(`--target expects one of: ${Object.keys(TARGETS).join(", ")}`);
98
+ process.exit(1);
99
+ }
100
+ targets.push(value);
101
+ i++;
102
+ }
103
+ return targets;
104
+ }
105
+
106
+ async function main() {
107
+ const skills = discoverSkills();
108
+ const flagTargets = parseTargetFlags(process.argv.slice(2));
109
+
110
+ p.intro(`@imfusion/web-ui — install the ${SKILL_PREFIX} skills (${skills.length})`);
111
+
112
+ if (skills.length === 0) {
113
+ p.log.error(`No skills found at ${skillsRoot}. Reinstall @imfusion/web-ui and try again.`);
114
+ p.outro("Nothing installed.");
115
+ process.exitCode = 1;
116
+ return;
117
+ }
118
+
119
+ const existingVersions = Object.values(TARGETS)
120
+ .flatMap(({ root }) => skills.map(name => readInstalledVersion(resolve(root, name))))
121
+ .filter(Boolean);
122
+ if (existingVersions.length > 0 && existingVersions.every(v => v === currentVersion)) {
123
+ p.log.info(`Already up to date (v${currentVersion}). Re-running will overwrite with the same content.`);
124
+ } else if (existingVersions.some(v => v !== currentVersion)) {
125
+ const from = existingVersions.find(v => v !== currentVersion);
126
+ p.log.info(`Updating installed skills from v${from} to v${currentVersion}.`);
127
+ }
128
+
129
+ p.log.message(`Skills in this bundle:\n${skills.map(name => ` - ${name}`).join("\n")}`);
130
+
131
+ let selected;
132
+ if (flagTargets.length > 0) {
133
+ selected = flagTargets;
134
+ p.log.info(`Targets from --target flags: ${selected.join(", ")}`);
135
+ } else {
136
+ selected = await p.multiselect({
137
+ message: "Install into which skill directory (or directories)?",
138
+ options: Object.entries(TARGETS).map(([key, { label, root }]) => ({
139
+ value: key,
140
+ label,
141
+ hint: displayPath(root)
142
+ })),
143
+ required: true
144
+ });
145
+
146
+ if (p.isCancel(selected)) {
147
+ p.cancel("Cancelled — nothing installed.");
148
+ return;
149
+ }
150
+ }
151
+
152
+ const both = selected.includes("claude") && selected.includes("agents");
153
+
154
+ for (const name of skills) {
155
+ const sourceDir = resolve(skillsRoot, name);
156
+ if (both) {
157
+ // .agents/ is the canonical real copy; .claude/ aliases it via symlink.
158
+ const realDir = resolve(TARGETS.agents.root, name);
159
+ writeRealCopy(sourceDir, realDir);
160
+ writeSymlink(resolve(TARGETS.claude.root, name), realDir);
161
+ } else {
162
+ for (const key of selected) {
163
+ writeRealCopy(sourceDir, resolve(TARGETS[key].root, name));
164
+ }
165
+ }
166
+ }
167
+
168
+ if (both) {
169
+ p.log.success(`Vendor-neutral (.agents/) -> ${displayPath(TARGETS.agents.root)}/${SKILL_PREFIX}*`);
170
+ p.log.success(`Claude Code -> ${displayPath(TARGETS.claude.root)}/${SKILL_PREFIX}* (symlinks -> .agents/)`);
171
+ } else {
172
+ for (const key of selected) {
173
+ p.log.success(`${TARGETS[key].label} -> ${displayPath(TARGETS[key].root)}/${SKILL_PREFIX}*`);
174
+ }
175
+ }
176
+
177
+ p.outro(`Done — ${skills.length} skills installed.`);
178
+ }
179
+
180
+ await main();
package/dist/index.d.ts CHANGED
@@ -2,8 +2,6 @@ export { Button, buttonMeta } from './components/button';
2
2
  export { ChipLink, chipLinkMeta } from './components/chip-link';
3
3
  export { CopyButton, copyButtonMeta } from './components/copy-button';
4
4
  export { Checkbox, checkboxMeta } from './components/checkbox';
5
- export { Field, fieldMeta } from './components/field';
6
- export { Fieldset, fieldsetMeta } from './components/fieldset';
7
5
  export { Input, inputMeta } from './components/input';
8
6
  export { Select, selectMeta } from './components/select';
9
7
  export { Slider, sliderMeta } from './components/slider';