@newheap/platform-ai-chat 0.6.0 → 0.8.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.
package/i18n/en.json CHANGED
@@ -25,6 +25,9 @@
25
25
  "open-preferences": "Your assistant preferences",
26
26
  "open-admin": "Assistant administration",
27
27
  "share": "Share conversation",
28
+ "add-members": "Add people to the conversation",
29
+ "notifications-on": "Turn notifications on",
30
+ "notifications-off": "Turn notifications off",
28
31
  "members": "People in this conversation"
29
32
  },
30
33
  "agent-picker": {
@@ -70,12 +73,29 @@
70
73
  "characters": "{{count}} of {{max}} characters",
71
74
  "too-long": "The message is too long.",
72
75
  "status": {
73
- "running": "You can keep typing while the assistant works. Sending is temporarily unavailable.",
74
- "waiting-for-approval": "You can keep typing while an action waits for your approval. Sending is temporarily unavailable.",
76
+ "running": "The assistant is working",
77
+ "waiting-for-approval": "Waiting for approval",
75
78
  "running-by": "{{name}} is working with the assistant…",
76
79
  "waiting-for-approval-by": "Waiting for {{name}} to decide…"
77
80
  }
78
81
  },
82
+ "queue": {
83
+ "title": "Queue ({{count}})",
84
+ "add": "Add message to queue",
85
+ "hint": "Enter queues, Shift+Enter adds a new line",
86
+ "steer": "Steer now",
87
+ "steer-hint": "Stop the current answer and continue this conversation with this message first",
88
+ "edit": "Edit queued message",
89
+ "save": "Save message",
90
+ "cancel-edit": "Cancel editing",
91
+ "remove": "Remove queued message",
92
+ "resume": "Resume queue",
93
+ "state": {
94
+ "preparing": "Preparing…",
95
+ "sending": "Sending…",
96
+ "failed": "Not sent; resume to retry"
97
+ }
98
+ },
79
99
  "tool-call": {
80
100
  "label": "Tool call: {{name}}",
81
101
  "show-details": "Show details",
package/i18n/nl.json CHANGED
@@ -25,6 +25,9 @@
25
25
  "open-preferences": "Je assistentvoorkeuren",
26
26
  "open-admin": "Beheer van de assistent",
27
27
  "share": "Gesprek delen",
28
+ "add-members": "Mensen toevoegen aan het gesprek",
29
+ "notifications-on": "Notificaties aanzetten",
30
+ "notifications-off": "Notificaties uitzetten",
28
31
  "members": "Mensen in dit gesprek"
29
32
  },
30
33
  "agent-picker": {
@@ -70,12 +73,29 @@
70
73
  "characters": "{{count}} van {{max}} tekens",
71
74
  "too-long": "Het bericht is te lang.",
72
75
  "status": {
73
- "running": "Je kunt verder typen terwijl de assistent bezig is. Versturen is tijdelijk niet mogelijk.",
74
- "waiting-for-approval": "Je kunt verder typen terwijl een actie op je goedkeuring wacht. Versturen is tijdelijk niet mogelijk.",
76
+ "running": "De assistent is bezig",
77
+ "waiting-for-approval": "Wacht op goedkeuring",
75
78
  "running-by": "{{name}} werkt met de assistent…",
76
79
  "waiting-for-approval-by": "Wacht op de beslissing van {{name}}…"
77
80
  }
78
81
  },
