@flamingo-stack/openframe-frontend-core 0.0.319 → 0.0.321-snapshot.20260625085235

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 (121) hide show
  1. package/dist/{chunk-V2OAUUF6.cjs → chunk-27UIZKPP.cjs} +31 -31
  2. package/dist/{chunk-V2OAUUF6.cjs.map → chunk-27UIZKPP.cjs.map} +1 -1
  3. package/dist/{chunk-JIU2I6LU.cjs → chunk-2JFIPRZM.cjs} +25 -25
  4. package/dist/{chunk-JIU2I6LU.cjs.map → chunk-2JFIPRZM.cjs.map} +1 -1
  5. package/dist/{chunk-2RQV7JLA.js → chunk-2L6XJRWU.js} +2 -2
  6. package/dist/{chunk-ODMCD663.js → chunk-2ZMEIVHB.js} +4 -4
  7. package/dist/{chunk-7FIWPFLE.js → chunk-3CUHOXPN.js} +4 -4
  8. package/dist/{chunk-G7CRSNFS.js → chunk-3NOGHXE5.js} +2 -2
  9. package/dist/{chunk-7ZHCRY2V.cjs → chunk-6GHEXJ6H.cjs} +5 -5
  10. package/dist/{chunk-7ZHCRY2V.cjs.map → chunk-6GHEXJ6H.cjs.map} +1 -1
  11. package/dist/{chunk-J4FCWWO6.cjs → chunk-AOD7KNNL.cjs} +62 -62
  12. package/dist/{chunk-J4FCWWO6.cjs.map → chunk-AOD7KNNL.cjs.map} +1 -1
  13. package/dist/{chunk-5B37J3B5.cjs → chunk-APGXPHP2.cjs} +15 -15
  14. package/dist/{chunk-5B37J3B5.cjs.map → chunk-APGXPHP2.cjs.map} +1 -1
  15. package/dist/{chunk-NG7P653A.js → chunk-HYW3BYDX.js} +2 -2
  16. package/dist/{chunk-ARQ3R7WZ.js → chunk-KFEIMA2T.js} +2 -2
  17. package/dist/{chunk-XAGD3XZV.js → chunk-KJNTCTV4.js} +4 -4
  18. package/dist/{chunk-APEJR6DV.cjs → chunk-M5RW5ASP.cjs} +26 -26
  19. package/dist/{chunk-APEJR6DV.cjs.map → chunk-M5RW5ASP.cjs.map} +1 -1
  20. package/dist/{chunk-7WMHKVV7.cjs → chunk-MQFGEYOG.cjs} +12 -12
  21. package/dist/{chunk-7WMHKVV7.cjs.map → chunk-MQFGEYOG.cjs.map} +1 -1
  22. package/dist/{chunk-SVPVDSHA.js → chunk-MQHD6CTN.js} +4280 -4021
  23. package/dist/chunk-MQHD6CTN.js.map +1 -0
  24. package/dist/{chunk-CGG7EWYG.cjs → chunk-NCFCQWMH.cjs} +56 -56
  25. package/dist/{chunk-CGG7EWYG.cjs.map → chunk-NCFCQWMH.cjs.map} +1 -1
  26. package/dist/{chunk-4XHPUYL7.cjs → chunk-NTEAD4ZM.cjs} +37 -37
  27. package/dist/{chunk-4XHPUYL7.cjs.map → chunk-NTEAD4ZM.cjs.map} +1 -1
  28. package/dist/{chunk-QJOSQVIR.js → chunk-PZYSR23M.js} +2 -2
  29. package/dist/{chunk-LF5LDJOP.js → chunk-S3X2KEFA.js} +2 -2
  30. package/dist/{chunk-RXCP4OV4.cjs → chunk-S6W5YPAB.cjs} +9 -9
  31. package/dist/{chunk-RXCP4OV4.cjs.map → chunk-S6W5YPAB.cjs.map} +1 -1
  32. package/dist/{chunk-ZD5ZDEL5.cjs → chunk-UFUOM6ZT.cjs} +1644 -1385
  33. package/dist/chunk-UFUOM6ZT.cjs.map +1 -0
  34. package/dist/{chunk-2D3RINOJ.js → chunk-WQ4OIM4E.js} +2 -2
  35. package/dist/{chunk-4YFOBTFE.js → chunk-XF3GIE5U.js} +4 -4
  36. package/dist/{chunk-B34YGPIB.cjs → chunk-YKIU2GXU.cjs} +7 -7
  37. package/dist/{chunk-B34YGPIB.cjs.map → chunk-YKIU2GXU.cjs.map} +1 -1
  38. package/dist/components/case-studies/index.cjs +8 -8
  39. package/dist/components/case-studies/index.js +2 -2
  40. package/dist/components/chat/chat-context-picker.d.ts +11 -1
  41. package/dist/components/chat/chat-context-picker.d.ts.map +1 -1
  42. package/dist/components/chat/chat-input.d.ts.map +1 -1
  43. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  44. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  45. package/dist/components/chat/context-items-list.d.ts.map +1 -1
  46. package/dist/components/chat/embeddable-chat.d.ts +13 -1
  47. package/dist/components/chat/embeddable-chat.d.ts.map +1 -1
  48. package/dist/components/chat/index.cjs +2 -2
  49. package/dist/components/chat/index.js +1 -1
  50. package/dist/components/chat/mingo-chat-history.d.ts +11 -2
  51. package/dist/components/chat/mingo-chat-history.d.ts.map +1 -1
  52. package/dist/components/chat/mingo-welcome.d.ts +5 -1
  53. package/dist/components/chat/mingo-welcome.d.ts.map +1 -1
  54. package/dist/components/chat/remark-mention-chips.d.ts +11 -5
  55. package/dist/components/chat/remark-mention-chips.d.ts.map +1 -1
  56. package/dist/components/chat/types/component.types.d.ts +30 -7
  57. package/dist/components/chat/types/component.types.d.ts.map +1 -1
  58. package/dist/components/contact/index.cjs +3 -3
  59. package/dist/components/contact/index.js +2 -2
  60. package/dist/components/docs/index.cjs +5 -5
  61. package/dist/components/docs/index.js +4 -4
  62. package/dist/components/embeds/index.cjs +3 -3
  63. package/dist/components/embeds/index.js +2 -2
  64. package/dist/components/faq/index.cjs +3 -3
  65. package/dist/components/faq/index.js +2 -2
  66. package/dist/components/features/index.cjs +8 -2
  67. package/dist/components/features/index.cjs.map +1 -1
  68. package/dist/components/features/index.d.ts +1 -0
  69. package/dist/components/features/index.d.ts.map +1 -1
  70. package/dist/components/features/index.js +7 -1
  71. package/dist/components/features/paths-display.d.ts +16 -1
  72. package/dist/components/features/paths-display.d.ts.map +1 -1
  73. package/dist/components/features/warning-block.d.ts +32 -0
  74. package/dist/components/features/warning-block.d.ts.map +1 -0
  75. package/dist/components/help-center-pages/index.cjs +20 -20
  76. package/dist/components/help-center-pages/index.js +11 -11
  77. package/dist/components/index.cjs +126 -120
  78. package/dist/components/index.cjs.map +1 -1
  79. package/dist/components/index.js +15 -9
  80. package/dist/components/index.js.map +1 -1
  81. package/dist/components/navigation/index.cjs +2 -2
  82. package/dist/components/navigation/index.js +1 -1
  83. package/dist/components/onboarding-guides/index.cjs +5 -5
  84. package/dist/components/onboarding-guides/index.js +4 -4
  85. package/dist/components/related-content/index.cjs +3 -3
  86. package/dist/components/related-content/index.js +2 -2
  87. package/dist/components/tickets/index.cjs +5 -5
  88. package/dist/components/tickets/index.js +4 -4
  89. package/dist/components/ui/index.cjs +2 -2
  90. package/dist/components/ui/index.js +1 -1
  91. package/dist/index.cjs +8 -2
  92. package/dist/index.cjs.map +1 -1
  93. package/dist/index.js +7 -1
  94. package/package.json +1 -1
  95. package/src/components/chat/chat-context-picker.tsx +77 -9
  96. package/src/components/chat/chat-input.tsx +524 -489
  97. package/src/components/chat/chat-message-enhanced.tsx +4 -2
  98. package/src/components/chat/chat-message-list.tsx +2 -0
  99. package/src/components/chat/context-items-list.tsx +9 -1
  100. package/src/components/chat/embeddable-chat.tsx +70 -57
  101. package/src/components/chat/mingo-chat-history.tsx +136 -53
  102. package/src/components/chat/mingo-welcome.tsx +6 -1
  103. package/src/components/chat/remark-mention-chips.ts +13 -7
  104. package/src/components/chat/types/component.types.ts +31 -7
  105. package/src/components/features/index.ts +1 -0
  106. package/src/components/features/paths-display.tsx +32 -1
  107. package/src/components/features/warning-block.tsx +54 -0
  108. package/src/stories/WarningBlock.stories.tsx +167 -0
  109. package/dist/chunk-SVPVDSHA.js.map +0 -1
  110. package/dist/chunk-ZD5ZDEL5.cjs.map +0 -1
  111. /package/dist/{chunk-2RQV7JLA.js.map → chunk-2L6XJRWU.js.map} +0 -0
  112. /package/dist/{chunk-ODMCD663.js.map → chunk-2ZMEIVHB.js.map} +0 -0
  113. /package/dist/{chunk-7FIWPFLE.js.map → chunk-3CUHOXPN.js.map} +0 -0
  114. /package/dist/{chunk-G7CRSNFS.js.map → chunk-3NOGHXE5.js.map} +0 -0
  115. /package/dist/{chunk-NG7P653A.js.map → chunk-HYW3BYDX.js.map} +0 -0
  116. /package/dist/{chunk-ARQ3R7WZ.js.map → chunk-KFEIMA2T.js.map} +0 -0
  117. /package/dist/{chunk-XAGD3XZV.js.map → chunk-KJNTCTV4.js.map} +0 -0
  118. /package/dist/{chunk-QJOSQVIR.js.map → chunk-PZYSR23M.js.map} +0 -0
  119. /package/dist/{chunk-LF5LDJOP.js.map → chunk-S3X2KEFA.js.map} +0 -0
  120. /package/dist/{chunk-2D3RINOJ.js.map → chunk-WQ4OIM4E.js.map} +0 -0
  121. /package/dist/{chunk-4YFOBTFE.js.map → chunk-XF3GIE5U.js.map} +0 -0
