@stina/extension-api 1.7.0 → 1.16.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.
@@ -770,6 +770,60 @@ interface CalendarEventProps extends ExtensionComponentData {
770
770
  /** One short line of context. */
771
771
  notes?: string;
772
772
  }
773
+ /**
774
+ * One event on an agenda.
775
+ *
776
+ * Timestamps rather than worded times, for the same reason as `CalendarEvent`:
777
+ * the agenda is about where today stands, and it can only keep that true if it
778
+ * knows when things actually start and end.
779
+ */
780
+ interface AgendaEvent {
781
+ /** Handed back to `onEventClickAction` as `$event.id`. Not shown. */
782
+ id?: string;
783
+ title: string;
784
+ /** ISO 8601, with an offset. */
785
+ start: string;
786
+ /** ISO 8601, with an offset. Absent for an event with no stated end. */
787
+ end?: string;
788
+ /** Drawn as a chip above the day's list rather than in it. */
789
+ allDay?: boolean;
790
+ /** One quiet line under the title: a place, a meeting link, a room. */
791
+ detail?: string;
792
+ }
793
+ /** One day on an agenda, as the caller groups them. */
794
+ interface AgendaDay {
795
+ /** The day's heading, e.g. "Idag". */
796
+ label: string;
797
+ /** A quieter line beside the heading, e.g. "tis 6 okt". */
798
+ date?: string;
799
+ events: AgendaEvent[];
800
+ }
801
+ /**
802
+ * The extension API properties for the Agenda component.
803
+ *
804
+ * A day's schedule that knows what time it is. What is behind us recedes, what
805
+ * is running is lifted out with its progress drawn down its edge, what comes
806
+ * next counts down, and a line marks the gap we are in. The host works all of
807
+ * that out from the timestamps and keeps it current while the panel is open.
808
+ *
809
+ * For milestones, or anything whose times are words rather than instants, use
810
+ * `Timeline`. This is for a schedule.
811
+ */
812
+ interface AgendaProps extends ExtensionComponentData {
813
+ component: 'Agenda';
814
+ /** Heading above the days. */
815
+ title?: string;
816
+ /** Icon shown to the left of the title. */
817
+ icon?: HugeIconName;
818
+ days: AgendaDay[];
819
+ /**
820
+ * Word clashes: "Krockar med 11:00", "2 samtidigt". Off by default, since a
821
+ * schedule of lessons or training sessions has nothing to warn about.
822
+ */
823
+ warnOverlaps?: boolean;
824
+ /** Called when an event is clicked, with the event in scope as `$event`. */
825
+ onEventClickAction?: ExtensionActionRef;
826
+ }
773
827
 
