@stina/extension-api 0.57.0 → 1.0.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.
@@ -581,6 +581,50 @@ interface StatTileProps extends ExtensionComponentData {
581
581
  */
582
582
  trendIsGood?: boolean;
583
583
  }
584
+ /** Whether a progress reading is drawn as a rail or as a ring. */
585
+ type ProgressShape = 'bar' | 'circle';
586
+ /**
587
+ * The colours a progress reading may take.
588
+ *
589
+ * A closed list rather than a colour string: the caller is usually a language
590
+ * model, and the six names here are the six the themes actually define, so a
591
+ * reading cannot end up in a hue the current theme has no contrast for.
592
+ */
593
+ type ProgressColor = 'accent' | 'success' | 'warning' | 'danger' | 'info' | 'neutral';
594
+ /**
595
+ * The extension API properties for the ProgressBar component.
596
+ *
597
+ * One value seen against the range it lives in — how far along something is,
598
+ * how loaded a day looks, how high a level sits. A StatTile says what the
599
+ * number *is*; this says where it *sits*, which is the thing a number alone
600
+ * cannot show.
601
+ *
602
+ * `min` and `max` are the range, not decoration: a value is drawn as its
603
+ * position between them, so "3 of 5" and "60 of 100" fill the same amount.
604
+ * Values outside the range are clamped rather than refused — a reading that
605
+ * ran past its ceiling should still draw as full.
606
+ */
607
+ interface ProgressBarProps extends ExtensionComponentData {
608
+ component: 'ProgressBar';
609
+ /** What is being measured, e.g. "Stressnivå". Shown beside the reading. */
610
+ label: string;
611
+ value: number;
612
+ /** Bottom of the range. Defaults to 0. */
613
+ min?: number;
614
+ /** Top of the range. Defaults to 100. */
615
+ max?: number;
616
+ /** Defaults to `bar`. */
617
+ shape?: ProgressShape;
618
+ /** Defaults to `accent`. */
619
+ color?: ProgressColor;
620
+ /** Written after the value, e.g. `%` or ` av 5`. */
621
+ unit?: string;
622
+ /** The readout in words, when the bare number does not say it. Replaces value and unit. */
623
+ valueLabel?: string;
624
+ /** One quiet line under the reading. */
625
+ caption?: string;
626
+ icon?: HugeIconName;
627
+ }
584
628
  /** One row of a KeyValueList. */