@@ -132,6 +132,17 @@ export interface ChatMessageEnhancedProps extends Omit<HTMLAttributes<HTMLDivEle
132
132
  * glyph). Optional — chips render label-only when omitted.
133
133
  */
134
134
  resolveContextIcon?: (item: ChatContextItem) => ReactNode
135
+ /**
136
+ * Host renderer that REPLACES the default label-only context chip for an
137
+ * attached item with a self-fetching entity chip — so a user's manually
138
+ * attached context renders IDENTICALLY to an inline `@marker:id` mention
139
+ * (same live name resolution, same link). Mirror of `renderMention`, but for
140
+ * the `contextItems` strip instead of inline tokens. Return `null` for an
141
+ * item the host can't render → the lib falls back to the label pill. Keep the
142
+ * function identity stable (module const / `useCallback`) so the message memo
143
+ * holds across streaming chunks.
144
+ */
145
+ renderContextItem?: (item: ChatContextItem) => ReactNode
135
146
  /**
136
147
  * Host renderer for inline AI mentions `@marker:id` — the ASSISTANT echoing
137
148
  * `@device:<machineId>` (etc.) in its reply. DIRECT MIRROR of
@@ -215,6 +226,10 @@ export interface ChatMessageListProps extends HTMLAttributes<HTMLDivElement> {
215
226
  /** Lead-icon resolver for per-message context chips (maps a context item to
216
227
  * its entity-type glyph). Forwarded to every message's ChatMessageEnhanced. */