82
+ "queue": {
83
+ "title": "Wachtrij ({{count}})",
84
+ "add": "Bericht in de wachtrij zetten",
85
+ "hint": "Enter zet in wachtrij, Shift+Enter voegt een regel toe",
86
+ "steer": "Bijsturen",
87
+ "steer-hint": "Stop het huidige antwoord en vervolg dit gesprek eerst met dit bericht",
88
+ "edit": "Bericht in wachtrij bewerken",
89
+ "save": "Bericht opslaan",
90
+ "cancel-edit": "Bewerken annuleren",
91
+ "remove": "Bericht uit wachtrij verwijderen",
92
+ "resume": "Wachtrij hervatten",
93
+ "state": {
94
+ "preparing": "Klaarzetten…",
95
+ "sending": "Versturen…",
96
+ "failed": "Niet verstuurd; hervat om opnieuw te proberen"
97
+ }
98
+ },
79
99
  "tool-call": {
80
100
  "label": "Toolaanroep: {{name}}",
81
101
  "show-details": "Details tonen",
package/index.d.ts CHANGED
@@ -761,6 +761,13 @@ interface NhAssistantError {
761
761
  * answer short. The conversation stays usable; the notice only explains the answer.
762
762
  */
763
763
  type NhAssistantNotice = NhAssistantError;
764
+ /** An unsent message held in this tab, scoped to its original conversation. */
765
+ interface NhAssistantQueuedMessage {
766
+ id: string;
767
+ conversationId: string;
768
+ text: string;
769
+ state: 'preparing' | 'queued' | 'sending' | 'failed';
770
+ }
764
771
  /** Notice code for a completed turn that produced no answer text and no server code. */
765
772
  declare const NH_ASSISTANT_NO_ANSWER_NOTICE_CODE = "assistant-no-answer";
766
773
  /**
@@ -814,6 +821,12 @@ declare class NhAssistantStore {
814
821
  private readonly restorePanelOpenState;
815
822
  private readonly viewingState;
816
823
  private readonly pageVisibleState;
824
+ private readonly queuedState;
825
+ private readonly pausedQueuesState;
826
+ private readonly queueDispatchState;
827
+ private readonly steeringState;
828
+ private readonly submittingState;
829
+ private destroyed;
817
830
  private readonly streams;
818
831
  private readonly cancelTimers;
819
832
  private readonly pendingSendResolves;
@@ -865,6 +878,13 @@ declare class NhAssistantStore {
865
878
  readonly restorePanelOpen: _angular_core.Signal<boolean>;
866
879
  /** True while the user can send: enabled, an agent is chosen and no turn runs or waits. */
867
880
  readonly canSend: _angular_core.Signal<boolean>;
881
+ /** Messages not yet accepted by the server, for the open conversation. Never persisted. */
882
+ readonly queuedMessages: _angular_core.Signal<readonly NhAssistantQueuedMessage[]>;
883
+ /** Sending or queueing is available during a turn and while an approval waits. */
884
+ readonly canSubmit: _angular_core.Signal<boolean>;
885
+ readonly queuePaused: _angular_core.Signal<boolean>;
886
+ /** Steering cancels the active turn before sending the selected correction. */
887
+ readonly canSteer: _angular_core.Signal<boolean>;
868
888
  /** The owner and participants of the open conversation; empty while it is not shared. */
869
889
  readonly members: _angular_core.Signal<ConversationMember[]>;
870
890
  /** True when the current user owns the open conversation (or it is new). */
@@ -904,10 +924,24 @@ declare class NhAssistantStore {
904
924
  * their own turns. Resolves `false` when the message was not accepted.
905
925
  */
906
926
  send(text: string): Promise<boolean>;
927
+ /** Sends immediately when idle, otherwise appends to the conversation's FIFO queue. */
928
+ submit(text: string): Promise<boolean>;
929
+ /** Edits an unsent queued message without replacing the composer's current draft. */
930
+ updateQueuedMessage(id: string, text: string): boolean;
931
+ removeQueuedMessage(id: string): void;
932
+ /** Pauses automatic dispatch while keeping all unsent messages available. */
933
+ pauseQueue(): void;
934
+ /** Explicitly resumes after Stop or a failure; approval decisions remain separate. */
935
+ resumeQueue(): void;
936
+ /** Prioritizes a queued correction and waits for confirmed cancellation before dispatch. */
937
+ steerQueuedMessage(id: string): Promise<void>;
938
+ private dispatchQueued;
939
+ private sendMessage;
907
940
  /** Approves or rejects the pending approval. Ignores repeated calls while a decision is in flight. */
908
941
  decide(decision: ApprovalDecision, reason?: string): void;
909
942
  /** Asks the server to stop the running turn or to abandon a waiting approval of the open conversation. */
910
943
  cancel(): Promise<void>;
944
+ private cancelConversation;
911
945
  /** Joins a shared conversation with an invitation link and opens it. Resolves `false` on failure. */
912
946
  joinConversation(conversationId: string, token: string): Promise<boolean>;
913
947
  /** Owner only: creates a new invitation link for the open conversation and returns its token. */
@@ -1123,7 +1157,7 @@ declare class NhAssistantLauncherComponent {
1123
1157
  declare class NhAssistantPanelComponent implements AfterViewInit, OnDestroy {
1124
1158
  readonly store: NhAssistantStore;
1125
1159
  readonly panel: NhAssistantPanelService;
1126
- private readonly push;
1160
+ readonly push: NhAssistantPushService;
1127
1161
  private readonly config;
1128
1162
  private readonly viewContainerRef;
1129
1163
  private readonly router;
@@ -1134,6 +1168,9 @@ declare class NhAssistantPanelComponent implements AfterViewInit, OnDestroy {
1134
1168
  readonly showConversations: _angular_core.WritableSignal<boolean>;
1135
1169
  readonly showPreferences: _angular_core.WritableSignal<boolean>;
1136
1170
  readonly showShare: _angular_core.WritableSignal<boolean>;
1171
+ readonly shareSection: _angular_core.WritableSignal<"members" | "link" | "all">;
1172
+ readonly notificationError: _angular_core.WritableSignal<NhAssistantError | null>;
1173
+ readonly notificationsLabel: _angular_core.Signal<"nh-assistant.panel.notifications-off" | "nh-assistant.panel.notifications-on">;
1137
1174
  readonly adminRoute: string | any[] | null;
1138
1175
  readonly conversation: _angular_core.Signal<Conversation | null>;
1139
1176
  private readonly conversationId;
@@ -1141,6 +1178,10 @@ declare class NhAssistantPanelComponent implements AfterViewInit, OnDestroy {
1141
1178
  readonly closed: _angular_core.Signal<boolean>;
1142
1179
  readonly busy: _angular_core.Signal<boolean>;
1143
1180
  readonly composerDisabled: _angular_core.Signal<boolean>;
1181
+ readonly editingQueuedId: _angular_core.WritableSignal<string | null>;
1182
+ readonly queuedDraft: _angular_core.WritableSignal<string>;
1183
+ private resumeAfterEditing;
1184
+ readonly validQueuedDraft: _angular_core.Signal<boolean>;
1144
1185
  readonly composerStatus: _angular_core.Signal<"running" | "waiting-for-approval" | null>;
1145
1186
  /** Name of another participant whose turn runs or waits, or `null`. */
1146
1187
  readonly activeMemberName: _angular_core.Signal<string | null>;
@@ -1157,11 +1198,17 @@ declare class NhAssistantPanelComponent implements AfterViewInit, OnDestroy {
1157
1198
  describeContext(context: ClientContext): string;
1158
1199
  toggleConversations(): void;
1159
1200
  togglePreferences(): void;
1160
- toggleShare(): void;
1201
+ toggleShare(section?: 'all' | 'link' | 'members'): void;
1202
+ /** Applies the notification choice immediately, including browser permission handling. */
1203
+ toggleNotifications(): Promise<void>;
1161
1204
  newConversation(): void;
1162
1205
  openConversation(conversationId: string): void;
1163
1206
  deleteConversation(conversationId: string): void;
1164
1207
  send(text: string): void;
1208
+ editQueuedMessage(id: string, text: string): void;
1209
+ changeQueuedDraft(event: Event): void;
1210
+ saveQueuedMessage(id: string): void;
1211
+ cancelQueueEdit(): void;
1165
1212
  /**
1166
1213
  * Opens the panel for an invitation link or a clicked notification in the URL fragment and
1167
1214
  * removes the fragment, so a reload or a shared screenshot does not reuse the token.
@@ -1255,6 +1302,8 @@ declare class NhAssistantComposerComponent {
1255
1302
  readonly sendDisabled: _angular_core.InputSignal<boolean>;
1256
1303
  /** Shows the stop button instead of the send button. */
1257
1304
  readonly busy: _angular_core.InputSignal<boolean>;
1305
+ /** Keeps the send action available next to Stop so the host can queue messages. */
1306
+ readonly queueWhileBusy: _angular_core.InputSignal<boolean>;
1258
1307
  /** Announces why sending is temporarily unavailable. */
1259
1308
  readonly status: _angular_core.InputSignal<"running" | "waiting-for-approval" | null>;
1260
1309
  /** Name of the participant whose turn runs or waits, when it is someone else. */
@@ -1287,7 +1336,7 @@ declare class NhAssistantComposerComponent {
1287
1336
  submit(): void;
1288
1337
  private restoreOwnedFocus;
1289
1338
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantComposerComponent, never>;
1290
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantComposerComponent, "nh-assistant-composer", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "sendDisabled": { "alias": "sendDisabled"; "required": false; "isSignal": true; }; "busy": { "alias": "busy"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "statusActor": { "alias": "statusActor"; "required": false; "isSignal": true; }; "canStop": { "alias": "canStop"; "required": false; "isSignal": true; }; "maxLength": { "alias": "maxLength"; "required": false; "isSignal": true; }; "restore": { "alias": "restore"; "required": false; "isSignal": true; }; }, { "send": "send"; "cancel": "cancel"; "restored": "restored"; }, never, never, true, never>;
1339
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantComposerComponent, "nh-assistant-composer", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "sendDisabled": { "alias": "sendDisabled"; "required": false; "isSignal": true; }; "busy": { "alias": "busy"; "required": false; "isSignal": true; }; "queueWhileBusy": { "alias": "queueWhileBusy"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "statusActor": { "alias": "statusActor"; "required": false; "isSignal": true; }; "canStop": { "alias": "canStop"; "required": false; "isSignal": true; }; "maxLength": { "alias": "maxLength"; "required": false; "isSignal": true; }; "restore": { "alias": "restore"; "required": false; "isSignal": true; }; }, { "send": "send"; "cancel": "cancel"; "restored": "restored"; }, never, ["[nhAssistantComposerControls]"], true, never>;
1291
1340
  }
1292
1341
 
1293
1342
  /** Shows one tool invocation with its status and expandable input and result previews. */
@@ -1367,12 +1416,14 @@ declare class NhAssistantAgentPickerComponent {
1367
1416
  readonly agents: _angular_core.InputSignal<readonly AgentSummary[]>;
1368
1417
  readonly selectedAgentId: _angular_core.InputSignal<string | null>;
1369
1418
  readonly disabled: _angular_core.InputSignal<boolean>;
1419
+ /** Compact prompt-bar control; capability information remains in the tooltip and accessible description. */
1420
+ readonly compact: _angular_core.InputSignal<boolean>;
1370
1421
  readonly agentChange: _angular_core.OutputEmitterRef<string>;
1371
1422
  readonly selectId: string;
1372
1423
  readonly selected: _angular_core.Signal<AgentSummary | null>;
1373
1424
  onChange(event: Event): void;
1374
1425
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantAgentPickerComponent, never>;
1375
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantAgentPickerComponent, "nh-assistant-agent-picker", never, { "agents": { "alias": "agents"; "required": true; "isSignal": true; }; "selectedAgentId": { "alias": "selectedAgentId"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "agentChange": "agentChange"; }, never, never, true, never>;
1426
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantAgentPickerComponent, "nh-assistant-agent-picker", never, { "agents": { "alias": "agents"; "required": true; "isSignal": true; }; "selectedAgentId": { "alias": "selectedAgentId"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "compact": { "alias": "compact"; "required": false; "isSignal": true; }; }, { "agentChange": "agentChange"; }, never, never, true, never>;
1376
1427
  }
1377
1428
 
1378
1429
  /** Maximum length of the user's own instructions. */
@@ -1437,6 +1488,8 @@ declare class NhAssistantShareComponent {
1437
1488
  private searchRevision;
1438
1489
  /** Emitted when the user leaves the view. */
1439
1490
  readonly closed: _angular_core.OutputEmitterRef<void>;
1491
+ /** Show the invitation link, participants, or both (the default for custom hosts). */
1492
+ readonly section: _angular_core.InputSignal<"members" | "link" | "all">;
1440
1493
  readonly id: string;
1441
1494
  readonly conversation: _angular_core.Signal<Conversation | null>;
1442
1495
  readonly isOwner: _angular_core.Signal<boolean>;
@@ -1462,7 +1515,7 @@ declare class NhAssistantShareComponent {
1462
1515
  isCurrentUser(member: ConversationMember): boolean;
1463
1516
  private run;
1464
1517
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NhAssistantShareComponent, never>;
1465
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantShareComponent, "nh-assistant-share", never, {}, { "closed": "closed"; }, never, never, true, never>;
1518
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NhAssistantShareComponent, "nh-assistant-share", never, { "section": { "alias": "section"; "required": false; "isSignal": true; }; }, { "closed": "closed"; }, never, never, true, never>;
1466
1519
  }
1467
1520
 
1468
1521
  /**
@@ -1506,4 +1559,4 @@ declare function nhAssistantErrorKeys(error: NhAssistantError | null): string[];
1506
1559
  declare const NH_ASSISTANT_DASH_CASE: RegExp;
1507
1560
 
1508
1561
  export { NH_ASSISTANT_ACCESS_POLICY, NH_ASSISTANT_CONFIG, NH_ASSISTANT_CONVERSATION_FRAGMENT, NH_ASSISTANT_FETCH, NH_ASSISTANT_ICONS, NH_ASSISTANT_JOIN_FRAGMENT, NH_ASSISTANT_MAX_CUSTOM_INSTRUCTIONS, NH_ASSISTANT_NO_ANSWER_NOTICE_CODE, NH_ASSISTANT_PAGE_CONTEXT_LIMITS, NH_ASSISTANT_PANEL_MOBILE_QUERY, NH_ASSISTANT_PANEL_WIDTH, NH_ASSISTANT_SSE_EVENT_TYPES, NH_ASSISTANT_TRANSLATIONS, NH_ASSISTANT_VIRTUAL_SCROLL_THRESHOLD, NhAssistantActivityComponent, NhAssistantAdminApiService, NhAssistantAgentPickerComponent, NhAssistantAllowAllAccessPolicy, NhAssistantApiError, NhAssistantApiService, NhAssistantApprovalCardComponent, NhAssistantClientErrorCodes, NhAssistantComposerComponent, NhAssistantConversationListComponent, NhAssistantLauncherComponent, NhAssistantLiveService, NhAssistantPanelComponent, NhAssistantPanelService, NhAssistantPreferencesComponent, NhAssistantPushService, NhAssistantShareComponent, NhAssistantSseParser, NhAssistantStore, NhAssistantThreadComponent, NhAssistantToolCallCardComponent, NhAssistantToolCallGroupComponent, NhAssistantTranslationMerger, applyNhAssistantApprovalDecision, applyNhAssistantConversationChange, applyNhAssistantEvent, applyNhAssistantLiveEvent, describeNhAssistantClientContext, formatNhAssistantCountdown, nhAssistantCodeForStatus, nhAssistantErrorMessageKey, nhAssistantIsUnread, nhAssistantLatestTurnHasText, nhAssistantShareLink, normalizeNhAssistantClientContext, provideNhAssistant, NH_ASSISTANT_DASH_CASE as ɵNH_ASSISTANT_DASH_CASE, NhAssistantIconComponent as ɵNhAssistantIconComponent, NhAssistantTranslatePipe as ɵNhAssistantTranslatePipe, nhAssistantErrorKeys as ɵnhAssistantErrorKeys, toNhAssistantError as ɵtoNhAssistantError };
1509
- export type { AdminAgent, AdminAgentInput, AgentSummary, ApplicationContext, ApplicationContextVersion, ApprovalDecision, ApprovalPart, ApprovalPresentation, ApprovalPresentationField, ApprovalRequiredEvent, ApprovalStatus, AssistantAddressForm, AssistantAutonomy, AssistantCollaboration, AssistantErrorEvent, AssistantPreferences, AssistantResponseLength, AssistantStatus, AssistantStyle, ClientContext, ClientContextEntity, Conversation, ConversationMember, ConversationPage, ConversationRole, ConversationStatus, ConversationSummary, CreateConversationRequest, DecideApprovalRequest, DirectoryEntry, LiveConversationChanged, LiveConversationEvent, LiveConversationRead, LiveConversationRemoved, McpAuthMode, McpServer, McpServerInput, McpServerTestResult, McpTool, McpToolEffect, McpToolStatus, Message, MessageDeltaEvent, MessagePart, NhAssistantAccessPolicy, NhAssistantActivity, NhAssistantClientContext, NhAssistantClientErrorCode, NhAssistantConfig, NhAssistantError, NhAssistantFetch, NhAssistantIconName, NhAssistantLiveState, NhAssistantNotice, NhAssistantPushConfig, NhAssistantPushState, NhAssistantRawSseMessage, NhAssistantSseEvent, NhAssistantSseEventMap, NhAssistantSseEventType, NhAssistantStatusCodes, NhAssistantToolCallGroupState, NotificationSettings, PushSubscriptionRequest, SendMessageRequest, ShareLink, TextPart, ToolCallPart, ToolCallStatus, ToolCatalogEffect, ToolCatalogEntry, ToolCompletedEvent, ToolStartedEvent, TurnCompletedEvent, TurnCompletionStatus, TurnStartedEvent, TurnUsage, UpdateAdminAgentRequest, UpdateApplicationContextRequest, UpdateMcpToolRequest };
1562
+ export type { AdminAgent, AdminAgentInput, AgentSummary, ApplicationContext, ApplicationContextVersion, ApprovalDecision, ApprovalPart, ApprovalPresentation, ApprovalPresentationField, ApprovalRequiredEvent, ApprovalStatus, AssistantAddressForm, AssistantAutonomy, AssistantCollaboration, AssistantErrorEvent, AssistantPreferences, AssistantResponseLength, AssistantStatus, AssistantStyle, ClientContext, ClientContextEntity, Conversation, ConversationMember, ConversationPage, ConversationRole, ConversationStatus, ConversationSummary, CreateConversationRequest, DecideApprovalRequest, DirectoryEntry, LiveConversationChanged, LiveConversationEvent, LiveConversationRead, LiveConversationRemoved, McpAuthMode, McpServer, McpServerInput, McpServerTestResult, McpTool, McpToolEffect, McpToolStatus, Message, MessageDeltaEvent, MessagePart, NhAssistantAccessPolicy, NhAssistantActivity, NhAssistantClientContext, NhAssistantClientErrorCode, NhAssistantConfig, NhAssistantError, NhAssistantFetch, NhAssistantIconName, NhAssistantLiveState, NhAssistantNotice, NhAssistantPushConfig, NhAssistantPushState, NhAssistantQueuedMessage, NhAssistantRawSseMessage, NhAssistantSseEvent, NhAssistantSseEventMap, NhAssistantSseEventType, NhAssistantStatusCodes, NhAssistantToolCallGroupState, NotificationSettings, PushSubscriptionRequest, SendMessageRequest, ShareLink, TextPart, ToolCallPart, ToolCallStatus, ToolCatalogEffect, ToolCatalogEntry, ToolCompletedEvent, ToolStartedEvent, TurnCompletedEvent, TurnCompletionStatus, TurnStartedEvent, TurnUsage, UpdateAdminAgentRequest, UpdateApplicationContextRequest, UpdateMcpToolRequest };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newheap/platform-ai-chat",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "peerDependencies": {
5
5
  "@angular/cdk": "^20.2.14",
6
6
  "@angular/common": "^20.3.28",