your-ai-workflow-firebase-os 1.2.49 → 1.2.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vite.es.js CHANGED
@@ -146,7 +146,7 @@ var S = (e) => e.filter((e) => e.kind !== "other"), C = [{
146
146
  "dist",
147
147
  "build"
148
148
  ]);
149
- function T(n) {
149
+ function ee(n) {
150
150
  let r = [], i = t.join(n, "src"), a = (i, o) => {
151
151
  if (!(o > 6 || !e.existsSync(i))) for (let s of e.readdirSync(i, { withFileTypes: !0 })) {
152
152
  let e = t.join(i, s.name), u = d(t.relative(n, e));
@@ -164,18 +164,18 @@ function T(n) {
164
164
  };
165
165
  return a(i, 0), r.sort();
166
166
  }
167
- var E = (e) => {
167
+ var T = (e) => {
168
168
  let n = t.basename(e);
169
169
  return C.some((e) => e.test(n));
170
- }, D = (e) => JSON.stringify(e);
171
- function O(e) {
170
+ }, E = (e) => JSON.stringify(e);
171
+ function D(e) {
172
172
  let t = [], n = [], r = [], i = [];
173
173
  return S(e).forEach((e, a) => {
174
174
  let o = `m${a}`;
175
- if (t.push(`import * as ${o} from ${D(d(e.abs))};`), e.kind === "tab") n.push(`{
175
+ if (t.push(`import * as ${o} from ${E(d(e.abs))};`), e.kind === "tab") n.push(`{
176
176
  const configVal = pickConfig(${o});
177
177
  if (configVal) {
178
- const tabId = ${D(e.id)};
178
+ const tabId = ${E(e.id)};
179
179
  const finalTab = {
180
180
  config: {
181
181
  ...configVal,
@@ -194,7 +194,7 @@ function O(e) {
194
194
  else if (e.kind === "page") n.push(`{
195
195
  const configVal = pickConfig(${o});
196
196
  if (configVal) {
197
- const pageId = ${D(e.id)};
197
+ const pageId = ${E(e.id)};
198
198
  const finalPage = {
199
199
  config: {
200
200
  ...configVal,
@@ -213,7 +213,7 @@ function O(e) {
213
213
  else if (e.kind === "form") r.push(`{
214
214
  const configVal = pickConfig(${o});
215
215
  if (configVal) {
216
- const formId = ${D(e.id)};
216
+ const formId = ${E(e.id)};
217
217
  // The form's id is its file name; systemName always follows the file.
218
218
  const finalConfig = { ...configVal, systemName: formId };
219
219
  forms[formId] = finalConfig;
@@ -224,11 +224,11 @@ function O(e) {
224
224
  else if (e.kind === "microcomponent") {
225
225
  let [t, n] = h(e.name);
226
226
  i.push(`if (${o} && ${o}.default) {
227
- microcomponents[${D(t)}] = ${o}.default;
227
+ microcomponents[${E(t)}] = ${o}.default;
228
228
  // Also answer to the squashed form ("mobile_apps" -> "mobileapps"): a page id
229
229
  // derived from a file name (mobileAppsPage.config.ts -> "mobileapps") has no
230
230
  // underscores, and the page must still find MobileAppsContent.tsx.
231
- microcomponents[${D(n)}] = ${o}.default;
231
+ microcomponents[${E(n)}] = ${o}.default;
232
232
  }`);
233
233
  }
234
234
  }), `// Generated by Your AI Firebase from the files in ${s}/.
@@ -269,19 +269,19 @@ export const formsRegistry = forms;
269
269
  export const microcomponentRegistry = microcomponents;
270
270
  `;
271
271
  }
272
- var k = (e) => O(x(e)), A = (e) => e.split("/").pop() || e, j = (e) => /\/configs\/[^/]+$/.test(e), M = (e) => /\/microcomponents\/[^/]+\.tsx$/.test(e), N = (e) => e.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:\\'"`])\/\/.*$/gm, "$1"), P = (e, t) => {
272
+ var te = (e) => D(x(e)), O = (e) => e.split("/").pop() || e, k = (e) => /\/configs\/[^/]+$/.test(e), A = (e) => /\/microcomponents\/[^/]+\.tsx$/.test(e), j = (e) => e.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:\\'"`])\/\/.*$/gm, "$1"), M = (e, t) => {
273
273
  let n = RegExp(`(?:^|[\\s,{])${t}\\s*:\\s*([^,\\n}]+)`, "g"), r = [], i;
274
274
  for (; i = n.exec(e);) r.push(i[1].trim());
275
275
  return r;
276
- }, F = (e) => {
276
+ }, N = (e) => {
277
277
  let t = e.match(/^(['"`])([^'"`]*)\1$/);
278
278
  return t ? t[2] : null;
279
- }, I = (e) => /export\s+(?:const|let|var|function|class)\s+\w*Config\b/.test(e) || /export\s*\{[^}]*\b\w*Config\b[^}]*\}/.test(e), L = (e) => /export\s+default\b/.test(e), R = (e) => e.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, ""), z = [
279
+ }, P = (e) => /export\s+(?:const|let|var|function|class)\s+\w*Config\b/.test(e) || /export\s*\{[^}]*\b\w*Config\b[^}]*\}/.test(e), F = (e) => /export\s+default\b/.test(e), I = (e) => e.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, ""), L = [
280
280
  "board",
281
281
  "table",
282
282
  "calendar",
283
283
  "drive"
284
- ], B = {
284
+ ], R = {
285
285
  board: {
286
286
  call: "actions.openInlineEditor(categoryId)",
287
287
  token: "openInlineEditor"
@@ -298,43 +298,43 @@ var k = (e) => O(x(e)), A = (e) => e.split("/").pop() || e, j = (e) => /\/config
298
298
  call: "the openUploadModal() prop",
299
299
  token: "openUploadModal"
300
300
  }
301
- }, V = (e) => {
302
- let t = P(e, "route");
301
+ }, z = /(?:copy (?:this|the sentence|it) (?:in)?to|paste (?:this|it) (?:in)?to|copy for (?:your |the )?(?:ai|assistant)|ask your assistant|your assistant.{0,3}s chat|copy this to change)[^\n]{0,40}/i, B = (e) => {
302
+ let t = M(e, "route");
303
303
  return {
304
304
  first: t[0],
305
305
  count: t.length
306
306
  };
307
307
  };
308
- function H(e) {
308
+ function V(e) {
309
309
  let t = [], n = [], r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Set();
310
- for (let { file: t } of e) if (M(t)) for (let e of h(A(t))) i.add(e);
310
+ for (let { file: t } of e) if (A(t)) for (let e of h(O(t))) i.add(e);
311
311
  let a = /* @__PURE__ */ new Map();
312
312
  for (let { file: t, source: n } of e) {
313
- if (!j(t)) continue;
314
- let e = A(t), r = _(e);
313
+ if (!k(t)) continue;
314
+ let e = O(t), r = _(e);
315
315
  if (r !== "tab" && r !== "page") continue;
316
- let i = N(n), o = P(i, "template")[0], s = o === void 0 ? null : F(o);
317
- if (!s || !z.includes(s)) continue;
318
- let c = P(i, r === "tab" ? "tabName" : "pageName")[0], l = c === void 0 ? null : F(c), u = [r === "tab" ? f(e) : p(e), ...l ? [R(l), R(l).replace(/_/g, "")] : []];
316
+ let i = j(n), o = M(i, "template")[0], s = o === void 0 ? null : N(o);
317
+ if (!s || !L.includes(s)) continue;
318
+ let c = M(i, r === "tab" ? "tabName" : "pageName")[0], l = c === void 0 ? null : N(c), u = [r === "tab" ? f(e) : p(e), ...l ? [I(l), I(l).replace(/_/g, "")] : []];
319
319
  for (let e of u) a.set(e, s);
320
320
  }
321
321
  for (let { file: o, source: s } of e) {
322
- let e = A(o), c = N(s);
323
- if (j(o)) {
322
+ let e = O(o), c = j(s);
323
+ if (k(o)) {
324
324
  let n = _(e);
325
325
  if (n === "shipped") continue;
326
326
  if (n === "other") {
327
327
  t.push(`${o}: rename it to somethingTab.config.ts (a dashboard page), somethingPage.config.ts (a page for anyone) or somethingForm.config.ts (a form).`);
328
328
  continue;
329
329
  }
330
- if (!I(c) && !L(c) && t.push(`${o}: export one const named ${g(e)}Config.`), n === "tab" || n === "page") {
331
- let { first: a, count: s } = V(c), l = a === void 0 ? null : F(a);
330
+ if (!P(c) && !F(c) && t.push(`${o}: export one const named ${g(e)}Config.`), n === "tab" || n === "page") {
331
+ let { first: a, count: s } = B(c), l = a === void 0 ? null : N(a);
332
332
  if (s === 0 || l === null || !l.startsWith("/")) t.push(`${o}: route must be one string starting with /, e.g. route: '/onboarding'. A page has exactly one web address.`);
333
333
  else {
334
334
  let e = r.get(l);
335
335
  e ? t.push(`${o}: route '${l}' is already used by ${e}. One page, one file, one address.`) : r.set(l, o);
336
336
  }
337
- let u = P(c, "template")[0], d = u === void 0 ? null : F(u);
337
+ let u = M(c, "template")[0], d = u === void 0 ? null : N(u);
338
338
  if (!d || ![
339
339
  "board",
340
340
  "table",
@@ -343,7 +343,7 @@ function H(e) {
343
343
  "inline_form",
344
344
  "popup_form"
345
345
  ].includes(d)) {
346
- let r = n === "tab" ? f(e) : p(e), a = P(c, n === "tab" ? "tabName" : "pageName")[0], s = a === void 0 ? null : F(a), l = (e) => e.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
346
+ let r = n === "tab" ? f(e) : p(e), a = M(c, n === "tab" ? "tabName" : "pageName")[0], s = a === void 0 ? null : N(a), l = (e) => e.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
347
347
  if (![r, ...s ? [l(s), l(s).replace(/_/g, "")] : []].some((e) => i.has(e))) {
348
348
  let n = g(e).replace(/(Tab|Page)$/, ""), r = (s || n).split(/[^a-zA-Z0-9]+/).filter(Boolean).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("");
349
349
  t.push(`${o}: no content file matches this page, so it renders empty — create src/your-ai-workflow-firebase-os/microcomponents/${r}Content.tsx with export default.`);
@@ -351,25 +351,29 @@ function H(e) {
351
351
  }
352
352
  }
353
353
  if (n === "tab") {
354
- let e = P(c, "pageType")[0], n = e === void 0 ? null : F(e);
354
+ let e = M(c, "pageType")[0], n = e === void 0 ? null : N(e);
355
355
  n !== "user" && n !== "internal" && n !== "admin" && t.push(`${o}: pageType must be 'user', 'internal' or 'admin'. A dashboard page is never public.`);
356
356
  }
357
357
  if (n === "form") {
358
- let n = m(e), r = P(c, "systemName")[0];
359
- r !== void 0 && F(r) !== n && t.push(`${o}: systemName must be '${n}'.`);
358
+ let n = m(e), r = M(c, "systemName")[0];
359
+ r !== void 0 && N(r) !== n && t.push(`${o}: systemName must be '${n}'.`);
360
360
  }
361
361
  continue;
362
362
  }
363
- if (M(o)) {
364
- L(c) || t.push(`${o}: add export default.`);
363
+ if (A(o)) {
364
+ F(c) || t.push(`${o}: add export default.`);
365
365
  let r = h(e).map((e) => a.get(e)).find(Boolean), i = /<form\b/.test(c) || /\bonSubmit\b/.test(c);
366
366
  if (i && r) {
367
- let e = B[r];
367
+ let e = R[r];
368
368
  c.includes(e.token) || n.push(`${o}: this page is a ${r} and already has its own add and edit dialog, themed for light and dark — open it with ${e.call} instead of building a form here.`);
369
369
  } else i && !/ContactPopup/.test(c) && n.push(`${o}: forms are *Form.config.ts files shown with <ContactPopup formId="…" />; a hand-written form never reaches the Inbox.`);
370
370
  /<style[\s>]/.test(c) && t.push(`${o}: a <style> tag is global CSS and restyles every page of the app — delete it and style with theme classes (bg-background, text-foreground, glass-panel, btn-primary).`);
371
- let s = c.match(/\b(?:bg-(?:white|black)|(?:bg|text|border)-(?:gray|slate|zinc|neutral|stone)-\d+)\b/);
372
- s && n.push(`${o}: ${s[0]} is a hard-coded colour that ignores the owner's theme and stays wrong in light or dark mode — use bg-background, text-foreground, border-[var(--panel-border)], glass-panel or btn-primary.`);
371
+ let s = c.match(/(?<![\w-])(?:h|max-h)-(?:screen|dvh|svh|lvh|\[(?:100|9\d|8\d)(?:vh|dvh|svh|lvh)\])/);
372
+ s && n.push(`${o}: ${s[0]} makes the page exactly one screen tall and strands everything below it on a phone — the page is already inside a panel that scrolls, so let it be as long as it needs and drop the height and any overflow-hidden around it.`);
373
+ let l = c.match(z);
374
+ l && n.push(`${o}: "${l[0]}" is wording off the owner's admin screens — the page is for its visitors, not for the owner or for you. Delete it and any prompt or copy-this box on the page.`);
375
+ let u = c.match(/\b(?:bg-(?:white|black)|(?:bg|text|border)-(?:gray|slate|zinc|neutral|stone)-\d+)\b/);
376
+ u && n.push(`${o}: ${u[0]} is a hard-coded colour that ignores the owner's theme and stays wrong in light or dark mode — use bg-background, text-foreground, border-[var(--panel-border)], glass-panel or btn-primary.`);
373
377
  }
374
378
  }
375
379
  return {
@@ -377,8 +381,21 @@ function H(e) {
377
381
  warnings: n
378
382
  };
379
383
  }
384
+ var H = (e, t) => {
385
+ let n = [], r = t.replace(/\/\*[\s\S]*?\*\//g, "");
386
+ for (let [, t, i] of r.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
387
+ let r = t.trim(), a = /(?:^|[\s;])(?:font-size|line-height|font)\s*:/.test(i);
388
+ if (/\.page-title\b/.test(r)) {
389
+ n.push(`${e}: the rule for \`${r.replace(/\s+/g, " ")}\` styles the app's page title, which is the library's chrome and not this file's to restyle — delete the rule; a page heading you want to size is one you write yourself inside a content file.`);
390
+ continue;
391
+ }
392
+ let o = r.split(",").map((e) => e.trim()).filter((e) => /^h[1-3]$/.test(e));
393
+ o.length && a && n.push(`${e}: this rule sets a size on \`${o.join(", ")}\`, which changes every page title in the app — delete the size (font-weight here is fine) and size the headings you write inside your own content file instead.`);
394
+ }
395
+ return n;
396
+ };
380
397
  function U(e, t) {
381
- return H(e.map((e) => ({
398
+ return V(e.map((e) => ({
382
399
  file: e.file,
383
400
  source: t(e.abs)
384
401
  })));
@@ -418,12 +435,16 @@ var $ = (e, n) => {
418
435
  for (let { rel: n, source: i } of K) if (r === Y(t.join(e, n))) return i;
419
436
  return null;
420
437
  };
421
- function ee() {
422
- let t = process.cwd(), n = !1, r = "build", i = X, a = () => {
423
- let n = U(x(t), (t) => e.readFileSync(t, "utf8"));
438
+ function ne() {
439
+ let n = process.cwd(), r = !1, i = "build", a = X, o = () => {
440
+ let r = U(x(n), (t) => e.readFileSync(t, "utf8")), i = t.join(n, "src", "your-ai-workflow-firebase-os", "theme.css"), a = e.existsSync(i) ? H("src/your-ai-workflow-firebase-os/theme.css", e.readFileSync(i, "utf8")) : [];
424
441
  return {
425
- ...n,
426
- errors: [...n.errors, ...T(t)]
442
+ ...r,
443
+ errors: [
444
+ ...r.errors,
445
+ ...ee(n),
446
+ ...a
447
+ ]
427
448
  };
428
449
  };
429
450
  return {
@@ -436,49 +457,49 @@ function ee() {
436
457
  "react-router-dom"
437
458
  ] } }),
438
459
  configResolved(e) {
439
- t = e.root, r = e.command, i = e.logger, n = y(t), n && (Z(t, i), Q(t));
460
+ n = e.root, i = e.command, a = e.logger, r = y(n), r && (Z(n, a), Q(n));
440
461
  },
441
462
  resolveId(e) {
442
463
  return e === W ? G : null;
443
464
  },
444
465
  buildStart() {
445
- if (!n) return;
446
- let { errors: e, warnings: t } = a();
466
+ if (!r) return;
467
+ let { errors: e, warnings: t } = o();
447
468
  for (let e of t) this.warn(e);
448
- if (e.length !== 0) if (r === "build") this.error(e[0]);
449
- else for (let t of e) i.error(t);
469
+ if (e.length !== 0) if (i === "build") this.error(e[0]);
470
+ else for (let t of e) a.error(t);
450
471
  },
451
472
  load(e) {
452
- if (!n) return null;
473
+ if (!r) return null;
453
474
  if (e === G) {
454
- let e = x(t), { errors: n } = a();
455
- return n.length && this.error(n[0]), O(e);
475
+ let e = x(n), { errors: t } = o();
476
+ return t.length && this.error(t[0]), D(e);
456
477
  }
457
- return $(t, e);
478
+ return $(n, e);
458
479
  },
459
480
  configureServer(e) {
460
- if (!n) return;
461
- let r = () => {
481
+ if (!r) return;
482
+ let t = () => {
462
483
  let t = e.moduleGraph.getModuleById(G);
463
484
  t && e.moduleGraph.invalidateModule(t), e.ws.send({
464
485
  type: "full-reload",
465
486
  path: "*"
466
487
  });
467
- }, i = (n) => {
468
- let i = Y(n);
469
- if ($(t, i) !== null) {
470
- Z(t, e.config.logger);
488
+ }, i = (r) => {
489
+ let i = Y(r);
490
+ if ($(n, i) !== null) {
491
+ Z(n, e.config.logger);
471
492
  return;
472
493
  }
473
- if (!b(t, i) && !E(i)) return;
474
- r();
475
- let { errors: o, warnings: s } = a();
494
+ if (!b(n, i) && !T(i)) return;
495
+ t();
496
+ let { errors: a, warnings: s } = o();
476
497
  for (let t of s) e.config.logger.warn(t);
477
- for (let t of o) e.config.logger.error(t);
498
+ for (let t of a) e.config.logger.error(t);
478
499
  };
479
500
  e.watcher.on("add", i), e.watcher.on("unlink", i), e.watcher.on("change", i);
480
501
  }
481
502
  };
482
503
  }
483
504
  //#endregion
484
- export { i as CANONICAL_APP_TSX, o as CANONICAL_MAIN_TSX, c as CONFIGS_DIR, s as CONSUMER_DIR, a as CONSUMER_REGISTRY_TS, l as MICROCOMPONENTS_DIR, n as OWNED_BANNER, G as RESOLVED_VIRTUAL_ID, u as SHIPPED_CONFIG_FILES, W as VIRTUAL_ID, r as VIRTUAL_REGISTRIES_ID, _ as classifyConfigFile, x as discover, Q as ensureConsumerRegistry, g as fileIdFromConfigFile, m as formIdFromFile, y as isConsumerRoot, b as isDiscoveredPath, h as microcomponentKeysFromFile, q as ownedMessage, p as pageIdFromFile, S as registrable, Z as restoreOwnedFiles, N as stripComments, f as tabIdFromFile, H as validate, U as validateDiscovered, k as virtualModuleSource, O as virtualModuleSourceFor, ee as yourAiFirebase };
505
+ export { i as CANONICAL_APP_TSX, o as CANONICAL_MAIN_TSX, c as CONFIGS_DIR, s as CONSUMER_DIR, a as CONSUMER_REGISTRY_TS, l as MICROCOMPONENTS_DIR, n as OWNED_BANNER, G as RESOLVED_VIRTUAL_ID, u as SHIPPED_CONFIG_FILES, W as VIRTUAL_ID, r as VIRTUAL_REGISTRIES_ID, _ as classifyConfigFile, x as discover, Q as ensureConsumerRegistry, g as fileIdFromConfigFile, m as formIdFromFile, y as isConsumerRoot, b as isDiscoveredPath, h as microcomponentKeysFromFile, q as ownedMessage, p as pageIdFromFile, S as registrable, Z as restoreOwnedFiles, j as stripComments, f as tabIdFromFile, V as validate, U as validateDiscovered, te as virtualModuleSource, D as virtualModuleSourceFor, ne as yourAiFirebase };