217
228
  resolveContextIcon?: (item: ChatContextItem) => ReactNode
229
+ /** Host renderer that REPLACES the default context chip with a self-fetching
230
+ * entity chip (so attached context renders like an inline mention).
231
+ * Forwarded verbatim to every message's ChatMessageEnhanced. */
232
+ renderContextItem?: (item: ChatContextItem) => ReactNode
218
233
  /** Host renderer for inline AI mentions `@marker:id` (mirror of
219
234
  * `renderEntityCard`). Forwarded verbatim to every message's
220
235
  * ChatMessageEnhanced; returns a self-fetching chip per entity type. */
@@ -408,13 +423,22 @@ export interface ChatInputRef {
408
423
  * context item / closes the picker so the `@query` scaffolding doesn't get
409
424
  * sent as literal text. No-op when no mention token is active. */
410
425
  removeMentionTrigger: () => void
411
- /** Commit a SINGLE-SELECT mention: replace the trailing `@query` being typed
412
- * with the literal `@<type>:<id>` token (`token` = `"<type>:<id>"`, plus a
413
- * trailing space) and strip any previously committed token so only one
414
- * mention reference lives in the draft. Used by the composer's `@`-mention
415
- * flow so the picked entity stays visible in the input AND rides out in the
416
- * context — deleting the token text removes it from context. */
417
- commitMention: (token: string) => void
426
+ /** Commit a mention: replace the trailing `@query` being typed with the
427
+ * literal `@<type>:<id>` token (`token` = `"<type>:<id>"`, plus a trailing
428
+ * space). MULTIPLE mentions coexist — prior committed tokens are left in
429
+ * place. The optional `meta` gives the inline chip its display name + icon
430
+ * (the contenteditable renders the token as a chip); without it the chip
431
+ * falls back to the id. Used by the composer's `@`-mention flow so the picked
432
+ * entity rides out in the context — deleting the chip removes it from context. */
433
+ commitMention: (token: string, meta?: MentionMeta) => void
434
+ }
435
+
436
+ /** Display metadata for an inline mention chip rendered inside the composer. */
437
+ export interface MentionMeta {
438
+ /** Resolved entity name shown in the chip (e.g. `'ELK-PROD-07'`). */
439
+ label: string
440
+ /** Optional lead icon (entity-type glyph). */
441
+ icon?: ReactNode
418
442
  }
