@imfusion/web-ui 0.7.2-dev.3.g89ece49a → 0.7.2-dev.5.g78bbaac3
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 -0
- package/dist/web-ui-cli.js +78 -72
- package/package.json +1 -1
- package/src/llms/skills/imf-web-ui-update/SKILL.md +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -11,12 +11,16 @@
|
|
|
11
11
|
|
|
12
12
|
- Components — Nikolaus Brunner <brunner@imfusion.com>
|
|
13
13
|
- `Drawer` draws its open-edge border at `--imf-ui-border-size-1`.
|
|
14
|
+
- Agent skills — Nikolaus Brunner <brunner@imfusion.com>
|
|
15
|
+
- `imf-web-ui-update` measures the delta from a prerelease baseline by diffing the old package's types and styles.
|
|
14
16
|
|
|
15
17
|
### Fixed
|
|
16
18
|
|
|
17
19
|
- Storybook — Nikolaus Brunner <brunner@imfusion.com>
|
|
18
20
|
- Nested sidebar groups and components indent under their parent group.
|
|
19
21
|
- Font choices in the token drawer persist in the URL.
|
|
22
|
+
- Agent skills — Nikolaus Brunner <brunner@imfusion.com>
|
|
23
|
+
- `npx web-ui install skills` formats the skill version markers with the project's Prettier.
|
|
20
24
|
|
|
21
25
|
---
|
|
22
26
|
|
package/dist/web-ui-cli.js
CHANGED
|
@@ -28,7 +28,7 @@ var _ = {
|
|
|
28
28
|
};
|
|
29
29
|
//#endregion
|
|
30
30
|
//#region src/cli/paths.ts
|
|
31
|
-
function
|
|
31
|
+
function v(e) {
|
|
32
32
|
let t = e;
|
|
33
33
|
for (; !n(m(t, "package.json"));) {
|
|
34
34
|
let n = f(t);
|
|
@@ -37,97 +37,112 @@ function re(e) {
|
|
|
37
37
|
}
|
|
38
38
|
return t;
|
|
39
39
|
}
|
|
40
|
-
var
|
|
41
|
-
function
|
|
42
|
-
let t =
|
|
43
|
-
|
|
40
|
+
var y = v(f(ee(import.meta.url))), b = process.cwd();
|
|
41
|
+
function x(e) {
|
|
42
|
+
let t = b;
|
|
43
|
+
for (; t !== f(t) && !n(m(t, "node_modules", ".bin"));) t = f(t);
|
|
44
|
+
let r = m(t, "node_modules", ".bin", "prettier");
|
|
45
|
+
n(r) && g(r, ["--write", ...e], {
|
|
46
|
+
cwd: b,
|
|
47
|
+
stdio: "ignore"
|
|
48
|
+
});
|
|
44
49
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region src/cli/agents-md.ts
|
|
52
|
+
var re = `<!-- ${_.namespace}:begin`, S = `<!-- ${_.namespace}:end -->`, ie = m(y, _.templatesDir, "AGENTS.md"), C = m(b, "AGENTS.md");
|
|
53
|
+
function w(e) {
|
|
54
|
+
let t = e.indexOf(re), n = e.indexOf(S);
|
|
55
|
+
return t === -1 || n === -1 ? null : e.slice(t, n + S.length);
|
|
56
|
+
}
|
|
57
|
+
function ae() {
|
|
58
|
+
if (!n(C)) return "absent";
|
|
59
|
+
let e = w(a(ie, "utf-8"));
|
|
48
60
|
if (!e) return "absent";
|
|
49
|
-
let t = a(
|
|
50
|
-
return i === t ? "unchanged" : (d(
|
|
61
|
+
let t = a(C, "utf-8"), r = w(t), i = r ? t.replace(r, e) : `${t.trimEnd()}\n\n${e}\n`;
|
|
62
|
+
return i === t ? "unchanged" : (d(C, i), r ? "updated" : "added");
|
|
51
63
|
}
|
|
52
64
|
//#endregion
|
|
53
65
|
//#region src/cli/skills.ts
|
|
54
|
-
var
|
|
55
|
-
function
|
|
56
|
-
return e === "all" ?
|
|
66
|
+
var T = Object.keys(_.harnesses).filter((e) => e in _.harnesses), oe = [...T, "all"];
|
|
67
|
+
function E(e) {
|
|
68
|
+
return e === "all" ? T : [e];
|
|
57
69
|
}
|
|
58
|
-
function
|
|
59
|
-
return `./${p(
|
|
70
|
+
function D(e) {
|
|
71
|
+
return `./${p(b, e)}`;
|
|
60
72
|
}
|
|
61
|
-
var
|
|
62
|
-
if (typeof
|
|
63
|
-
var
|
|
64
|
-
function
|
|
65
|
-
return e ===
|
|
73
|
+
var O = _.namespace, k = _.versionMarker, A = m(y, _.skillsSource), j = m(b, _.skillsDir), M = m(b, _.linkDir), N = class extends Error {}, P = JSON.parse(a(m(y, "package.json"), "utf-8"));
|
|
74
|
+
if (typeof P != "object" || !P || !("version" in P) || typeof P.version != "string") throw Error(`${m(y, "package.json")} has no string "version" field`);
|
|
75
|
+
var F = P.version;
|
|
76
|
+
function I(e) {
|
|
77
|
+
return e === O || e.startsWith(`${O}-`);
|
|
66
78
|
}
|
|
67
|
-
function
|
|
68
|
-
return n(
|
|
79
|
+
function L() {
|
|
80
|
+
return n(A) ? o(A, { withFileTypes: !0 }).filter((e) => e.isDirectory() && I(e.name)).map((e) => e.name).sort() : [];
|
|
69
81
|
}
|
|
70
|
-
function
|
|
71
|
-
let t = m(
|
|
82
|
+
function se(e) {
|
|
83
|
+
let t = m(j, e, k);
|
|
72
84
|
if (!n(t)) return null;
|
|
73
85
|
try {
|
|
74
86
|
let e = JSON.parse(a(t, "utf-8"));
|
|
75
87
|
if (typeof e != "object" || !e) return null;
|
|
76
88
|
let n = "harnesses" in e && Array.isArray(e.harnesses) ? e.harnesses : null;
|
|
77
|
-
return n ?
|
|
89
|
+
return n ? T.filter((e) => n.includes(e)) : null;
|
|
78
90
|
} catch {
|
|
79
91
|
return null;
|
|
80
92
|
}
|
|
81
93
|
}
|
|
82
|
-
function
|
|
94
|
+
function R(e) {
|
|
83
95
|
for (let t of e) {
|
|
84
|
-
let e =
|
|
96
|
+
let e = se(t);
|
|
85
97
|
if (e && e.length > 0) return e;
|
|
86
98
|
}
|
|
87
99
|
return null;
|
|
88
100
|
}
|
|
89
|
-
function
|
|
90
|
-
if (n(e)) for (let n of o(e).filter(
|
|
101
|
+
function z(e, t, r) {
|
|
102
|
+
if (n(e)) for (let n of o(e).filter(I)) t.has(n) || (l(m(e, n), {
|
|
91
103
|
recursive: !0,
|
|
92
104
|
force: !0
|
|
93
105
|
}), h.log.info(`Removed skill: ${n} (${r})`));
|
|
94
106
|
}
|
|
95
107
|
function ce() {
|
|
96
|
-
return n(
|
|
108
|
+
return n(M) && n(j) && c(M) === c(j);
|
|
97
109
|
}
|
|
98
110
|
function le(e) {
|
|
99
|
-
let t = m(
|
|
111
|
+
let t = m(M, e), n = p(M, m(j, e)), a = r(t, { throwIfNoEntry: !1 });
|
|
100
112
|
a?.isSymbolicLink() && s(t) === n || (a && l(t, {
|
|
101
113
|
recursive: !0,
|
|
102
114
|
force: !0
|
|
103
|
-
}), i(
|
|
115
|
+
}), i(M, { recursive: !0 }), u(n, t));
|
|
104
116
|
}
|
|
105
|
-
function
|
|
117
|
+
function ue(e, n) {
|
|
106
118
|
try {
|
|
107
|
-
i(
|
|
108
|
-
|
|
109
|
-
|
|
119
|
+
i(j, { recursive: !0 });
|
|
120
|
+
let r = [];
|
|
121
|
+
for (let i of e) {
|
|
122
|
+
let e = m(j, i);
|
|
110
123
|
l(e, {
|
|
111
124
|
recursive: !0,
|
|
112
125
|
force: !0
|
|
113
|
-
}), t(m(
|
|
114
|
-
|
|
126
|
+
}), t(m(A, i), e, { recursive: !0 });
|
|
127
|
+
let a = m(e, k);
|
|
128
|
+
d(a, JSON.stringify({
|
|
129
|
+
version: F,
|
|
115
130
|
harnesses: n
|
|
116
|
-
}, null, 2) + "\n");
|
|
131
|
+
}, null, 2) + "\n"), r.push(a);
|
|
117
132
|
}
|
|
118
|
-
if (
|
|
133
|
+
if (x(r), z(j, new Set(e), "no longer in this bundle"), h.log.success(`Skills -> ${D(j)}/${O}*`), ce()) return;
|
|
119
134
|
if (n.includes("claude")) {
|
|
120
135
|
for (let t of e) le(t);
|
|
121
|
-
|
|
122
|
-
} else
|
|
136
|
+
z(M, new Set(e), "no longer in this bundle"), h.log.success(`Claude Code -> ${D(M)}/${O}* (symlinks -> ${D(j)})`);
|
|
137
|
+
} else z(M, /* @__PURE__ */ new Set(), "claude not selected");
|
|
123
138
|
} catch (e) {
|
|
124
|
-
throw e instanceof Error ? new
|
|
139
|
+
throw e instanceof Error ? new N(e.message) : e;
|
|
125
140
|
}
|
|
126
141
|
}
|
|
127
142
|
//#endregion
|
|
128
143
|
//#region src/cli/hooks.ts
|
|
129
|
-
var B = m(
|
|
130
|
-
function
|
|
144
|
+
var B = m(y, _.templatesDir), V = m(B, "hooks"), H = m(b, _.hooksDir), U = class extends Error {};
|
|
145
|
+
function de(e, t) {
|
|
131
146
|
if (typeof e != "object" || !e || Array.isArray(e)) throw new U(`${t} is not a JSON object.`);
|
|
132
147
|
let n = { ...e };
|
|
133
148
|
if ("hooks" in n) {
|
|
@@ -143,16 +158,7 @@ function W(e) {
|
|
|
143
158
|
} catch {
|
|
144
159
|
throw new U(`${e} is not valid JSON.`);
|
|
145
160
|
}
|
|
146
|
-
return
|
|
147
|
-
}
|
|
148
|
-
function de(e) {
|
|
149
|
-
let t = y;
|
|
150
|
-
for (; t !== f(t) && !n(m(t, "node_modules", ".bin"));) t = f(t);
|
|
151
|
-
let r = m(t, "node_modules", ".bin", "prettier");
|
|
152
|
-
n(r) && g(r, ["--write", e], {
|
|
153
|
-
cwd: y,
|
|
154
|
-
stdio: "ignore"
|
|
155
|
-
});
|
|
161
|
+
return de(t, e);
|
|
156
162
|
}
|
|
157
163
|
function fe() {
|
|
158
164
|
let n = o(V).filter((e) => e.endsWith(".sh"));
|
|
@@ -224,41 +230,41 @@ function pe(e, t, n) {
|
|
|
224
230
|
}
|
|
225
231
|
function me(e) {
|
|
226
232
|
let t = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map();
|
|
227
|
-
for (let i of
|
|
228
|
-
let a = m(
|
|
233
|
+
for (let i of T) {
|
|
234
|
+
let a = m(b, _.harnesses[i].hookSettings);
|
|
229
235
|
if (n(a) && t.set(i, W(a)), e.includes(i)) {
|
|
230
236
|
let e = m(B, _.harnesses[i].hookTemplate);
|
|
231
237
|
r.set(i, W(e).hooks ?? {});
|
|
232
238
|
}
|
|
233
239
|
}
|
|
234
240
|
let { installed: a, removed: o } = fe();
|
|
235
|
-
h.log.success(`Agent hooks -> ${
|
|
236
|
-
for (let n of
|
|
241
|
+
h.log.success(`Agent hooks -> ${D(H)} (${String(a.length)} scripts)`), o.length > 0 && h.log.info(`Removed stale hook script(s): ${o.join(", ")} (no longer shipped)`);
|
|
242
|
+
for (let n of T) {
|
|
237
243
|
let o = e.includes(n);
|
|
238
244
|
if (!o && !t.has(n)) continue;
|
|
239
|
-
let s = m(
|
|
245
|
+
let s = m(b, _.harnesses[n].hookSettings), c = r.get(n) ?? {}, l = t.get(n) ?? {}, u = pe(l, c, o ? a : []);
|
|
240
246
|
if (u.added === 0 && u.removed === 0) {
|
|
241
|
-
o && h.log.info(`Hook registrations already present in ${
|
|
247
|
+
o && h.log.info(`Hook registrations already present in ${D(s)}`);
|
|
242
248
|
continue;
|
|
243
249
|
}
|
|
244
|
-
i(f(s), { recursive: !0 }), d(s, JSON.stringify(l, null, 2) + "\n"),
|
|
250
|
+
i(f(s), { recursive: !0 }), d(s, JSON.stringify(l, null, 2) + "\n"), x([s]);
|
|
245
251
|
let p = [u.added > 0 && `registered ${String(u.added)}`, u.removed > 0 && `removed ${String(u.removed)} stale`].filter(Boolean);
|
|
246
|
-
h.log.success(`${p.join(", ")} hook registration(s) in ${
|
|
252
|
+
h.log.success(`${p.join(", ")} hook registration(s) in ${D(s)}`);
|
|
247
253
|
}
|
|
248
254
|
}
|
|
249
255
|
//#endregion
|
|
250
256
|
//#region src/cli/index.ts
|
|
251
257
|
function Z() {
|
|
252
|
-
return new ne("--harness <harness>", "claude, codex, or all").choices(
|
|
258
|
+
return new ne("--harness <harness>", "claude, codex, or all").choices(oe);
|
|
253
259
|
}
|
|
254
260
|
async function he(e, t, n) {
|
|
255
261
|
if (t) return h.log.info(`Harness from --harness flag: ${t.join(", ")}`), t;
|
|
256
|
-
let r =
|
|
262
|
+
let r = R(e);
|
|
257
263
|
if (r && !n) return h.log.info(`Refreshing the existing install: ${r.join(", ")} — pass --reconfigure to choose differently.`), r;
|
|
258
264
|
if (!process.stdin.isTTY) return console.error("Pass --harness=claude|codex|all — no terminal to prompt in."), process.exitCode = 1, null;
|
|
259
265
|
let i = await h.multiselect({
|
|
260
266
|
message: "Install into which harness (or harnesses)?",
|
|
261
|
-
options:
|
|
267
|
+
options: T.map((e) => ({
|
|
262
268
|
value: e,
|
|
263
269
|
label: _.harnesses[e].label
|
|
264
270
|
})),
|
|
@@ -267,7 +273,7 @@ async function he(e, t, n) {
|
|
|
267
273
|
return h.isCancel(i) ? (h.cancel("Cancelled — nothing installed."), null) : i;
|
|
268
274
|
}
|
|
269
275
|
async function ge(e) {
|
|
270
|
-
let t = e.harness ?
|
|
276
|
+
let t = e.harness ? E(e.harness) : null, n = L();
|
|
271
277
|
if (h.intro(`@imfusion/web-ui install skills — ${String(n.length)} skills`), n.length === 0) {
|
|
272
278
|
h.log.error("No skills found. Reinstall @imfusion/web-ui and try again."), h.outro("Nothing installed."), process.exitCode = 1;
|
|
273
279
|
return;
|
|
@@ -276,19 +282,19 @@ async function ge(e) {
|
|
|
276
282
|
if (!r) return;
|
|
277
283
|
h.log.message(`Skills in this bundle:\n${n.map((e) => ` - ${e}`).join("\n")}`);
|
|
278
284
|
try {
|
|
279
|
-
|
|
285
|
+
ue(n, r);
|
|
280
286
|
} catch (e) {
|
|
281
|
-
if (e instanceof
|
|
287
|
+
if (e instanceof N) {
|
|
282
288
|
h.log.error(e.message), h.outro("Install failed."), process.exitCode = 1;
|
|
283
289
|
return;
|
|
284
290
|
}
|
|
285
291
|
throw e;
|
|
286
292
|
}
|
|
287
|
-
let i =
|
|
293
|
+
let i = ae();
|
|
288
294
|
(i === "updated" || i === "added") && h.log.success(`Refreshed the ${_.namespace} block in ./AGENTS.md`), h.outro(`Done — ${String(n.length)} skills installed.`);
|
|
289
295
|
}
|
|
290
296
|
function _e(e) {
|
|
291
|
-
let t = e.harness ?
|
|
297
|
+
let t = e.harness ? E(e.harness) : null, n = R(L());
|
|
292
298
|
if (!t && !n) {
|
|
293
299
|
console.error("No harness recorded. Pass --harness=claude|codex|all."), process.exitCode = 1;
|
|
294
300
|
return;
|
|
@@ -312,7 +318,7 @@ function _e(e) {
|
|
|
312
318
|
h.outro("Done — agent hooks installed.");
|
|
313
319
|
}
|
|
314
320
|
var Q = new te();
|
|
315
|
-
Q.name("web-ui").description("Command-line tools for @imfusion/web-ui").version(
|
|
321
|
+
Q.name("web-ui").description("Command-line tools for @imfusion/web-ui").version(F);
|
|
316
322
|
var $ = Q.command("install").description("Install @imfusion/web-ui agent skills or hooks into a project");
|
|
317
323
|
$.command("skills").description("Install skills for the chosen harness").addOption(Z()).option("--reconfigure", "Re-open the harness selection prompt on an existing install").action(ge), $.command("hooks").description("Install agent lifecycle hooks (requires skills already installed for the harness)").addOption(Z()).action(_e), $.action(() => {
|
|
318
324
|
$.help();
|
package/package.json
CHANGED
|
@@ -99,6 +99,11 @@ section after the pre-update version, up to and including the new one. Each sect
|
|
|
99
99
|
`Breaking` entries are the release's own account of what changed. Then compare the old and new package metadata, current
|
|
100
100
|
generated docs, types, and examples, and run the full verification again.
|
|
101
101
|
|
|
102
|
+
A prerelease baseline (`<version>-dev.*`) already ships part of the next release, so its changelog sections overstate the
|
|
103
|
+
delta. Measure the delta directly: `npm pack @imfusion/web-ui@<pre-update-version>` into a scratch directory, then diff its
|
|
104
|
+
`dist/**/*.d.ts` and `dist/style.css` (one rule per line) against the installed package. A changelog entry with no matching
|
|
105
|
+
diff was already in the baseline; report it as present.
|
|
106
|
+
|
|
102
107
|
This phase reads and reports: every file stays as it is until the person approves the migration. Open the report with the
|
|
103
108
|
releases read, then report separately:
|
|
104
109
|
|