774
828
  /**
775
829
  * What an extension can contribute to Stina
@@ -2611,4 +2665,4 @@ interface ActionResult {
2611
2665
  error?: string;
2612
2666
  }
2613
2667
 
2614
- export { type ConnectedAccountsAPI as $, type ActionResult as A, type ProvidersAPI as B, type ChatMessage as C, type Disposable as D, type ExtensionContributions as E, type ToolsAPI as F, type GetModelsOptions as G, type HugeIconName as H, type ActionsAPI as I, type EventsAPI as J, type SchedulerAPI as K, type LocalizedString as L, type ModelInfo as M, type NetworkAPI as N, type SchedulerJobRequest as O, type PanelDefinition as P, type SchedulerSchedule as Q, type UserProfile as R, type SchedulerFirePayload as S, type ToolResult as T, type UserAPI as U, type VoiceSessionOptions as V, type ChatAPI as W, type ChatInstructionMessage as X, type ConversationPresentation as Y, type AttachmentsAPI as Z, type AttachmentContent as _, type ChatOptions as a, type MarkdownProps as a$, type ConnectedAccount as a0, type AccountAccessToken as a1, type LogAPI as a2, type BackgroundWorkersAPI as a3, type BackgroundTaskConfig as a4, type BackgroundTaskCallback as a5, type BackgroundTaskContext as a6, type BackgroundTaskHealth as a7, type BackgroundRestartPolicy as a8, type Query as a9, type ClockProps as aA, type ParagraphProps as aB, type ButtonProps as aC, type TextInputProps as aD, type PasswordInputProps as aE, type NumberInputProps as aF, type TextAreaProps as aG, type DateTimeInputProps as aH, type SelectProps as aI, type IconPickerProps as aJ, type VerticalStackProps as aK, type HorizontalStackProps as aL, type GridProps as aM, type DividerProps as aN, type IconProps as aO, type IconButtonType as aP, type IconButtonProps as aQ, type PanelAction as aR, type PanelProps as aS, type ToggleProps as aT, type CollapsibleProps as aU, type FrameVariant as aV, type FrameProps as aW, type ListProps as aX, type PillVariant as aY, type PillProps as aZ, type CheckboxProps as a_, type QueryOptions as aa, type StorageAPI as ab, type SecretsAPI as ac, type StorageCollectionConfig as ad, type StorageContributions as ae, type AIProvider as af, type ModelCapabilities as ag, type ChatImage as ah, type ChatFile as ai, type ToolCall as aj, type VoiceTransportRequest as ak, type Tool as al, type ToolAttachment as am, type Action as an, type ExtensionModule as ao, type AllowedCSSProperty as ap, type ExtensionComponentStyle as aq, type ExtensionComponentData as ar, type ExtensionComponentIterator as as, type ExtensionComponentChildren as at, type ExtensionActionCall as au, type ExtensionActionRef as av, type ExtensionDataSource as aw, type ExtensionPanelDefinition as ax, type HeaderProps as ay, type LabelProps as az, type StreamEvent as b, type TextPreviewProps as b0, type ModalProps as b1, type ConditionalGroupProps as b2, type WeatherCondition as b3, type WeatherWind as b4, type WeatherNowProps as b5, type WeatherForecastStep as b6, type WeatherForecastProps as b7, type ChartKind as b8, type ChartSeries as b9, type ChartProps as ba, type StatTrend as bb, type StatTileProps as bc, type ProgressShape as bd, type ProgressColor as be, type ProgressBarProps as bf, type KeyValueRow as bg, type KeyValueListProps as bh, type TimelineVariant as bi, type TimelineEntry as bj, type TimelineProps as bk, type NoteVariant as bl, type NoteProps as bm, type CalendarEventStatus as bn, type CalendarEventProps as bo, type ExecutionContext as bp, type VoiceSessionDescriptor as c, type ToolSettingsViewDefinition as d, type ToolSettingsView as e, type ToolSettingsListView as f, type ToolSettingsListMapping as g, type ToolSettingsComponentView as h, type ToolSettingsActionDataSource as i, type StatusCardDefinition as j, type PanelView as k, type PanelComponentView as l, type PanelActionDataSource as m, type PanelUnknownView as n, type ProviderDefinition as o, type ProviderConfigView as p, type PromptContribution as q, resolveLocalizedString as r, type PromptSection as s, type ToolDefinition as t, type ToolConfirmationConfig as u, type CommandDefinition as v, type AccountProvider as w, type AccountContribution as x, type ExtensionContext as y, type SettingsAPI as z };
2668
+ export { type ConnectedAccountsAPI as $, type ActionResult as A, type ProvidersAPI as B, type ChatMessage as C, type Disposable as D, type ExtensionContributions as E, type ToolsAPI as F, type GetModelsOptions as G, type HugeIconName as H, type ActionsAPI as I, type EventsAPI as J, type SchedulerAPI as K, type LocalizedString as L, type ModelInfo as M, type NetworkAPI as N, type SchedulerJobRequest as O, type PanelDefinition as P, type SchedulerSchedule as Q, type UserProfile as R, type SchedulerFirePayload as S, type ToolResult as T, type UserAPI as U, type VoiceSessionOptions as V, type ChatAPI as W, type ChatInstructionMessage as X, type ConversationPresentation as Y, type AttachmentsAPI as Z, type AttachmentContent as _, type ChatOptions as a, type MarkdownProps as a$, type ConnectedAccount as a0, type AccountAccessToken as a1, type LogAPI as a2, type BackgroundWorkersAPI as a3, type BackgroundTaskConfig as a4, type BackgroundTaskCallback as a5, type BackgroundTaskContext as a6, type BackgroundTaskHealth as a7, type BackgroundRestartPolicy as a8, type Query as a9, type ClockProps as aA, type ParagraphProps as aB, type ButtonProps as aC, type TextInputProps as aD, type PasswordInputProps as aE, type NumberInputProps as aF, type TextAreaProps as aG, type DateTimeInputProps as aH, type SelectProps as aI, type IconPickerProps as aJ, type VerticalStackProps as aK, type HorizontalStackProps as aL, type GridProps as aM, type DividerProps as aN, type IconProps as aO, type IconButtonType as aP, type IconButtonProps as aQ, type PanelAction as aR, type PanelProps as aS, type ToggleProps as aT, type CollapsibleProps as aU, type FrameVariant as aV, type FrameProps as aW, type ListProps as aX, type PillVariant as aY, type PillProps as aZ, type CheckboxProps as a_, type QueryOptions as aa, type StorageAPI as ab, type SecretsAPI as ac, type StorageCollectionConfig as ad, type StorageContributions as ae, type AIProvider as af, type ModelCapabilities as ag, type ChatImage as ah, type ChatFile as ai, type ToolCall as aj, type VoiceTransportRequest as ak, type Tool as al, type ToolAttachment as am, type Action as an, type ExtensionModule as ao, type AllowedCSSProperty as ap, type ExtensionComponentStyle as aq, type ExtensionComponentData as ar, type ExtensionComponentIterator as as, type ExtensionComponentChildren as at, type ExtensionActionCall as au, type ExtensionActionRef as av, type ExtensionDataSource as aw, type ExtensionPanelDefinition as ax, type HeaderProps as ay, type LabelProps as az, type StreamEvent as b, type TextPreviewProps as b0, type ModalProps as b1, type ConditionalGroupProps as b2, type WeatherCondition as b3, type WeatherWind as b4, type WeatherNowProps as b5, type WeatherForecastStep as b6, type WeatherForecastProps as b7, type ChartKind as b8, type ChartSeries as b9, type ChartProps as ba, type StatTrend as bb, type StatTileProps as bc, type ProgressShape as bd, type ProgressColor as be, type ProgressBarProps as bf, type KeyValueRow as bg, type KeyValueListProps as bh, type TimelineVariant as bi, type TimelineEntry as bj, type TimelineProps as bk, type NoteVariant as bl, type NoteProps as bm, type CalendarEventStatus as bn, type CalendarEventProps as bo, type AgendaEvent as bp, type AgendaDay as bq, type AgendaProps as br, type ExecutionContext as bs, type VoiceSessionDescriptor as c, type ToolSettingsViewDefinition as d, type ToolSettingsView as e, type ToolSettingsListView as f, type ToolSettingsListMapping as g, type ToolSettingsComponentView as h, type ToolSettingsActionDataSource as i, type StatusCardDefinition as j, type PanelView as k, type PanelComponentView as l, type PanelActionDataSource as m, type PanelUnknownView as n, type ProviderDefinition as o, type ProviderConfigView as p, type PromptContribution as q, resolveLocalizedString as r, type PromptSection as s, type ToolDefinition as t, type ToolConfirmationConfig as u, type CommandDefinition as v, type AccountProvider as w, type AccountContribution as x, type ExtensionContext as y, type SettingsAPI as z };
@@ -770,6 +770,60 @@ interface CalendarEventProps extends ExtensionComponentData {
770
770
  /** One short line of context. */