419
443
 
420
444
  // ========== Chat Typing Indicator Props ==========
@@ -48,6 +48,7 @@ export * from './social-links-manager'
48
48
  export * from './start-with-openframe-button'
49
49
  export * from './status-filter-component'
50
50
  export * from './tags-selector'
51
+ export * from './warning-block'
51
52
  // Unified video primitives — single source of truth across all platforms.
52
53
  // `<Video>` replaces the deleted `<VideoPlayer>` + `<YouTubeEmbed>` pair;
53
54
  // `<EntityVideoSection>` + `<VideoBitesDisplay>` are the public detail-page
@@ -39,6 +39,13 @@ export interface PathsDisplayProps {
39
39
  * Size of the copy icon (default: 'w-6 h-6')
40
40
  */
41
41
  copyIconSize?: string
42
+
43
+ /**
44
+ * Optional icon rendered at the start of every row, before the path text.
45
+ * Useful for showing a platform logo next to a command (e.g. the Windows
46
+ * logo beside "Run PowerShell as Local Administrator").
47
+ */
48
+ leadingIcon?: React.ReactNode
42
49
  }
43
50
 
44
51
  /**
@@ -77,7 +84,8 @@ export function PathsDisplay({
77
84
  description,
78
85
  className,
79
86
  showCopyButtons = true,
80
- copyIconSize = 'w-6 h-6'
87
+ copyIconSize = 'w-6 h-6',
88
+ leadingIcon
81
89
  }: PathsDisplayProps) {
82
90
  if (!paths || paths.length === 0) {
83
91
  return null
@@ -101,6 +109,9 @@ export function PathsDisplay({
101
109
  key={path}
102
110
  className="flex items-center gap-4 p-4 border-b border-ods-border last:border-b-0"
103
111
  >
112
+ {leadingIcon && (
113
+ <span className="shrink-0 text-ods-text-primary">{leadingIcon}</span>
114
+ )}
104
115
  <span className="flex-1 min-w-0 text-h4 text-ods-text-primary truncate">
105
116
  {path}
106
117
  </span>
@@ -152,3 +163,23 @@ export type OpenFramePathsPlatform = keyof typeof OPENFRAME_PATHS
152
163
  export function getOpenFramePaths(platform: OpenFramePathsPlatform): string[] {
153
164
  return [...OPENFRAME_PATHS[platform]]
154
165
  }
166
+
167
+ /**
168
+ * Doctor command per platform. Run to diagnose installation issues and repair
169
+ * the agent (works even if the agent didn't install correctly).
170
+ */
171
+ export const OPENFRAME_DOCTOR_COMMANDS: Record<OpenFramePathsPlatform, string> = {
172
+ // PowerShell: Invoke-WebRequest / .\openframe-client.exe, mirroring the
173
+ // Windows install command pattern.
174
+ windows:
175
+ "Set-Location ~; Invoke-WebRequest -Uri 'github.com/openframe-client' -OutFile 'openframe-client.exe'; .\\openframe-client.exe doctor",
176
+ darwin: 'cd ~; wget github.com/openframe-client; openframe-client doctor',
177
+ linux: 'cd ~; wget github.com/openframe-client; openframe-client doctor'
178
+ } as const
179
+
180
+ /**
181
+ * Get the OpenFrame doctor command for a specific platform
182
+ */
183
+ export function getOpenFrameDoctorCommand(platform: OpenFramePathsPlatform): string {
184
+ return OPENFRAME_DOCTOR_COMMANDS[platform]
185
+ }
@@ -0,0 +1,54 @@
1
+ 'use client'
2
+
3
+ import { AlertTriangle } from 'lucide-react'
4
+ import React from 'react'
5
+ import { cn } from '../../utils/cn'
6
+
7
+ export interface WarningBlockProps {
8
+ /** Text rendered inside the highlighted warning banner header. */
9
+ title: React.ReactNode
10
+ /**
11
+ * Icon shown at the start of the banner. Defaults to a triangle alert icon.
12
+ * Pass `null` to hide the icon entirely.
13
+ */
14
+ icon?: React.ReactNode
15
+ /**
16
+ * Body content rendered below the banner — description paragraphs, one or more
17
+ * `PathsDisplay` lists, command rows, etc. Fully composable so a single block
18
+ * can mix text and multiple path groups (see the New Device warning blocks).
19
+ */
20
+ children?: React.ReactNode
21
+ /** Extra classes for the outer card container. */
22
+ className?: string
23
+ }
24
+
25
+ const DEFAULT_ICON = <AlertTriangle className="h-6 w-6" />
26
+
27
+ /**
28
+ * WarningBlock - a card with a highlighted "attention / warning" banner header
29
+ * followed by arbitrary body content.
30
+ *
31
+ * The banner reproduces the ODS warning callout (warning color on a muted
32
+ * warning background). Body content is fully composable: pass description
33
+ * paragraphs, one or more `PathsDisplay` lists, command rows, etc. as children.
34
+ *
35
+ * Spacing follows the ODS scale: card padding 16px / gap 12px, banner padding
36
+ * 12px / gap 16px. Typography uses `text-h3`, which is responsive (14px on
37
+ * mobile, 18px from `md` up) and bold by design-token default.
38
+ */
39
+ export function WarningBlock({ title, icon = DEFAULT_ICON, children, className }: WarningBlockProps) {
40
+ return (
41
+ <div
42
+ className={cn(
43
+ 'flex flex-col gap-3 rounded-[6px] border border-ods-border bg-ods-card p-4',
44
+ className
45
+ )}
46
+ >
47
+ <div className="flex items-start gap-4 overflow-hidden rounded-[6px] bg-ods-warning-secondary p-3 text-ods-warning">
48
+ {icon != null && <span className="shrink-0">{icon}</span>}
49
+ <p className="min-w-0 flex-1 text-h3">{title}</p>
50
+ </div>
51
+ {children}
52
+ </div>
53
+ )
54
+ }
@@ -0,0 +1,167 @@
1
+ import type { Meta, StoryObj } from '@storybook/nextjs-vite';
2
+ import { OSTypeIcon } from '../components/features/os-type-badge';
3
+ import { OPENFRAME_DOCTOR_COMMANDS, PathsDisplay } from '../components/features/paths-display';
4
+ import { WarningBlock } from '../components/features/warning-block';
5
+
6
+ const meta = {
7
+ title: 'Features/WarningBlock',
8
+ component: WarningBlock,
9
+ parameters: {
10
+ docs: {
11
+ description: {
12
+ component:
13
+ 'A card with a highlighted "attention / warning" banner header followed by composable body content. Body is passed as children, so a single block can mix description paragraphs with one or more `PathsDisplay` lists (see the New Device warning blocks). Typography is responsive via ODS tokens (14px on mobile, 18px from `md` up).',
14
+ },
15
+ },
16
+ },
17
+ argTypes: {
18
+ title: { control: 'text' },
19
+ },
20
+ decorators: [
21
+ (Story) => (
22
+ <div style={{ maxWidth: 720 }}>
23
+ <Story />
24
+ </div>
25
+ ),
26
+ ],
27
+ } satisfies Meta<typeof WarningBlock>;
28
+
29
+ export default meta;
30
+ type Story = StoryObj<typeof meta>;
31
+
32
+ const copyPath = (path: string) => {
33
+ if (typeof navigator !== 'undefined' && navigator.clipboard) {
34
+ void navigator.clipboard.writeText(path);
35
+ }
36
+ };
37
+
38
+ /** Minimal usage — a banner title with a single description paragraph. */
39
+ export const Default: Story = {
40
+ args: {
41
+ title: 'Administrator privileges are required to install the OpenFrame agent.',
42
+ children: (
43
+ <p className="text-h4 text-ods-text-primary">
44
+ Run the command with the appropriate permissions for your platform.
45
+ </p>
46
+ ),
47
+ },
48
+ };
49
+
50
+ /**
51
+ * Antivirus warning from the New Device screen — description, a `PathsDisplay`
52
+ * list of exclusion folders, then a closing paragraph.
53
+ */
54
+ export const AntivirusWarning: Story = {
55
+ args: {
56
+ title: 'Your antivirus may block OpenFrame installation. This is a false positive.',
57
+ children: (
58
+ <>
59
+ <PathsDisplay
60
+ title="If blocked, add these folders to your antivirus exclusions list:"
61
+ paths={['C:\\Program Files\\OpenFrame\\', 'C:\\Users\\[Username]\\AppData\\Local\\OpenFrame\\']}
62
+ onCopyPath={copyPath}
63
+ />
64
+ <p className="text-h4 text-ods-text-primary">
65
+ Or temporarily disable protection during installation. OpenFrame is safe open-source software.
66
+ Blocks happen because new software needs time to build reputation with security vendors.
67
+ </p>
68
+ </>
69
+ ),
70
+ },
71
+ };
72
+
73
+ /**
74
+ * Doctor mode warning from the New Device screen — description plus a single
75
+ * copyable command row.
76
+ */
77
+ export const DoctorMode: Story = {
78
+ args: {
79
+ title: 'Device not appearing or stuck pending?',
80
+ children: (
81
+ <>
82
+ <p className="text-h4 text-ods-text-primary">
83
+ Run the doctor command to diagnose installation issues and repair the agent. It works even if
84
+ the agent didn&apos;t install correctly.
85
+ </p>
86
+ <PathsDisplay
87
+ paths={[OPENFRAME_DOCTOR_COMMANDS.windows]}
88
+ onCopyPath={copyPath}
89
+ />
90
+ </>
91
+ ),
92
+ },
93
+ };
94
+
95
+ /**
96
+ * Administrator privileges warning — a platform-specific instruction row (no
97
+ * copy button) framed by description paragraphs.
98
+ */
99
+ export const AdministratorPrivileges: Story = {
100
+ args: {
101
+ title: 'Administrator privileges are required to install the OpenFrame agent.',
102
+ children: (
103
+ <>
104
+ <p className="text-h4 text-ods-text-primary">
105
+ Run the command with the appropriate permissions for your platform:
106
+ </p>
107
+ <PathsDisplay
108
+ paths={['Run PowerShell as Local Administrator']}
109
+ showCopyButtons={false}
110
+ leadingIcon={<OSTypeIcon osType="windows" size="w-6 h-6" />}
111
+ />
112
+ <p className="text-h4 text-ods-text-primary">
113
+ Without elevated privileges, the installation will fail silently. Right-click PowerShell and
114
+ select &quot;Run as administrator,&quot; or contact your IT admin if you don&apos;t have local
115
+ admin rights.
116
+ </p>
117
+ </>
118
+ ),
119
+ },
120
+ };
121
+
122
+ /** All three New Device warning blocks stacked, matching the Figma layout. */
123
+ export const NewDeviceBlocks: Story = {
124
+ args: { title: '' },
125
+ render: () => (
126
+ <div className="flex flex-col gap-6">
127
+ <WarningBlock title="Administrator privileges are required to install the OpenFrame agent.">
128
+ <p className="text-h4 text-ods-text-primary">
129
+ Run the command with the appropriate permissions for your platform:
130
+ </p>
131
+ <PathsDisplay
132
+ paths={['Run PowerShell as Local Administrator']}
133
+ showCopyButtons={false}
134
+ leadingIcon={<OSTypeIcon osType="windows" size="w-6 h-6" />}
135
+ />
136
+ <p className="text-h4 text-ods-text-primary">
137
+ Without elevated privileges, the installation will fail silently. Right-click PowerShell and
138
+ select &quot;Run as administrator,&quot; or contact your IT admin if you don&apos;t have local
139
+ admin rights.
140
+ </p>
141
+ </WarningBlock>
142
+
143
+ <WarningBlock title="Your antivirus may block OpenFrame installation. This is a false positive.">
144
+ <PathsDisplay
145
+ title="If blocked, add these folders to your antivirus exclusions list:"
146
+ paths={['C:\\Program Files\\OpenFrame\\', 'C:\\Users\\[Username]\\AppData\\Local\\OpenFrame\\']}
147
+ onCopyPath={copyPath}
148
+ />
149
+ <p className="text-h4 text-ods-text-primary">
150
+ Or temporarily disable protection during installation. OpenFrame is safe open-source software.
151
+ Blocks happen because new software needs time to build reputation with security vendors.
152
+ </p>
153
+ </WarningBlock>
154
+
155
+ <WarningBlock title="Device not appearing or stuck pending?">
156
+ <p className="text-h4 text-ods-text-primary">
157
+ Run the doctor command to diagnose installation issues and repair the agent. It works even if
158
+ the agent didn&apos;t install correctly.
159
+ </p>
160
+ <PathsDisplay
161
+ paths={[OPENFRAME_DOCTOR_COMMANDS.windows]}
162
+ onCopyPath={copyPath}
163
+ />
164
+ </WarningBlock>
165
+ </div>
166
+ ),
167
+ };