585
629
  interface KeyValueRow {
586
630
  label: string;
@@ -721,6 +765,8 @@ interface CalendarEventProps extends ExtensionComponentData {
721
765
  interface ExtensionContributions {
722
766
  /** Tool settings views for UI */
723
767
  toolSettings?: ToolSettingsViewDefinition[];
768
+ /** Cards for the strip above the conversation list */
769
+ statusCards?: StatusCardDefinition[];
724
770
  /** Right panel contributions */
725
771
  panels?: PanelDefinition[];
726
772
  /** AI providers */
@@ -861,6 +907,38 @@ interface PanelDefinition {
861
907
  /** Panel view schema */
862
908
  view: PanelView;
863
909
  }
910
+ /**
911
+ * A card for the strip above the conversation list.
912
+ *
913
+ * The same declarative machinery as a panel, in a much smaller space and with
914
+ * one rule that is not a style guide: a card says what is true right now. It
915
+ * has no controls, because a sidebar is read in passing and anything the user
916
+ * wants to do about what it says, they say in words.
917
+ *
918
+ * The user chooses which cards they want and in what order, so an extension
919
+ * offering three is offering three, not imposing them.
920
+ */
921
+ interface StatusCardDefinition {
922
+ /** Unique card ID within the extension */
923
+ id: string;
924
+ /** What it is called where the user picks it */
925
+ title: string;
926
+ /** Icon name (from huge-icons) */
927
+ icon?: string;
928
+ /**
929
+ * How much room it may take.
930
+ *
931
+ * Part of the contract rather than a guideline, because the sidebar is a few
932
+ * hundred pixels wide and the first card written without a limit will be
933
+ * written against a screen.
934
+ *
935
+ * - `line`: one row. A figure, a label, a pill.
936
+ * - `block`: up to three rows.
937
+ */
938
+ size: 'line' | 'block';
939
+ /** What it draws, and where the data comes from */
940
+ view: PanelComponentView;
941
+ }
864
942
  /**
865
943
  * Panel view schema (declarative)
866
944
  */
@@ -2242,8 +2320,26 @@ interface ToolResult {
2242
2320
  * Validate with `validateChatCard` before returning one. A card that fails the
2243
2321
  * profile is dropped by the host rather than half-rendered, so a tool that
2244
2322
  * skips the check finds out from the user, which is the wrong end.
2323
+ *
2324
+ * Most tools should prefer {@link ToolResult.cardSuggestion}: a card drawn here
2325
+ * is shown whatever the user asked, and a timeline of ten mails is the wrong
2326
+ * answer to "did Anna write back?".
2245
2327
  */
2246
2328
  display?: ExtensionComponentData;
2329
+ /**
2330
+ * The shape this tool thinks its answer has: one component name from the chat
2331
+ * card profile, such as `"Timeline"` or `"WeatherForecast"`.
2332
+ *
2333
+ * A suggestion, not a drawing. It travels to the model with the result, and
2334
+ * Stina decides whether to show a card at all, what goes in it, and how much of
2335
+ * the data belongs there — summing three days into one figure, or answering in
2336
+ * a sentence because the user asked a yes-or-no question. The tool knows the
2337
+ * shape of its data; only she knows the shape of the question.
2338
+ *
2339
+ * A name outside the profile is dropped by the host with a warning, since it
2340
+ * would send her after a component that does not exist.
2341
+ */
2342
+ cardSuggestion?: string;
2247
2343
  }
2248
2344
  /**
2249
2345
  * Action implementation for UI interactions.
@@ -2271,4 +2367,4 @@ interface ActionResult {
2271
2367
  error?: string;
2272
2368
  }
2273
2369
 
2274
- export { type BackgroundTaskHealth as $, type ActionResult as A, type EventsAPI as B, type ChatMessage as C, type Disposable as D, type ExtensionContributions as E, type SchedulerAPI as F, type GetModelsOptions as G, type HugeIconName as H, type SchedulerJobRequest as I, type SchedulerSchedule as J, type UserProfile as K, type LocalizedString as L, type ModelInfo as M, type NetworkAPI as N, type ChatAPI as O, type PanelDefinition as P, type ChatInstructionMessage as Q, type ConversationPresentation as R, type SchedulerFirePayload as S, type ToolResult as T, type UserAPI as U, type VoiceSessionOptions as V, type LogAPI as W, type BackgroundWorkersAPI as X, type BackgroundTaskConfig as Y, type BackgroundTaskCallback as Z, type BackgroundTaskContext as _, type ChatOptions as a, type ChartProps as a$, type BackgroundRestartPolicy as a0, type Query as a1, type QueryOptions as a2, type StorageAPI as a3, type SecretsAPI as a4, type StorageCollectionConfig as a5, type StorageContributions as a6, type AIProvider as a7, type ModelCapabilities as a8, type ChatImage as a9, type HorizontalStackProps as aA, type GridProps as aB, type DividerProps as aC, type IconProps as aD, type IconButtonType as aE, type IconButtonProps as aF, type PanelAction as aG, type PanelProps as aH, type ToggleProps as aI, type CollapsibleProps as aJ, type FrameVariant as aK, type FrameProps as aL, type ListProps as aM, type PillVariant as aN, type PillProps as aO, type CheckboxProps as aP, type MarkdownProps as aQ, type TextPreviewProps as aR, type ModalProps as aS, type ConditionalGroupProps as aT, type WeatherCondition as aU, type WeatherWind as aV, type WeatherNowProps as aW, type WeatherForecastStep as aX, type WeatherForecastProps as aY, type ChartKind as aZ, type ChartSeries as a_, type ToolCall as aa, type VoiceTransportRequest as ab, type Tool as ac, type Action as ad, type ExtensionModule as ae, type AllowedCSSProperty as af, type ExtensionComponentStyle as ag, type ExtensionComponentData as ah, type ExtensionComponentIterator as ai, type ExtensionComponentChildren as aj, type ExtensionActionCall as ak, type ExtensionActionRef as al, type ExtensionDataSource as am, type ExtensionPanelDefinition as an, type HeaderProps as ao, type LabelProps as ap, type ParagraphProps as aq, type ButtonProps as ar, type TextInputProps as as, type PasswordInputProps as at, type NumberInputProps as au, type TextAreaProps as av, type DateTimeInputProps as aw, type SelectProps as ax, type IconPickerProps as ay, type VerticalStackProps as az, type StreamEvent as b, type StatTrend as b0, type StatTileProps as b1, type KeyValueRow as b2, type KeyValueListProps as b3, type TimelineVariant as b4, type TimelineEntry as b5, type TimelineProps as b6, type NoteVariant as b7, type NoteProps as b8, type CalendarEventStatus as b9, type CalendarEventProps as ba, type ExecutionContext as bb, 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 PanelView as j, type PanelComponentView as k, type PanelActionDataSource as l, type PanelUnknownView as m, type ProviderDefinition as n, type ProviderConfigView as o, type PromptContribution as p, type PromptSection as q, resolveLocalizedString as r, type ToolDefinition as s, type ToolConfirmationConfig as t, type CommandDefinition as u, type ExtensionContext as v, type SettingsAPI as w, type ProvidersAPI as x, type ToolsAPI as y, type ActionsAPI as z };
2370
+ export { type BackgroundTaskContext as $, type ActionResult as A, type ActionsAPI as B, type ChatMessage as C, type Disposable as D, type ExtensionContributions as E, type EventsAPI as F, type GetModelsOptions as G, type HugeIconName as H, type SchedulerAPI as I, type SchedulerJobRequest as J, type SchedulerSchedule as K, type LocalizedString as L, type ModelInfo as M, type NetworkAPI as N, type UserProfile as O, type PanelDefinition as P, type ChatAPI as Q, type ChatInstructionMessage as R, type SchedulerFirePayload as S, type ToolResult as T, type UserAPI as U, type VoiceSessionOptions as V, type ConversationPresentation as W, type LogAPI as X, type BackgroundWorkersAPI as Y, type BackgroundTaskConfig as Z, type BackgroundTaskCallback as _, type ChatOptions as a, type ChartSeries as a$, type BackgroundTaskHealth as a0, type BackgroundRestartPolicy as a1, type Query as a2, type QueryOptions as a3, type StorageAPI as a4, type SecretsAPI as a5, type StorageCollectionConfig as a6, type StorageContributions as a7, type AIProvider as a8, type ModelCapabilities as a9, type VerticalStackProps as aA, type HorizontalStackProps as aB, type GridProps as aC, type DividerProps as aD, type IconProps as aE, type IconButtonType as aF, type IconButtonProps as aG, type PanelAction as aH, type PanelProps as aI, type ToggleProps as aJ, type CollapsibleProps as aK, type FrameVariant as aL, type FrameProps as aM, type ListProps as aN, type PillVariant as aO, type PillProps as aP, type CheckboxProps as aQ, type MarkdownProps as aR, type TextPreviewProps as aS, type ModalProps as aT, type ConditionalGroupProps as aU, type WeatherCondition as aV, type WeatherWind as aW, type WeatherNowProps as aX, type WeatherForecastStep as aY, type WeatherForecastProps as aZ, type ChartKind as a_, type ChatImage as aa, type ToolCall as ab, type VoiceTransportRequest as ac, type Tool as ad, type Action as ae, type ExtensionModule as af, type AllowedCSSProperty as ag, type ExtensionComponentStyle as ah, type ExtensionComponentData as ai, type ExtensionComponentIterator as aj, type ExtensionComponentChildren as ak, type ExtensionActionCall as al, type ExtensionActionRef as am, type ExtensionDataSource as an, type ExtensionPanelDefinition as ao, type HeaderProps as ap, type LabelProps as aq, type ParagraphProps as ar, type ButtonProps as as, type TextInputProps as at, type PasswordInputProps as au, type NumberInputProps as av, type TextAreaProps as aw, type DateTimeInputProps as ax, type SelectProps as ay, type IconPickerProps as az, type StreamEvent as b, type ChartProps as b0, type StatTrend as b1, type StatTileProps as b2, type ProgressShape as b3, type ProgressColor as b4, type ProgressBarProps as b5, type KeyValueRow as b6, type KeyValueListProps as b7, type TimelineVariant as b8, type TimelineEntry as b9, type TimelineProps as ba, type NoteVariant as bb, type NoteProps as bc, type CalendarEventStatus as bd, type CalendarEventProps as be, type ExecutionContext as bf, 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 ExtensionContext as w, type SettingsAPI as x, type ProvidersAPI as y, type ToolsAPI as z };
@@ -581,6 +581,50 @@ interface StatTileProps extends ExtensionComponentData {
581
581
  */
582
582
  trendIsGood?: boolean;
583
583
  }
584
+ /** Whether a progress reading is drawn as a rail or as a ring. */
585
+ type ProgressShape = 'bar' | 'circle';
586
+ /**
587
+ * The colours a progress reading may take.
588
+ *
589
+ * A closed list rather than a colour string: the caller is usually a language
590
+ * model, and the six names here are the six the themes actually define, so a
591
+ * reading cannot end up in a hue the current theme has no contrast for.
592
+ */
593
+ type ProgressColor = 'accent' | 'success' | 'warning' | 'danger' | 'info' | 'neutral';
594
+ /**
595
+ * The extension API properties for the ProgressBar component.
596
+ *
597
+ * One value seen against the range it lives in — how far along something is,
598
+ * how loaded a day looks, how high a level sits. A StatTile says what the
599
+ * number *is*; this says where it *sits*, which is the thing a number alone
600
+ * cannot show.
601
+ *
602
+ * `min` and `max` are the range, not decoration: a value is drawn as its
603
+ * position between them, so "3 of 5" and "60 of 100" fill the same amount.
604
+ * Values outside the range are clamped rather than refused — a reading that
605
+ * ran past its ceiling should still draw as full.
606
+ */
607
+ interface ProgressBarProps extends ExtensionComponentData {
608
+ component: 'ProgressBar';
609
+ /** What is being measured, e.g. "Stressnivå". Shown beside the reading. */
610
+ label: string;
611
+ value: number;
612
+ /** Bottom of the range. Defaults to 0. */
613
+ min?: number;
614
+ /** Top of the range. Defaults to 100. */
615
+ max?: number;
616
+ /** Defaults to `bar`. */
617
+ shape?: ProgressShape;
618
+ /** Defaults to `accent`. */
619
+ color?: ProgressColor;
620
+ /** Written after the value, e.g. `%` or ` av 5`. */
621
+ unit?: string;
622
+ /** The readout in words, when the bare number does not say it. Replaces value and unit. */
623
+ valueLabel?: string;
624
+ /** One quiet line under the reading. */
625
+ caption?: string;
626
+ icon?: HugeIconName;
627
+ }
584
628
  /** One row of a KeyValueList. */
585
629
  interface KeyValueRow {
586
630
  label: string;
@@ -721,6 +765,8 @@ interface CalendarEventProps extends ExtensionComponentData {
721
765
  interface ExtensionContributions {
722
766
  /** Tool settings views for UI */
723
767
  toolSettings?: ToolSettingsViewDefinition[];
768
+ /** Cards for the strip above the conversation list */
769
+ statusCards?: StatusCardDefinition[];
724
770
  /** Right panel contributions */
725
771
  panels?: PanelDefinition[];
726
772
  /** AI providers */
@@ -861,6 +907,38 @@ interface PanelDefinition {
861
907
  /** Panel view schema */
862
908
  view: PanelView;
863
909
  }
910
+ /**
911
+ * A card for the strip above the conversation list.
912
+ *
913
+ * The same declarative machinery as a panel, in a much smaller space and with
914
+ * one rule that is not a style guide: a card says what is true right now. It
915
+ * has no controls, because a sidebar is read in passing and anything the user
916
+ * wants to do about what it says, they say in words.
917
+ *
918
+ * The user chooses which cards they want and in what order, so an extension
919
+ * offering three is offering three, not imposing them.
920
+ */
921
+ interface StatusCardDefinition {
922
+ /** Unique card ID within the extension */
923
+ id: string;
924
+ /** What it is called where the user picks it */
925
+ title: string;
926
+ /** Icon name (from huge-icons) */
927
+ icon?: string;
928
+ /**
929
+ * How much room it may take.
930
+ *
931
+ * Part of the contract rather than a guideline, because the sidebar is a few
932
+ * hundred pixels wide and the first card written without a limit will be
933
+ * written against a screen.
934
+ *
935
+ * - `line`: one row. A figure, a label, a pill.
936
+ * - `block`: up to three rows.
937
+ */
938
+ size: 'line' | 'block';
939
+ /** What it draws, and where the data comes from */
940
+ view: PanelComponentView;
941
+ }
864
942
  /**
865
943
  * Panel view schema (declarative)
866
944
  */
@@ -2242,8 +2320,26 @@ interface ToolResult {
2242
2320
  * Validate with `validateChatCard` before returning one. A card that fails the
2243
2321
  * profile is dropped by the host rather than half-rendered, so a tool that
2244
2322
  * skips the check finds out from the user, which is the wrong end.
2323
+ *
2324
+ * Most tools should prefer {@link ToolResult.cardSuggestion}: a card drawn here
2325
+ * is shown whatever the user asked, and a timeline of ten mails is the wrong
2326
+ * answer to "did Anna write back?".
2245
2327
  */
2246
2328
  display?: ExtensionComponentData;
2329
+ /**
2330
+ * The shape this tool thinks its answer has: one component name from the chat
2331
+ * card profile, such as `"Timeline"` or `"WeatherForecast"`.
2332
+ *
2333
+ * A suggestion, not a drawing. It travels to the model with the result, and
2334
+ * Stina decides whether to show a card at all, what goes in it, and how much of
2335
+ * the data belongs there — summing three days into one figure, or answering in
2336
+ * a sentence because the user asked a yes-or-no question. The tool knows the
2337
+ * shape of its data; only she knows the shape of the question.
2338
+ *
2339
+ * A name outside the profile is dropped by the host with a warning, since it
2340
+ * would send her after a component that does not exist.
2341
+ */
2342
+ cardSuggestion?: string;
2247
2343
  }
2248
2344
  /**
2249
2345
  * Action implementation for UI interactions.
@@ -2271,4 +2367,4 @@ interface ActionResult {
2271
2367
  error?: string;
2272
2368
  }
2273
2369
 
2274
- export { type BackgroundTaskHealth as $, type ActionResult as A, type EventsAPI as B, type ChatMessage as C, type Disposable as D, type ExtensionContributions as E, type SchedulerAPI as F, type GetModelsOptions as G, type HugeIconName as H, type SchedulerJobRequest as I, type SchedulerSchedule as J, type UserProfile as K, type LocalizedString as L, type ModelInfo as M, type NetworkAPI as N, type ChatAPI as O, type PanelDefinition as P, type ChatInstructionMessage as Q, type ConversationPresentation as R, type SchedulerFirePayload as S, type ToolResult as T, type UserAPI as U, type VoiceSessionOptions as V, type LogAPI as W, type BackgroundWorkersAPI as X, type BackgroundTaskConfig as Y, type BackgroundTaskCallback as Z, type BackgroundTaskContext as _, type ChatOptions as a, type ChartProps as a$, type BackgroundRestartPolicy as a0, type Query as a1, type QueryOptions as a2, type StorageAPI as a3, type SecretsAPI as a4, type StorageCollectionConfig as a5, type StorageContributions as a6, type AIProvider as a7, type ModelCapabilities as a8, type ChatImage as a9, type HorizontalStackProps as aA, type GridProps as aB, type DividerProps as aC, type IconProps as aD, type IconButtonType as aE, type IconButtonProps as aF, type PanelAction as aG, type PanelProps as aH, type ToggleProps as aI, type CollapsibleProps as aJ, type FrameVariant as aK, type FrameProps as aL, type ListProps as aM, type PillVariant as aN, type PillProps as aO, type CheckboxProps as aP, type MarkdownProps as aQ, type TextPreviewProps as aR, type ModalProps as aS, type ConditionalGroupProps as aT, type WeatherCondition as aU, type WeatherWind as aV, type WeatherNowProps as aW, type WeatherForecastStep as aX, type WeatherForecastProps as aY, type ChartKind as aZ, type ChartSeries as a_, type ToolCall as aa, type VoiceTransportRequest as ab, type Tool as ac, type Action as ad, type ExtensionModule as ae, type AllowedCSSProperty as af, type ExtensionComponentStyle as ag, type ExtensionComponentData as ah, type ExtensionComponentIterator as ai, type ExtensionComponentChildren as aj, type ExtensionActionCall as ak, type ExtensionActionRef as al, type ExtensionDataSource as am, type ExtensionPanelDefinition as an, type HeaderProps as ao, type LabelProps as ap, type ParagraphProps as aq, type ButtonProps as ar, type TextInputProps as as, type PasswordInputProps as at, type NumberInputProps as au, type TextAreaProps as av, type DateTimeInputProps as aw, type SelectProps as ax, type IconPickerProps as ay, type VerticalStackProps as az, type StreamEvent as b, type StatTrend as b0, type StatTileProps as b1, type KeyValueRow as b2, type KeyValueListProps as b3, type TimelineVariant as b4, type TimelineEntry as b5, type TimelineProps as b6, type NoteVariant as b7, type NoteProps as b8, type CalendarEventStatus as b9, type CalendarEventProps as ba, type ExecutionContext as bb, 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 PanelView as j, type PanelComponentView as k, type PanelActionDataSource as l, type PanelUnknownView as m, type ProviderDefinition as n, type ProviderConfigView as o, type PromptContribution as p, type PromptSection as q, resolveLocalizedString as r, type ToolDefinition as s, type ToolConfirmationConfig as t, type CommandDefinition as u, type ExtensionContext as v, type SettingsAPI as w, type ProvidersAPI as x, type ToolsAPI as y, type ActionsAPI as z };
2370
+ export { type BackgroundTaskContext as $, type ActionResult as A, type ActionsAPI as B, type ChatMessage as C, type Disposable as D, type ExtensionContributions as E, type EventsAPI as F, type GetModelsOptions as G, type HugeIconName as H, type SchedulerAPI as I, type SchedulerJobRequest as J, type SchedulerSchedule as K, type LocalizedString as L, type ModelInfo as M, type NetworkAPI as N, type UserProfile as O, type PanelDefinition as P, type ChatAPI as Q, type ChatInstructionMessage as R, type SchedulerFirePayload as S, type ToolResult as T, type UserAPI as U, type VoiceSessionOptions as V, type ConversationPresentation as W, type LogAPI as X, type BackgroundWorkersAPI as Y, type BackgroundTaskConfig as Z, type BackgroundTaskCallback as _, type ChatOptions as a, type ChartSeries as a$, type BackgroundTaskHealth as a0, type BackgroundRestartPolicy as a1, type Query as a2, type QueryOptions as a3, type StorageAPI as a4, type SecretsAPI as a5, type StorageCollectionConfig as a6, type StorageContributions as a7, type AIProvider as a8, type ModelCapabilities as a9, type VerticalStackProps as aA, type HorizontalStackProps as aB, type GridProps as aC, type DividerProps as aD, type IconProps as aE, type IconButtonType as aF, type IconButtonProps as aG, type PanelAction as aH, type PanelProps as aI, type ToggleProps as aJ, type CollapsibleProps as aK, type FrameVariant as aL, type FrameProps as aM, type ListProps as aN, type PillVariant as aO, type PillProps as aP, type CheckboxProps as aQ, type MarkdownProps as aR, type TextPreviewProps as aS, type ModalProps as aT, type ConditionalGroupProps as aU, type WeatherCondition as aV, type WeatherWind as aW, type WeatherNowProps as aX, type WeatherForecastStep as aY, type WeatherForecastProps as aZ, type ChartKind as a_, type ChatImage as aa, type ToolCall as ab, type VoiceTransportRequest as ac, type Tool as ad, type Action as ae, type ExtensionModule as af, type AllowedCSSProperty as ag, type ExtensionComponentStyle as ah, type ExtensionComponentData as ai, type ExtensionComponentIterator as aj, type ExtensionComponentChildren as ak, type ExtensionActionCall as al, type ExtensionActionRef as am, type ExtensionDataSource as an, type ExtensionPanelDefinition as ao, type HeaderProps as ap, type LabelProps as aq, type ParagraphProps as ar, type ButtonProps as as, type TextInputProps as at, type PasswordInputProps as au, type NumberInputProps as av, type TextAreaProps as aw, type DateTimeInputProps as ax, type SelectProps as ay, type IconPickerProps as az, type StreamEvent as b, type ChartProps as b0, type StatTrend as b1, type StatTileProps as b2, type ProgressShape as b3, type ProgressColor as b4, type ProgressBarProps as b5, type KeyValueRow as b6, type KeyValueListProps as b7, type TimelineVariant as b8, type TimelineEntry as b9, type TimelineProps as ba, type NoteVariant as bb, type NoteProps as bc, type CalendarEventStatus as bd, type CalendarEventProps as be, type ExecutionContext as bf, 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 ExtensionContext as w, type SettingsAPI as x, type ProvidersAPI as y, type ToolsAPI as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stina/extension-api",
3
- "version": "0.57.0",
3
+ "version": "1.0.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -119,6 +119,7 @@
119
119
  "settings.register",
120
120
  "commands.register",
121
121
  "panels.register",
122
+ "statusCards.register",
122
123
  "events.emit",
123
124
  "scheduler.register",
124
125
  "background.workers",
@@ -564,6 +565,63 @@
564
565
  },
565
566
  "description": "Right panel contributions"
566
567
  },
568
+ "statusCards": {
569
+ "type": "array",
570
+ "items": {
571
+ "type": "object",
572
+ "properties": {
573
+ "id": {
574
+ "type": "string",
575
+ "description": "Unique card ID within the extension"
576
+ },
577
+ "title": {
578
+ "type": "string",
579
+ "description": "What it is called where the user picks it"
580
+ },
581
+ "icon": {
582
+ "type": "string",
583
+ "description": "Icon name (from huge-icons)"
584
+ },
585
+ "size": {
586
+ "type": "string",
587
+ "enum": [
588
+ "line",
589
+ "block"
590
+ ],
591
+ "description": "How much room it may take: one row, or up to three"
592
+ },
593
+ "view": {
594
+ "type": "object",
595
+ "properties": {
596
+ "kind": {
597
+ "$ref": "#/definitions/ExtensionManifest/properties/contributes/properties/panels/items/properties/view/anyOf/0/properties/kind"
598
+ },
599
+ "data": {
600
+ "$ref": "#/definitions/ExtensionManifest/properties/contributes/properties/panels/items/properties/view/anyOf/0/properties/data"
601
+ },
602
+ "content": {
603
+ "$ref": "#/definitions/ExtensionManifest/properties/contributes/properties/panels/items/properties/view/anyOf/0/properties/content"
604
+ }
605
+ },
606
+ "required": [
607
+ "kind",
608
+ "content"
609
+ ],
610
+ "additionalProperties": false,
611
+ "description": "What it draws, and where the data comes from"
612
+ }
613
+ },
614
+ "required": [
615
+ "id",
616
+ "title",
617
+ "size",
618
+ "view"
619
+ ],
620
+ "additionalProperties": false,
621
+ "description": "Status card definition"
622
+ },
623
+ "description": "Cards for the strip above the conversation list"
624
+ },
567
625
  "providers": {
568
626
  "type": "array",
569
627
  "items": {
package/src/index.ts CHANGED
@@ -24,6 +24,7 @@ export type {
24
24
  ToolSettingsComponentView,
25
25
  ToolSettingsActionDataSource,
26
26
  PanelDefinition,
27
+ StatusCardDefinition,
27
28
  PanelView,
28
29
  PanelComponentView,
29
30
  PanelActionDataSource,
@@ -203,6 +204,9 @@ export type {
203
204
  ChartProps,
204
205
  StatTrend,
205
206
  StatTileProps,
207
+ ProgressShape,
208
+ ProgressColor,
209
+ ProgressBarProps,
206
210
  KeyValueRow,
207
211
  KeyValueListProps,
208
212
  TimelineVariant,
@@ -34,6 +34,8 @@ import {
34
34
  WeatherWindSchema,
35
35
  ChartKindSchema,
36
36
  StatTrendSchema,
37
+ ProgressShapeSchema,
38
+ ProgressColorSchema,
37
39
  TimelineVariantSchema,
38
40
  NoteVariantSchema,
39
41
  CalendarEventStatusSchema,
@@ -259,6 +261,23 @@ const StatTileCardSchema = z
259
261
  })
260
262
  .strict()
261
263
 
264
+ const ProgressBarCardSchema = z
265
+ .object({
266
+ component: z.literal('ProgressBar'),
267
+ label: z.string(),
268
+ value: z.number(),
269
+ min: z.number().optional(),
270
+ max: z.number().optional(),
271
+ shape: ProgressShapeSchema.optional(),
272
+ color: ProgressColorSchema.optional(),
273
+ unit: z.string().optional(),
274
+ valueLabel: z.string().optional(),
275
+ caption: z.string().optional(),
276
+ icon: z.string().optional(),
277
+ style,
278
+ })
279
+ .strict()
280
+
262
281
  const KeyValueListCardSchema = z
263
282
  .object({
264
283
  component: z.literal('KeyValueList'),
@@ -350,6 +369,7 @@ export const CHAT_CARD_COMPONENTS = [
350
369
  'WeatherForecast',
351
370
  'Chart',
352
371
  'StatTile',
372
+ 'ProgressBar',
353
373
  'KeyValueList',
354
374
  'Timeline',
355
375
  'Note',
@@ -382,12 +402,35 @@ const CARD_MEMBERS = [
382
402
  WeatherForecastCardSchema,
383
403
  ChartCardSchema,
384
404
  StatTileCardSchema,
405
+ ProgressBarCardSchema,
385
406
  KeyValueListCardSchema,
386
407
  TimelineCardSchema,
387
408
  NoteCardSchema,
388
409
  CalendarEventCardSchema,
389
410
  ] as const
390
411
 
412
+ /**
413
+ * The properties each card component accepts, read off the schemas themselves.
414
+ *
415
+ * Derived rather than listed, for the same reason `describeChatCardProfile`
416
+ * is: a hand-kept copy of this drifts, and a drifted copy rejects components
417
+ * that are in fact legal.
418
+ *
419
+ * Used by profiles that validate a card *template* rather than a finished card
420
+ * — the status card, whose leaves are references to data that does not exist
421
+ * yet and so cannot be type-checked by these schemas. They can still be held to
422
+ * this vocabulary, which is what catches a property the model invented.
423
+ */
424
+ export const CHAT_CARD_PROPS: Readonly<Record<string, readonly string[]>> = Object.freeze(
425
+ Object.fromEntries(
426
+ CARD_MEMBERS.map((member) => {
427
+ const shape = (member as unknown as z.AnyZodObject).shape as Record<string, z.ZodTypeAny>
428
+ const name = (shape['component']!._def as { value: string }).value
429
+ return [name, Object.freeze(Object.keys(shape))]
430
+ })
431
+ )
432
+ )
433
+
391
434
  /**
392
435
  * One component of a chat card.
393
436
  *
@@ -578,7 +621,7 @@ export function validateChatCard(card: unknown): ChatCardValidation {
578
621
  // -----------------------------------------------------------------------------
579
622
 
580
623
  /**
581
- * Render one field's type compactly: `line|bar|area`, `number?`, `{a, b?}[]`.
624
+ * Render one field's type compactly: `line|bar|area`, `number?`, `{a, b?}[≤24]`.
582
625
  *
583
626
  * Enough for a reader to write a valid value, and short enough that the whole
584
627
  * vocabulary fits in a tool description without crowding out everything else
@@ -597,7 +640,12 @@ function describeType(schema: z.ZodTypeAny): string {
597
640
  return 'component[]'
598
641
  case 'ZodArray': {
599
642
  const inner = describeType((def as { type: z.ZodTypeAny }).type)
600
- return `${inner}[]`
643
+ // The cap belongs in the vocabulary. A model writing a card from a tool's
644
+ // data has no other way to learn that a forecast takes 24 steps and not
645
+ // the 48 hours it is holding, and finds out by having the whole card
646
+ // refused — which is the expensive way to be told.
647
+ const max = (def as { maxLength?: { value: number } | null }).maxLength?.value
648
+ return typeof max === 'number' ? `${inner}[≤${max}]` : `${inner}[]`
601
649
  }
602
650
  case 'ZodObject': {
603
651
  const shape = (schema as unknown as z.AnyZodObject).shape
@@ -651,6 +651,32 @@ export const StatTilePropsSchema = z
651
651
  .passthrough()
652
652
  .describe('Single-number stat tile component')
653
653
 
654
+ export const ProgressShapeSchema = z
655
+ .enum(['bar', 'circle'])
656
+ .describe('Drawn as a rail or as a ring')
657
+
658
+ export const ProgressColorSchema = z
659
+ .enum(['accent', 'success', 'warning', 'danger', 'info', 'neutral'])
660
+ .describe('One of the theme colours')
661
+
662
+ export const ProgressBarPropsSchema = z
663
+ .object({
664
+ component: z.literal('ProgressBar'),
665
+ label: z.string().describe('What is being measured'),
666
+ value: z.number().describe('Where the reading sits. Clamped to the range'),
667
+ min: z.number().optional().describe('Bottom of the range. Defaults to 0'),
668
+ max: z.number().optional().describe('Top of the range. Defaults to 100'),
669
+ shape: ProgressShapeSchema.optional().describe('Defaults to bar'),
670
+ color: ProgressColorSchema.optional().describe('Defaults to accent'),
671
+ unit: z.string().optional().describe('Written after the value'),
672
+ valueLabel: z.string().optional().describe('The readout in words, replacing value and unit'),
673
+ caption: z.string().optional().describe('One quiet line under the reading'),
674
+ icon: z.string().optional().describe('Icon name'),
675
+ style: ExtensionComponentStyleSchema.optional(),
676
+ })
677
+ .passthrough()
678
+ .describe('Progress component')
679
+
654
680
  export const KeyValueRowSchema = z
655
681
  .object({
656
682
  label: z.string(),
@@ -794,6 +820,9 @@ export type ChartSeries = z.infer<typeof ChartSeriesSchema>
794
820
  export type ChartProps = z.infer<typeof ChartPropsSchema>
795
821
  export type StatTrend = z.infer<typeof StatTrendSchema>
796
822
  export type StatTileProps = z.infer<typeof StatTilePropsSchema>
823
+ export type ProgressShape = z.infer<typeof ProgressShapeSchema>
824
+ export type ProgressColor = z.infer<typeof ProgressColorSchema>
825
+ export type ProgressBarProps = z.infer<typeof ProgressBarPropsSchema>
797
826
  export type KeyValueRow = z.infer<typeof KeyValueRowSchema>
798
827
  export type KeyValueListProps = z.infer<typeof KeyValueListPropsSchema>
799
828
  export type TimelineVariant = z.infer<typeof TimelineVariantSchema>
@@ -176,6 +176,27 @@ export const PanelDefinitionSchema = z
176
176
  })
177
177
  .describe('Panel definition')
178
178
 
179
+ /**
180
+ * A card for the strip above the conversation list.
181
+ *
182
+ * Deliberately the panel's component view rather than a profile of its own: a
183
+ * card and a panel are the same declarative idea at two sizes, and a second
184
+ * vocabulary would be a second thing to keep in step. `size` is what makes it a
185
+ * card, and it is checked rather than suggested because the sidebar is a few
186
+ * hundred pixels wide.
187
+ */
188
+ export const StatusCardDefinitionSchema = z
189
+ .object({
190
+ id: z.string().describe('Unique card ID within the extension'),
191
+ title: z.string().describe('What it is called where the user picks it'),
192
+ icon: z.string().optional().describe('Icon name (from huge-icons)'),
193
+ size: z
194
+ .enum(['line', 'block'])
195
+ .describe('How much room it may take: one row, or up to three'),
196
+ view: PanelComponentViewSchema.describe('What it draws, and where the data comes from'),
197
+ })
198
+ .describe('Status card definition')
199
+
179
200
  // =============================================================================
180
201
  // Providers
181
202
  // =============================================================================
@@ -294,6 +315,10 @@ export const ExtensionContributionsSchema = z
294
315
  .object({
295
316
  toolSettings: z.array(ToolSettingsViewDefinitionSchema).optional().describe('Tool settings views'),
296
317
  panels: z.array(PanelDefinitionSchema).optional().describe('Right panel contributions'),
318
+ statusCards: z
319
+ .array(StatusCardDefinitionSchema)
320
+ .optional()
321
+ .describe('Cards for the strip above the conversation list'),
297
322
  providers: z.array(ProviderDefinitionSchema).optional().describe('AI providers'),
298
323
  tools: z.array(ToolDefinitionSchema).optional().describe('Tools for Stina to use'),
299
324
  commands: z.array(CommandDefinitionSchema).optional().describe('Slash commands'),
@@ -306,6 +331,7 @@ export const ExtensionContributionsSchema = z
306
331
  // Type Exports
307
332
  // =============================================================================
308
333
 
334
+ export type StatusCardDefinition = z.infer<typeof StatusCardDefinitionSchema>
309
335
  export type LocalizedString = z.infer<typeof LocalizedStringSchema>
310
336
  export type ToolSettingsListMapping = z.infer<typeof ToolSettingsListMappingSchema>
311
337
  export type ToolSettingsActionDataSource = z.infer<typeof ToolSettingsActionDataSourceSchema>
@@ -47,6 +47,7 @@ export {
47
47
  ToolSettingsListMappingSchema,
48
48
  ToolSettingsActionDataSourceSchema,
49
49
  PanelDefinitionSchema,
50
+ StatusCardDefinitionSchema,
50
51
  PanelViewSchema,
51
52
  PanelComponentViewSchema,
52
53
  PanelUnknownViewSchema,
@@ -67,6 +68,7 @@ export {
67
68
  type ToolSettingsListMapping,
68
69
  type ToolSettingsActionDataSource,
69
70
  type PanelDefinition,
71
+ type StatusCardDefinition,
70
72
  type PanelView,
71
73
  type PanelComponentView,
72
74
  type PanelUnknownView,
@@ -128,6 +130,9 @@ export {
128
130
  ChartPropsSchema,
129
131
  StatTrendSchema,
130
132
  StatTilePropsSchema,
133
+ ProgressShapeSchema,
134
+ ProgressColorSchema,
135
+ ProgressBarPropsSchema,
131
136
  KeyValueRowSchema,
132
137
  KeyValueListPropsSchema,
133
138
  TimelineVariantSchema,
@@ -181,8 +186,10 @@ export {
181
186
  ChatCardSchema,
182
187
  ChatCardComponentSchema,
183
188
  CHAT_CARD_COMPONENTS,
189
+ CHAT_CARD_PROPS,
184
190
  validateChatCard,
185
191
  describeChatCardProfile,
186
192
  type ChatCardComponent,
187
193
  type ChatCardValidation,
188
194
  } from './card.schema.js'
195
+
@@ -29,6 +29,7 @@ export const VALID_PERMISSIONS = [
29
29
  'settings.register',
30
30
  'commands.register',
31
31
  'panels.register',
32
+ 'statusCards.register',
32
33
  'events.emit',
33
34
  'scheduler.register',
34
35
  'background.workers',
@@ -90,6 +91,7 @@ const CapabilityPermissionSchema = z
90
91
  'settings.register',
91
92
  'commands.register',
92
93
  'panels.register',
94
+ 'statusCards.register',
93
95
  'events.emit',
94
96
  'scheduler.register',
95
97
  'chat.message.write',