771
771
  notes?: string;
772
772
  }
773
+ /**
774
+ * One event on an agenda.
775
+ *
776
+ * Timestamps rather than worded times, for the same reason as `CalendarEvent`:
777
+ * the agenda is about where today stands, and it can only keep that true if it
778
+ * knows when things actually start and end.
779
+ */
780
+ interface AgendaEvent {
781
+ /** Handed back to `onEventClickAction` as `$event.id`. Not shown. */
782
+ id?: string;
783
+ title: string;
784
+ /** ISO 8601, with an offset. */
785
+ start: string;
786
+ /** ISO 8601, with an offset. Absent for an event with no stated end. */
787
+ end?: string;
788
+ /** Drawn as a chip above the day's list rather than in it. */
789
+ allDay?: boolean;
790
+ /** One quiet line under the title: a place, a meeting link, a room. */
791
+ detail?: string;
792
+ }
793
+ /** One day on an agenda, as the caller groups them. */
794
+ interface AgendaDay {
795
+ /** The day's heading, e.g. "Idag". */
796
+ label: string;
797
+ /** A quieter line beside the heading, e.g. "tis 6 okt". */
798
+ date?: string;
799
+ events: AgendaEvent[];
800
+ }
801
+ /**
802
+ * The extension API properties for the Agenda component.
803
+ *
804
+ * A day's schedule that knows what time it is. What is behind us recedes, what
805
+ * is running is lifted out with its progress drawn down its edge, what comes
806
+ * next counts down, and a line marks the gap we are in. The host works all of
807
+ * that out from the timestamps and keeps it current while the panel is open.
808
+ *
809
+ * For milestones, or anything whose times are words rather than instants, use
810
+ * `Timeline`. This is for a schedule.
811
+ */
812
+ interface AgendaProps extends ExtensionComponentData {
813
+ component: 'Agenda';
814
+ /** Heading above the days. */
815
+ title?: string;
816
+ /** Icon shown to the left of the title. */
817
+ icon?: HugeIconName;
818
+ days: AgendaDay[];
819
+ /**
820
+ * Word clashes: "Krockar med 11:00", "2 samtidigt". Off by default, since a
821
+ * schedule of lessons or training sessions has nothing to warn about.
822
+ */
823
+ warnOverlaps?: boolean;
824
+ /** Called when an event is clicked, with the event in scope as `$event`. */
825
+ onEventClickAction?: ExtensionActionRef;
826
+ }
773
827
 
