@open-mercato/ui 0.6.7-develop.6784.1.f80b9afce5 → 0.6.7-develop.6788.1.c2a1520a30

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.
@@ -1,3 +1,3 @@
1
1
  Generated lucide registry with 145 icons -> /home/runner/work/open-mercato/open-mercato/packages/ui/src/backend/icons/lucideRegistry.generated.tsx
2
- [build:ui] found 396 entry points
2
+ [build:ui] found 397 entry points
3
3
  [build:ui] built successfully
package/build.mjs CHANGED
@@ -3,6 +3,7 @@ import { readFileSync, writeFileSync } from 'node:fs'
3
3
  import { dirname, join } from 'node:path'
4
4
  import { fileURLToPath } from 'node:url'
5
5
  import { buildPackage } from '../../scripts/build-package.mjs'
6
+ import { buildLucideRegistrySource } from './scripts/lucideRegistrySource.cjs'
6
7
 
7
8
  const packageDir = dirname(fileURLToPath(import.meta.url))
8
9
 
@@ -88,61 +89,8 @@ async function generateLucideRegistry() {
88
89
  }
89
90
  }
90
91
 
91
- resolved.sort((a, b) => a.kebab.localeCompare(b.kebab))
92
- const uniqueExports = [...new Set(resolved.map((r) => r.exportName))].sort((a, b) => a.localeCompare(b))
93
-
94
- const importSection = uniqueExports.length
95
- ? `import {\n${uniqueExports.map((n) => ` ${n},`).join('\n')}\n} from 'lucide-react'\n`
96
- : ``
97
-
98
- const registryEntries = resolved.map((r) => ` '${r.kebab}': ${r.exportName},`).join('\n')
99
-
100
92
  const outPath = join(packageDir, 'src/backend/icons/lucideRegistry.generated.tsx')
101
- const file = `/* eslint-disable */
102
- // AUTO-GENERATED by @open-mercato/ui build. Do not edit by hand.
103
- // Generated from discovered icon string usages across the repo.
104
-
105
- import type * as React from 'react'
106
- import type { LucideIcon } from 'lucide-react'
107
- ${importSection}
108
- export const LUCIDE_ICON_REGISTRY: Record<string, LucideIcon> = {
109
- ${registryEntries ? `${registryEntries}\n` : ''}}
110
-
111
- function normalizeKebabIconName(input: string): string {
112
- const trimmed = input.trim()
113
- if (!trimmed) return ''
114
- const withoutPrefix = trimmed.startsWith('lucide:') ? trimmed.slice('lucide:'.length) : trimmed
115
- if (!withoutPrefix) return ''
116
- if (!withoutPrefix.includes('-') && !withoutPrefix.includes('_') && !withoutPrefix.includes(' ') && /[A-Z]/.test(withoutPrefix)) {
117
- return withoutPrefix
118
- .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
119
- .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
120
- .toLowerCase()
121
- }
122
- return withoutPrefix
123
- .replace(/[_\\s]+/g, '-')
124
- .replace(/-+/g, '-')
125
- .toLowerCase()
126
- }
127
-
128
- export function resolveRegisteredLucideIcon(name: string | undefined): LucideIcon | null {
129
- if (!name) return null
130
- const normalized = normalizeKebabIconName(name)
131
- if (!normalized) return null
132
- return (LUCIDE_ICON_REGISTRY as Record<string, LucideIcon | undefined>)[normalized] ?? null
133
- }
134
-
135
- export function resolveRegisteredLucideIconNode(
136
- name: string | undefined,
137
- className: string
138
- ): React.ReactNode | null {
139
- const Icon = resolveRegisteredLucideIcon(name)
140
- if (!Icon) return null
141
- return <Icon className={className} />
142
- }
143
- `
144
-
145
- writeFileSync(outPath, file)
93
+ writeFileSync(outPath, buildLucideRegistrySource(resolved))
146
94
  console.log(`Generated lucide registry with ${resolved.length} icons -> ${outPath}`)
147
95
  }
148
96
 
package/dist/ai/AiChat.js CHANGED
@@ -127,10 +127,29 @@ function mapErrorCodeToVariant(code) {
127
127
  const warningCodes = /* @__PURE__ */ new Set([
128
128
  "tool_not_whitelisted",
129
129
  "tool_features_denied",
130
- "attachment_type_not_accepted"
130
+ "attachment_type_not_accepted",
131
+ // Content-safety rejections are soft: the user can rephrase and retry.
132
+ "moderation_blocked",
133
+ "moderation_unavailable"
131
134
  ]);
132
135
  return warningCodes.has(code) ? "warning" : "destructive";
133
136
  }
137
+ function resolveChatErrorMessage(code, fallback, translate) {
138
+ switch (code) {
139
+ case "moderation_blocked":
140
+ return translate(
141
+ "ai_assistant.errors.moderationBlocked",
142
+ "Your message was blocked by the content safety filter. Please rephrase and try again."
143
+ );
144
+ case "moderation_unavailable":
145
+ return translate(
146
+ "ai_assistant.errors.moderationUnavailable",
147
+ "The content safety check is temporarily unavailable. Please try again in a moment."
148
+ );
149
+ default:
150
+ return fallback;
151
+ }
152
+ }
134
153
  const MARKDOWN_TYPOGRAPHY_CLASS = cn(
135
154
  "[&_p]:my-1 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0",
136
155
  "[&_ul]:my-2 [&_ol]:my-2 [&_ul]:ml-4 [&_ol]:ml-4 [&_ul]:list-disc [&_ol]:list-decimal",
@@ -1176,7 +1195,7 @@ function AiChat({
1176
1195
  /* @__PURE__ */ jsx(AlertTitle, { children: t("ai_assistant.chat.errorTitle", "Agent dispatch failed") }),
1177
1196
  /* @__PURE__ */ jsxs(AlertDescription, { children: [
1178
1197
  chat.error.code ? /* @__PURE__ */ jsx("span", { className: "mr-2 font-mono text-xs", children: chat.error.code }) : null,
1179
- chat.error.message
1198
+ resolveChatErrorMessage(chat.error.code, chat.error.message, t)
1180
1199
  ] })
1181
1200
  ] }) : null,
1182
1201
  chat.isOwner === false ? /* @__PURE__ */ jsx(