@nimtech/nimpress 2.3.9 → 2.5.0

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 (66) hide show
  1. package/.claude/rules/doc-pages.md +2 -2
  2. package/.claude/rules/docs-authoring.md +40 -4
  3. package/.claude/rules/frontmatter.md +30 -2
  4. package/.claude/rules/page-types.md +52 -0
  5. package/.claude/rules/style.md +4 -0
  6. package/.claude/skills/nimpress/SKILL.md +65 -7
  7. package/dist/cli.es.js +1415 -746
  8. package/dist/katex-BHBbz4bq.js +11283 -0
  9. package/dist/nimpress.es.js +7121 -5674
  10. package/dist/plugin-DOmbMyy0.js +6743 -0
  11. package/dist/plugin.es.js +11 -3
  12. package/dist/src/cli/cache.d.ts +2 -0
  13. package/dist/src/cli/cache.d.ts.map +1 -0
  14. package/dist/src/cli/completion.d.ts +12 -0
  15. package/dist/src/cli/completion.d.ts.map +1 -1
  16. package/dist/src/cli/init.d.ts.map +1 -1
  17. package/dist/src/cli/lint.d.ts.map +1 -1
  18. package/dist/src/cli/mcp.d.ts +2 -0
  19. package/dist/src/cli/mcp.d.ts.map +1 -0
  20. package/dist/src/cli/plugin.d.ts +3 -0
  21. package/dist/src/cli/plugin.d.ts.map +1 -0
  22. package/dist/src/cli/seo.d.ts +25 -0
  23. package/dist/src/cli/seo.d.ts.map +1 -0
  24. package/dist/src/cli/view.d.ts +53 -0
  25. package/dist/src/cli/view.d.ts.map +1 -0
  26. package/dist/src/cli.d.ts.map +1 -1
  27. package/dist/src/config/defaults.d.ts.map +1 -1
  28. package/dist/src/config/load.d.ts +8 -1
  29. package/dist/src/config/load.d.ts.map +1 -1
  30. package/dist/src/config/schema.d.ts +486 -3
  31. package/dist/src/config/schema.d.ts.map +1 -1
  32. package/dist/src/feedback/feedback.d.ts +5 -0
  33. package/dist/src/feedback/feedback.d.ts.map +1 -0
  34. package/dist/src/framework/configStore.d.ts +3 -1
  35. package/dist/src/framework/configStore.d.ts.map +1 -1
  36. package/dist/src/framework/createNimpressApp.d.ts +2 -1
  37. package/dist/src/framework/createNimpressApp.d.ts.map +1 -1
  38. package/dist/src/framework/gated.d.ts.map +1 -1
  39. package/dist/src/framework/hashSpy.d.ts.map +1 -1
  40. package/dist/src/framework/pageMeta.d.ts.map +1 -1
  41. package/dist/src/framework/stores/tabs.d.ts +3 -0
  42. package/dist/src/framework/stores/tabs.d.ts.map +1 -0
  43. package/dist/src/index.d.ts +15 -7
  44. package/dist/src/index.d.ts.map +1 -1
  45. package/dist/src/markdown/GlossaryPage.svelte.d.ts +1 -0
  46. package/dist/src/markdown/Lightbox.svelte.d.ts +1 -0
  47. package/dist/src/markdown/MathBlock.svelte.d.ts +1 -0
  48. package/dist/src/markdown/NotFoundPage.svelte.d.ts +1 -0
  49. package/dist/src/markdown/PricingPage.svelte.d.ts +1 -0
  50. package/dist/src/markdown/SectionPage.svelte.d.ts +1 -0
  51. package/dist/src/markdown/Tabs.svelte.d.ts +1 -0
  52. package/dist/src/markdown/TagsPage.svelte.d.ts +1 -0
  53. package/dist/src/markdown/TeamPage.svelte.d.ts +1 -0
  54. package/dist/src/types.d.ts +149 -7
  55. package/dist/src/types.d.ts.map +1 -1
  56. package/dist/style.css +1 -1
  57. package/package.json +11 -2
  58. package/src/styles/preflight.css +247 -46
  59. package/src/styles/theme.css +7 -6
  60. package/src/styles/tokens.css +25 -0
  61. package/dist/plugin-C3C36uvj.js +0 -3851
  62. /package/dist/src/{markdown/CalloutCheck.svelte.d.ts → layout/Announce.svelte.d.ts} +0 -0
  63. /package/dist/src/{markdown/CalloutInfo.svelte.d.ts → layout/Footer.svelte.d.ts} +0 -0
  64. /package/dist/src/markdown/{CalloutNote.svelte.d.ts → Callout.svelte.d.ts} +0 -0
  65. /package/dist/src/markdown/{CalloutTip.svelte.d.ts → Feedback.svelte.d.ts} +0 -0
  66. /package/dist/src/markdown/{CalloutWarning.svelte.d.ts → FullPage.svelte.d.ts} +0 -0