774
828
  /**
775
829
  * What an extension can contribute to Stina
@@ -2611,4 +2665,4 @@ interface ActionResult {
2611
2665
  error?: string;
2612
2666
  }
2613
2667
 
2614
- export { type ConnectedAccountsAPI as $, type ActionResult as A, type ProvidersAPI as B, type ChatMessage as C, type Disposable as D, type ExtensionContributions as E, type ToolsAPI as F, type GetModelsOptions as G, type HugeIconName as H, type ActionsAPI as I, type EventsAPI as J, type SchedulerAPI as K, type LocalizedString as L, type ModelInfo as M, type NetworkAPI as N, type SchedulerJobRequest as O, type PanelDefinition as P, type SchedulerSchedule as Q, type UserProfile as R, type SchedulerFirePayload as S, type ToolResult as T, type UserAPI as U, type VoiceSessionOptions as V, type ChatAPI as W, type ChatInstructionMessage as X, type ConversationPresentation as Y, type AttachmentsAPI as Z, type AttachmentContent as _, type ChatOptions as a, type MarkdownProps as a$, type ConnectedAccount as a0, type AccountAccessToken as a1, type LogAPI as a2, type BackgroundWorkersAPI as a3, type BackgroundTaskConfig as a4, type BackgroundTaskCallback as a5, type BackgroundTaskContext as a6, type BackgroundTaskHealth as a7, type BackgroundRestartPolicy as a8, type Query as a9, type ClockProps as aA, type ParagraphProps as aB, type ButtonProps as aC, type TextInputProps as aD, type PasswordInputProps as aE, type NumberInputProps as aF, type TextAreaProps as aG, type DateTimeInputProps as aH, type SelectProps as aI, type IconPickerProps as aJ, type VerticalStackProps as aK, type HorizontalStackProps as aL, type GridProps as aM, type DividerProps as aN, type IconProps as aO, type IconButtonType as aP, type IconButtonProps as aQ, type PanelAction as aR, type PanelProps as aS, type ToggleProps as aT, type CollapsibleProps as aU, type FrameVariant as aV, type FrameProps as aW, type ListProps as aX, type PillVariant as aY, type PillProps as aZ, type CheckboxProps as a_, type QueryOptions as aa, type StorageAPI as ab, type SecretsAPI as ac, type StorageCollectionConfig as ad, type StorageContributions as ae, type AIProvider as af, type ModelCapabilities as ag, type ChatImage as ah, type ChatFile as ai, type ToolCall as aj, type VoiceTransportRequest as ak, type Tool as al, type ToolAttachment as am, type Action as an, type ExtensionModule as ao, type AllowedCSSProperty as ap, type ExtensionComponentStyle as aq, type ExtensionComponentData as ar, type ExtensionComponentIterator as as, type ExtensionComponentChildren as at, type ExtensionActionCall as au, type ExtensionActionRef as av, type ExtensionDataSource as aw, type ExtensionPanelDefinition as ax, type HeaderProps as ay, type LabelProps as az, type StreamEvent as b, type TextPreviewProps as b0, type ModalProps as b1, type ConditionalGroupProps as b2, type WeatherCondition as b3, type WeatherWind as b4, type WeatherNowProps as b5, type WeatherForecastStep as b6, type WeatherForecastProps as b7, type ChartKind as b8, type ChartSeries as b9, type ChartProps as ba, type StatTrend as bb, type StatTileProps as bc, type ProgressShape as bd, type ProgressColor as be, type ProgressBarProps as bf, type KeyValueRow as bg, type KeyValueListProps as bh, type TimelineVariant as bi, type TimelineEntry as bj, type TimelineProps as bk, type NoteVariant as bl, type NoteProps as bm, type CalendarEventStatus as bn, type CalendarEventProps as bo, type ExecutionContext as bp, type VoiceSessionDescriptor as c, type ToolSettingsViewDefinition as d, type ToolSettingsView as e, type ToolSettingsListView as f, type ToolSettingsListMapping as g, type ToolSettingsComponentView as h, type ToolSettingsActionDataSource as i, type StatusCardDefinition as j, type PanelView as k, type PanelComponentView as l, type PanelActionDataSource as m, type PanelUnknownView as n, type ProviderDefinition as o, type ProviderConfigView as p, type PromptContribution as q, resolveLocalizedString as r, type PromptSection as s, type ToolDefinition as t, type ToolConfirmationConfig as u, type CommandDefinition as v, type AccountProvider as w, type AccountContribution as x, type ExtensionContext as y, type SettingsAPI as z };
2668
+ export { type ConnectedAccountsAPI as $, type ActionResult as A, type ProvidersAPI as B, type ChatMessage as C, type Disposable as D, type ExtensionContributions as E, type ToolsAPI as F, type GetModelsOptions as G, type HugeIconName as H, type ActionsAPI as I, type EventsAPI as J, type SchedulerAPI as K, type LocalizedString as L, type ModelInfo as M, type NetworkAPI as N, type SchedulerJobRequest as O, type PanelDefinition as P, type SchedulerSchedule as Q, type UserProfile as R, type SchedulerFirePayload as S, type ToolResult as T, type UserAPI as U, type VoiceSessionOptions as V, type ChatAPI as W, type ChatInstructionMessage as X, type ConversationPresentation as Y, type AttachmentsAPI as Z, type AttachmentContent as _, type ChatOptions as a, type MarkdownProps as a$, type ConnectedAccount as a0, type AccountAccessToken as a1, type LogAPI as a2, type BackgroundWorkersAPI as a3, type BackgroundTaskConfig as a4, type BackgroundTaskCallback as a5, type BackgroundTaskContext as a6, type BackgroundTaskHealth as a7, type BackgroundRestartPolicy as a8, type Query as a9, type ClockProps as aA, type ParagraphProps as aB, type ButtonProps as aC, type TextInputProps as aD, type PasswordInputProps as aE, type NumberInputProps as aF, type TextAreaProps as aG, type DateTimeInputProps as aH, type SelectProps as aI, type IconPickerProps as aJ, type VerticalStackProps as aK, type HorizontalStackProps as aL, type GridProps as aM, type DividerProps as aN, type IconProps as aO, type IconButtonType as aP, type IconButtonProps as aQ, type PanelAction as aR, type PanelProps as aS, type ToggleProps as aT, type CollapsibleProps as aU, type FrameVariant as aV, type FrameProps as aW, type ListProps as aX, type PillVariant as aY, type PillProps as aZ, type CheckboxProps as a_, type QueryOptions as aa, type StorageAPI as ab, type SecretsAPI as ac, type StorageCollectionConfig as ad, type StorageContributions as ae, type AIProvider as af, type ModelCapabilities as ag, type ChatImage as ah, type ChatFile as ai, type ToolCall as aj, type VoiceTransportRequest as ak, type Tool as al, type ToolAttachment as am, type Action as an, type ExtensionModule as ao, type AllowedCSSProperty as ap, type ExtensionComponentStyle as aq, type ExtensionComponentData as ar, type ExtensionComponentIterator as as, type ExtensionComponentChildren as at, type ExtensionActionCall as au, type ExtensionActionRef as av, type ExtensionDataSource as aw, type ExtensionPanelDefinition as ax, type HeaderProps as ay, type LabelProps as az, type StreamEvent as b, type TextPreviewProps as b0, type ModalProps as b1, type ConditionalGroupProps as b2, type WeatherCondition as b3, type WeatherWind as b4, type WeatherNowProps as b5, type WeatherForecastStep as b6, type WeatherForecastProps as b7, type ChartKind as b8, type ChartSeries as b9, type ChartProps as ba, type StatTrend as bb, type StatTileProps as bc, type ProgressShape as bd, type ProgressColor as be, type ProgressBarProps as bf, type KeyValueRow as bg, type KeyValueListProps as bh, type TimelineVariant as bi, type TimelineEntry as bj, type TimelineProps as bk, type NoteVariant as bl, type NoteProps as bm, type CalendarEventStatus as bn, type CalendarEventProps as bo, type AgendaEvent as bp, type AgendaDay as bq, type AgendaProps as br, type ExecutionContext as bs, type VoiceSessionDescriptor as c, type ToolSettingsViewDefinition as d, type ToolSettingsView as e, type ToolSettingsListView as f, type ToolSettingsListMapping as g, type ToolSettingsComponentView as h, type ToolSettingsActionDataSource as i, type StatusCardDefinition as j, type PanelView as k, type PanelComponentView as l, type PanelActionDataSource as m, type PanelUnknownView as n, type ProviderDefinition as o, type ProviderConfigView as p, type PromptContribution as q, resolveLocalizedString as r, type PromptSection as s, type ToolDefinition as t, type ToolConfirmationConfig as u, type CommandDefinition as v, type AccountProvider as w, type AccountContribution as x, type ExtensionContext as y, type SettingsAPI as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stina/extension-api",
3
- "version": "1.7.0",
3
+ "version": "1.16.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
package/src/index.ts CHANGED
@@ -226,4 +226,7 @@ export type {
226
226
  NoteProps,
227
227
  CalendarEventStatus,
228
228
  CalendarEventProps,
229
+ AgendaEvent,
230
+ AgendaDay,
231
+ AgendaProps,
229
232
  } from './types.components.js'
@@ -30,6 +30,30 @@ describe('validateChatCard', () => {
30
30
  expect(result.ok).toBe(true)
31
31
  })
32
32
 
33
+ it('accepts a quotation with its attribution', () => {
34
+ const result = validateChatCard({
35
+ component: 'Quote',
36
+ text: 'Fyll gärna i del två i mallen innan vi ses.',
37
+ source: 'Maria Lind',
38
+ context: 'i morse 07:42',
39
+ footer: 'Ur mejlet om medarbetarsamtalet',
40
+ })
41
+
42
+ expect(result.ok).toBe(true)
43
+ })
44
+
45
+ it('rejects markup properties on a quotation', () => {
46
+ // Quoted text is printed as it arrived. A property that implied formatting
47
+ // would let someone else's words be dressed up as Stina's own.
48
+ const result = validateChatCard({
49
+ component: 'Quote',
50
+ text: 'Fyll gärna i del två.',
51
+ variant: 'accent',
52
+ })
53
+
54
+ expect(result.ok).toBe(false)
55
+ })
56
+
33
57
  it('accepts an icon beside every heading that has one', () => {
34
58
  for (const card of [
35
59
  { component: 'Chart', icon: 'temperature', series: [{ points: [1] }] },
@@ -333,6 +333,17 @@ const NoteCardSchema = z
333
333
  })
334
334
  .strict()
335
335
 
336
+ const QuoteCardSchema = z
337
+ .object({
338
+ component: z.literal('Quote'),
339
+ text: z.string(),
340
+ source: z.string().optional(),
341
+ context: z.string().optional(),
342
+ footer: z.string().optional(),
343
+ style,
344
+ })
345
+ .strict()
346
+
336
347
  const CalendarEventCardSchema = z
337
348
  .object({
338
349
  component: z.literal('CalendarEvent'),
@@ -373,6 +384,7 @@ export const CHAT_CARD_COMPONENTS = [
373
384
  'KeyValueList',
374
385
  'Timeline',
375
386
  'Note',
387
+ 'Quote',
376
388
  'CalendarEvent',
377
389
  ] as const
378
390
 
@@ -406,6 +418,7 @@ const CARD_MEMBERS = [
406
418
  KeyValueListCardSchema,
407
419
  TimelineCardSchema,
408
420
  NoteCardSchema,
421
+ QuoteCardSchema,
409
422
  CalendarEventCardSchema,
410
423
  ] as const
411
424
 
@@ -774,6 +774,42 @@ export const CalendarEventPropsSchema = z
774
774
  .passthrough()
775
775
  .describe('Single calendar event component')
776
776
 
777
+ export const AgendaEventSchema = z
778
+ .object({
779
+ id: z.string().optional().describe('Handed back to onEventClickAction as $event.id'),
780
+ title: z.string(),
781
+ start: z.string().describe('ISO 8601 with an offset'),
782
+ end: z.string().optional().describe('ISO 8601 with an offset'),
783
+ allDay: z.boolean().optional(),
784
+ detail: z.string().optional().describe('One quiet line under the title'),
785
+ })
786
+ .passthrough()
787
+ .describe('One agenda event')
788
+
789
+ export const AgendaDaySchema = z
790
+ .object({
791
+ label: z.string().describe('The day heading'),
792
+ date: z.string().optional().describe('A quieter line beside the heading'),
793
+ events: z.array(AgendaEventSchema),
794
+ })
795
+ .passthrough()
796
+ .describe('One agenda day')
797
+
798
+ export const AgendaPropsSchema = z
799
+ .object({
800
+ component: z.literal('Agenda'),
801
+ title: z.string().optional(),
802
+ icon: z.string().optional().describe('Icon shown to the left of the title'),
803
+ days: z.array(AgendaDaySchema),
804
+ warnOverlaps: z.boolean().optional().describe('Word clashes between events'),
805
+ onEventClickAction: ExtensionActionRefSchema.optional().describe(
806
+ 'Action to call when an event is clicked, with the event as $event'
807
+ ),
808
+ style: ExtensionComponentStyleSchema.optional(),
809
+ })
810
+ .passthrough()
811
+ .describe('Schedule component that tracks the current time')
812
+
777
813
  // =============================================================================
778
814
  // Type Exports
779
815
  // =============================================================================
@@ -841,3 +877,6 @@ export type NoteVariant = z.infer<typeof NoteVariantSchema>
841
877
  export type NoteProps = z.infer<typeof NotePropsSchema>
842
878
  export type CalendarEventStatus = z.infer<typeof CalendarEventStatusSchema>
843
879
  export type CalendarEventProps = z.infer<typeof CalendarEventPropsSchema>
880
+ export type AgendaEvent = z.infer<typeof AgendaEventSchema>
881
+ export type AgendaDay = z.infer<typeof AgendaDaySchema>
882
+ export type AgendaProps = z.infer<typeof AgendaPropsSchema>
@@ -149,6 +149,9 @@ export {
149
149
  NotePropsSchema,
150
150
  CalendarEventStatusSchema,
151
151
  CalendarEventPropsSchema,
152
+ AgendaEventSchema,
153
+ AgendaDaySchema,
154
+ AgendaPropsSchema,
152
155
  type ExtensionComponentData,
153
156
  type ExtensionComponentStyle,
154
157
  type ExtensionActionCall,
@@ -886,6 +886,33 @@ export interface NoteProps extends ExtensionComponentData {
886
886
  variant?: NoteVariant
887
887
  }
888
888
 
889
+ /**
890
+ * The extension API properties for the Quote component.
891
+ *
892
+ * Someone else's words, set apart and attributed. For the sentence out of a mail
893
+ * that actually answers the question, the line from a document worth reading as
894
+ * written, the message a colleague sent.
895
+ *
896
+ * The text is rendered as written and never as markdown, which is the whole
897
+ * point of it existing beside `Note`: a link or a heading inside quoted text
898
+ * would be formatted as though Stina had put it there. `Note` is for the user's
899
+ * own writing and for hers; this is for everyone else's.
900
+ *
901
+ * Quote what bears quoting, not the whole message. A card is a thing to glance
902
+ * at, and a page of pasted mail is a page nobody reads.
903
+ */
904
+ export interface QuoteProps extends ExtensionComponentData {
905
+ component: 'Quote'
906
+ /** The words themselves, verbatim. Rendered as written, never as markdown. */
907
+ text: string
908
+ /** Who wrote or said it, as they are known: a name, an address, a title. */
909
+ source?: string
910
+ /** When or where it came from: `i morse 07:42`, `i mötesanteckningarna`. */
911
+ context?: string
912
+ /** One quiet line under the quotation, for what is worth adding about it. */
913
+ footer?: string
914
+ }
915
+
889
916
  /** Whether an event is going ahead. */
890
917
  export type CalendarEventStatus = 'confirmed' | 'tentative' | 'cancelled'
891
918
 
@@ -932,3 +959,60 @@ export interface CalendarEventProps extends ExtensionComponentData {
932
959
  /** One short line of context. */
933
960
  notes?: string
934
961
  }
962
+
963
+ /**
964
+ * One event on an agenda.
965
+ *
966
+ * Timestamps rather than worded times, for the same reason as `CalendarEvent`:
967
+ * the agenda is about where today stands, and it can only keep that true if it
968
+ * knows when things actually start and end.
969
+ */
970
+ export interface AgendaEvent {
971
+ /** Handed back to `onEventClickAction` as `$event.id`. Not shown. */
972
+ id?: string
973
+ title: string
974
+ /** ISO 8601, with an offset. */
975
+ start: string
976
+ /** ISO 8601, with an offset. Absent for an event with no stated end. */
977
+ end?: string
978
+ /** Drawn as a chip above the day's list rather than in it. */
979
+ allDay?: boolean
980
+ /** One quiet line under the title: a place, a meeting link, a room. */
981
+ detail?: string
982
+ }
983
+
984
+ /** One day on an agenda, as the caller groups them. */
985
+ export interface AgendaDay {
986
+ /** The day's heading, e.g. "Idag". */
987
+ label: string
988
+ /** A quieter line beside the heading, e.g. "tis 6 okt". */
989
+ date?: string
990
+ events: AgendaEvent[]
991
+ }
992
+
993
+ /**
994
+ * The extension API properties for the Agenda component.
995
+ *
996
+ * A day's schedule that knows what time it is. What is behind us recedes, what
997
+ * is running is lifted out with its progress drawn down its edge, what comes
998
+ * next counts down, and a line marks the gap we are in. The host works all of
999
+ * that out from the timestamps and keeps it current while the panel is open.
1000
+ *
1001
+ * For milestones, or anything whose times are words rather than instants, use
1002
+ * `Timeline`. This is for a schedule.
1003
+ */
1004
+ export interface AgendaProps extends ExtensionComponentData {
1005
+ component: 'Agenda'
1006
+ /** Heading above the days. */
1007
+ title?: string
1008
+ /** Icon shown to the left of the title. */
1009
+ icon?: HugeIconName
1010
+ days: AgendaDay[]
1011
+ /**
1012
+ * Word clashes: "Krockar med 11:00", "2 samtidigt". Off by default, since a
1013
+ * schedule of lessons or training sessions has nothing to warn about.
1014
+ */
1015
+ warnOverlaps?: boolean
1016
+ /** Called when an event is clicked, with the event in scope as `$event`. */
1017
+ onEventClickAction?: ExtensionActionRef
1018
+ }