package/dist/cli.es.js CHANGED
@@ -1,48 +1,51 @@
1
- import { d as z, c as ke, r as Se, s as rt, p as it, a as Ne, b as se, e as at, f as ct, g as $e, h as Pe, i as lt, j as Te, k as ut, l as mt, m as pt, n as Ee, w as ne, o as Ae, q as ft, t as dt, u as ht, v as gt, x as $t } from "./plugin-C3C36uvj.js";
2
- import { join as d, dirname as L, relative as O, sep as q, extname as oe, resolve as F, basename as C } from "node:path";
3
- import { readdirSync as Y, existsSync as b, writeFileSync as A, mkdirSync as Q, rmSync as ae, readFileSync as W, statSync as Me } from "node:fs";
4
- import yt from "gray-matter";
5
- import { readFile as fe, readdir as wt, writeFile as G, mkdir as ye, copyFile as Re } from "node:fs/promises";
6
- import { s as bt, r as ce } from "./typeMembers-CNvE92EX.js";
7
- import { createServer as Ie, build as ze } from "vite";
8
- import { createHash as xt } from "node:crypto";
9
- import { createInterface as vt } from "node:readline/promises";
10
- import { fileURLToPath as kt } from "node:url";
11
- import { homedir as Le } from "node:os";
12
- function T(e, t) {
13
- return e.find((s) => s.startsWith(`--${t}=`))?.slice(t.length + 3);
14
- }
15
- function X(e, t) {
1
+ import { d as z, c as Pe, r as Me, s as Jt, p as Bt, a as et, b as ue, e as Gt, f as Ht, g as De, h as tt, i as Ut, j as st, k as Zt, l as Vt, m as Kt, C as ge, n as Yt, o as nt, q as Ge, w as pe, t as ot, u as Qt, v as Xt, x as qt, y as es, z as ts, A as ss, B as we } from "./plugin-DOmbMyy0.js";
2
+ import { join as d, dirname as _, relative as D, sep as I, extname as me, resolve as j, basename as F } from "node:path";
3
+ import { readdirSync as se, existsSync as $, writeFileSync as W, mkdirSync as H, rmSync as ne, readFileSync as C, statSync as rt, watch as He } from "node:fs";
4
+ import fe from "gray-matter";
5
+ import { readFile as Se, readdir as ns, writeFile as Q, mkdir as Ne, copyFile as it } from "node:fs/promises";
6
+ import { s as os, r as $e } from "./typeMembers-CNvE92EX.js";
7
+ import { createServer as at, build as ct } from "vite";
8
+ import { createHash as lt } from "node:crypto";
9
+ import { createInterface as ut } from "node:readline/promises";
10
+ import { fileURLToPath as pt } from "node:url";
11
+ import { homedir as K, platform as rs } from "node:os";
12
+ import { spawnSync as X, spawn as Ie } from "node:child_process";
13
+ import { createInterface as is } from "node:readline";
14
+ import { parse as as } from "yaml";
15
+ function N(e, t) {
16
+ return e.find((n) => n.startsWith(`--${t}=`))?.slice(t.length + 3);
17
+ }
18
+ function M(e, t) {
16
19
  return e.includes(`--${t}`);
17
20
  }
18
- function ee(e, t) {
19
- return e.filter((s) => !s.startsWith("--"))[t];
21
+ function re(e, t) {
22
+ return e.filter((n) => !n.startsWith("--"))[t];
20
23
  }
21
- function re(e, t = []) {
22
- let n;
24
+ function oe(e, t = []) {
25
+ let s;
23
26
  try {
24
- n = Y(e, { withFileTypes: !0 });
27
+ s = se(e, { withFileTypes: !0 });
25
28
  } catch {
26
29
  return t;
27
30
  }
28
- for (const s of n) {
29
- const o = d(e, s.name);
30
- if (s.isDirectory()) {
31
- if (s.name === "node_modules" || s.name.startsWith(".")) continue;
32
- re(o, t);
33
- } else s.isFile() && t.push(o);
31
+ for (const n of s) {
32
+ const o = d(e, n.name);
33
+ if (n.isDirectory()) {
34
+ if (n.name === "node_modules" || n.name.startsWith(".")) continue;
35
+ oe(o, t);
36
+ } else n.isFile() && t.push(o);
34
37
  }
35
38
  return t;
36
39
  }
37
- function we(e, t, n) {
40
+ function _e(e, t, s) {
38
41
  if (t.length) {
39
42
  console.error(`${e} failed with ${t.length} problems`);
40
- for (const s of t) console.error(` ${s}`);
43
+ for (const n of t) console.error(` ${n}`);
41
44
  process.exit(1);
42
45
  }
43
- console.log(n);
46
+ console.log(s);
44
47
  }
45
- function St() {
48
+ function cs() {
46
49
  return `import { defineConfig } from '@nimtech/nimpress/plugin'
47
50
 
48
51
  /**
@@ -81,8 +84,41 @@ export default defineConfig({
81
84
  /** Brand colors written onto the theme tokens --np-brand and --np-brand-hover. */
82
85
  // brand: { primary: '#CC785C', primaryHover: '#B86A52' },
83
86
 
84
- /** Site wide footer line, overridable per page with the footer frontmatter field. */
85
- // footer: 'Made with nimpress',
87
+ /** Footer: text is the site wide line, overridable per page with the footer frontmatter field, beside a copyright, social links, previous and next links, and the generator notice. */
88
+ // footer: { text: 'Made with nimpress', copyright: '© 2026 Nimling', social: [{ icon: '/assets/github.svg', link: 'https://github.com/nimling', name: 'Nimling on GitHub' }], navigation: true },
89
+
90
+ /** Announcement bar above the header. text is one markdown line, link wraps it, dismiss adds a close button remembered per text. */
91
+ // announce: { text: 'v2.4 is out', link: '/changelog', dismiss: true },
92
+
93
+ /** Repository actions on every doc page. url defaults to github, editUri to edit/main/<contentDir>/, actions lists edit and view. */
94
+ // repo: { actions: ['edit', 'view'] },
95
+
96
+ /** The was this page helpful widget, shown on pages with feedback: true. Each rating carries an icon, a name, the data, and a markdown note shown after the click; endpoint receives every click as a json post. */
97
+ // feedback: { title: 'Was this page helpful?', endpoint: 'https://auth.example.io/api/feedback', ratings: [{ icon: '👍', name: 'This page was helpful', data: '1', note: 'Thanks for your feedback!' }] },
98
+
99
+ /** Page status identifiers mapped to the label the sidebar mark carries. new and deprecated are present without configuration. */
100
+ // status: { beta: 'Beta' },
101
+
102
+ /** Content tab groups. linked selects the same label in every tab group on the site when one is clicked, remembered across pages. */
103
+ // tabs: { linked: true },
104
+
105
+ /** Image behavior in the prose. lightbox opens every image full size on click; without it only images carrying the zoom class open. */
106
+ // images: { lightbox: true },
107
+
108
+ /** Folder of custom svg icons a :name: shortcode resolves in, beside the lucide set. */
109
+ // icons: './assets/icons',
110
+
111
+ /** Math syntax in the prose. false turns off $...$ and $$...$$ for sites that write dollar signs. */
112
+ // math: false,
113
+
114
+ /** Tag icons by identifier, default for every tag without one, and the tag to identifier map so a group shares an icon. */
115
+ // tags: { icons: { default: ':lucide-tag:', api: ':lucide-plug:' }, map: { OpenAPI: 'api' } },
116
+
117
+ /** Custom page types: a type name to a Svelte component file. A new name registers a type, a built in name such as hero replaces its renderer. */
118
+ // pageTypes: { spotlight: './docs/types/Spotlight.svelte' },
119
+
120
+ /** Generated metadata: auto fills keywords and a description on every page without authored ones, ai.index false blocks every known ai crawler. */
121
+ // seo: { auto: true, ai: { index: false } },
86
122
 
87
123
  /** Extra header navigation routes. gate hides an entry from viewers that fail the check. */
88
124
  // navRoutes: [{ text: 'API', link: '/api' }],
@@ -105,7 +141,7 @@ export default defineConfig({
105
141
  // guard: (frontmatter, filePath, relatedFiles) => frontmatter.gate ?? 'default'
106
142
  // },
107
143
 
108
- /** Path to a client module exporting authFunctions and subscribeFunctions. */
144
+ /** Path to a client module exporting authFunctions, subscribeFunctions, and feedbackFunctions. */
109
145
  // client: './docs/client.ts',
110
146
 
111
147
  /** Changelog subscription wiring. */
@@ -145,7 +181,7 @@ export default defineConfig({
145
181
  })
146
182
  `;
147
183
  }
148
- function jt() {
184
+ function ls() {
149
185
  return JSON.stringify(
150
186
  {
151
187
  $schema: "./node_modules/@nimtech/nimpress/config.schema.json",
@@ -159,7 +195,7 @@ function jt() {
159
195
  ) + `
160
196
  `;
161
197
  }
162
- function Ct(e) {
198
+ function us(e) {
163
199
  return `# Nimpress project
164
200
 
165
201
  This site is built with @nimtech/nimpress. Content lives in \`${e}/\` as markdown with typed frontmatter.
@@ -201,11 +237,11 @@ The authoritative AI working rules ship inside the package at \`node_modules/@ni
201
237
  8. \`nimpress guard map\` and \`nimpress guard apply\` wire gated pages, marked with the \`gate:\` frontmatter field, to the auth provider artifacts.
202
238
  `;
203
239
  }
204
- function Ft(e) {
205
- const t = d(e, "nimpress.config.ts"), n = d(e, "nimpress.config.json"), s = X(process.argv.slice(2), "json");
206
- !b(t) && !b(n) && (s ? (A(n, jt()), console.log(`nimpress init: ${n} written, field descriptions come from the referenced config.schema.json`)) : (A(t, St()), console.log(`nimpress init: ${t} written with every field documented, uncomment what you need`)));
240
+ function ps(e) {
241
+ const t = d(e, "nimpress.config.ts"), s = d(e, "nimpress.config.json"), n = M(process.argv.slice(2), "json");
242
+ !$(t) && !$(s) && (n ? (W(s, ls()), console.log(`nimpress init: ${s} written, field descriptions come from the referenced config.schema.json`)) : (W(t, cs()), console.log(`nimpress init: ${t} written with every field documented, uncomment what you need`)));
207
243
  const o = d(e, z.contentDir);
208
- (!b(o) || Y(o).length === 0) && (Q(o, { recursive: !0 }), A(
244
+ (!$(o) || se(o).length === 0) && (H(o, { recursive: !0 }), W(
209
245
  d(o, "index.md"),
210
246
  `---
211
247
  title: Home
@@ -214,332 +250,346 @@ title: Home
214
250
  Welcome to your Nimpress site.
215
251
  `
216
252
  ));
217
- const i = Ct(z.contentDir);
218
- for (const a of ["CLAUDE.md", "AGENTS.md"]) {
219
- const l = d(e, a);
220
- b(l) || (A(l, i), console.log(`nimpress init: ${a} written, pointing at the packaged rules in node_modules/@nimtech/nimpress/.claude/rules/`));
253
+ const i = us(z.contentDir);
254
+ for (const c of ["CLAUDE.md", "AGENTS.md"]) {
255
+ const l = d(e, c);
256
+ $(l) || (W(l, i), console.log(`nimpress init: ${c} written, pointing at the packaged rules in node_modules/@nimtech/nimpress/.claude/rules/`));
221
257
  }
222
258
  }
223
- const Ot = { vue: "vueStory", svelte: "svelteStory" }, Et = { vue: ".svelte", svelte: ".vue" };
224
- function K(e) {
259
+ const ms = { vue: "vueStory", svelte: "svelteStory" }, fs = { vue: ".svelte", svelte: ".vue" };
260
+ function ie(e) {
225
261
  return `run nimpress modules update ${e}`;
226
262
  }
227
- async function Dt(e) {
263
+ async function ds(e) {
228
264
  let t;
229
265
  try {
230
- t = await wt(e, { withFileTypes: !0 });
266
+ t = await ns(e, { withFileTypes: !0 });
231
267
  } catch {
232
268
  return [];
233
269
  }
234
- return t.filter((n) => n.isFile() && /\.story\.tsx?$/.test(n.name)).map((n) => n.name);
235
- }
236
- function _t(e, t) {
237
- const n = t === "integer" ? "number" : t;
238
- return e.every((s) => typeof s === n);
239
- }
240
- function Wt(e, t, n, s, o) {
241
- const r = [], i = s.properties ?? {}, a = o.properties ?? {};
242
- for (const h of Object.keys(a))
243
- h in i || r.push(`${e}: prop ${h} is missing from the schema, ${K(t)}`);
244
- for (const h of Object.keys(i))
245
- h in a || r.push(`${e}: schema prop ${h} has no counterpart in ${n}, remove it or restore the prop`);
246
- for (const [h, p] of Object.entries(i)) {
247
- const f = a[h];
248
- if (f && (p.type && f.type && p.type !== f.type && !p.enum && r.push(
249
- `${e}: prop ${h} schema type ${p.type} conflicts with source type ${f.type}, ${K(t)}`
250
- ), p.enum && f.type && !_t(p.enum, f.type) && r.push(`${e}: prop ${h} enum values mismatch the source type ${f.type}`), p.enum && f.enum)) {
251
- const w = new Set(f.enum.map((k) => JSON.stringify(k))), $ = p.enum.filter((k) => !w.has(JSON.stringify(k)));
252
- $.length && r.push(
253
- `${e}: prop ${h} enum carries ${$.map((k) => JSON.stringify(k)).join(", ")} outside the source union`
270
+ return t.filter((s) => s.isFile() && /\.story\.tsx?$/.test(s.name)).map((s) => s.name);
271
+ }
272
+ function hs(e, t) {
273
+ const s = t === "integer" ? "number" : t;
274
+ return e.every((n) => typeof n === s);
275
+ }
276
+ function gs(e, t, s, n, o) {
277
+ const r = [], i = n.properties ?? {}, c = o.properties ?? {};
278
+ for (const m of Object.keys(c))
279
+ m in i || r.push(`${e}: prop ${m} is missing from the schema, ${ie(t)}`);
280
+ for (const m of Object.keys(i))
281
+ m in c || r.push(`${e}: schema prop ${m} has no counterpart in ${s}, remove it or restore the prop`);
282
+ for (const [m, f] of Object.entries(i)) {
283
+ const h = c[m];
284
+ if (h && (f.type && h.type && f.type !== h.type && !f.enum && r.push(
285
+ `${e}: prop ${m} schema type ${f.type} conflicts with source type ${h.type}, ${ie(t)}`
286
+ ), f.enum && h.type && !hs(f.enum, h.type) && r.push(`${e}: prop ${m} enum values mismatch the source type ${h.type}`), f.enum && h.enum)) {
287
+ const g = new Set(h.enum.map((v) => JSON.stringify(v))), w = f.enum.filter((v) => !g.has(JSON.stringify(v)));
288
+ w.length && r.push(
289
+ `${e}: prop ${m} enum carries ${w.map((v) => JSON.stringify(v)).join(", ")} outside the source union`
254
290
  );
255
291
  }
256
292
  }
257
- const l = s.slots ?? {}, c = o.slots ?? {};
258
- for (const h of Object.keys(c))
259
- h in l || r.push(`${e}: slot ${h} is missing from the schema, ${K(t)}`);
260
- for (const h of Object.keys(l))
261
- h in c || r.push(`${e}: schema slot ${h} has no counterpart in ${n}`);
262
- const m = new Set(s.emits ?? []), u = new Set(o.emits ?? []);
263
- for (const h of u)
264
- m.has(h) || r.push(`${e}: emit ${h} is missing from the schema, ${K(t)}`);
265
- for (const h of m)
266
- u.has(h) || r.push(`${e}: schema emit ${h} has no counterpart in ${n}`);
293
+ const l = n.slots ?? {}, a = o.slots ?? {};
294
+ for (const m of Object.keys(a))
295
+ m in l || r.push(`${e}: slot ${m} is missing from the schema, ${ie(t)}`);
296
+ for (const m of Object.keys(l))
297
+ m in a || r.push(`${e}: schema slot ${m} has no counterpart in ${s}`);
298
+ const p = new Set(n.emits ?? []), u = new Set(o.emits ?? []);
299
+ for (const m of u)
300
+ p.has(m) || r.push(`${e}: emit ${m} is missing from the schema, ${ie(t)}`);
301
+ for (const m of p)
302
+ u.has(m) || r.push(`${e}: schema emit ${m} has no counterpart in ${s}`);
267
303
  return r;
268
304
  }
269
- async function Je(e, t, n) {
270
- const s = n ? [n] : Object.keys(t.modules.systems), o = [], r = await ke(e, t.contentDir);
271
- for (const i of s) {
272
- const a = t.modules.systems[i];
273
- if (!a) {
305
+ async function mt(e, t, s) {
306
+ const n = s ? [s] : Object.keys(t.modules.systems), o = [], r = await Pe(e, t.contentDir);
307
+ for (const i of n) {
308
+ const c = t.modules.systems[i];
309
+ if (!c) {
274
310
  o.push(`${i}: not a configured system`);
275
311
  continue;
276
312
  }
277
- const l = a.framework, c = Ot[l === "vue" ? "svelte" : "vue"], m = Et[l];
313
+ const l = c.framework, a = ms[l === "vue" ? "svelte" : "vue"], p = fs[l];
278
314
  for (const u of r) {
279
315
  if (u.system !== i) continue;
280
- const h = L(u.pageFile), p = O(e, h).split(q).join("/"), f = await Dt(h);
281
- f.length || o.push(`${p}: no story, run nimpress modules story --system=${i} ${u.component}`);
282
- const w = /* @__PURE__ */ new Set();
283
- for (const S of f) {
284
- let D;
316
+ const m = _(u.pageFile), f = D(e, m).split(I).join("/"), h = await ds(m);
317
+ h.length || o.push(`${f}: no story, run nimpress modules story --system=${i} ${u.component}`);
318
+ const g = /* @__PURE__ */ new Set();
319
+ for (const x of h) {
320
+ let R;
285
321
  try {
286
- D = await fe(d(h, S), "utf-8");
322
+ R = await Se(d(m, x), "utf-8");
287
323
  } catch {
288
324
  continue;
289
325
  }
290
- (/\bharness\s*:/.test(D) || /\brender\s*:/.test(D)) && w.add(S), D.includes(c) && o.push(`${p}/${S}: uses ${c} inside the ${l} system ${i}`);
291
- for (const g of D.matchAll(/from\s+['"]([^'"]+)['"]/g))
292
- oe(g[1]) === m && o.push(`${p}/${S}: imports ${g[1]} inside the ${l} system ${i}`);
326
+ (/\bharness\s*:/.test(R) || /\brender\s*:/.test(R)) && g.add(x), R.includes(a) && o.push(`${f}/${x}: uses ${a} inside the ${l} system ${i}`);
327
+ for (const y of R.matchAll(/from\s+['"]([^'"]+)['"]/g))
328
+ me(y[1]) === p && o.push(`${f}/${x}: imports ${y[1]} inside the ${l} system ${i}`);
293
329
  }
294
- const $ = Se(e, t.modules, i, u.component, u.file);
295
- if ($ && oe($.componentFile) === m && o.push(
296
- `${p}: component file ${O(e, $.componentFile)} mismatches the ${l} system ${i}`
297
- ), b(d(h, "schema.json")) && b(d(h, "schema.yml"))) {
298
- o.push(`${p}: both schema.json and schema.yml exist, keep one`);
330
+ const w = Me(e, t.modules, i, u.component, u.file);
331
+ if (w && me(w.componentFile) === p && o.push(
332
+ `${f}: component file ${D(e, w.componentFile)} mismatches the ${l} system ${i}`
333
+ ), $(d(m, "schema.json")) && $(d(m, "schema.yml"))) {
334
+ o.push(`${f}: both schema.json and schema.yml exist, keep one`);
299
335
  continue;
300
336
  }
301
- const k = rt(h);
302
- if (!k) {
303
- o.push(`${p}: schema file missing, ${K(u.component)}`);
337
+ const v = Jt(m);
338
+ if (!v) {
339
+ o.push(`${f}: schema file missing, ${ie(u.component)}`);
304
340
  continue;
305
341
  }
306
- let E;
342
+ let O;
307
343
  try {
308
- E = await fe(k.path, "utf-8");
344
+ O = await Se(v.path, "utf-8");
309
345
  } catch {
310
- o.push(`${p}: ${k.form} schema unreadable`);
346
+ o.push(`${f}: ${v.form} schema unreadable`);
311
347
  continue;
312
348
  }
313
- let j;
349
+ let E;
314
350
  try {
315
- j = it(E, k.form);
351
+ E = Bt(O, v.form);
316
352
  } catch {
317
- o.push(`${p}: schema is not valid ${k.form}, fix it by hand`);
353
+ o.push(`${f}: schema is not valid ${v.form}, fix it by hand`);
318
354
  continue;
319
355
  }
320
- const x = new Set(Object.keys(j.properties ?? {}));
321
- for (const S of await Ne(h))
322
- if (!w.has(S.file))
323
- for (const D of Object.keys(S.props ?? {}))
324
- x.has(D) || o.push(`${p}/${S.file}: prop ${D} is absent from the schema, ${K(u.component)}`);
325
- const N = $ ? await fe($.componentFile, "utf-8").catch(() => {
356
+ const k = new Set(Object.keys(E.properties ?? {}));
357
+ for (const x of await et(m))
358
+ if (!g.has(x.file))
359
+ for (const R of Object.keys(x.props ?? {}))
360
+ k.has(R) || o.push(`${f}/${x.file}: prop ${R} is absent from the schema, ${ie(u.component)}`);
361
+ const T = w ? await Se(w.componentFile, "utf-8").catch(() => {
326
362
  }) : void 0;
327
- if ($) {
328
- const S = await se($.componentFile, l, u.component);
329
- if (S) {
330
- const D = bt(u.component, S.props, S.slots, S.emits);
363
+ if (w) {
364
+ const x = await ue(w.componentFile, l, u.component);
365
+ if (x) {
366
+ const R = os(u.component, x.props, x.slots, x.emits);
331
367
  o.push(
332
- ...Wt(p, u.component, O(e, $.componentFile), j, D)
368
+ ...gs(f, u.component, D(e, w.componentFile), E, R)
333
369
  );
334
370
  }
335
371
  }
336
- at(ct(u.component, j, { sourceFile: $?.componentFile, sourceText: N }));
372
+ Gt(Ht(u.component, E, { sourceFile: w?.componentFile, sourceText: T }));
337
373
  }
338
374
  }
339
- return $e(e), o;
375
+ return De(e), o;
340
376
  }
341
- function Be(e) {
377
+ function ft(e) {
342
378
  return Object.entries(e.modules.systems).filter(([, t]) => t.visibility !== "dev-only").map(([t]) => t);
343
379
  }
344
- async function Ue(e, t, n) {
345
- for (const s of n)
380
+ async function dt(e, t, s) {
381
+ for (const n of s)
346
382
  try {
347
- await (await Ie(await Te(e, t, s, "serve"))).listen(), console.log(`nimpress modules: ${s} harness on port ${ut(t.modules, s)}`);
383
+ await (await at(await st(e, t, n, "serve"))).listen(), console.log(`nimpress modules: ${n} harness on port ${Zt(t.modules, n)}`);
348
384
  } catch (o) {
349
- console.warn(`nimpress modules: harness for ${s} failed to start: ${String(o)}`);
385
+ console.warn(`nimpress modules: harness for ${n} failed to start: ${String(o)}`);
350
386
  }
351
387
  }
352
- async function Ge(e, t, n) {
353
- for (const s of n)
354
- await ze(await Te(e, t, s, "build")), console.log(`nimpress modules: built ${s}`);
388
+ async function ht(e, t, s) {
389
+ for (const n of s)
390
+ await ct(await st(e, t, n, "build")), console.log(`nimpress modules: built ${n}`);
355
391
  }
356
- async function Nt(e, t) {
357
- const n = await Ie(Pe({ cwd: e, command: "serve", resolved: t }));
358
- await n.listen(), await Ue(e, t, Object.keys(t.modules.systems)), n.printUrls(), n.bindCLIShortcuts({ print: !0 });
392
+ async function ws(e, t) {
393
+ const s = await at(tt({ cwd: e, command: "serve", resolved: t }));
394
+ await s.listen(), await dt(e, t, Object.keys(t.modules.systems)), s.printUrls(), s.bindCLIShortcuts({ print: !0 });
359
395
  }
360
- async function He(e, t) {
361
- const n = d(e, "index.html"), s = !b(n);
362
- s && A(n, lt(t));
396
+ async function gt(e, t) {
397
+ const s = d(e, "index.html"), n = !$(s);
398
+ n && W(s, Ut(t));
363
399
  const o = () => {
364
- s && ae(n, { force: !0 });
400
+ n && ne(s, { force: !0 });
365
401
  }, r = () => {
366
402
  o(), process.exit(130);
367
403
  };
368
404
  process.once("SIGINT", r), process.once("SIGTERM", r);
369
405
  try {
370
- await ze(Pe({ cwd: e, command: "build", resolved: t, htmlInput: n }));
406
+ await ct(tt({ cwd: e, command: "build", resolved: t, htmlInput: s }));
371
407
  } finally {
372
408
  process.off("SIGINT", r), process.off("SIGTERM", r), o();
373
409
  }
374
- await Ge(e, t, Be(t));
410
+ await ht(e, t, ft(t));
375
411
  }
376
- const Pt = [".ts", ".tsx", ".js", ".mjs", ".vue", ".svelte"], Tt = ["", ".ts", ".tsx", ".js", ".mjs", ".vue", ".svelte", "/index.ts", "/index.js"], De = /^[a-z0-9][a-z0-9.-]*$/, At = /^[A-Z][A-Za-z0-9]*$/;
377
- function Mt(e) {
412
+ const $s = [".ts", ".tsx", ".js", ".mjs", ".vue", ".svelte"], ys = ["", ".ts", ".tsx", ".js", ".mjs", ".vue", ".svelte", "/index.ts", "/index.js"], Ue = /^[a-z0-9][a-z0-9.-]*$/, bs = /^[A-Z][A-Za-z0-9]*$/;
413
+ function vs(e) {
378
414
  const t = e.resolve;
379
415
  if (!t || typeof t != "object") return [];
380
- const n = t.alias;
381
- return !n || typeof n != "object" ? [] : Array.isArray(n) ? n.flatMap((s) => {
382
- if (!s || typeof s != "object") return [];
383
- const { find: o, replacement: r } = s;
416
+ const s = t.alias;
417
+ return !s || typeof s != "object" ? [] : Array.isArray(s) ? s.flatMap((n) => {
418
+ if (!n || typeof n != "object") return [];
419
+ const { find: o, replacement: r } = n;
384
420
  return typeof o != "string" || typeof r != "string" ? [] : [{ find: o, replacement: r }];
385
- }) : Object.entries(n).flatMap(
386
- ([s, o]) => typeof o == "string" ? [{ find: s, replacement: o }] : []
421
+ }) : Object.entries(s).flatMap(
422
+ ([n, o]) => typeof o == "string" ? [{ find: n, replacement: o }] : []
387
423
  );
388
424
  }
389
- function Rt(e) {
390
- const t = [], n = [
425
+ function ks(e) {
426
+ const t = [], s = [
391
427
  /(?:^|\n)[ \t]*import[^'"\n]*?from[ \t]*['"]([^'"\n]+)['"]/g,
392
428
  /(?:^|\n)[ \t]*export[^'"\n]*?from[ \t]*['"]([^'"\n]+)['"]/g,
393
429
  /(?:^|\n)[ \t]*import[ \t]+['"]([^'"\n]+)['"]/g,
394
430
  /\bimport\(\s*['"]([^'"\n]+)['"]\s*\)/g
395
431
  ];
396
- for (const s of n) {
432
+ for (const n of s) {
397
433
  let o;
398
- for (; o = s.exec(e); ) t.push(o[1]);
434
+ for (; o = n.exec(e); ) t.push(o[1]);
399
435
  }
400
436
  return t;
401
437
  }
402
- function _e(e) {
403
- return Tt.some((t) => {
404
- const n = e + t;
405
- if (!b(n)) return !1;
438
+ function Ze(e) {
439
+ return ys.some((t) => {
440
+ const s = e + t;
441
+ if (!$(s)) return !1;
406
442
  try {
407
- return Me(n).isFile();
443
+ return rt(s).isFile();
408
444
  } catch {
409
445
  return !1;
410
446
  }
411
447
  });
412
448
  }
413
- function It(e, t) {
414
- const n = F(e, t.contentDir), s = Mt(t.vite), o = [];
415
- for (const r of re(n)) {
416
- if (!Pt.some((l) => r.endsWith(l))) continue;
449
+ function xs(e, t) {
450
+ const s = j(e, t.contentDir), n = vs(t.vite), o = [];
451
+ for (const r of oe(s)) {
452
+ if (!$s.some((l) => r.endsWith(l))) continue;
417
453
  let i;
418
454
  try {
419
- i = W(r, "utf-8");
455
+ i = C(r, "utf-8");
420
456
  } catch {
421
457
  continue;
422
458
  }
423
- const a = O(n, r).split(q).join("/");
424
- for (const l of Rt(i)) {
459
+ const c = D(s, r).split(I).join("/");
460
+ for (const l of ks(i)) {
425
461
  if (l.includes("_shared/") || l.startsWith("_shared")) {
426
462
  o.push(
427
- `${a}: imports ${l}, shared fixture folders are forbidden, stories are self contained and shared setup lives in a group harness component`
463
+ `${c}: imports ${l}, shared fixture folders are forbidden, stories are self contained and shared setup lives in a group harness component`
428
464
  );
429
465
  continue;
430
466
  }
431
- const c = l.split("?")[0];
432
- if (c.startsWith("./") || c.startsWith("../")) {
433
- const u = F(L(r), c);
434
- _e(u) || o.push(`${a}: unresolved import ${l}, fix the path or create the file`);
467
+ const a = l.split("?")[0];
468
+ if (a.startsWith("./") || a.startsWith("../")) {
469
+ const u = j(_(r), a);
470
+ Ze(u) || o.push(`${c}: unresolved import ${l}, fix the path or create the file`);
435
471
  continue;
436
472
  }
437
- const m = s.find((u) => c === u.find || c.startsWith(u.find + "/"));
438
- if (m) {
439
- const u = F(e, m.replacement + c.slice(m.find.length));
440
- _e(u) || o.push(`${a}: unresolved import ${l} via alias ${m.find}`);
473
+ const p = n.find((u) => a === u.find || a.startsWith(u.find + "/"));
474
+ if (p) {
475
+ const u = j(e, p.replacement + a.slice(p.find.length));
476
+ Ze(u) || o.push(`${c}: unresolved import ${l} via alias ${p.find}`);
441
477
  }
442
478
  }
443
479
  }
444
480
  return o;
445
481
  }
446
- function zt(e, t) {
447
- const n = F(e, t.contentDir), s = [];
448
- if (!b(n)) return [`${t.contentDir}: contentDir does not exist`];
449
- const o = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map();
450
- for (const a of re(n)) {
451
- const l = O(n, a).split(q).join("/"), c = L(a), m = C(a);
482
+ function Ss(e, t) {
483
+ const s = j(e, t.contentDir), n = [];
484
+ if (!$(s)) return [`${t.contentDir}: contentDir does not exist`];
485
+ const o = /* @__PURE__ */ new Map();
486
+ let r, i;
487
+ const c = /* @__PURE__ */ new Map();
488
+ for (const a of oe(s)) {
489
+ const p = D(s, a).split(I).join("/"), u = _(a), m = F(a);
452
490
  if (m.endsWith(".md")) {
453
- const u = r.get(c) ?? [];
454
- u.push(a), r.set(c, u);
491
+ const f = c.get(u) ?? [];
492
+ f.push(a), c.set(u, f);
455
493
  const h = m.slice(0, -3);
456
- De.test(h) || s.push(`${l}: markdown file names are lowercase kebab case, rename to ${h.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase().replace(/[^a-z0-9.-]+/g, "-")}.md`);
457
- let p;
494
+ Ue.test(h) || n.push(`${p}: markdown file names are lowercase kebab case, rename to ${h.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase().replace(/[^a-z0-9.-]+/g, "-")}.md`);
495
+ let g;
458
496
  try {
459
- p = yt(W(a, "utf-8")).data;
497
+ g = fe(C(a, "utf-8")).data, typeof g.type == "number" && (g.type = String(g.type));
460
498
  } catch {
461
499
  continue;
462
500
  }
463
- if (p?.type === "component") {
464
- const f = o.get(c);
465
- f ? s.push(`${l}: second type component page in one folder, ${O(n, f).split(q).join("/")} already owns it, one component per folder`) : o.set(c, a);
501
+ if (g?.type === "glossary" && (i ? n.push(`${p}: second type glossary page in the site, ${D(s, i).split(I).join("/")} already owns it, one glossary per site`) : i = a, /^: /m.test(fe(C(a, "utf-8")).content) || n.push(`${p}: type glossary needs a definition list body, term lines followed by lines starting with a colon`)), g?.type === "section" && !a.endsWith(`${I}index.md`) && n.push(`${p}: type section belongs on a folder index.md, move the page or drop the type`), g?.type === "404" && (r ? n.push(`${p}: second type 404 page in the site, ${D(s, r).split(I).join("/")} already owns it, one not found page per site`) : r = a), g?.type === "component") {
502
+ const w = o.get(u);
503
+ w ? n.push(`${p}: second type component page in one folder, ${D(s, w).split(I).join("/")} already owns it, one component per folder`) : o.set(u, a);
504
+ }
505
+ if (g?.type === "dbml") {
506
+ const w = typeof g.spec == "string" ? g.spec : "";
507
+ w ? $(j(u, w)) || n.push(`${p}: spec ${w} does not resolve, create the file or fix the path`) : n.push(`${p}: type dbml needs a spec field pointing at the .dbml file`);
466
508
  }
467
- if (p?.type === "dbml") {
468
- const f = typeof p.spec == "string" ? p.spec : "";
469
- f ? b(F(c, f)) || s.push(`${l}: spec ${f} does not resolve, create the file or fix the path`) : s.push(`${l}: type dbml needs a spec field pointing at the .dbml file`);
509
+ g?.type === "changelog" && typeof g.path == "string" && n.push(`${p}: changelog entries never set path, the collection mounts at the folder route, remove the path field`);
510
+ }
511
+ if (m.endsWith(".css") && !m.startsWith("_") && F(_(a)) === "styles" && _(_(a)) === s) {
512
+ const f = m.replace(/\.css$/, "");
513
+ ge.includes(f) || n.push(`${p}: ${f} is not a component class root, name the file after one of ${ge.join(", ")}`);
514
+ continue;
515
+ }
516
+ if (m.endsWith(".css") && !m.startsWith("_") && m.split(".").length > 2) {
517
+ const f = m.split(".")[0], h = Yt(m, f);
518
+ if (h && $(d(_(a), `${f}.md`))) {
519
+ ge.includes(h) || n.push(`${p}: ${h} is not a component class root, name the file after one of ${ge.join(", ")}`);
520
+ continue;
470
521
  }
471
- p?.type === "changelog" && typeof p.path == "string" && s.push(`${l}: changelog entries never set path, the collection mounts at the folder route, remove the path field`);
472
522
  }
473
523
  if (m.endsWith(".css") && !m.startsWith("_")) {
474
- const u = a.replace(/\.css$/, ".md");
475
- b(u) || s.push(`${l}: page css without a matching ${C(u)}, page styles are named after the page they scope`);
524
+ const f = a.replace(/\.css$/, ".md");
525
+ $(f) || n.push(`${p}: page css without a matching ${F(f)}, page styles are named after the page they scope`);
476
526
  }
477
527
  }
478
- for (const [a, l] of r) {
479
- const c = O(n, a).split(q).join("/") || ".", m = o.has(a);
480
- let u = [];
528
+ for (const [a, p] of c) {
529
+ const u = D(s, a).split(I).join("/") || ".", m = o.has(a);
530
+ let f = [];
481
531
  try {
482
- u = Y(a);
532
+ f = se(a);
483
533
  } catch {
484
534
  continue;
485
535
  }
486
- u.filter((p) => /\.story\.tsx?$/.test(p)).length && !m && s.push(`${c}: story files without a type component page, add the component index.md or move the stories`);
487
- for (const p of ["schema.json", "schema.yml"])
488
- u.includes(p) && !m && s.push(`${c}: ${p} without a type component page, it belongs beside the component index.md`);
489
- if (m && l.length > 1) {
490
- const p = l.filter((f) => f !== o.get(a)).map((f) => C(f));
491
- s.push(`${c}: a component folder holds exactly one md file, move ${p.join(", ")} out`);
536
+ f.filter((g) => /\.story\.tsx?$/.test(g)).length && !m && n.push(`${u}: story files without a type component page, add the component index.md or move the stories`);
537
+ for (const g of ["schema.json", "schema.yml"])
538
+ f.includes(g) && !m && n.push(`${u}: ${g} without a type component page, it belongs beside the component index.md`);
539
+ if (m && p.length > 1) {
540
+ const g = p.filter((w) => w !== o.get(a)).map((w) => F(w));
541
+ n.push(`${u}: a component folder holds exactly one md file, move ${g.join(", ")} out`);
492
542
  }
493
543
  }
494
- const i = (a) => {
495
- let l;
544
+ const l = (a) => {
545
+ let p;
496
546
  try {
497
- l = Y(a, { withFileTypes: !0 });
547
+ p = se(a, { withFileTypes: !0 });
498
548
  } catch {
499
549
  return;
500
550
  }
501
- for (const c of l)
502
- if (c.isDirectory() && !(c.name.startsWith(".") || c.name === "node_modules")) {
503
- if (!De.test(c.name) && !At.test(c.name)) {
504
- const m = O(n, d(a, c.name)).split(q).join("/");
505
- s.push(`${m}/: folder names are lowercase kebab case, or PascalCase for component and group folders, rename it`);
551
+ for (const u of p)
552
+ if (u.isDirectory() && !(u.name.startsWith(".") || u.name === "node_modules")) {
553
+ if (!Ue.test(u.name) && !bs.test(u.name)) {
554
+ const m = D(s, d(a, u.name)).split(I).join("/");
555
+ n.push(`${m}/: folder names are lowercase kebab case, or PascalCase for component and group folders, rename it`);
506
556
  }
507
- i(d(a, c.name));
557
+ l(d(a, u.name));
508
558
  }
509
559
  };
510
- return i(n), s;
560
+ return l(s), n;
511
561
  }
512
- async function Lt(e, t) {
513
- const n = pt(e, t, "lint"), s = () => ae(n, { recursive: !0, force: !0 }), o = () => {
514
- s(), process.exit(130);
562
+ async function js(e, t) {
563
+ const s = nt(e, t, "lint"), n = () => ne(s, { recursive: !0, force: !0 }), o = () => {
564
+ n(), process.exit(130);
515
565
  };
516
566
  process.once("SIGINT", o), process.once("SIGTERM", o);
517
567
  try {
518
- return await He(e, { ...t, paths: { ...t.paths, out: n } }), [];
568
+ return await gt(e, { ...t, paths: { ...t.paths, out: s } }), [];
519
569
  } catch (r) {
520
570
  return (r instanceof Error ? r.message : String(r)).split(`
521
- `).filter((a) => a.trim()).map((a) => `build: ${a.trim()}`);
571
+ `).filter((c) => c.trim()).map((c) => `build: ${c.trim()}`);
522
572
  } finally {
523
- process.off("SIGINT", o), process.off("SIGTERM", o), s();
573
+ process.off("SIGINT", o), process.off("SIGTERM", o), n();
524
574
  }
525
575
  }
526
- async function Jt(e, t) {
527
- const n = process.argv.slice(2), s = [
528
- ...zt(e, t),
529
- ...await mt(e, t.contentDir),
530
- ...It(e, t),
531
- ...await Je(e, t)
576
+ async function Cs(e, t) {
577
+ const s = process.argv.slice(2), n = [
578
+ ...Ss(e, t),
579
+ ...(Vt(e, t.pageTypes ?? {}), await Kt(e, t.contentDir)),
580
+ ...xs(e, t),
581
+ ...await mt(e, t)
532
582
  ];
533
- if (s.length) {
534
- we("nimpress lint", s, "");
583
+ if (n.length) {
584
+ _e("nimpress lint", n, "");
535
585
  return;
536
586
  }
537
- if (console.log("nimpress lint: structure, frontmatter, imports, and modules ok"), X(n, "no-build")) return;
587
+ if (console.log("nimpress lint: structure, frontmatter, imports, and modules ok"), M(s, "no-build")) return;
538
588
  console.log("nimpress lint: building to verify the output compiles");
539
- const o = await Lt(e, t);
540
- we("nimpress lint", o, "nimpress lint: build ok, everything passes");
589
+ const o = await js(e, t);
590
+ _e("nimpress lint", o, "nimpress lint: build ok, everything passes");
541
591
  }
542
- const Bt = {
592
+ const Es = {
543
593
  ".json": "application/json",
544
594
  ".xml": "application/rss+xml",
545
595
  ".html": "text/html",
@@ -552,123 +602,123 @@ const Bt = {
552
602
  ".webp": "image/webp",
553
603
  ".pdf": "application/pdf"
554
604
  };
555
- function Ut(e, t, n) {
556
- const s = n[0], o = d(e, T(n, "dist") ?? t.paths.out), r = `/${t.paths.guarded}/`, i = d(o, "access.json");
557
- if (!b(i))
605
+ function Os(e, t, s) {
606
+ const n = s[0], o = d(e, N(s, "dist") ?? t.paths.out), r = `/${t.paths.guarded}/`, i = d(o, "access.json");
607
+ if (!$(i))
558
608
  throw new Error(`[nimpress] guard: ${i} not found, run a build first`);
559
- const a = JSON.parse(W(i, "utf-8"));
560
- if (s === "map") {
561
- const l = Ee(o, t), c = d(o, "guard.map.json"), m = b(c) ? JSON.parse(W(c, "utf-8")) : { prefix: a.prefix ?? r, routes: a.routes, bundles: {} }, u = b(l) ? re(l) : [], h = m.prefix ?? r, p = u.map(($) => {
562
- const k = O(l, $).split("\\").join("/"), E = k.split("/")[0] ?? "", j = [
609
+ const c = JSON.parse(C(i, "utf-8"));
610
+ if (n === "map") {
611
+ const l = Ge(o, t), a = d(o, "guard.map.json"), p = $(a) ? JSON.parse(C(a, "utf-8")) : { prefix: c.prefix ?? r, routes: c.routes, bundles: {} }, u = $(l) ? oe(l) : [], m = p.prefix ?? r, f = u.map((w) => {
612
+ const v = D(l, w).split("\\").join("/"), O = v.split("/")[0] ?? "", E = [
563
613
  ...new Set(
564
- Object.values(m.routes ?? {}).filter((N) => N.bundle === E && N.gate).map((N) => N.gate)
614
+ Object.values(p.routes ?? {}).filter((T) => T.bundle === O && T.gate).map((T) => T.gate)
565
615
  )
566
- ], x = W($);
616
+ ], k = C(w);
567
617
  return {
568
- path: `${h}${k}`,
569
- file: k,
570
- bundle: E,
571
- sha256: xt("sha256").update(x).digest("hex"),
572
- size: Me($).size,
573
- mime: Bt[oe($).toLowerCase()] ?? "application/octet-stream",
574
- gates: j
618
+ path: `${m}${v}`,
619
+ file: v,
620
+ bundle: O,
621
+ sha256: lt("sha256").update(k).digest("hex"),
622
+ size: rt(w).size,
623
+ mime: Es[me(w).toLowerCase()] ?? "application/octet-stream",
624
+ gates: E
575
625
  };
576
- }), f = T(n, "out"), w = f ? d(e, f) : c;
577
- A(
578
- w,
579
- JSON.stringify({ ...m, prefix: h, files: p }, null, 2) + `
626
+ }), h = N(s, "out"), g = h ? d(e, h) : a;
627
+ W(
628
+ g,
629
+ JSON.stringify({ ...p, prefix: m, files: f }, null, 2) + `
580
630
  `
581
- ), console.log(`nimpress guard: mapped ${p.length} guarded files to ${w}`);
631
+ ), console.log(`nimpress guard: mapped ${f.length} guarded files to ${g}`);
582
632
  return;
583
633
  }
584
- if (s === "apply") {
585
- const l = T(n, "map");
634
+ if (n === "apply") {
635
+ const l = N(s, "map");
586
636
  if (!l) throw new Error("[nimpress] guard apply requires --map=<uploaded mapping json>");
587
- const c = JSON.parse(W(d(e, l), "utf-8"));
588
- if (!c.base) throw new Error("[nimpress] guard apply: mapping json carries no base url");
589
- a.base = c.base.replace(/\/$/, ""), a.files = (c.files ?? []).map((m) => ({
590
- path: m.path,
591
- file: m.file,
592
- bundle: m.bundle,
593
- asset_id: m.asset_id,
594
- url: m.url
595
- })), A(i, JSON.stringify(a, null, 2) + `
596
- `), ae(Ee(o, t), { recursive: !0, force: !0 }), ae(d(o, "guard.map.json"), { force: !0 }), console.log(`nimpress guard: base ${a.base} applied, ${t.paths.guarded} removed from ${o}`);
637
+ const a = JSON.parse(C(d(e, l), "utf-8"));
638
+ if (!a.base) throw new Error("[nimpress] guard apply: mapping json carries no base url");
639
+ c.base = a.base.replace(/\/$/, ""), c.files = (a.files ?? []).map((p) => ({
640
+ path: p.path,
641
+ file: p.file,
642
+ bundle: p.bundle,
643
+ asset_id: p.asset_id,
644
+ url: p.url
645
+ })), W(i, JSON.stringify(c, null, 2) + `
646
+ `), ne(Ge(o, t), { recursive: !0, force: !0 }), ne(d(o, "guard.map.json"), { force: !0 }), console.log(`nimpress guard: base ${c.base} applied, ${t.paths.guarded} removed from ${o}`);
597
647
  return;
598
648
  }
599
649
  throw new Error("[nimpress] guard expects map or apply");
600
650
  }
601
- function Ze(e) {
602
- const t = oe(e);
651
+ function wt(e) {
652
+ const t = me(e);
603
653
  return t === ".vue" ? "vue" : t === ".svelte" ? "svelte" : null;
604
654
  }
605
- async function je(e, t, n, s, o) {
606
- const i = (await ke(e, t.contentDir)).find((h) => h.system === n && h.component === s);
655
+ async function Le(e, t, s, n, o) {
656
+ const i = (await Pe(e, t.contentDir)).find((m) => m.system === s && m.component === n);
607
657
  if (!i)
608
- return console.warn(`[nimpress] modules story: no type component page found for ${n}/${s}`), null;
609
- const a = Se(e, t.modules, n, s, i.file);
610
- if (!a)
611
- return console.warn(`[nimpress] modules story: no source found for ${n}/${s}`), null;
612
- const l = o ?? Ze(a.componentFile);
658
+ return console.warn(`[nimpress] modules story: no type component page found for ${s}/${n}`), null;
659
+ const c = Me(e, t.modules, s, n, i.file);
660
+ if (!c)
661
+ return console.warn(`[nimpress] modules story: no source found for ${s}/${n}`), null;
662
+ const l = o ?? wt(c.componentFile);
613
663
  if (!l)
614
664
  throw new Error(
615
- `[nimpress] modules story: failed to detect framework for ${a.componentFile}, pass --framework=vue or --framework=svelte`
665
+ `[nimpress] modules story: failed to detect framework for ${c.componentFile}, pass --framework=vue or --framework=svelte`
616
666
  );
617
- const c = l === "vue" ? "vueStory" : "svelteStory", m = `import { ${c} } from '@nimtech/nimpress/story'
667
+ const a = l === "vue" ? "vueStory" : "svelteStory", p = `import { ${a} } from '@nimtech/nimpress/story'
618
668
 
619
669
  // story: Default
620
- export default ${c}({
670
+ export default ${a}({
621
671
  name: "Default"
622
672
  })
623
- `, u = d(L(i.pageFile), "default.story.tsx");
624
- return b(u) ? (console.warn(`[nimpress] modules story: ${u} exists, not overwriting`), null) : (await G(u, m), u);
673
+ `, u = d(_(i.pageFile), "default.story.tsx");
674
+ return $(u) ? (console.warn(`[nimpress] modules story: ${u} exists, not overwriting`), null) : (await Q(u, p), u);
625
675
  }
626
- async function Gt(e, t, n) {
627
- const s = await ke(e, t.contentDir);
676
+ async function Fs(e, t, s) {
677
+ const n = await Pe(e, t.contentDir);
628
678
  let o = 0;
629
- for (const r of s)
630
- if (!(r.system !== n || (await Ne(L(r.pageFile))).length))
679
+ for (const r of n)
680
+ if (!(r.system !== s || (await et(_(r.pageFile))).length))
631
681
  try {
632
- await je(e, t, n, r.component) && o++;
633
- } catch (a) {
634
- console.warn(String(a));
682
+ await Le(e, t, s, r.component) && o++;
683
+ } catch (c) {
684
+ console.warn(String(c));
635
685
  }
636
686
  return o;
637
687
  }
638
- async function Ht(e, t, n, s, o) {
639
- const r = t.modules.systems[n];
640
- if (!r) throw new Error(`[nimpress] modules create: unknown system ${n}`);
641
- const i = d(e, t.contentDir, "components", "Components", s), a = d(i, "index.md");
642
- if (b(a))
643
- throw new Error(`[nimpress] modules create: ${a} exists`);
688
+ async function Ds(e, t, s, n, o) {
689
+ const r = t.modules.systems[s];
690
+ if (!r) throw new Error(`[nimpress] modules create: unknown system ${s}`);
691
+ const i = d(e, t.contentDir, "components", "Components", n), c = d(i, "index.md");
692
+ if ($(c))
693
+ throw new Error(`[nimpress] modules create: ${c} exists`);
644
694
  const { mkdir: l } = await import("node:fs/promises");
645
695
  await l(i, { recursive: !0 });
646
- const c = r.package;
647
- await G(
648
- a,
696
+ const a = r.package;
697
+ await Q(
698
+ c,
649
699
  `---
650
- title: ${s}
700
+ title: ${n}
651
701
  type: component
652
702
  data:
653
- system: ${n}
654
- component: ${s}${c ? `
655
- package: "${c}"` : ""}
703
+ system: ${s}
704
+ component: ${n}${a ? `
705
+ package: "${a}"` : ""}
656
706
  ---
657
707
 
658
708
  ## Usage
659
709
 
660
710
  \`\`\`ts
661
- import { ${s} } from "${c ?? n}";
711
+ import { ${n} } from "${a ?? s}";
662
712
  \`\`\`
663
713
  `
664
714
  );
665
- const m = Se(e, t.modules, n, s);
666
- if (m) {
667
- const u = o ?? Ze(m.componentFile) ?? r.framework;
668
- await ne(i, s, await se(m.componentFile, u, s)), await je(e, t, n, s, o);
715
+ const p = Me(e, t.modules, s, n);
716
+ if (p) {
717
+ const u = o ?? wt(p.componentFile) ?? r.framework;
718
+ await pe(i, n, await ue(p.componentFile, u, n)), await Le(e, t, s, n, o);
669
719
  } else {
670
720
  const u = r.framework === "vue" ? "vueStory" : "svelteStory";
671
- await G(
721
+ await Q(
672
722
  d(i, "default.story.tsx"),
673
723
  `import { ${u} } from '@nimtech/nimpress/story'
674
724
 
@@ -679,153 +729,153 @@ export default ${u}({
679
729
  })
680
730
  `
681
731
  ), console.warn(
682
- `nimpress modules: no source found for ${s}, wrote a stub story, schema.json follows once the component exists and import or create runs again`
732
+ `nimpress modules: no source found for ${n}, wrote a stub story, schema.json follows once the component exists and import or create runs again`
683
733
  );
684
734
  }
685
735
  return i;
686
736
  }
687
- function le(e) {
737
+ function ye(e) {
688
738
  try {
689
- return JSON.parse(JSON.stringify(e, (t, n) => typeof n == "function" ? void 0 : n));
739
+ return JSON.parse(JSON.stringify(e, (t, s) => typeof s == "function" ? void 0 : s));
690
740
  } catch {
691
741
  return {};
692
742
  }
693
743
  }
694
- function ue(e, t = []) {
695
- let n;
744
+ function be(e, t = []) {
745
+ let s;
696
746
  try {
697
- n = Y(e, { withFileTypes: !0 });
747
+ s = se(e, { withFileTypes: !0 });
698
748
  } catch {
699
749
  return t;
700
750
  }
701
- for (const s of n) {
702
- const o = d(e, s.name);
703
- if (s.isDirectory()) {
704
- if (s.name === "node_modules" || s.name.startsWith(".")) continue;
705
- ue(o, t);
706
- } else s.isFile() && t.push(o);
751
+ for (const n of s) {
752
+ const o = d(e, n.name);
753
+ if (n.isDirectory()) {
754
+ if (n.name === "node_modules" || n.name.startsWith(".")) continue;
755
+ be(o, t);
756
+ } else n.isFile() && t.push(o);
707
757
  }
708
758
  return t;
709
759
  }
710
- function be(e) {
760
+ function We(e) {
711
761
  return e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase().replace(/[^a-z0-9-]/g, "");
712
762
  }
713
- function xe(e) {
714
- const t = W(e, "utf-8"), n = t.split(`
715
- `), s = [];
763
+ function Te(e) {
764
+ const t = C(e, "utf-8"), s = t.split(`
765
+ `), n = [];
716
766
  let o = 0;
717
- for (; o < n.length; ) {
718
- const p = n[o];
719
- if (/^\s*import\b/.test(p)) {
720
- let f = p;
721
- for (; !/from\s+["'][^"']+["'];?\s*$/.test(f) && !/^\s*import\s+["'][^"']+["'];?\s*$/.test(f) && o + 1 < n.length; )
722
- o++, f += `
723
- ` + n[o];
724
- s.push(f), o++;
767
+ for (; o < s.length; ) {
768
+ const f = s[o];
769
+ if (/^\s*import\b/.test(f)) {
770
+ let h = f;
771
+ for (; !/from\s+["'][^"']+["'];?\s*$/.test(h) && !/^\s*import\s+["'][^"']+["'];?\s*$/.test(h) && o + 1 < s.length; )
772
+ o++, h += `
773
+ ` + s[o];
774
+ n.push(h), o++;
725
775
  continue;
726
776
  }
727
- if (/^\s*$/.test(p)) {
777
+ if (/^\s*$/.test(f)) {
728
778
  o++;
729
779
  continue;
730
780
  }
731
781
  break;
732
782
  }
733
- const r = L(e), i = [], a = (p) => {
734
- const f = F(r, p);
735
- return /\.(vue|svelte)$/.test(p) ? { kind: "source", abs: f } : p.endsWith(".ts") ? b(f) ? { kind: "data", abs: f } : null : b(`${f}.ts`) ? { kind: "data", abs: `${f}.ts` } : b(`${f}.vue`) || b(`${f}.svelte`) || b(d(f, "index.ts")) ? { kind: "source", abs: f } : null;
783
+ const r = _(e), i = [], c = (f) => {
784
+ const h = j(r, f);
785
+ return /\.(vue|svelte)$/.test(f) ? { kind: "source", abs: h } : f.endsWith(".ts") ? $(h) ? { kind: "data", abs: h } : null : $(`${h}.ts`) ? { kind: "data", abs: `${h}.ts` } : $(`${h}.vue`) || $(`${h}.svelte`) || $(d(h, "index.ts")) ? { kind: "source", abs: h } : null;
736
786
  };
737
- for (const p of s) {
738
- const f = p.match(/from\s+["'](\.\.?\/[^"']+)["']/)?.[1];
739
- if (!f) continue;
740
- const w = a(f);
741
- w?.kind === "data" && i.push(w.abs);
742
- }
743
- const l = s.filter((p) => !p.includes("@storybook")).map(
744
- (p) => p.replace(/from\s+["'](\.\.?\/[^"']+)["']/g, (f, w) => {
745
- const $ = a(w);
746
- return $?.kind === "source" ? `from ${JSON.stringify($.abs)}` : `from "./${C(w).replace(/\.ts$/, "")}"`;
787
+ for (const f of n) {
788
+ const h = f.match(/from\s+["'](\.\.?\/[^"']+)["']/)?.[1];
789
+ if (!h) continue;
790
+ const g = c(h);
791
+ g?.kind === "data" && i.push(g.abs);
792
+ }
793
+ const l = n.filter((f) => !f.includes("@storybook")).map(
794
+ (f) => f.replace(/from\s+["'](\.\.?\/[^"']+)["']/g, (h, g) => {
795
+ const w = c(g);
796
+ return w?.kind === "source" ? `from ${JSON.stringify(w.abs)}` : `from "./${F(g).replace(/\.ts$/, "")}"`;
747
797
  })
748
798
  ).join(`
749
799
  `);
750
- let c = t.slice(n.slice(0, o).join(`
800
+ let a = t.slice(s.slice(0, o).join(`
751
801
  `).length);
752
- const m = (p) => {
753
- const f = c.search(p);
754
- if (f < 0) return;
755
- const w = c.indexOf("{", f);
756
- if (w < 0) {
757
- c = c.slice(0, f) + c.slice(c.indexOf(`
758
- `, f) + 1);
802
+ const p = (f) => {
803
+ const h = a.search(f);
804
+ if (h < 0) return;
805
+ const g = a.indexOf("{", h);
806
+ if (g < 0) {
807
+ a = a.slice(0, h) + a.slice(a.indexOf(`
808
+ `, h) + 1);
759
809
  return;
760
810
  }
761
- const $ = ce(c, w + 1), k = w + 1 + $.length + 1, E = c.slice(k).match(/^[^\n]*/)?.[0] ?? "";
762
- c = c.slice(0, f) + c.slice(k + E.length);
811
+ const w = $e(a, g + 1), v = g + 1 + w.length + 1, O = a.slice(v).match(/^[^\n]*/)?.[0] ?? "";
812
+ a = a.slice(0, h) + a.slice(v + O.length);
763
813
  };
764
- m(/^const meta\b[^\n]*/m), c = c.replace(/^export default meta;?\s*$/m, ""), c = c.replace(/^(?:export )?type \w+[^\n]*\n(?:[ \t]+[^\n]*\n?)*/gm, "");
814
+ p(/^const meta\b[^\n]*/m), a = a.replace(/^export default meta;?\s*$/m, ""), a = a.replace(/^(?:export )?type \w+[^\n]*\n(?:[ \t]+[^\n]*\n?)*/gm, "");
765
815
  let u = 0;
766
- for (; /^(?:export )?interface \w+/m.test(c) && u < 50; )
767
- m(/^(?:export )?interface \w+[^\n]*/m), u++;
768
- let h = 0;
769
- for (; /^export const \w+/m.test(c) && h < 200; )
770
- m(/^export const \w+[^\n]*/m), h++;
816
+ for (; /^(?:export )?interface \w+/m.test(a) && u < 50; )
817
+ p(/^(?:export )?interface \w+[^\n]*/m), u++;
818
+ let m = 0;
819
+ for (; /^export const \w+/m.test(a) && m < 200; )
820
+ p(/^export const \w+[^\n]*/m), m++;
771
821
  return {
772
822
  file: e,
773
823
  text: t,
774
824
  title: t.match(/\btitle:\s*["']([^"']+)["']/)?.[1],
775
825
  metaComponent: t.match(/\bcomponent:\s*([A-Za-z_$][\w$]*)\s*[,\n}]/)?.[1],
776
826
  imports: l,
777
- declarations: c.trim(),
827
+ declarations: a.trim(),
778
828
  dataModules: i
779
829
  };
780
830
  }
781
- function Zt(e, t) {
782
- const n = e.indexOf(":", t) + 1;
783
- let s = 0, o = null;
784
- for (let r = n; r < e.length; r++) {
785
- const i = e[r], a = e[r - 1];
831
+ function Ns(e, t) {
832
+ const s = e.indexOf(":", t) + 1;
833
+ let n = 0, o = null;
834
+ for (let r = s; r < e.length; r++) {
835
+ const i = e[r], c = e[r - 1];
786
836
  if (o) {
787
- i === o && a !== "\\" && (o = null);
837
+ i === o && c !== "\\" && (o = null);
788
838
  continue;
789
839
  }
790
840
  if (i === "'" || i === '"' || i === "`") {
791
841
  o = i;
792
842
  continue;
793
843
  }
794
- if (i === "{" || i === "(" || i === "[") s++;
795
- else if (i === "}" || i === ")" || i === "]") s--;
796
- else if (i === "," && s === 0) return e.slice(n, r).trim();
844
+ if (i === "{" || i === "(" || i === "[") n++;
845
+ else if (i === "}" || i === ")" || i === "]") n--;
846
+ else if (i === "," && n === 0) return e.slice(s, r).trim();
797
847
  }
798
- return e.slice(n).trim();
848
+ return e.slice(s).trim();
799
849
  }
800
- function Ve(e) {
850
+ function $t(e) {
801
851
  return e.replace(/\bsatisfies\s+[A-Za-z_$][\w$.]*(?:<[^>]*>)?/g, "").replace(/\bas\s+const\b/g, "").replace(/\)\s*:\s*[A-Za-z_$][\w$<>\[\], .|&]*\s*=>/g, ") =>").replace(/\(\s*([A-Za-z_$][\w$]*)\s*:\s*[A-Za-z_$][\w$<>\[\], .|&]*\)/g, "($1)");
802
852
  }
803
- function qe(e) {
804
- const t = [], n = /export const (\w+)\s*(?::[^=]*)?=\s*\{/g;
805
- let s;
806
- for (; s = n.exec(e.text); ) {
807
- const o = s[1];
853
+ function yt(e) {
854
+ const t = [], s = /export const (\w+)\s*(?::[^=]*)?=\s*\{/g;
855
+ let n;
856
+ for (; n = s.exec(e.text); ) {
857
+ const o = n[1];
808
858
  if (o === "default" || o === "meta") continue;
809
- const r = ce(e.text, n.lastIndex), i = r.search(/\brender\s*:/);
859
+ const r = $e(e.text, s.lastIndex), i = r.search(/\brender\s*:/);
810
860
  if (i >= 0) {
811
- const c = Zt(r, i);
812
- if (c) {
813
- t.push({ name: o, renderFn: c });
861
+ const a = Ns(r, i);
862
+ if (a) {
863
+ t.push({ name: o, renderFn: a });
814
864
  continue;
815
865
  }
816
866
  }
817
- const a = r.search(/\bargs\s*:/);
867
+ const c = r.search(/\bargs\s*:/);
818
868
  let l = {};
819
- if (a >= 0) {
820
- const c = r.indexOf("{", a);
821
- if (c >= 0) {
822
- const m = ce(r, c + 1);
869
+ if (c >= 0) {
870
+ const a = r.indexOf("{", c);
871
+ if (a >= 0) {
872
+ const p = $e(r, a + 1);
823
873
  try {
824
- l = le(new Function(`${Ve(e.declarations)}
825
- return {${m}}`)());
874
+ l = ye(new Function(`${$t(e.declarations)}
875
+ return {${p}}`)());
826
876
  } catch {
827
877
  try {
828
- l = le(new Function(`return {${m}}`)());
878
+ l = ye(new Function(`return {${p}}`)());
829
879
  } catch {
830
880
  l = {};
831
881
  }
@@ -836,47 +886,47 @@ return {${m}}`)());
836
886
  }
837
887
  return t;
838
888
  }
839
- function Ke(e) {
889
+ function bt(e) {
840
890
  const t = e.text.search(/\bargTypes\s*:\s*\{/);
841
891
  if (t < 0) return;
842
- const n = e.text.indexOf("{", t), s = ce(e.text, n + 1);
892
+ const s = e.text.indexOf("{", t), n = $e(e.text, s + 1);
843
893
  let o;
844
894
  try {
845
- o = le(new Function(`return {${s}}`)());
895
+ o = ye(new Function(`return {${n}}`)());
846
896
  } catch {
847
897
  try {
848
- o = le(
849
- new Function(`${Ve(e.declarations)}
850
- return {${s}}`)()
898
+ o = ye(
899
+ new Function(`${$t(e.declarations)}
900
+ return {${n}}`)()
851
901
  );
852
902
  } catch {
853
903
  return;
854
904
  }
855
905
  }
856
906
  const r = {};
857
- for (const [i, a] of Object.entries(o)) {
858
- if (!a || typeof a != "object") continue;
859
- const l = a.control, c = typeof l == "string" ? l : String(l?.type ?? ""), m = a.options ?? (typeof l == "object" ? l?.options : void 0), u = {};
860
- typeof a.description == "string" && (u.description = a.description), Array.isArray(m) ? u.enum = m : c === "boolean" ? u.type = "boolean" : c === "number" || c === "range" ? u.type = "number" : c === "text" || c === "color" || c === "date" ? u.type = "string" : c === "object" && (u.type = "object"), a.defaultValue !== void 0 && (u.default = a.defaultValue), Object.keys(u).length && (r[i] = u);
907
+ for (const [i, c] of Object.entries(o)) {
908
+ if (!c || typeof c != "object") continue;
909
+ const l = c.control, a = typeof l == "string" ? l : String(l?.type ?? ""), p = c.options ?? (typeof l == "object" ? l?.options : void 0), u = {};
910
+ typeof c.description == "string" && (u.description = c.description), Array.isArray(p) ? u.enum = p : a === "boolean" ? u.type = "boolean" : a === "number" || a === "range" ? u.type = "number" : a === "text" || a === "color" || a === "date" ? u.type = "string" : a === "object" && (u.type = "object"), c.defaultValue !== void 0 && (u.default = c.defaultValue), Object.keys(u).length && (r[i] = u);
861
911
  }
862
912
  return Object.keys(r).length ? r : void 0;
863
913
  }
864
- async function Ye(e) {
914
+ async function vt(e) {
865
915
  const t = [...e].sort();
866
916
  for (let i = 0; i < t.length; i++)
867
917
  console.log(`${String(i + 1).padStart(4)} ${t[i]}`);
868
- const n = vt({ input: process.stdin, output: process.stdout }), s = await n.question(
918
+ const s = ut({ input: process.stdin, output: process.stdout }), n = await s.question(
869
919
  "select components to import, comma separated numbers, names, or /regex/, empty imports all: "
870
920
  );
871
- n.close();
872
- const o = s.trim();
921
+ s.close();
922
+ const o = n.trim();
873
923
  if (!o) return new Set(t);
874
924
  const r = /* @__PURE__ */ new Set();
875
- for (const i of o.split(",").map((a) => a.trim()).filter(Boolean)) {
876
- const a = i.match(/^\/(.+)\/$/);
877
- if (a) {
878
- const l = new RegExp(a[1]);
879
- for (const c of t) l.test(c) && r.add(c);
925
+ for (const i of o.split(",").map((c) => c.trim()).filter(Boolean)) {
926
+ const c = i.match(/^\/(.+)\/$/);
927
+ if (c) {
928
+ const l = new RegExp(c[1]);
929
+ for (const a of t) l.test(a) && r.add(a);
880
930
  continue;
881
931
  }
882
932
  if (/^\d+$/.test(i)) {
@@ -888,154 +938,154 @@ async function Ye(e) {
888
938
  }
889
939
  return r;
890
940
  }
891
- function Qe(e, t) {
892
- const n = /* @__PURE__ */ new Map(), s = d(e, "node_modules", t, "index.mjs");
893
- if (!b(s)) return n;
894
- const o = W(s, "utf-8");
941
+ function kt(e, t) {
942
+ const s = /* @__PURE__ */ new Map(), n = d(e, "node_modules", t, "index.mjs");
943
+ if (!$(n)) return s;
944
+ const o = C(n, "utf-8");
895
945
  for (const r of o.matchAll(/export \{ default as ([A-Za-z]+) \}/g))
896
- n.set(r[1].toLowerCase(), r[1]);
897
- return n;
898
- }
899
- async function Vt(e, t, n, s) {
900
- const o = t.modules.systems[n];
901
- if (!o) throw new Error(`[nimpress] modules import: unknown system ${n}`);
902
- const r = o.framework, i = r === "vue" ? ".vue" : ".svelte", a = d(e, t.contentDir, "components"), l = o.package, c = s.match ? new RegExp(s.match) : null;
903
- if (s.file) {
904
- const g = F(e, s.file);
905
- if (!b(g)) throw new Error(`[nimpress] modules import: ${g} not found`);
906
- if (oe(g) !== i)
907
- throw new Error(`[nimpress] modules import: ${g} does not match system framework ${r}`);
908
- const y = s.name ?? C(g, i), J = o.source ? F(e, o.source) : e, _ = d(a, "Components", y);
909
- await ye(_, { recursive: !0 });
910
- const P = O(J, g);
911
- await G(d(_, "index.md"), ve(n, y, l, P)), await ne(_, y, await se(g, r, y)), console.log(`nimpress modules: imported ${y} at ${O(e, _)}`);
946
+ s.set(r[1].toLowerCase(), r[1]);
947
+ return s;
948
+ }
949
+ async function _s(e, t, s, n) {
950
+ const o = t.modules.systems[s];
951
+ if (!o) throw new Error(`[nimpress] modules import: unknown system ${s}`);
952
+ const r = o.framework, i = r === "vue" ? ".vue" : ".svelte", c = d(e, t.contentDir, "components"), l = o.package, a = n.match ? new RegExp(n.match) : null;
953
+ if (n.file) {
954
+ const y = j(e, n.file);
955
+ if (!$(y)) throw new Error(`[nimpress] modules import: ${y} not found`);
956
+ if (me(y) !== i)
957
+ throw new Error(`[nimpress] modules import: ${y} does not match system framework ${r}`);
958
+ const b = n.name ?? F(y, i), U = o.source ? j(e, o.source) : e, A = d(c, "Components", b);
959
+ await Ne(A, { recursive: !0 });
960
+ const P = D(U, y);
961
+ await Q(d(A, "index.md"), Re(s, b, l, P)), await pe(A, b, await ue(y, r, b)), console.log(`nimpress modules: imported ${b} at ${D(e, A)}`);
912
962
  return;
913
963
  }
914
- if (s.fromStories) {
915
- await qt(e, t, n, s);
964
+ if (n.fromStories) {
965
+ await Ws(e, t, s, n);
916
966
  return;
917
967
  }
918
- const m = F(e, s.source ?? o.source ?? "");
919
- if (!b(m))
920
- throw new Error(`[nimpress] modules import: source ${m} not found`);
921
- const u = ue(m), h = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map(), f = u.filter((g) => g.endsWith(".stories.ts")), w = s.stories ? [F(e, s.stories)] : [];
922
- for (const g of w)
923
- for (const y of ue(g))
924
- y.endsWith(".stories.ts") && f.push(y);
925
- const $ = u.filter(
926
- (g) => g.endsWith(i) && /^[A-Z][A-Za-z0-9]*$/.test(C(g, i))
927
- ), k = new Set($.map((g) => C(g, i))), E = l && !o.source ? Qe(e, l) : null;
928
- for (const g of f) {
929
- const y = xe(g);
930
- if (y.title?.includes("/")) {
931
- const [R, M] = y.title.split("/");
932
- h.set(M, R.replace(/\s+/g, ""));
968
+ const p = j(e, n.source ?? o.source ?? "");
969
+ if (!$(p))
970
+ throw new Error(`[nimpress] modules import: source ${p} not found`);
971
+ const u = be(p), m = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map(), h = u.filter((y) => y.endsWith(".stories.ts")), g = n.stories ? [j(e, n.stories)] : [];
972
+ for (const y of g)
973
+ for (const b of be(y))
974
+ b.endsWith(".stories.ts") && h.push(b);
975
+ const w = u.filter(
976
+ (y) => y.endsWith(i) && /^[A-Z][A-Za-z0-9]*$/.test(F(y, i))
977
+ ), v = new Set(w.map((y) => F(y, i))), O = l && !o.source ? kt(e, l) : null;
978
+ for (const y of h) {
979
+ const b = Te(y);
980
+ if (b.title?.includes("/")) {
981
+ const [J, L] = b.title.split("/");
982
+ m.set(L, J.replace(/\s+/g, ""));
933
983
  }
934
- const J = C(g, ".stories.ts");
935
- let P = b(d(L(g), `${J}${i}`)) ? J : y.metaComponent ?? J;
936
- if (!k.has(P)) {
937
- let R = "";
938
- for (const M of k)
939
- J.startsWith(M) && M.length > R.length && (R = M);
940
- R ? P = R : console.warn(`nimpress modules: ${C(g)} targets ${P} which has no component page`);
984
+ const U = F(y, ".stories.ts");
985
+ let P = $(d(_(y), `${U}${i}`)) ? U : b.metaComponent ?? U;
986
+ if (!v.has(P)) {
987
+ let J = "";
988
+ for (const L of v)
989
+ U.startsWith(L) && L.length > J.length && (J = L);
990
+ J ? P = J : console.warn(`nimpress modules: ${F(y)} targets ${P} which has no component page`);
941
991
  }
942
- const v = E?.get(P.toLowerCase()) ?? P, B = p.get(v) ?? [];
943
- B.push(y), p.set(v, B);
944
- }
945
- const j = /* @__PURE__ */ new Map();
946
- let x = 0, N = 0;
947
- const S = $.filter((g) => !c || c.test(C(g, i))), D = s.select ? await Ye(S.map((g) => C(g, i))) : null;
948
- for (const g of S) {
949
- const y = C(g, i);
950
- if (D && !D.has(y)) continue;
951
- if (j.has(y)) {
952
- console.warn(`nimpress modules: skip duplicate ${y}, kept ${j.get(y)}`);
992
+ const S = O?.get(P.toLowerCase()) ?? P, Z = f.get(S) ?? [];
993
+ Z.push(b), f.set(S, Z);
994
+ }
995
+ const E = /* @__PURE__ */ new Map();
996
+ let k = 0, T = 0;
997
+ const x = w.filter((y) => !a || a.test(F(y, i))), R = n.select ? await vt(x.map((y) => F(y, i))) : null;
998
+ for (const y of x) {
999
+ const b = F(y, i);
1000
+ if (R && !R.has(b)) continue;
1001
+ if (E.has(b)) {
1002
+ console.warn(`nimpress modules: skip duplicate ${b}, kept ${E.get(b)}`);
953
1003
  continue;
954
1004
  }
955
- j.set(y, O(m, g));
956
- const J = h.get(y) ?? "Components", _ = d(a, J, y);
957
- await ye(_, { recursive: !0 });
958
- const P = O(m, g), v = P === `${y}/${y}${i}` || P === `${y}${i}`, B = (p.get(y) ?? []).map((I) => Ke(I)).reduce(
959
- (I, Z) => Z ? { ...I ?? {}, ...Z } : I,
1005
+ E.set(b, D(p, y));
1006
+ const U = m.get(b) ?? "Components", A = d(c, U, b);
1007
+ await Ne(A, { recursive: !0 });
1008
+ const P = D(p, y), S = P === `${b}/${b}${i}` || P === `${b}${i}`, Z = (f.get(b) ?? []).map((B) => bt(B)).reduce(
1009
+ (B, q) => q ? { ...B ?? {}, ...q } : B,
960
1010
  void 0
961
1011
  );
962
- await G(d(_, "index.md"), ve(n, y, l, v ? void 0 : P)), await ne(_, y, await se(g, r, y)), B && await Ae(_, { properties: B }), x++;
963
- const R = p.get(y) ?? [], M = /* @__PURE__ */ new Set();
964
- for (const I of R) {
965
- const Z = C(I.file, ".stories.ts"), Ce = qe(I);
966
- Ce.length || console.warn(`nimpress modules: no stories mined from ${C(I.file)}`);
967
- for (const U of I.dataModules)
968
- await Re(U, d(_, C(U)));
969
- for (const U of Ce) {
970
- const Fe = U.name === y ? "Default" : Z === y ? U.name : `${Z} ${U.name}`;
971
- let ie = be(Fe);
972
- M.has(ie) && (ie = be(`${Z}-${U.name}`));
973
- const Oe = d(_, `${ie}.story.tsx`);
974
- M.add(ie), !b(Oe) && (await G(Oe, Xe(r, Fe, Z, U, I)), N++);
1012
+ await Q(d(A, "index.md"), Re(s, b, l, S ? void 0 : P)), await pe(A, b, await ue(y, r, b)), Z && await ot(A, { properties: Z }), k++;
1013
+ const J = f.get(b) ?? [], L = /* @__PURE__ */ new Set();
1014
+ for (const B of J) {
1015
+ const q = F(B.file, ".stories.ts"), ze = yt(B);
1016
+ ze.length || console.warn(`nimpress modules: no stories mined from ${F(B.file)}`);
1017
+ for (const Y of B.dataModules)
1018
+ await it(Y, d(A, F(Y)));
1019
+ for (const Y of ze) {
1020
+ const Je = Y.name === b ? "Default" : q === b ? Y.name : `${q} ${Y.name}`;
1021
+ let he = We(Je);
1022
+ L.has(he) && (he = We(`${q}-${Y.name}`));
1023
+ const Be = d(A, `${he}.story.tsx`);
1024
+ L.add(he), !$(Be) && (await Q(Be, xt(r, Je, q, Y, B)), T++);
975
1025
  }
976
1026
  }
977
1027
  }
978
- console.log(`nimpress modules: imported ${x} components with ${N} stories for ${n}`);
1028
+ console.log(`nimpress modules: imported ${k} components with ${T} stories for ${s}`);
979
1029
  }
980
- async function qt(e, t, n, s) {
981
- const o = t.modules.systems[n], r = o.framework, i = d(e, t.contentDir, "components"), a = F(e, s.stories ?? "");
982
- if (!s.stories || !b(a))
1030
+ async function Ws(e, t, s, n) {
1031
+ const o = t.modules.systems[s], r = o.framework, i = d(e, t.contentDir, "components"), c = j(e, n.stories ?? "");
1032
+ if (!n.stories || !$(c))
983
1033
  throw new Error("[nimpress] modules import --from-stories requires --stories=<csf dir>");
984
- const l = o.source ? F(e, o.source) : e, c = s.match ? new RegExp(s.match) : null, m = /* @__PURE__ */ new Set();
985
- let u = 0, h = 0;
986
- const p = ue(a).filter((w) => w.endsWith(".stories.ts")), f = s.select ? await Ye(
987
- p.map((w) => xe(w).metaComponent ?? C(w, ".stories.ts"))
1034
+ const l = o.source ? j(e, o.source) : e, a = n.match ? new RegExp(n.match) : null, p = /* @__PURE__ */ new Set();
1035
+ let u = 0, m = 0;
1036
+ const f = be(c).filter((g) => g.endsWith(".stories.ts")), h = n.select ? await vt(
1037
+ f.map((g) => Te(g).metaComponent ?? F(g, ".stories.ts"))
988
1038
  ) : null;
989
- for (const w of p) {
990
- const $ = xe(w), k = C(w, ".stories.ts"), E = $.metaComponent ?? k;
991
- if (f && !f.has(E)) continue;
992
- const j = $.text.match(
993
- new RegExp(`import\\s+(?:\\{\\s*)?${E}(?:\\s*\\})?\\s+from\\s+["']([^"']+)["']`)
1039
+ for (const g of f) {
1040
+ const w = Te(g), v = F(g, ".stories.ts"), O = w.metaComponent ?? v;
1041
+ if (h && !h.has(O)) continue;
1042
+ const E = w.text.match(
1043
+ new RegExp(`import\\s+(?:\\{\\s*)?${O}(?:\\s*\\})?\\s+from\\s+["']([^"']+)["']`)
994
1044
  )?.[1];
995
- let x = E, N = o.package, S;
996
- if (j && !j.startsWith(".") && !j.startsWith("@/")) {
997
- const v = j.split("/")[0].startsWith("@") ? j.split("/").slice(0, 2).join("/") : j.split("/")[0];
998
- N = v, x = Qe(e, v).get(E.toLowerCase()) ?? E;
999
- } else if (j?.startsWith("@/components/")) {
1000
- const v = j.slice(13);
1001
- v === x || v === `${x}/${x}.vue` || (S = v.endsWith(".vue") || v.endsWith(".svelte") ? v : `${v}/${x}.vue`);
1002
- } else if (j?.startsWith(".")) {
1003
- const v = F(L(w), j);
1004
- S = O(l, v);
1045
+ let k = O, T = o.package, x;
1046
+ if (E && !E.startsWith(".") && !E.startsWith("@/")) {
1047
+ const S = E.split("/")[0].startsWith("@") ? E.split("/").slice(0, 2).join("/") : E.split("/")[0];
1048
+ T = S, k = kt(e, S).get(O.toLowerCase()) ?? O;
1049
+ } else if (E?.startsWith("@/components/")) {
1050
+ const S = E.slice(13);
1051
+ S === k || S === `${k}/${k}.vue` || (x = S.endsWith(".vue") || S.endsWith(".svelte") ? S : `${S}/${k}.vue`);
1052
+ } else if (E?.startsWith(".")) {
1053
+ const S = j(_(g), E);
1054
+ x = D(l, S);
1005
1055
  }
1006
- if (c && !c.test(x)) continue;
1007
- if (m.has(x)) {
1008
- console.warn(`nimpress modules: skip duplicate ${x} from ${C(w)}`);
1056
+ if (a && !a.test(k)) continue;
1057
+ if (p.has(k)) {
1058
+ console.warn(`nimpress modules: skip duplicate ${k} from ${F(g)}`);
1009
1059
  continue;
1010
1060
  }
1011
- m.add(x);
1012
- const D = $.title?.includes("/") ? $.title.split("/")[0].replace(/\s+/g, "") : "Components", g = d(i, D, x);
1013
- await ye(g, { recursive: !0 }), await G(d(g, "index.md"), ve(n, x, N, S));
1014
- const y = r === "vue" ? ".vue" : ".svelte", _ = (S ? [F(l, S)] : [
1015
- d(l, x, `${x}${y}`),
1016
- d(l, `${x}${y}`)
1017
- ]).find((v) => b(v));
1018
- if (_)
1019
- await ne(g, x, await se(_, r, x));
1020
- else if (N) {
1021
- const v = ft(e, N, x);
1022
- v ? await ne(g, x, dt(W(v, "utf-8"), x)) : console.warn(`nimpress modules: no source or d.ts found for ${x}, the schema seed is skipped`);
1061
+ p.add(k);
1062
+ const R = w.title?.includes("/") ? w.title.split("/")[0].replace(/\s+/g, "") : "Components", y = d(i, R, k);
1063
+ await Ne(y, { recursive: !0 }), await Q(d(y, "index.md"), Re(s, k, T, x));
1064
+ const b = r === "vue" ? ".vue" : ".svelte", A = (x ? [j(l, x)] : [
1065
+ d(l, k, `${k}${b}`),
1066
+ d(l, `${k}${b}`)
1067
+ ]).find((S) => $(S));
1068
+ if (A)
1069
+ await pe(y, k, await ue(A, r, k));
1070
+ else if (T) {
1071
+ const S = Qt(e, T, k);
1072
+ S ? await pe(y, k, Xt(C(S, "utf-8"), k)) : console.warn(`nimpress modules: no source or d.ts found for ${k}, the schema seed is skipped`);
1023
1073
  }
1024
- const P = Ke($);
1025
- P && await Ae(g, { properties: P }), u++;
1026
- for (const v of $.dataModules)
1027
- await Re(v, d(g, C(v)));
1028
- for (const v of qe($)) {
1029
- const B = v.name === x ? "Default" : v.name, R = be(B), M = d(g, `${R}.story.tsx`);
1030
- b(M) || (await G(M, Xe(r, B, k, v, $)), h++);
1074
+ const P = bt(w);
1075
+ P && await ot(y, { properties: P }), u++;
1076
+ for (const S of w.dataModules)
1077
+ await it(S, d(y, F(S)));
1078
+ for (const S of yt(w)) {
1079
+ const Z = S.name === k ? "Default" : S.name, J = We(Z), L = d(y, `${J}.story.tsx`);
1080
+ $(L) || (await Q(L, xt(r, Z, v, S, w)), m++);
1031
1081
  }
1032
1082
  }
1033
- console.log(`nimpress modules: imported ${u} components with ${h} stories for ${n} from stories`);
1083
+ console.log(`nimpress modules: imported ${u} components with ${m} stories for ${s} from stories`);
1034
1084
  }
1035
- function ve(e, t, n, s) {
1036
- const o = n ? `
1037
- package: "${n}"` : "", r = s ? `
1038
- file: ${JSON.stringify(s)}` : "";
1085
+ function Re(e, t, s, n) {
1086
+ const o = s ? `
1087
+ package: "${s}"` : "", r = n ? `
1088
+ file: ${JSON.stringify(n)}` : "";
1039
1089
  return `---
1040
1090
  title: ${t}
1041
1091
  type: component
@@ -1047,13 +1097,13 @@ data:
1047
1097
  ## Usage
1048
1098
 
1049
1099
  \`\`\`ts
1050
- import { ${t} } from "${n ?? e}";
1100
+ import { ${t} } from "${s ?? e}";
1051
1101
  \`\`\`
1052
1102
  `;
1053
1103
  }
1054
- function Xe(e, t, n, s, o) {
1104
+ function xt(e, t, s, n, o) {
1055
1105
  const r = e === "vue" ? "vueStory" : "svelteStory";
1056
- return s.renderFn ? `import { ${r} } from '@nimtech/nimpress/story'
1106
+ return n.renderFn ? `import { ${r} } from '@nimtech/nimpress/story'
1057
1107
  ${o.imports}
1058
1108
 
1059
1109
  ${o.declarations}
@@ -1061,212 +1111,230 @@ ${o.declarations}
1061
1111
  // story: ${t}
1062
1112
  export default ${r}({
1063
1113
  name: ${JSON.stringify(t)},
1064
- description: ${JSON.stringify(`Scenario from ${n}`)},
1065
- render: ${s.renderFn}
1114
+ description: ${JSON.stringify(`Scenario from ${s}`)},
1115
+ render: ${n.renderFn}
1066
1116
  })
1067
1117
  ` : `import { ${r} } from '@nimtech/nimpress/story'
1068
1118
 
1069
1119
  // story: ${t}
1070
1120
  export default ${r}({
1071
1121
  name: ${JSON.stringify(t)},
1072
- props: ${JSON.stringify(s.props ?? {}, null, 2)}
1122
+ props: ${JSON.stringify(n.props ?? {}, null, 2)}
1073
1123
  })
1074
1124
  `;
1075
1125
  }
1076
- function te(e, t) {
1077
- const n = T(t, "system");
1078
- if (n === void 0) return;
1079
- const s = Object.keys(e.modules.systems);
1080
- if (!s.includes(n))
1081
- throw new Error(`[nimpress] modules: unknown system ${n}, configured: ${s.join(", ") || "none"}`);
1082
- return n;
1083
- }
1084
- function de(e, t, n) {
1085
- const s = te(e, t);
1086
- if (s) return s;
1126
+ function le(e, t) {
1127
+ const s = N(t, "system");
1128
+ if (s === void 0) return;
1129
+ const n = Object.keys(e.modules.systems);
1130
+ if (!n.includes(s))
1131
+ throw new Error(`[nimpress] modules: unknown system ${s}, configured: ${n.join(", ") || "none"}`);
1132
+ return s;
1133
+ }
1134
+ function je(e, t, s) {
1135
+ const n = le(e, t);
1136
+ if (n) return n;
1087
1137
  const o = Object.keys(e.modules.systems);
1088
1138
  if (o.length === 1) return o[0];
1089
1139
  throw o.length ? new Error(
1090
- `[nimpress] modules ${n}: several systems configured (${o.join(", ")}), pass --system=<name>`
1091
- ) : new Error(`[nimpress] modules ${n}: no systems configured`);
1140
+ `[nimpress] modules ${s}: several systems configured (${o.join(", ")}), pass --system=<name>`
1141
+ ) : new Error(`[nimpress] modules ${s}: no systems configured`);
1092
1142
  }
1093
- async function Kt(e, t, n) {
1094
- const s = n[0], o = n.slice(1), r = Object.keys(t.modules.systems);
1095
- if (s === "init") {
1096
- Yt(e, t);
1143
+ async function Ts(e, t, s) {
1144
+ const n = s[0], o = s.slice(1), r = Object.keys(t.modules.systems);
1145
+ if (n === "init") {
1146
+ Rs(e, t);
1097
1147
  return;
1098
1148
  }
1099
- if (s === "dev") {
1100
- const i = te(t, o), a = i ? [i] : r;
1101
- if (!a.length) throw new Error("[nimpress] modules dev: no systems configured");
1102
- await Ue(e, t, a), await new Promise(() => {
1149
+ if (n === "dev") {
1150
+ const i = le(t, o), c = i ? [i] : r;
1151
+ if (!c.length) throw new Error("[nimpress] modules dev: no systems configured");
1152
+ await dt(e, t, c), await new Promise(() => {
1103
1153
  });
1104
1154
  }
1105
- if (s === "build") {
1106
- const i = te(t, o), a = i ? [i] : Be(t);
1107
- if (!a.length) throw new Error("[nimpress] modules build: no systems configured");
1108
- await Ge(e, t, a);
1155
+ if (n === "build") {
1156
+ const i = le(t, o), c = i ? [i] : ft(t);
1157
+ if (!c.length) throw new Error("[nimpress] modules build: no systems configured");
1158
+ await ht(e, t, c);
1109
1159
  return;
1110
1160
  }
1111
- if (s === "lint") {
1112
- const i = await Je(e, t, te(t, o));
1113
- we("nimpress modules lint", i, "nimpress modules lint: systems, schemas, and stories ok");
1161
+ if (n === "lint") {
1162
+ const i = await mt(e, t, le(t, o));
1163
+ _e("nimpress modules lint", i, "nimpress modules lint: systems, schemas, and stories ok");
1114
1164
  return;
1115
1165
  }
1116
- if (s === "story") {
1117
- const i = de(t, o, "story"), a = ee(o, 0), l = T(o, "framework");
1118
- if (a) {
1119
- const m = await je(e, t, i, a, l);
1120
- m && console.log(`nimpress modules: story written to ${m}`);
1166
+ if (n === "story") {
1167
+ const i = je(t, o, "story"), c = re(o, 0), l = N(o, "framework");
1168
+ if (c) {
1169
+ const p = await Le(e, t, i, c, l);
1170
+ p && console.log(`nimpress modules: story written to ${p}`);
1121
1171
  return;
1122
1172
  }
1123
- const c = await Gt(e, t, i);
1124
- console.log(`nimpress modules: ${c} auto stories written for ${i}`);
1173
+ const a = await Fs(e, t, i);
1174
+ console.log(`nimpress modules: ${a} auto stories written for ${i}`);
1125
1175
  return;
1126
1176
  }
1127
- if (s === "import") {
1128
- const i = de(t, o, "import"), a = ee(o, 0);
1129
- await Vt(e, t, i, {
1130
- file: a,
1131
- name: T(o, "name"),
1132
- source: T(o, "source"),
1133
- stories: T(o, "stories"),
1134
- match: T(o, "match"),
1177
+ if (n === "import") {
1178
+ const i = je(t, o, "import"), c = re(o, 0);
1179
+ await _s(e, t, i, {
1180
+ file: c,
1181
+ name: N(o, "name"),
1182
+ source: N(o, "source"),
1183
+ stories: N(o, "stories"),
1184
+ match: N(o, "match"),
1135
1185
  fromStories: o.includes("--from-stories"),
1136
1186
  select: o.includes("--select")
1137
- }), $e(e);
1187
+ }), De(e);
1138
1188
  return;
1139
1189
  }
1140
- if (s === "update") {
1141
- const i = T(o, "component") ?? ee(o, 0), a = await ht(e, t, { ref: i, system: te(t, o) });
1142
- console.log(`nimpress modules: ${a} schema${a === 1 ? "" : "s"} upserted`), $e(e);
1190
+ if (n === "update") {
1191
+ const i = N(o, "component") ?? re(o, 0), c = await qt(e, t, { ref: i, system: le(t, o) });
1192
+ console.log(`nimpress modules: ${c} schema${c === 1 ? "" : "s"} upserted`), De(e);
1143
1193
  return;
1144
1194
  }
1145
- if (s === "create") {
1146
- const i = T(o, "component");
1195
+ if (n === "create") {
1196
+ const i = N(o, "component");
1147
1197
  if (i) {
1148
- if (!X(o, "schema"))
1198
+ if (!M(o, "schema"))
1149
1199
  throw new Error("[nimpress] modules create --component expects --schema to upsert the schema");
1150
- const u = await gt(e, t, i);
1200
+ const u = await es(e, t, i);
1151
1201
  console.log(`nimpress modules: schema upserted at ${u}`);
1152
1202
  return;
1153
1203
  }
1154
- const a = ee(o, 0);
1155
- if (!a)
1204
+ const c = re(o, 0);
1205
+ if (!c)
1156
1206
  throw new Error("[nimpress] modules create expects: nimpress modules create <Component> [--system=<name>], or --component=<ref> --schema");
1157
- const l = de(t, o, "create"), c = T(o, "framework"), m = await Ht(e, t, l, a, c);
1158
- console.log(`nimpress modules: created ${a} at ${O(e, m)}`);
1207
+ const l = je(t, o, "create"), a = N(o, "framework"), p = await Ds(e, t, l, c, a);
1208
+ console.log(`nimpress modules: created ${c} at ${D(e, p)}`);
1159
1209
  return;
1160
1210
  }
1161
1211
  throw new Error("[nimpress] modules expects init, dev, build, lint, story, import, create or update");
1162
1212
  }
1163
- function Yt(e, t) {
1164
- const n = d(e, t.modules.dir);
1165
- Q(n, { recursive: !0 });
1166
- const s = d(e, "nimpress.config.json");
1167
- if (b(s)) {
1168
- const o = JSON.parse(W(s, "utf-8"));
1169
- o.modules || (o.modules = { dir: t.modules.dir, route: t.modules.route, systems: {} }, A(s, JSON.stringify(o, null, 2) + `
1170
- `), console.log(`nimpress modules: modules block added to ${s}`));
1213
+ function Rs(e, t) {
1214
+ const s = d(e, t.modules.dir);
1215
+ H(s, { recursive: !0 });
1216
+ const n = d(e, "nimpress.config.json");
1217
+ if ($(n)) {
1218
+ const o = JSON.parse(C(n, "utf-8"));
1219
+ o.modules || (o.modules = { dir: t.modules.dir, route: t.modules.route, systems: {} }, W(n, JSON.stringify(o, null, 2) + `
1220
+ `), console.log(`nimpress modules: modules block added to ${n}`));
1171
1221
  } else
1172
1222
  console.log("nimpress modules: add a modules block with systems entries to your nimpress config");
1173
- console.log(`nimpress modules: folder ready at ${n}`);
1223
+ console.log(`nimpress modules: folder ready at ${s}`);
1174
1224
  }
1175
- function et(e) {
1225
+ function St(e) {
1176
1226
  if (!e.startsWith(`---
1177
1227
  `)) return null;
1178
1228
  const t = e.indexOf(`
1179
1229
  ---`, 4);
1180
1230
  return t < 0 ? null : e.slice(4, t);
1181
1231
  }
1182
- function Qt(e) {
1232
+ function As(e) {
1183
1233
  for (const t of e.split(`
1184
1234
  `)) {
1185
1235
  if (!t.startsWith("export:")) continue;
1186
- const n = t.slice(7).trim().replace(/^["']|["']$/g, "");
1187
- return n === "" || n === "false" ? null : n;
1236
+ const s = t.slice(7).trim().replace(/^["']|["']$/g, "");
1237
+ return s === "" || s === "false" ? null : s;
1188
1238
  }
1189
1239
  return null;
1190
1240
  }
1191
- function Xt(e, t) {
1192
- const n = et(e);
1193
- if (n === null) return e;
1194
- const s = n.split(`
1195
- `).filter((r) => !r.startsWith("export:") && !r.startsWith(" file:")), o = s.findIndex((r) => r.startsWith(" package:"));
1196
- return t && o >= 0 && !s.some((r) => r.startsWith(" version:")) && s.splice(o + 1, 0, ` version: ${JSON.stringify(t)}`), `---
1197
- ${s.join(`
1198
- `)}${e.slice(4 + n.length)}`;
1199
- }
1200
- function es(e, t, n) {
1201
- const s = T(n, "target") ?? "", o = d(e, T(n, "out") ?? t.paths.export), r = d(e, t.contentDir);
1241
+ function Ps(e, t) {
1242
+ const s = St(e);
1243
+ if (s === null) return e;
1244
+ const n = s.split(`
1245
+ `).filter((r) => !r.startsWith("export:") && !r.startsWith(" file:")), o = n.findIndex((r) => r.startsWith(" package:"));
1246
+ return t && o >= 0 && !n.some((r) => r.startsWith(" version:")) && n.splice(o + 1, 0, ` version: ${JSON.stringify(t)}`), `---
1247
+ ${n.join(`
1248
+ `)}${e.slice(4 + s.length)}`;
1249
+ }
1250
+ function Ae(e, t, s) {
1251
+ const n = N(s, "target") ?? "", o = d(e, N(s, "out") ?? t.paths.export), r = d(e, t.contentDir);
1202
1252
  let i = "";
1203
1253
  try {
1204
- i = JSON.parse(W(d(e, "package.json"), "utf-8")).version ?? "";
1254
+ i = JSON.parse(C(d(e, "package.json"), "utf-8")).version ?? "";
1205
1255
  } catch {
1206
1256
  i = "";
1207
1257
  }
1208
- let a = 0;
1209
- for (const l of re(r)) {
1258
+ let c = 0;
1259
+ for (const l of oe(r)) {
1210
1260
  if (!l.endsWith(".md")) continue;
1211
- const c = W(l, "utf-8"), m = et(c);
1212
- if (m === null) continue;
1213
- const u = Qt(m);
1214
- if (u === null || s && u !== s && u !== "true") continue;
1215
- const h = L(l), p = d(o, O(r, h));
1216
- Q(p, { recursive: !0 });
1217
- for (const f of Y(h, { withFileTypes: !0 })) {
1218
- if (!f.isFile()) continue;
1219
- const w = W(d(h, f.name), "utf-8");
1220
- A(
1221
- d(p, f.name),
1222
- f.name.endsWith(".md") ? Xt(w, i) : w
1261
+ const a = C(l, "utf-8"), p = St(a);
1262
+ if (p === null) continue;
1263
+ const u = As(p);
1264
+ if (u === null || n && u !== n && u !== "true") continue;
1265
+ const m = _(l), f = d(o, D(r, m));
1266
+ H(f, { recursive: !0 });
1267
+ for (const h of se(m, { withFileTypes: !0 })) {
1268
+ if (!h.isFile()) continue;
1269
+ const g = C(d(m, h.name), "utf-8");
1270
+ W(
1271
+ d(f, h.name),
1272
+ h.name.endsWith(".md") ? Ps(g, i) : g
1223
1273
  );
1224
1274
  }
1225
- a++;
1275
+ c++;
1226
1276
  }
1227
- console.log(`nimpress export: ${a} pages collected into ${o}`);
1277
+ console.log(`nimpress export: ${c} pages collected into ${o}`);
1228
1278
  }
1229
- const he = d(".claude", "skills", "nimpress", "SKILL.md");
1230
- function tt() {
1231
- const e = L(kt(import.meta.url)), t = [
1232
- F(e, he),
1233
- F(e, "..", he),
1234
- F(e, "..", "..", he)
1279
+ const Ce = d(".claude", "skills", "nimpress", "SKILL.md");
1280
+ function jt() {
1281
+ const e = _(pt(import.meta.url)), t = [
1282
+ j(e, Ce),
1283
+ j(e, "..", Ce),
1284
+ j(e, "..", "..", Ce)
1235
1285
  ];
1236
- for (const n of t)
1286
+ for (const s of t)
1237
1287
  try {
1238
- return W(n, "utf-8");
1288
+ return C(s, "utf-8");
1239
1289
  } catch {
1240
1290
  }
1241
1291
  throw new Error(`[nimpress] skill: SKILL.md not found, looked in ${t.join(", ")}`);
1242
1292
  }
1243
- function st(e, t) {
1244
- const n = t ? d(Le(), ".claude") : d(e, ".claude"), s = d(n, "skills", "nimpress");
1245
- Q(s, { recursive: !0 });
1246
- const o = d(s, "SKILL.md");
1247
- return A(o, tt()), console.log(`wrote ${o}`), o;
1293
+ function Ct(e, t) {
1294
+ const s = t ? d(K(), ".claude") : d(e, ".claude"), n = d(s, "skills", "nimpress");
1295
+ H(n, { recursive: !0 });
1296
+ const o = d(n, "SKILL.md");
1297
+ return W(o, jt()), console.log(`wrote ${o}`), o;
1248
1298
  }
1249
- function ts(e, t) {
1250
- const n = t[0];
1251
- if (n === "get") {
1252
- process.stdout.write(tt());
1299
+ function Ms(e, t) {
1300
+ const s = t[0];
1301
+ if (s === "get") {
1302
+ process.stdout.write(jt());
1253
1303
  return;
1254
1304
  }
1255
- if (n === "put") {
1256
- st(e, !X(t, "project"));
1305
+ if (s === "put") {
1306
+ Ct(e, !M(t, "project"));
1257
1307
  return;
1258
1308
  }
1259
1309
  throw new Error("[nimpress] skill expects get or put");
1260
1310
  }
1261
- const V = {
1311
+ const Is = "nimling/nimpress", Ls = "nimpress@nimpress";
1312
+ function Ve(e, t) {
1313
+ console.log(`claude ${t.join(" ")}`);
1314
+ const s = X("claude", t, { cwd: e, stdio: "inherit" });
1315
+ if (s.error) throw new Error(`[nimpress] plugin: could not run claude, install Claude Code first: ${s.error.message}`);
1316
+ if (s.status !== 0) throw new Error(`[nimpress] plugin: claude ${t.join(" ")} exited with ${s.status}`);
1317
+ }
1318
+ function zs(e, t) {
1319
+ const s = t ? "user" : "project";
1320
+ Ve(e, ["plugin", "marketplace", "add", Is, "--scope", s]), Ve(e, ["plugin", "install", Ls, "--scope", s]);
1321
+ }
1322
+ function Js(e, t) {
1323
+ if (t[0] === "put") {
1324
+ zs(e, !M(t, "project"));
1325
+ return;
1326
+ }
1327
+ throw new Error("[nimpress] plugin expects put");
1328
+ }
1329
+ const ee = {
1262
1330
  name: "--system",
1263
1331
  value: !0,
1264
1332
  describe: "the configured component system to act on"
1265
- }, We = {
1333
+ }, Ke = {
1266
1334
  name: "--framework",
1267
1335
  value: !0,
1268
1336
  describe: "vue or svelte, overriding the framework of the system"
1269
- }, H = [
1337
+ }, V = [
1270
1338
  {
1271
1339
  name: "init",
1272
1340
  describe: "Write the config, the content folder, and the agent guide",
@@ -1276,7 +1344,7 @@ const V = {
1276
1344
  {
1277
1345
  name: "dev",
1278
1346
  describe: "Serve the site and every component harness",
1279
- flags: [],
1347
+ flags: [{ name: "--view", value: !1, describe: "serve the central docs site with this repo's exported pages in place" }],
1280
1348
  subs: []
1281
1349
  },
1282
1350
  {
@@ -1291,21 +1359,27 @@ const V = {
1291
1359
  flags: [{ name: "--no-build", value: !1, describe: "stop after the checks and skip the verification build" }],
1292
1360
  subs: []
1293
1361
  },
1362
+ {
1363
+ name: "seo",
1364
+ describe: "Report the search and robot metadata of every page, and write the generated fields",
1365
+ flags: [{ name: "--write", value: !1, describe: "put the generated keywords and description into the frontmatter where the page has none" }, { name: "--out", value: !0, describe: "where the map is written instead of seo.map.json" }],
1366
+ subs: []
1367
+ },
1294
1368
  {
1295
1369
  name: "modules",
1296
1370
  describe: "Drive the component workshop",
1297
1371
  flags: [],
1298
1372
  subs: [
1299
1373
  { name: "init", describe: "Create the modules folder and the config block", flags: [], subs: [] },
1300
- { name: "dev", describe: "Serve the harnesses and stay running", flags: [V], subs: [] },
1301
- { name: "build", describe: "Build the harness bundles", flags: [V], subs: [] },
1302
- { name: "lint", describe: "Check the systems, the schemas, and the stories", flags: [V], subs: [] },
1303
- { name: "story", describe: "Write auto stories for one component or for every component", flags: [V, We], subs: [] },
1374
+ { name: "dev", describe: "Serve the harnesses and stay running", flags: [ee], subs: [] },
1375
+ { name: "build", describe: "Build the harness bundles", flags: [ee], subs: [] },
1376
+ { name: "lint", describe: "Check the systems, the schemas, and the stories", flags: [ee], subs: [] },
1377
+ { name: "story", describe: "Write auto stories for one component or for every component", flags: [ee, Ke], subs: [] },
1304
1378
  {
1305
1379
  name: "import",
1306
1380
  describe: "Import components and storybook stories into component pages",
1307
1381
  flags: [
1308
- V,
1382
+ ee,
1309
1383
  { name: "--name", value: !0, describe: "the component name when a single file is imported" },
1310
1384
  { name: "--source", value: !0, describe: "the component source root, overriding the system source" },
1311
1385
  { name: "--stories", value: !0, describe: "an extra folder of storybook csf files" },
@@ -1319,8 +1393,8 @@ const V = {
1319
1393
  name: "create",
1320
1394
  describe: "Create a component page, or upsert one schema",
1321
1395
  flags: [
1322
- V,
1323
- We,
1396
+ ee,
1397
+ Ke,
1324
1398
  { name: "--component", value: !0, describe: "the component reference whose schema is upserted" },
1325
1399
  { name: "--schema", value: !1, describe: "required with --component, upserts the schema" }
1326
1400
  ],
@@ -1329,7 +1403,7 @@ const V = {
1329
1403
  {
1330
1404
  name: "update",
1331
1405
  describe: "Upsert the component schemas from the component types",
1332
- flags: [V, { name: "--component", value: !0, describe: "limit the upsert to one component reference" }],
1406
+ flags: [ee, { name: "--component", value: !0, describe: "limit the upsert to one component reference" }],
1333
1407
  subs: []
1334
1408
  }
1335
1409
  ]
@@ -1343,6 +1417,35 @@ const V = {
1343
1417
  ],
1344
1418
  subs: []
1345
1419
  },
1420
+ {
1421
+ name: "view",
1422
+ describe: "Preview the export folder inside the central docs site it publishes to",
1423
+ flags: [
1424
+ { name: "--no-browser", value: !1, describe: "print the url instead of opening a browser" },
1425
+ { name: "--docs-repo", value: !0, describe: "the docs site as owner/repo or a url when the workflows do not name it" },
1426
+ { name: "--export-dir", value: !0, describe: "the export folder when no workflow names it" },
1427
+ { name: "--target", value: !0, describe: "the export target name when the repo has a nimpress config" },
1428
+ { name: "--offline", value: !1, describe: "serve from the cached clone without fetching" }
1429
+ ],
1430
+ subs: []
1431
+ },
1432
+ {
1433
+ name: "cache",
1434
+ describe: "Clear the links and clones view keeps, and the local cache root",
1435
+ flags: [],
1436
+ subs: [
1437
+ {
1438
+ name: "clear",
1439
+ describe: "Clear the links, the docs site clones, or the local cache root",
1440
+ flags: [
1441
+ { name: "--links", value: !1, describe: "clear only the links and login methods" },
1442
+ { name: "--sites", value: !1, describe: "clear only the docs site clones" },
1443
+ { name: "--local", value: !1, describe: "clear only the cache root of the current repo" }
1444
+ ],
1445
+ subs: []
1446
+ }
1447
+ ]
1448
+ },
1346
1449
  {
1347
1450
  name: "guard",
1348
1451
  describe: "Wire the gated pages to the auth provider artifacts",
@@ -1382,6 +1485,25 @@ const V = {
1382
1485
  }
1383
1486
  ]
1384
1487
  },
1488
+ {
1489
+ name: "plugin",
1490
+ describe: "The claude plugin that carries the skill and the nimpress mcp server",
1491
+ flags: [],
1492
+ subs: [
1493
+ {
1494
+ name: "put",
1495
+ describe: "Add the nimpress marketplace and install the plugin for the user, or for the current project with --project",
1496
+ flags: [{ name: "--project", value: !1, describe: "install into the project settings of the current directory instead of the user settings" }],
1497
+ subs: []
1498
+ }
1499
+ ]
1500
+ },
1501
+ {
1502
+ name: "mcp",
1503
+ describe: "Serve every command as a tool over the model context protocol on stdio",
1504
+ flags: [],
1505
+ subs: []
1506
+ },
1385
1507
  {
1386
1508
  name: "completion",
1387
1509
  describe: "Print the shell completion script, or wire it up with --auto",
@@ -1396,55 +1518,55 @@ const V = {
1396
1518
  { name: "powershell", describe: "the powershell completion script", flags: [], subs: [] }
1397
1519
  ]
1398
1520
  }
1399
- ], nt = ["bash", "zsh", "fish", "powershell"];
1400
- function me(e) {
1521
+ ], Et = ["bash", "zsh", "fish", "powershell"];
1522
+ function ke(e) {
1401
1523
  const t = [];
1402
- for (const n of [...e.flags, ...e.subs.flatMap((s) => s.flags)])
1403
- t.some((s) => s.name === n.name) || t.push(n);
1524
+ for (const s of [...e.flags, ...e.subs.flatMap((n) => n.flags)])
1525
+ t.some((n) => n.name === s.name) || t.push(s);
1404
1526
  return t;
1405
1527
  }
1406
- function pe(e, t) {
1528
+ function xe(e, t) {
1407
1529
  return t && e.value ? `${e.name}=` : e.name;
1408
1530
  }
1409
- function ss() {
1531
+ function Bs() {
1410
1532
  const e = ["_nimpress() {", ' local cur="${COMP_WORDS[COMP_CWORD]}"'];
1411
- e.push(` local words="${H.map((t) => t.name).join(" ")}"`), e.push(' if [ "$COMP_CWORD" -gt 1 ]; then'), e.push(' case "${COMP_WORDS[1]}" in');
1412
- for (const t of H) {
1413
- const n = [...t.subs.map((s) => s.name), ...me(t).map((s) => pe(s, !1))];
1414
- e.push(` ${t.name}) words="${n.join(" ")}" ;;`);
1533
+ e.push(` local words="${V.map((t) => t.name).join(" ")}"`), e.push(' if [ "$COMP_CWORD" -gt 1 ]; then'), e.push(' case "${COMP_WORDS[1]}" in');
1534
+ for (const t of V) {
1535
+ const s = [...t.subs.map((n) => n.name), ...ke(t).map((n) => xe(n, !1))];
1536
+ e.push(` ${t.name}) words="${s.join(" ")}" ;;`);
1415
1537
  }
1416
1538
  return e.push(' *) words="" ;;'), e.push(" esac"), e.push(" fi"), e.push(' COMPREPLY=( $(compgen -W "$words" -- "$cur") )'), e.push("}"), e.push("complete -o default -F _nimpress nimpress"), e.join(`
1417
1539
  `) + `
1418
1540
  `;
1419
1541
  }
1420
- function ge(e, t, n) {
1421
- const s = [`${e}entries=(`];
1422
- for (const o of n) s.push(`${e} ${o}`);
1423
- return s.push(`${e})`), s.push(`${e}_describe '${t}' entries`), s.push(`${e}return`), s;
1542
+ function Ee(e, t, s) {
1543
+ const n = [`${e}entries=(`];
1544
+ for (const o of s) n.push(`${e} ${o}`);
1545
+ return n.push(`${e})`), n.push(`${e}_describe '${t}' entries`), n.push(`${e}return`), n;
1424
1546
  }
1425
- function ns() {
1547
+ function Gs() {
1426
1548
  const e = ["#compdef nimpress", "", "_nimpress() {", " local -a entries", " if (( CURRENT == 2 )); then"];
1427
1549
  e.push(
1428
- ...ge(
1550
+ ...Ee(
1429
1551
  " ",
1430
1552
  "nimpress command",
1431
- H.map((t) => `'${t.name}:${t.describe}'`)
1553
+ V.map((t) => `'${t.name}:${t.describe}'`)
1432
1554
  )
1433
1555
  ), e.push(" fi"), e.push(' case "$words[2]" in');
1434
- for (const t of H) {
1556
+ for (const t of V) {
1435
1557
  e.push(` ${t.name})`), t.subs.length && (e.push(" if (( CURRENT == 3 )); then"), e.push(
1436
- ...ge(
1558
+ ...Ee(
1437
1559
  " ",
1438
1560
  `${t.name} argument`,
1439
- t.subs.map((s) => `'${s.name}:${s.describe}'`)
1561
+ t.subs.map((n) => `'${n.name}:${n.describe}'`)
1440
1562
  )
1441
1563
  ), e.push(" fi"));
1442
- const n = me(t);
1443
- n.length ? e.push(
1444
- ...ge(
1564
+ const s = ke(t);
1565
+ s.length ? e.push(
1566
+ ...Ee(
1445
1567
  " ",
1446
1568
  "nimpress flag",
1447
- n.map((s) => `'${pe(s, !0)}:${s.describe}'`)
1569
+ s.map((n) => `'${xe(n, !0)}:${n.describe}'`)
1448
1570
  )
1449
1571
  ) : e.push(" return"), e.push(" ;;");
1450
1572
  }
@@ -1452,153 +1574,700 @@ function ns() {
1452
1574
  `) + `
1453
1575
  `;
1454
1576
  }
1455
- function os() {
1577
+ function Hs() {
1456
1578
  const e = ["complete -c nimpress -f"];
1457
- for (const t of H)
1579
+ for (const t of V)
1458
1580
  e.push(
1459
1581
  `complete -c nimpress -n '__fish_use_subcommand' -a '${t.name}' -d '${t.describe}'`
1460
1582
  );
1461
- for (const t of H) {
1462
- const n = `__fish_seen_subcommand_from ${t.name}`;
1463
- for (const s of t.subs)
1464
- e.push(`complete -c nimpress -n '${n}' -a '${s.name}' -d '${s.describe}'`);
1465
- for (const s of me(t))
1583
+ for (const t of V) {
1584
+ const s = `__fish_seen_subcommand_from ${t.name}`;
1585
+ for (const n of t.subs)
1586
+ e.push(`complete -c nimpress -n '${s}' -a '${n.name}' -d '${n.describe}'`);
1587
+ for (const n of ke(t))
1466
1588
  e.push(
1467
- `complete -c nimpress -n '${n}' -a '${pe(s, !0)}' -d '${s.describe}'`
1589
+ `complete -c nimpress -n '${s}' -a '${xe(n, !0)}' -d '${n.describe}'`
1468
1590
  );
1469
1591
  }
1470
1592
  return e.join(`
1471
1593
  `) + `
1472
1594
  `;
1473
1595
  }
1474
- function rs() {
1596
+ function Us() {
1475
1597
  const e = [
1476
1598
  "Register-ArgumentCompleter -Native -CommandName nimpress -ScriptBlock {",
1477
1599
  " param($wordToComplete, $commandAst, $cursorPosition)",
1478
1600
  " $words = @($commandAst.CommandElements | ForEach-Object { $_.ToString() })",
1479
1601
  " $candidates = @()",
1480
1602
  " if ($words.Count -le 2) {",
1481
- ` $candidates = @(${H.map((t) => `'${t.name}'`).join(", ")})`,
1603
+ ` $candidates = @(${V.map((t) => `'${t.name}'`).join(", ")})`,
1482
1604
  " } else {",
1483
1605
  " switch ($words[1]) {"
1484
1606
  ];
1485
- for (const t of H) {
1486
- const n = [...t.subs.map((s) => s.name), ...me(t).map((s) => pe(s, !0))];
1487
- e.push(` '${t.name}' { $candidates = @(${n.map((s) => `'${s}'`).join(", ")}) }`);
1607
+ for (const t of V) {
1608
+ const s = [...t.subs.map((n) => n.name), ...ke(t).map((n) => xe(n, !0))];
1609
+ e.push(` '${t.name}' { $candidates = @(${s.map((n) => `'${n}'`).join(", ")}) }`);
1488
1610
  }
1489
1611
  return e.push(" }"), e.push(" }"), e.push(' $candidates | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {'), e.push(" [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)"), e.push(" }"), e.push("}"), e.join(`
1490
1612
  `) + `
1491
1613
  `;
1492
1614
  }
1493
- function ot(e) {
1494
- if (e === "bash") return ss();
1495
- if (e === "zsh") return ns();
1496
- if (e === "fish") return os();
1497
- if (e === "powershell") return rs();
1498
- throw new Error(`[nimpress] completion: unsupported shell ${e}, use ${nt.join(", ")}`);
1615
+ function Ot(e) {
1616
+ if (e === "bash") return Bs();
1617
+ if (e === "zsh") return Gs();
1618
+ if (e === "fish") return Hs();
1619
+ if (e === "powershell") return Us();
1620
+ throw new Error(`[nimpress] completion: unsupported shell ${e}, use ${Et.join(", ")}`);
1499
1621
  }
1500
- function is() {
1501
- const e = C(process.env.SHELL ?? "");
1622
+ function Zs() {
1623
+ const e = F(process.env.SHELL ?? "");
1502
1624
  for (const t of ["zsh", "bash", "fish"])
1503
1625
  if (e.includes(t)) return t;
1504
1626
  return "";
1505
1627
  }
1506
- function as(e, t) {
1507
- const n = "# >>> nimpress completion >>>", s = "# <<< nimpress completion <<<", o = `${n}
1628
+ function Vs(e, t) {
1629
+ const s = "# >>> nimpress completion >>>", n = "# <<< nimpress completion <<<", o = `${s}
1508
1630
  ${t}
1509
- ${s}`, r = e.indexOf(n), i = e.indexOf(s);
1510
- return r >= 0 && i > r ? e.slice(0, r) + o + e.slice(i + s.length) : r >= 0 ? e.replace(/\n+$/, "") + `
1631
+ ${n}`, r = e.indexOf(s), i = e.indexOf(n);
1632
+ return r >= 0 && i > r ? e.slice(0, r) + o + e.slice(i + n.length) : r >= 0 ? e.replace(/\n+$/, "") + `
1511
1633
  ` + o + `
1512
1634
  ` : (e === "" || e.endsWith(`
1513
1635
  `) ? e : e + `
1514
1636
  `) + o + `
1515
1637
  `;
1516
1638
  }
1517
- function cs(e, t) {
1518
- let n = "";
1639
+ function Ks(e, t) {
1640
+ let s = "";
1519
1641
  try {
1520
- n = W(e, "utf-8");
1642
+ s = C(e, "utf-8");
1521
1643
  } catch {
1522
- n = "";
1644
+ s = "";
1523
1645
  }
1524
- A(e, as(n, t));
1646
+ W(e, Vs(s, t));
1525
1647
  }
1526
- function ls(e) {
1527
- const t = e || is();
1648
+ function Ys(e) {
1649
+ const t = e || Zs();
1528
1650
  if (!t)
1529
1651
  throw new Error("[nimpress] completion: could not detect the shell from $SHELL, name it: nimpress completion <shell> --auto");
1530
- const n = ot(t), s = Le();
1652
+ const s = Ot(t), n = K();
1531
1653
  if (t === "fish") {
1532
- const l = d(s, ".config", "fish", "completions");
1533
- Q(l, { recursive: !0 });
1534
- const c = d(l, "nimpress.fish");
1535
- A(c, n), console.log(`wrote ${c}`), console.log("fish loads it on the next shell");
1654
+ const l = d(n, ".config", "fish", "completions");
1655
+ H(l, { recursive: !0 });
1656
+ const a = d(l, "nimpress.fish");
1657
+ W(a, s), console.log(`wrote ${a}`), console.log("fish loads it on the next shell");
1536
1658
  return;
1537
1659
  }
1538
1660
  if (t !== "bash" && t !== "zsh")
1539
1661
  throw new Error(`[nimpress] completion: auto install covers bash, zsh, and fish, for ${t} run: nimpress completion ${t}`);
1540
- const o = d(s, ".config", "nimpress", "completions");
1541
- Q(o, { recursive: !0 });
1662
+ const o = d(n, ".config", "nimpress", "completions");
1663
+ H(o, { recursive: !0 });
1542
1664
  const r = d(o, t === "zsh" ? "_nimpress" : "nimpress.bash");
1543
- A(r, n), console.log(`wrote ${r}`);
1544
- const i = d(s, t === "zsh" ? ".zshrc" : ".bashrc"), a = t === "zsh" ? `fpath=("${o}" $fpath)
1665
+ W(r, s), console.log(`wrote ${r}`);
1666
+ const i = d(n, t === "zsh" ? ".zshrc" : ".bashrc"), c = t === "zsh" ? `fpath=("${o}" $fpath)
1545
1667
  autoload -Uz compinit && compinit -u` : `[ -f "${r}" ] && source "${r}"`;
1546
- cs(i, a), console.log(`wired ${i}`), console.log(`start a new shell or run: source ${i}`);
1668
+ Ks(i, c), console.log(`wired ${i}`), console.log(`start a new shell or run: source ${i}`);
1547
1669
  }
1548
- function us(e, t) {
1549
- const n = ee(t, 0) ?? "", s = X(t, "auto"), o = X(t, "skill");
1550
- if (!s) {
1670
+ function Qs(e, t) {
1671
+ const s = re(t, 0) ?? "", n = M(t, "auto"), o = M(t, "skill");
1672
+ if (!n) {
1551
1673
  if (o) throw new Error("[nimpress] completion: --skill installs alongside --auto");
1552
- if (!n) throw new Error(`[nimpress] completion: name a shell (${nt.join(", ")}) or pass --auto`);
1553
- process.stdout.write(ot(n));
1674
+ if (!s) throw new Error(`[nimpress] completion: name a shell (${Et.join(", ")}) or pass --auto`);
1675
+ process.stdout.write(Ot(s));
1676
+ return;
1677
+ }
1678
+ Ys(s), o && Ct(e, !0);
1679
+ }
1680
+ const Xs = /* @__PURE__ */ new Set(["skill", "plugin", "mcp", "completion"]), qs = /* @__PURE__ */ new Set(["dev", "view", "modules dev"]), en = 2e4, de = /* @__PURE__ */ new Map();
1681
+ function Ft(e, t) {
1682
+ const s = [...t, e.name];
1683
+ return e.subs.length ? e.subs.flatMap((n) => Ft(n, s)) : [
1684
+ {
1685
+ name: s.join("_"),
1686
+ argv: s,
1687
+ describe: e.describe,
1688
+ flags: e.flags,
1689
+ serves: qs.has(s.join(" "))
1690
+ }
1691
+ ];
1692
+ }
1693
+ const Dt = V.filter((e) => !Xs.has(e.name)).flatMap((e) => Ft(e, []));
1694
+ function tn() {
1695
+ const e = _(pt(import.meta.url));
1696
+ for (const t of [j(e, "..", "package.json"), j(e, "..", "..", "package.json")])
1697
+ try {
1698
+ return JSON.parse(C(t, "utf-8")).version;
1699
+ } catch {
1700
+ }
1701
+ return "0.0.0";
1702
+ }
1703
+ function sn(e) {
1704
+ const t = {};
1705
+ for (const s of e.flags)
1706
+ t[s.name.slice(2)] = { type: s.value ? "string" : "boolean", description: s.describe };
1707
+ return {
1708
+ type: "object",
1709
+ properties: {
1710
+ cwd: { type: "string", description: "the site root the command runs in, relative to the project root, the project root by default" },
1711
+ args: { type: "array", items: { type: "string" }, description: "positional arguments, such as a component name or a file" },
1712
+ flags: { type: "object", properties: t, additionalProperties: !1 }
1713
+ },
1714
+ additionalProperties: !1
1715
+ };
1716
+ }
1717
+ function nn() {
1718
+ return [
1719
+ ...Dt.map((e) => ({
1720
+ name: e.name,
1721
+ description: `nimpress ${e.argv.join(" ")}: ${e.describe}${e.serves ? ". Keeps running in the background and returns its pid with the first output" : ""}`,
1722
+ inputSchema: sn(e)
1723
+ })),
1724
+ {
1725
+ name: "stop",
1726
+ description: "Stop a server a dev, view, or modules dev tool started, by its pid",
1727
+ inputSchema: {
1728
+ type: "object",
1729
+ properties: { pid: { type: "number", description: "the pid the serving tool returned" } },
1730
+ required: ["pid"],
1731
+ additionalProperties: !1
1732
+ }
1733
+ }
1734
+ ];
1735
+ }
1736
+ function on(e, t) {
1737
+ const s = [...e.argv, ...t.args ?? []];
1738
+ for (const [n, o] of Object.entries(t.flags ?? {}))
1739
+ o === !0 ? s.push(`--${n}`) : typeof o == "string" && s.push(`--${n}=${o}`);
1740
+ return s;
1741
+ }
1742
+ function G(e, t = !1) {
1743
+ return { content: [{ type: "text", text: e || "(no output)" }], ...t ? { isError: t } : {} };
1744
+ }
1745
+ function Nt(e, t, s) {
1746
+ return Ie(process.execPath, [process.argv[1], ...on(t, s)], {
1747
+ cwd: j(e, s.cwd ?? "."),
1748
+ env: { ...process.env, NO_COLOR: "1", FORCE_COLOR: "0" },
1749
+ stdio: ["ignore", "pipe", "pipe"]
1750
+ });
1751
+ }
1752
+ function rn(e, t, s) {
1753
+ const n = Nt(e, t, s);
1754
+ let o = "";
1755
+ return n.stdout?.on("data", (r) => o += r), n.stderr?.on("data", (r) => o += r), new Promise((r) => {
1756
+ n.on("error", (i) => r(G(`${o}${i.message}`, !0))), n.on("close", (i) => r(G(o, i !== 0)));
1757
+ });
1758
+ }
1759
+ function an(e, t, s) {
1760
+ const n = Nt(e, t, s);
1761
+ let o = "";
1762
+ return new Promise((r) => {
1763
+ const i = (a) => {
1764
+ clearTimeout(l), n.stdout?.removeAllListeners("data"), n.stderr?.removeAllListeners("data"), n.stdout?.resume(), n.stderr?.resume(), r(a);
1765
+ }, c = (a) => {
1766
+ o += a, /https?:\/\/\S+/.test(o) && i(G(`pid ${n.pid}
1767
+ ${o}`));
1768
+ }, l = setTimeout(() => i(G(`pid ${n.pid}
1769
+ ${o}`)), en);
1770
+ n.stdout?.on("data", c), n.stderr?.on("data", c), n.on("error", (a) => i(G(`${o}${a.message}`, !0))), n.on("exit", (a) => {
1771
+ de.delete(n.pid ?? -1), i(G(o, a !== 0));
1772
+ }), n.pid && de.set(n.pid, n);
1773
+ });
1774
+ }
1775
+ function cn(e) {
1776
+ const t = de.get(e);
1777
+ return t ? (t.kill("SIGTERM"), de.delete(e), G(`stopped ${e}`)) : G(`no server with pid ${e} was started by this session`, !0);
1778
+ }
1779
+ async function ln(e, t) {
1780
+ const s = String(t.name ?? ""), n = t.arguments ?? {};
1781
+ if (s === "stop") return cn(Number(n.pid));
1782
+ const o = Dt.find((r) => r.name === s);
1783
+ return o ? $(j(e, n.cwd ?? ".")) ? o.serves ? an(e, o, n) : rn(e, o, n) : G(`no folder ${n.cwd} under ${e}`, !0) : G(`unknown tool ${s}`, !0);
1784
+ }
1785
+ function te(e, t) {
1786
+ process.stdout.write(JSON.stringify({ jsonrpc: "2.0", id: e, ...t }) + `
1787
+ `);
1788
+ }
1789
+ async function un(e, t) {
1790
+ if (t.id !== void 0) {
1791
+ if (t.method === "initialize") {
1792
+ te(t.id, {
1793
+ result: {
1794
+ protocolVersion: t.params?.protocolVersion ?? "2025-06-18",
1795
+ capabilities: { tools: {} },
1796
+ serverInfo: { name: "nimpress", version: tn() }
1797
+ }
1798
+ });
1799
+ return;
1800
+ }
1801
+ if (t.method === "ping") {
1802
+ te(t.id, { result: {} });
1803
+ return;
1804
+ }
1805
+ if (t.method === "tools/list") {
1806
+ te(t.id, { result: { tools: nn() } });
1807
+ return;
1808
+ }
1809
+ if (t.method === "tools/call") {
1810
+ te(t.id, { result: await ln(e, t.params ?? {}) });
1811
+ return;
1812
+ }
1813
+ te(t.id, { error: { code: -32601, message: `method not found: ${t.method}` } });
1814
+ }
1815
+ }
1816
+ function pn(e) {
1817
+ const t = is({ input: process.stdin }), s = /* @__PURE__ */ new Set();
1818
+ t.on("line", (n) => {
1819
+ if (!n.trim()) return;
1820
+ let o;
1821
+ try {
1822
+ o = JSON.parse(n);
1823
+ } catch {
1824
+ te(null, { error: { code: -32700, message: "parse error" } });
1825
+ return;
1826
+ }
1827
+ const r = un(e, o).catch((i) => te(o.id, { error: { code: -32603, message: String(i?.message ?? i) } })).finally(() => s.delete(r));
1828
+ s.add(r);
1829
+ }), t.on("close", async () => {
1830
+ await Promise.all(s);
1831
+ for (const n of de.values()) n.kill("SIGTERM");
1832
+ process.exit(0);
1833
+ });
1834
+ }
1835
+ function mn(e, t, s) {
1836
+ if (typeof s.path == "string") return s.path.startsWith("/") ? s.path : `/${s.path}`;
1837
+ const n = D(e, t).split(I).join("/").replace(/\.md$/, "");
1838
+ return n === "index" ? "/" : `/${n.replace(/\/index$/, "")}`;
1839
+ }
1840
+ function Ye(e) {
1841
+ return e ? (Array.isArray(e) ? e : String(e).split(",")).map((s) => String(s).trim()).filter(Boolean) : [];
1842
+ }
1843
+ function fn(e) {
1844
+ return e.split(`
1845
+ `).filter((t) => /^#{1,6}\s/.test(t)).map((t) => t.replace(/^#{1,6}\s+/, "").trim());
1846
+ }
1847
+ function dn(e, t) {
1848
+ const s = j(e, t.contentDir), o = oe(s).filter((a) => a.endsWith(".md")).map((a) => {
1849
+ const { data: p, content: u } = fe(C(a, "utf-8"));
1850
+ return { file: a, data: p, content: u };
1851
+ }).filter((a) => typeof a.data.title == "string" && a.data.visibility !== "hidden" && !a.data.link), r = o.map((a) => ({
1852
+ slug: a.file,
1853
+ title: String(a.data.title),
1854
+ headings: fn(a.content),
1855
+ tags: Ye(a.data.tags),
1856
+ body: a.content
1857
+ })), i = ts(r), c = t.site?.url?.replace(/\/$/, "") ?? "", l = t.base.replace(/\/$/, "");
1858
+ return o.map((a) => {
1859
+ const p = i.get(a.file) ?? { keywords: [], description: "" }, u = a.data.meta ?? {}, m = Array.isArray(u.keywords) ? u.keywords : typeof u.keywords == "string" ? [u.keywords] : void 0, f = typeof u.description == "string" ? u.description : typeof a.data.description == "string" ? a.data.description : void 0, h = u.override === !0, g = t.seo?.auto === !0, w = g ? h && m ? m : p.keywords.length ? p.keywords : m ?? [] : m ?? Ye(a.data.tags), v = g ? h && f ? f : p.description || f || "" : f ?? "", O = mn(s, a.file, a.data);
1860
+ return {
1861
+ path: O,
1862
+ file: D(e, a.file).split(I).join("/"),
1863
+ title: String(a.data.title),
1864
+ keywords: w,
1865
+ description: v,
1866
+ robots: ss(typeof u.robots == "string" ? u.robots : "index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1", t.seo?.ai?.index, typeof u.ai == "boolean" ? u.ai : void 0),
1867
+ canonical: typeof u.canonical == "string" ? u.canonical : c ? `${c}${l}${O === "/" ? "/" : O}` : "",
1868
+ generated: p,
1869
+ authored: { keywords: m, description: f, override: h, ai: typeof u.ai == "boolean" ? u.ai : void 0 }
1870
+ };
1871
+ });
1872
+ }
1873
+ function hn(e, t) {
1874
+ let s = 0;
1875
+ for (const n of t) {
1876
+ const o = j(e, n.file), { data: r, content: i } = fe(C(o, "utf-8")), c = { ...r.meta ?? {} };
1877
+ let l = !1;
1878
+ c.keywords === void 0 && n.generated.keywords.length && (c.keywords = n.generated.keywords, l = !0), c.description === void 0 && n.generated.description && (c.description = n.generated.description, l = !0), l && (W(o, fe.stringify(i, { ...r, meta: c })), s += 1);
1879
+ }
1880
+ return s;
1881
+ }
1882
+ function gn(e, t, s) {
1883
+ const n = dn(e, t), o = N(s, "out") ?? "seo.map.json";
1884
+ for (const r of n) {
1885
+ const i = t.seo?.auto ? r.authored.override ? "authored" : "generated" : "authored";
1886
+ console.log(`${r.path.padEnd(40)} ${String(r.keywords.length).padStart(2)} keywords ${String(r.description.length).padStart(3)} chars ${r.robots.includes("noai") ? "noai" : "ai ok"} ${i}`);
1887
+ }
1888
+ if (W(j(e, o), JSON.stringify(n, null, 2) + `
1889
+ `), console.log(`nimpress seo: ${n.length} pages, map written to ${o}`), s.includes("--write")) {
1890
+ const r = hn(e, n);
1891
+ console.log(`nimpress seo: generated fields written into ${r} pages`);
1892
+ }
1893
+ }
1894
+ function _t(e = K()) {
1895
+ return d(e, ".nimpress", "config.json");
1896
+ }
1897
+ function Wt(e = K()) {
1898
+ return d(e, ".tide", "nimpress", "sites");
1899
+ }
1900
+ function Tt(e = K()) {
1901
+ const t = _t(e);
1902
+ return $(t) ? { links: JSON.parse(C(t, "utf-8")).links ?? {} } : { links: {} };
1903
+ }
1904
+ function Rt(e, t = K()) {
1905
+ const s = _t(t);
1906
+ H(_(s), { recursive: !0 }), W(s, `${JSON.stringify(e, null, 2)}
1907
+ `);
1908
+ }
1909
+ function ve(e) {
1910
+ const t = e.trim().replace(/\.git$/, "").replace(/\/+$/, ""), s = t.match(/[:/]([^/:]+)\/([^/]+)$/);
1911
+ if (s && t.includes("github.com")) return `${s[1]}/${s[2]}`;
1912
+ const n = t.match(/^([^/\s]+)\/([^/\s]+)$/);
1913
+ if (n) return `${n[1]}/${n[2]}`;
1914
+ throw new Error(`[nimpress] view: cannot read owner/repo from ${e}`);
1915
+ }
1916
+ function Oe(e) {
1917
+ const t = e.trim();
1918
+ return /^(https?:\/\/|git@|ssh:\/\/)/.test(t) ? t : `https://github.com/${ve(t)}.git`;
1919
+ }
1920
+ function At(e) {
1921
+ const t = d(e, ".github", "workflows");
1922
+ return $(t) ? se(t).filter((s) => s.endsWith(".yml") || s.endsWith(".yaml")).sort().map((s) => d(t, s)) : [];
1923
+ }
1924
+ function Pt(e) {
1925
+ try {
1926
+ const t = as(C(e, "utf-8"));
1927
+ return typeof t == "object" && t !== null ? t : null;
1928
+ } catch {
1929
+ return null;
1930
+ }
1931
+ }
1932
+ function ae(e, t) {
1933
+ return String(e ?? "").replace(/\$\{\{\s*env\.([A-Za-z_][A-Za-z0-9_]*)\s*\}\}/g, (n, o) => {
1934
+ for (const r of t)
1935
+ if (r && r[o] !== void 0) return String(r[o]);
1936
+ return "";
1937
+ }).trim();
1938
+ }
1939
+ function Mt(e, t) {
1940
+ const s = [];
1941
+ for (const n of Object.values(e.jobs ?? {}))
1942
+ for (const o of n.steps ?? [])
1943
+ typeof o.uses == "string" && o.uses.includes(`/actions/${t}@`) && s.push({ step: o, scopes: [o.env, n.env, e.env] });
1944
+ return s;
1945
+ }
1946
+ function wn(e) {
1947
+ const t = /* @__PURE__ */ new Map();
1948
+ for (const s of At(e)) {
1949
+ const n = Pt(s);
1950
+ if (n)
1951
+ for (const { step: o, scopes: r } of Mt(n, "docs-notify")) {
1952
+ const i = ae(o.with?.["docs-repo"], r);
1953
+ if (!i) continue;
1954
+ const c = ae(o.with?.["export-dir"], r) || ".nimpress";
1955
+ t.set(i, { repo: i, exportDir: c });
1956
+ }
1957
+ }
1958
+ return [...t.values()];
1959
+ }
1960
+ function Qe(e) {
1961
+ return e.replace(/\$\{\{\s*github\.workspace\s*\}\}\/?/g, "").replace(/^\.\//, "");
1962
+ }
1963
+ function $n(e, t) {
1964
+ const s = {
1965
+ contentRoot: t,
1966
+ mapping: $(d(e, "nimpress.sources.json")) ? "nimpress.sources.json" : "",
1967
+ defaults: {}
1968
+ };
1969
+ for (const n of At(e)) {
1970
+ const o = Pt(n);
1971
+ if (o)
1972
+ for (const { step: r, scopes: i } of Mt(o, "docs-sync")) {
1973
+ const c = Qe(ae(r.with?.["docs-dir"], i)), l = (m) => {
1974
+ const f = Qe(m);
1975
+ return (c && f.startsWith(`${c}/`) ? f.slice(c.length + 1) : f).replace(/\/+$/, "");
1976
+ }, a = ae(r.with?.["content-root"], i);
1977
+ a && (s.contentRoot = l(a));
1978
+ const p = ae(r.with?.mapping, i);
1979
+ p && (s.mapping = l(p));
1980
+ const u = ae(r.with?.defaults, i);
1981
+ return u && (s.defaults = JSON.parse(u)), s;
1982
+ }
1983
+ }
1984
+ return s;
1985
+ }
1986
+ function yn(e, t) {
1987
+ const s = { ...e };
1988
+ return t.target && (s.target = t.target), t.targets?.length && (s.targets = t.targets), t.mode && (s.mode = t.mode), s;
1989
+ }
1990
+ function bn(e) {
1991
+ const t = e.mode || "mirror";
1992
+ return e.targets?.length ? e.targets.map((s) => ({ from: s.from ?? "", to: s.to, mode: s.mode || t })) : e.target ? [{ from: "", to: e.target, mode: t }] : [];
1993
+ }
1994
+ function vn(e, t, s) {
1995
+ let n = t.defaults;
1996
+ const o = t.mapping ? d(e, t.mapping) : "";
1997
+ if (o && $(o)) {
1998
+ const i = JSON.parse(C(o, "utf-8")).sources?.[s];
1999
+ i && (n = yn(n, i));
2000
+ }
2001
+ return n;
2002
+ }
2003
+ function Xe(e) {
2004
+ const t = /* @__PURE__ */ new Map();
2005
+ if (!$(e)) return t;
2006
+ for (const s of oe(e))
2007
+ t.set(D(e, s).split(I).join("/"), C(s));
2008
+ return t;
2009
+ }
2010
+ function kn(e, t, s) {
2011
+ const n = { added: [], modified: [], deleted: [] }, o = Xe(e), r = Xe(t);
2012
+ for (const [i, c] of o) {
2013
+ const l = r.get(i);
2014
+ if (l && l.equals(c)) continue;
2015
+ const a = d(t, ...i.split("/"));
2016
+ H(_(a), { recursive: !0 }), W(a, c), l ? n.modified.push(i) : n.added.push(i);
2017
+ }
2018
+ if (s === "mirror")
2019
+ for (const i of r.keys())
2020
+ o.has(i) || (ne(d(t, ...i.split("/")), { force: !0 }), n.deleted.push(i));
2021
+ return n;
2022
+ }
2023
+ function ce(e, t, s) {
2024
+ const n = X("git", e, { cwd: t, encoding: "utf-8", env: { ...process.env, ...s } });
2025
+ return { ok: n.status === 0, out: `${n.stdout ?? ""}${n.stderr ?? ""}`.trim() };
2026
+ }
2027
+ function It(e) {
2028
+ const t = ce(["rev-parse", "--show-toplevel"], e);
2029
+ return t.ok ? t.out : e;
2030
+ }
2031
+ function xn(e) {
2032
+ const t = ce(["remote", "get-url", "origin"], e);
2033
+ if (!t.ok) throw new Error(`[nimpress] view: ${e} has no origin remote, so its docs site mapping cannot be looked up`);
2034
+ return ve(t.out);
2035
+ }
2036
+ function Sn() {
2037
+ return X("gh", ["--version"], { encoding: "utf-8" }).status === 0;
2038
+ }
2039
+ function Lt(e) {
2040
+ return e?.method === "ssh" && e.key ? { GIT_SSH_COMMAND: `ssh -i ${e.key} -o IdentitiesOnly=yes` } : {};
2041
+ }
2042
+ function Fe(e) {
2043
+ return e.login?.method === "gh" ? X("gh", ["repo", "view", e.repo, "--json", "name"], { encoding: "utf-8" }).status === 0 : ce(["ls-remote", "--exit-code", "-h", e.url], void 0, Lt(e.login)).ok;
2044
+ }
2045
+ async function zt(e) {
2046
+ const t = ut({ input: process.stdin, output: process.stdout });
2047
+ try {
2048
+ return (await t.question(e)).trim();
2049
+ } finally {
2050
+ t.close();
2051
+ }
2052
+ }
2053
+ async function jn(e) {
2054
+ if (Fe(e)) return e;
2055
+ if (console.log(`nimpress view: ${e.url} refused the connection`), Sn()) {
2056
+ if (console.log("nimpress view: logging in through gh"), X("gh", ["auth", "login"], { stdio: "inherit" }).status !== 0) throw new Error("[nimpress] view: gh auth login did not complete");
2057
+ const o = { ...e, login: { method: "gh" } };
2058
+ if (Fe(o)) return o;
2059
+ throw new Error(`[nimpress] view: ${e.repo} is still unreachable after the gh login, ask for access to it`);
2060
+ }
2061
+ const t = await zt("nimpress view: path to the ssh key with access to the repo: ");
2062
+ if (!t) throw new Error("[nimpress] view: no ssh key given and gh is not installed");
2063
+ const s = { ...e, login: { method: "ssh", key: j(t.replace(/^~/, K())) } };
2064
+ if (Fe(s)) return s;
2065
+ throw new Error(`[nimpress] view: ${e.repo} is still unreachable with ${s.login.key}, ask for access to it`);
2066
+ }
2067
+ async function Cn(e, t, s = K()) {
2068
+ const n = It(e), o = Tt(s), r = o.links[n] ?? [], i = wn(n), c = N(t, "docs-repo");
2069
+ let l;
2070
+ if (c) {
2071
+ const p = ve(c), u = i.find((m) => m.repo === p)?.exportDir ?? N(t, "export-dir") ?? ".nimpress";
2072
+ l = [{ repo: p, url: Oe(c), exportDir: u, login: r.find((m) => m.repo === p)?.login }];
2073
+ } else if (i.length)
2074
+ l = i.map((p) => ({
2075
+ repo: p.repo,
2076
+ url: r.find((u) => u.repo === p.repo)?.url ?? Oe(p.repo),
2077
+ exportDir: p.exportDir,
2078
+ login: r.find((u) => u.repo === p.repo)?.login
2079
+ }));
2080
+ else if (r.length)
2081
+ l = r;
2082
+ else {
2083
+ console.log(`nimpress view: no workflow under ${n} names a docs site`);
2084
+ const p = await zt("nimpress view: docs site repo, owner/repo or a url, http or ssh: ");
2085
+ if (!p) throw new Error("[nimpress] view: no docs site given");
2086
+ l = [{ repo: ve(p), url: Oe(p), exportDir: N(t, "export-dir") ?? ".nimpress" }];
2087
+ }
2088
+ const a = [];
2089
+ for (const p of l) a.push(await jn(p));
2090
+ return o.links[n] = a, Rt(o, s), a;
2091
+ }
2092
+ function En(e, t = K()) {
2093
+ return d(Wt(t), e.repo.replace("/", "__"));
2094
+ }
2095
+ function On(e, t, s) {
2096
+ const n = Lt(e.login);
2097
+ if (!$(d(t, ".git"))) {
2098
+ H(_(t), { recursive: !0 }), console.log(`nimpress view: cloning ${e.repo}`);
2099
+ const r = e.login?.method === "gh" ? X("gh", ["repo", "clone", e.repo, t, "--", "--depth", "1"], { encoding: "utf-8" }) : X("git", ["clone", "--depth", "1", e.url, t], { encoding: "utf-8", env: { ...process.env, ...n } });
2100
+ if (r.status !== 0) throw new Error(`[nimpress] view: clone of ${e.repo} failed
2101
+ ${r.stderr ?? ""}`);
1554
2102
  return;
1555
2103
  }
1556
- ls(n), o && st(e, !0);
2104
+ if (s) return;
2105
+ const o = ce(["fetch", "--depth", "1", "origin", "HEAD"], t, n);
2106
+ if (!o.ok) throw new Error(`[nimpress] view: fetch of ${e.repo} failed
2107
+ ${o.out}`);
2108
+ ce(["reset", "--hard", "FETCH_HEAD"], t), ce(["clean", "-fd"], t);
2109
+ }
2110
+ function Fn(e) {
2111
+ const t = ["pnpm-lock.yaml", "package.json"].map((s) => d(e, s)).find((s) => $(s));
2112
+ return t ? lt("sha256").update(C(t)).digest("hex") : "";
2113
+ }
2114
+ function Dn(e) {
2115
+ const t = d(e, z.paths.cache, "view", "lockfile.sha256"), s = Fn(e);
2116
+ if ($(d(e, "node_modules")) && $(t) && C(t, "utf-8").trim() === s) return;
2117
+ if (console.log("nimpress view: installing the docs site dependencies"), X("pnpm", ["install"], { cwd: e, stdio: "inherit" }).status !== 0) throw new Error("[nimpress] view: pnpm install failed in the docs site clone");
2118
+ H(_(t), { recursive: !0 }), W(t, `${s}
2119
+ `);
1557
2120
  }
1558
- async function ks(e) {
1559
- const t = e[0] ?? "dev", n = e.slice(1), s = process.cwd();
2121
+ function Nn(e) {
2122
+ const t = rs(), s = t === "darwin" ? ["open", e] : t === "win32" ? ["cmd", "/c", "start", "", e] : ["xdg-open", e], n = Ie(s[0], s.slice(1), { stdio: "ignore", detached: !0 });
2123
+ n.on("error", () => console.log(`nimpress view: open ${e} in a browser`)), n.unref();
2124
+ }
2125
+ function qe(e, t) {
2126
+ let s;
2127
+ return () => {
2128
+ s && clearTimeout(s), s = setTimeout(e, t);
2129
+ };
2130
+ }
2131
+ function _n(e, t) {
2132
+ t.added.length + t.modified.length + t.deleted.length !== 0 && console.log(`nimpress view: ${e} ${t.added.length} added, ${t.modified.length} modified, ${t.deleted.length} deleted`);
2133
+ }
2134
+ function Wn(e) {
2135
+ const t = Ie("pnpm", ["exec", "nimpress", "dev"], { cwd: e, stdio: ["ignore", "pipe", "inherit"] }), s = new Promise((n, o) => {
2136
+ let r = !1;
2137
+ t.stdout?.on("data", (i) => {
2138
+ const c = i.toString();
2139
+ if (process.stdout.write(c), r) return;
2140
+ const l = c.replace(/\x1b\[[0-9;]*m/g, "").match(/Local\s*:?\s+(https?:\/\/\S+)/);
2141
+ l && (r = !0, n(l[1]));
2142
+ }), t.on("exit", (i) => {
2143
+ r || o(new Error(`[nimpress] view: the docs site dev server exited with ${i ?? "a signal"} before it printed a url`));
2144
+ }), t.on("error", (i) => o(new Error(`[nimpress] view: cannot run the docs site dev server, ${i.message}`)));
2145
+ });
2146
+ return { child: t, origin: s };
2147
+ }
2148
+ async function Tn(e, t) {
2149
+ const s = M(t, "offline"), n = await Cn(e, t), o = xn(e), r = It(e), i = await we(e), c = N(t, "target") ? [`--target=${N(t, "target")}`] : [], l = [];
2150
+ for (const p of n) {
2151
+ const u = j(r, p.exportDir);
2152
+ if (i.configFile && Ae(e, i.resolved, [...c, `--out=${u}`]), !$(u))
2153
+ throw new Error(`[nimpress] view: no export folder at ${u}, write the pages there or mark pages with export: and add a config`);
2154
+ const m = En(p);
2155
+ On(p, m, s), Dn(m);
2156
+ const f = await we(m);
2157
+ if (!f.configFile) throw new Error(`[nimpress] view: ${p.repo} carries no nimpress config, so it is not a docs site`);
2158
+ const h = $n(m, f.resolved.contentDir), g = bn(vn(m, h, o));
2159
+ if (!g.length)
2160
+ throw new Error(
2161
+ `[nimpress] view: ${p.repo} has no target for ${o}, add it to nimpress.sources.json or the receiver defaults`
2162
+ );
2163
+ const w = j(m, h.contentRoot), v = () => {
2164
+ for (const x of g)
2165
+ _n(x.to, kn(d(u, ...x.from.split("/").filter(Boolean)), d(w, ...x.to.split("/")), x.mode));
2166
+ };
2167
+ v();
2168
+ const O = He(u, { recursive: !0 }, qe(v, 150));
2169
+ if (l.push(() => O.close()), i.configFile) {
2170
+ const x = He(
2171
+ j(e, i.resolved.contentDir),
2172
+ { recursive: !0 },
2173
+ qe(() => Ae(e, i.resolved, [...c, `--out=${u}`]), 150)
2174
+ );
2175
+ l.push(() => x.close());
2176
+ }
2177
+ const { child: E, origin: k } = Wn(m);
2178
+ l.push(() => E.kill());
2179
+ const T = `${(await k).replace(/\/$/, "")}/${g[0].to}`;
2180
+ console.log(`nimpress view: ${o} inside ${p.repo} at ${T}`), M(t, "no-browser") || Nn(T);
2181
+ }
2182
+ const a = () => {
2183
+ for (const p of l) p();
2184
+ process.exit(0);
2185
+ };
2186
+ process.on("SIGINT", a), process.on("SIGTERM", a);
2187
+ }
2188
+ async function Rn(e, t) {
2189
+ const s = re(t, 0);
2190
+ if (s !== "clear") throw new Error(`[nimpress] cache: unknown subcommand ${s ?? ""}, use clear`);
2191
+ const n = M(t, "links"), o = M(t, "sites"), r = M(t, "local"), i = !n && !o && !r;
2192
+ if (n || i) {
2193
+ const c = Tt(), l = Object.keys(c.links).length;
2194
+ Rt({ links: {} }), console.log(`nimpress cache: cleared ${l} links`);
2195
+ }
2196
+ if (o || i) {
2197
+ const c = Wt();
2198
+ ne(c, { recursive: !0, force: !0 }), console.log(`nimpress cache: cleared the docs site clones under ${c}`);
2199
+ }
2200
+ if (r) {
2201
+ const { resolved: c, configFile: l } = await we(e);
2202
+ if (!l) throw new Error(`[nimpress] cache: --local needs a nimpress config in ${e}`);
2203
+ const a = nt(e, c);
2204
+ $(a) && ne(a, { recursive: !0, force: !0 }), console.log(`nimpress cache: cleared ${a}`);
2205
+ }
2206
+ }
2207
+ async function Qn(e) {
2208
+ const t = e[0] ?? "dev", s = e.slice(1), n = process.cwd();
1560
2209
  if (t === "init") {
1561
- Ft(s);
2210
+ ps(n);
1562
2211
  return;
1563
2212
  }
1564
2213
  if (t === "skill") {
1565
- ts(s, n);
2214
+ Ms(n, s);
2215
+ return;
2216
+ }
2217
+ if (t === "plugin") {
2218
+ Js(n, s);
2219
+ return;
2220
+ }
2221
+ if (t === "mcp") {
2222
+ pn(n);
1566
2223
  return;
1567
2224
  }
1568
2225
  if (t === "completion") {
1569
- us(s, n);
2226
+ Qs(n, s);
2227
+ return;
2228
+ }
2229
+ if (t === "view" || t === "dev" && M(s, "view")) {
2230
+ await Tn(n, s);
2231
+ return;
2232
+ }
2233
+ if (t === "cache") {
2234
+ await Rn(n, s);
2235
+ return;
2236
+ }
2237
+ const { resolved: o } = await we(n);
2238
+ if (t === "seo") {
2239
+ gn(n, o, s);
1570
2240
  return;
1571
2241
  }
1572
- const { resolved: o } = await $t(s);
1573
2242
  if (t === "lint") {
1574
- await Jt(s, o);
2243
+ await Cs(n, o);
1575
2244
  return;
1576
2245
  }
1577
2246
  if (t === "dev") {
1578
- await Nt(s, o);
2247
+ await ws(n, o);
1579
2248
  return;
1580
2249
  }
1581
2250
  if (t === "build") {
1582
- await He(s, o);
2251
+ await gt(n, o);
1583
2252
  return;
1584
2253
  }
1585
2254
  if (t === "guard") {
1586
- Ut(s, o, n);
2255
+ Os(n, o, s);
1587
2256
  return;
1588
2257
  }
1589
2258
  if (t === "modules") {
1590
- await Kt(s, o, n);
2259
+ await Ts(n, o, s);
1591
2260
  return;
1592
2261
  }
1593
2262
  if (t === "export") {
1594
- es(s, o, n);
2263
+ Ae(n, o, s);
1595
2264
  return;
1596
2265
  }
1597
2266
  throw new Error(`[nimpress] unknown command: ${t}`);
1598
2267
  }
1599
2268
  export {
1600
- Pe as buildViteConfig,
1601
- lt as indexHtml,
1602
- $t as loadNimpressConfig,
1603
- ks as run
2269
+ tt as buildViteConfig,
2270
+ Ut as indexHtml,
2271
+ we as loadNimpressConfig,
2272
+ Qn as run
1604
2273
  };