@yadsh/dsh-qa-surface 0.13.0 → 0.15.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/README.md +148 -22
- package/compatibility.json +7 -3
- package/lib/access/capability-catalog.js +22 -6
- package/lib/access/capability-catalog.js.map +1 -1
- package/lib/access/model.js +36 -2
- package/lib/access/model.js.map +1 -1
- package/lib/access/service.js +19 -4
- package/lib/access/service.js.map +1 -1
- package/lib/account-remotes.js +4 -0
- package/lib/account-remotes.js.map +1 -1
- package/lib/accounts/database.js +49 -9
- package/lib/accounts/database.js.map +1 -1
- package/lib/accounts/errors.js.map +1 -1
- package/lib/accounts/file.js.map +1 -1
- package/lib/accounts/store.js +53 -8
- package/lib/accounts/store.js.map +1 -1
- package/lib/admin/permissions.js +6 -0
- package/lib/admin/permissions.js.map +1 -1
- package/lib/admin/quality-store.js +95 -19
- package/lib/admin/quality-store.js.map +1 -1
- package/lib/admin/service.js +178 -0
- package/lib/admin/service.js.map +1 -1
- package/lib/cli.js +24 -4
- package/lib/cli.js.map +1 -1
- package/lib/client/QaAccountsController.js +52 -5
- package/lib/client/QaAccountsController.js.map +1 -1
- package/lib/client/QaConfigController.js.map +1 -1
- package/lib/client/QaSessionController.js +626 -63
- package/lib/client/QaSessionController.js.map +1 -1
- package/lib/client/QaSurface.js +293 -43
- package/lib/client/QaSurface.js.map +1 -1
- package/lib/client/QaSurfaceGuard.js +2 -2
- package/lib/client/QaSurfaceGuard.js.map +1 -1
- package/lib/client/QaTranscriptAdapter.js +4 -2
- package/lib/client/QaTranscriptAdapter.js.map +1 -1
- package/lib/client/admin/QaAdmin.js +59 -34
- package/lib/client/admin/QaAdmin.js.map +1 -1
- package/lib/client/admin/pages/Conversations.js +12 -12
- package/lib/client/admin/pages/Conversations.js.map +1 -1
- package/lib/client/admin/pages/ExpertMemory.js +210 -0
- package/lib/client/admin/pages/ExpertMemory.js.map +1 -0
- package/lib/client/admin/pages/Overview.js +4 -4
- package/lib/client/admin/pages/Overview.js.map +1 -1
- package/lib/client/admin/pages/Quality.js +5 -5
- package/lib/client/admin/pages/Quality.js.map +1 -1
- package/lib/client/admin/pages/Review.js +5 -5
- package/lib/client/admin/pages/Review.js.map +1 -1
- package/lib/client/admin/pages/SkillFiles.js +3 -3
- package/lib/client/admin/pages/SkillFiles.js.map +1 -1
- package/lib/client/admin/pages/Users.js +12 -12
- package/lib/client/admin/pages/Users.js.map +1 -1
- package/lib/client/admin/routes.js +4 -0
- package/lib/client/admin/routes.js.map +1 -1
- package/lib/client/admin/shared.js +15 -6
- package/lib/client/admin/shared.js.map +1 -1
- package/lib/client/admin/styles.js +3 -0
- package/lib/client/admin/styles.js.map +1 -1
- package/lib/client/attestation.js +11 -2
- package/lib/client/attestation.js.map +1 -1
- package/lib/client/audit/QaAuditDialog.js +2 -2
- package/lib/client/audit/QaAuditDialog.js.map +1 -1
- package/lib/client/audit/QaAuditRowBadge.js +1 -1
- package/lib/client/audit/QaAuditRowBadge.js.map +1 -1
- package/lib/client/components/Markdown.js +7 -2
- package/lib/client/components/Markdown.js.map +1 -1
- package/lib/client/components/QaAgentsDrawer.js +7 -5
- package/lib/client/components/QaAgentsDrawer.js.map +1 -1
- package/lib/client/components/QaApproval.js +2 -2
- package/lib/client/components/QaApproval.js.map +1 -1
- package/lib/client/components/QaAuthGate.js +6 -6
- package/lib/client/components/QaAuthGate.js.map +1 -1
- package/lib/client/components/QaChangelog.js +77 -0
- package/lib/client/components/QaChangelog.js.map +1 -1
- package/lib/client/components/QaComposer.js +9 -6
- package/lib/client/components/QaComposer.js.map +1 -1
- package/lib/client/components/QaFileAttachment.js +1 -1
- package/lib/client/components/QaFileAttachment.js.map +1 -1
- package/lib/client/components/QaFilesPanel.js +7 -7
- package/lib/client/components/QaFilesPanel.js.map +1 -1
- package/lib/client/components/QaHeader.js +4 -4
- package/lib/client/components/QaHeader.js.map +1 -1
- package/lib/client/components/QaMessage.js +12 -12
- package/lib/client/components/QaMessage.js.map +1 -1
- package/lib/client/components/QaModal.js +11 -2
- package/lib/client/components/QaModal.js.map +1 -1
- package/lib/client/components/QaQuestions.js +4 -4
- package/lib/client/components/QaQuestions.js.map +1 -1
- package/lib/client/components/QaQueueDock.js +137 -0
- package/lib/client/components/QaQueueDock.js.map +1 -0
- package/lib/client/components/QaRequestQueue.js +22 -0
- package/lib/client/components/QaRequestQueue.js.map +1 -0
- package/lib/client/components/QaRightRail.js +2 -2
- package/lib/client/components/QaRightRail.js.map +1 -1
- package/lib/client/components/QaSidebar.js +98 -7
- package/lib/client/components/QaSidebar.js.map +1 -1
- package/lib/client/components/QaSourcesPanel.js +10 -8
- package/lib/client/components/QaSourcesPanel.js.map +1 -1
- package/lib/client/components/QaThemeSwitcher.js +19 -0
- package/lib/client/components/QaThemeSwitcher.js.map +1 -0
- package/lib/client/components/QaTurnNotice.js +40 -0
- package/lib/client/components/QaTurnNotice.js.map +1 -0
- package/lib/client/components/QaTurnRail.js +3 -3
- package/lib/client/components/QaTurnRail.js.map +1 -1
- package/lib/client/components/QaWelcomeNotice.js +2 -6
- package/lib/client/components/QaWelcomeNotice.js.map +1 -1
- package/lib/client/components/QaWidthHandle.js +2 -2
- package/lib/client/components/QaWidthHandle.js.map +1 -1
- package/lib/client/components/QaWorkGroup.js +5 -5
- package/lib/client/components/QaWorkGroup.js.map +1 -1
- package/lib/client/components/QaWorkspaceBrowser.js +10 -10
- package/lib/client/components/QaWorkspaceBrowser.js.map +1 -1
- package/lib/client/components/VariantSwitcher.js +1 -1
- package/lib/client/components/VariantSwitcher.js.map +1 -1
- package/lib/client/failure-copy.js +26 -8
- package/lib/client/failure-copy.js.map +1 -1
- package/lib/client/focus-ring.js +193 -0
- package/lib/client/focus-ring.js.map +1 -0
- package/lib/client/index.js +40 -20
- package/lib/client/index.js.map +1 -1
- package/lib/client/lineage.js +3 -16
- package/lib/client/lineage.js.map +1 -1
- package/lib/client/markdown/CodeBlock.js +2 -2
- package/lib/client/markdown/CodeBlock.js.map +1 -1
- package/lib/client/markdown/blocks.js +118 -31
- package/lib/client/markdown/blocks.js.map +1 -1
- package/lib/client/markdown/math.js +1 -1
- package/lib/client/markdown/math.js.map +1 -1
- package/lib/client/markdown/render.js +32 -16
- package/lib/client/markdown/render.js.map +1 -1
- package/lib/client/markdown/source-chip.js +3 -3
- package/lib/client/markdown/source-chip.js.map +1 -1
- package/lib/client/notifications/notification-dispatcher.js +90 -0
- package/lib/client/notifications/notification-dispatcher.js.map +1 -0
- package/lib/client/notifications/preferences.js +61 -0
- package/lib/client/notifications/preferences.js.map +1 -0
- package/lib/client/notifications/turn-completion-source.js +82 -0
- package/lib/client/notifications/turn-completion-source.js.map +1 -0
- package/lib/client/notifications/use-turn-notifications.js +108 -0
- package/lib/client/notifications/use-turn-notifications.js.map +1 -0
- package/lib/client/panels/PanelHost.js +5 -5
- package/lib/client/panels/PanelHost.js.map +1 -1
- package/lib/client/panels/PanelLauncher.js +2 -2
- package/lib/client/panels/PanelLauncher.js.map +1 -1
- package/lib/client/project-session-state.js +156 -4
- package/lib/client/project-session-state.js.map +1 -1
- package/lib/client/role/RoleSelector.js +9 -4
- package/lib/client/role/RoleSelector.js.map +1 -1
- package/lib/client/settings/card.js +58 -17
- package/lib/client/settings/card.js.map +1 -1
- package/lib/client/settings/fields.js +11 -10
- package/lib/client/settings/fields.js.map +1 -1
- package/lib/client/settings/format.js +0 -9
- package/lib/client/settings/format.js.map +1 -1
- package/lib/client/settings/sections/access.js +5 -5
- package/lib/client/settings/sections/access.js.map +1 -1
- package/lib/client/settings/sections/accounts.js +10 -10
- package/lib/client/settings/sections/accounts.js.map +1 -1
- package/lib/client/settings/sections/attachments.js +6 -6
- package/lib/client/settings/sections/attachments.js.map +1 -1
- package/lib/client/settings/sections/branding.js +7 -7
- package/lib/client/settings/sections/branding.js.map +1 -1
- package/lib/client/settings/sections/common.js +4 -2
- package/lib/client/settings/sections/common.js.map +1 -1
- package/lib/client/settings/sections/docs.js +4 -3
- package/lib/client/settings/sections/docs.js.map +1 -1
- package/lib/client/settings/sections/embedding.js +2 -2
- package/lib/client/settings/sections/embedding.js.map +1 -1
- package/lib/client/settings/sections/interface.js +12 -12
- package/lib/client/settings/sections/interface.js.map +1 -1
- package/lib/client/settings/sections/lockdown.js +9 -9
- package/lib/client/settings/sections/lockdown.js.map +1 -1
- package/lib/client/settings/sections/notes.js +12 -12
- package/lib/client/settings/sections/notes.js.map +1 -1
- package/lib/client/settings/sections/session.js +15 -12
- package/lib/client/settings/sections/session.js.map +1 -1
- package/lib/client/settings/sections/slash.js +9 -9
- package/lib/client/settings/sections/slash.js.map +1 -1
- package/lib/client/settings/sections/sources.js +26 -26
- package/lib/client/settings/sections/sources.js.map +1 -1
- package/lib/client/settings/sections/status.js +2 -2
- package/lib/client/settings/sections/status.js.map +1 -1
- package/lib/client/settings/styles.js +15 -9
- package/lib/client/settings/styles.js.map +1 -1
- package/lib/client/slash/SlashPalette.js +4 -4
- package/lib/client/slash/SlashPalette.js.map +1 -1
- package/lib/client/styles.js +145 -83
- package/lib/client/styles.js.map +1 -1
- package/lib/client/theme-preference.js +162 -0
- package/lib/client/theme-preference.js.map +1 -0
- package/lib/client/types.js +8 -0
- package/lib/client/types.js.map +1 -1
- package/lib/client/use-session-ui-state.js +7 -5
- package/lib/client/use-session-ui-state.js.map +1 -1
- package/lib/client/user-settings/GeneralSettingsPage.js +6 -6
- package/lib/client/user-settings/GeneralSettingsPage.js.map +1 -1
- package/lib/client/user-settings/IntegrationTokensPage.js +6 -6
- package/lib/client/user-settings/IntegrationTokensPage.js.map +1 -1
- package/lib/client/user-settings/NotificationSettingsPage.js +107 -0
- package/lib/client/user-settings/NotificationSettingsPage.js.map +1 -0
- package/lib/client/user-settings/PasswordSettingsPage.js +1 -1
- package/lib/client/user-settings/PasswordSettingsPage.js.map +1 -1
- package/lib/client/user-settings/ProfileSettingsPage.js +2 -2
- package/lib/client/user-settings/ProfileSettingsPage.js.map +1 -1
- package/lib/client/user-settings/SkillCatalog.js +3 -3
- package/lib/client/user-settings/SkillCatalog.js.map +1 -1
- package/lib/client/user-settings/SkillEditor.js +26 -8
- package/lib/client/user-settings/SkillEditor.js.map +1 -1
- package/lib/client/user-settings/SkillToolPicker.js +3 -3
- package/lib/client/user-settings/SkillToolPicker.js.map +1 -1
- package/lib/client/user-settings/SkillsSettingsPage.js +1 -1
- package/lib/client/user-settings/SkillsSettingsPage.js.map +1 -1
- package/lib/client/user-settings/StartersSettingsPage.js +6 -6
- package/lib/client/user-settings/StartersSettingsPage.js.map +1 -1
- package/lib/client/user-settings/UserSettingsDialog.js +7 -2
- package/lib/client/user-settings/UserSettingsDialog.js.map +1 -1
- package/lib/client/user-settings/copy.js +2 -0
- package/lib/client/user-settings/copy.js.map +1 -1
- package/lib/client/user-settings/draft.js +4 -1
- package/lib/client/user-settings/draft.js.map +1 -1
- package/lib/client/user-settings/fields.js +5 -5
- package/lib/client/user-settings/fields.js.map +1 -1
- package/lib/client.js +7307 -4010
- package/lib/client.js.map +1 -1
- package/lib/config-resolvers/defaults.js +7 -0
- package/lib/config-resolvers/defaults.js.map +1 -1
- package/lib/config-resolvers/lockdown.js +7 -0
- package/lib/config-resolvers/lockdown.js.map +1 -1
- package/lib/config-resolvers/notifications.js +15 -0
- package/lib/config-resolvers/notifications.js.map +1 -0
- package/lib/config-resolvers/session.js +11 -1
- package/lib/config-resolvers/session.js.map +1 -1
- package/lib/config.js +67 -18
- package/lib/config.js.map +1 -1
- package/lib/enforcement/tool-grants.js +6 -6
- package/lib/enforcement/tool-grants.js.map +1 -1
- package/lib/index.js +145 -30
- package/lib/index.js.map +1 -1
- package/lib/integration/answer.js +74 -8
- package/lib/integration/answer.js.map +1 -1
- package/lib/integration/expert-memory.js +39 -0
- package/lib/integration/expert-memory.js.map +1 -0
- package/lib/integration/host-runner.js +26 -14
- package/lib/integration/host-runner.js.map +1 -1
- package/lib/notifications.js +66 -0
- package/lib/notifications.js.map +1 -0
- package/lib/personal-skills/errors.js.map +1 -1
- package/lib/personal-skills/service.js +81 -7
- package/lib/personal-skills/service.js.map +1 -1
- package/lib/prompt-notes.js +2 -10
- package/lib/prompt-notes.js.map +1 -1
- package/lib/provenance/host-store.js +8 -5
- package/lib/provenance/host-store.js.map +1 -1
- package/lib/qa-tools/docs-tools.js +1 -1
- package/lib/qa-tools/docs-tools.js.map +1 -1
- package/lib/qa-tools/lifecycle.js +6 -3
- package/lib/qa-tools/lifecycle.js.map +1 -1
- package/lib/request-queue.js +32 -0
- package/lib/request-queue.js.map +1 -0
- package/lib/resolve-config.js +2 -0
- package/lib/resolve-config.js.map +1 -1
- package/lib/secure-session.js +7 -2
- package/lib/secure-session.js.map +1 -1
- package/lib/shared/settings.js +19 -2
- package/lib/shared/settings.js.map +1 -1
- package/lib/turn-failure-log.js +67 -0
- package/lib/turn-failure-log.js.map +1 -0
- package/lib/typert.host.js +1398 -651
- package/lib/typert.remote-client.d.ts +15 -1
- package/lib/typert.remote-client.js +1315 -645
- package/lib/types/access/capability-catalog.d.ts +20 -4
- package/lib/types/access/model.d.ts +23 -0
- package/lib/types/access/service.d.ts +2 -3
- package/lib/types/account-remotes.d.ts +8 -1
- package/lib/types/accounts/database.d.ts +13 -3
- package/lib/types/accounts/errors.d.ts +9 -1
- package/lib/types/accounts/file.d.ts +12 -0
- package/lib/types/accounts/store.d.ts +30 -2
- package/lib/types/admin/quality-store.d.ts +33 -0
- package/lib/types/admin/service.d.ts +60 -1
- package/lib/types/client/QaAccountsController.d.ts +25 -2
- package/lib/types/client/QaConfigController.d.ts +2 -2
- package/lib/types/client/QaSessionController.d.ts +199 -6
- package/lib/types/client/QaSurface.d.ts +6 -1
- package/lib/types/client/admin/pages/ExpertMemory.d.ts +19 -0
- package/lib/types/client/admin/routes.d.ts +3 -1
- package/lib/types/client/admin/shared.d.ts +4 -0
- package/lib/types/client/components/Markdown.d.ts +8 -1
- package/lib/types/client/components/QaHeader.d.ts +18 -4
- package/lib/types/client/components/QaModal.d.ts +7 -0
- package/lib/types/client/components/QaQueueDock.d.ts +27 -0
- package/lib/types/client/components/QaRequestQueue.d.ts +20 -0
- package/lib/types/client/components/QaSidebar.d.ts +14 -0
- package/lib/types/client/components/QaThemeSwitcher.d.ts +14 -0
- package/lib/types/client/components/QaTurnNotice.d.ts +55 -0
- package/lib/types/client/focus-ring.d.ts +65 -0
- package/lib/types/client/lineage.d.ts +3 -13
- package/lib/types/client/markdown/blocks.d.ts +30 -2
- package/lib/types/client/markdown/render.d.ts +4 -1
- package/lib/types/client/notifications/notification-dispatcher.d.ts +68 -0
- package/lib/types/client/notifications/preferences.d.ts +44 -0
- package/lib/types/client/notifications/turn-completion-source.d.ts +114 -0
- package/lib/types/client/notifications/use-turn-notifications.d.ts +51 -0
- package/lib/types/client/project-session-state.d.ts +35 -1
- package/lib/types/client/role/RoleSelector.d.ts +7 -1
- package/lib/types/client/settings/card.d.ts +36 -5
- package/lib/types/client/settings/fields.d.ts +24 -0
- package/lib/types/client/settings/format.d.ts +0 -5
- package/lib/types/client/settings/sections/common.d.ts +3 -1
- package/lib/types/client/settings/sections/session.d.ts +2 -1
- package/lib/types/client/settings/styles.d.ts +9 -4
- package/lib/types/client/settings-extensions/user-session.d.ts +1 -1
- package/lib/types/client/theme-preference.d.ts +69 -0
- package/lib/types/client/types.d.ts +25 -1
- package/lib/types/client/use-session-ui-state.d.ts +6 -4
- package/lib/types/client/user-settings/GeneralSettingsPage.d.ts +5 -5
- package/lib/types/client/user-settings/NotificationSettingsPage.d.ts +40 -0
- package/lib/types/client/user-settings/UserSettingsDialog.d.ts +12 -2
- package/lib/types/client/user-settings/draft.d.ts +4 -1
- package/lib/types/client/user-settings/fields.d.ts +7 -0
- package/lib/types/config-resolvers/notifications.d.ts +10 -0
- package/lib/types/config-resolvers/session.d.ts +6 -0
- package/lib/types/config.d.ts +20 -1
- package/lib/types/index.d.ts +53 -5
- package/lib/types/integration/answer.d.ts +27 -0
- package/lib/types/integration/expert-memory.d.ts +49 -0
- package/lib/types/notifications.d.ts +32 -0
- package/lib/types/personal-skills/errors.d.ts +1 -1
- package/lib/types/personal-skills/service.d.ts +6 -0
- package/lib/types/prompt-notes.d.ts +17 -4
- package/lib/types/request-queue.d.ts +32 -0
- package/lib/types/shared/settings.d.ts +19 -2
- package/lib/types/turn-failure-log.d.ts +18 -0
- package/lib/types/types.d.ts +180 -4
- package/package.json +64 -63
- package/scripts/attach-workspace-sessions.mjs +24 -5
- package/scripts/repair-session-events.mjs +25 -5
- package/lib/client/markdown/MermaidBlock.js +0 -80
- package/lib/client/markdown/MermaidBlock.js.map +0 -1
- package/lib/types/client/markdown/MermaidBlock.d.ts +0 -6
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { KeyboardEvent } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Whether a modal gate has taken this element away from the keyboard: the
|
|
4
|
+
* element itself or an ancestor of it is marked inert.
|
|
5
|
+
*
|
|
6
|
+
* `inert` is read as a property, not looked up as an attribute. The gate marks
|
|
7
|
+
* the page inert from script (`QaWelcomeNotice`), a browser reflects that into
|
|
8
|
+
* the attribute, and jsdom stores nothing but the property on the element it
|
|
9
|
+
* was given — so the property is the one thing the two agree on, and the walk
|
|
10
|
+
* up the parent chain is what stands in for the browser's own inheritance.
|
|
11
|
+
* That a browser additionally refuses focus to everything found here is the
|
|
12
|
+
* browser's doing: what a live stand has to settle is that the ring's edge and
|
|
13
|
+
* the gate's own trap hold the keyboard between them without help from this
|
|
14
|
+
* file.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isInert(element: HTMLElement): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Every control of `root` the keyboard can still reach, in DOM order: what the
|
|
19
|
+
* page has not hidden, in its markup or in its layout, what still carries a
|
|
20
|
+
* place in the tab order, what no `inert` ancestor has handed to a dialog, and
|
|
21
|
+
* what no closed fold keeps out of sight.
|
|
22
|
+
*/
|
|
23
|
+
export declare function focusable(root: HTMLElement): HTMLElement[];
|
|
24
|
+
/**
|
|
25
|
+
* Hand the keyboard to the first candidate that takes it.
|
|
26
|
+
*
|
|
27
|
+
* `focusable` reads the layout as well as the markup, so the candidates are
|
|
28
|
+
* already the controls the width leaves in the path. This is the post-condition
|
|
29
|
+
* for a refusal that no read predicts: a page can keep a control from taking
|
|
30
|
+
* focus in ways its own styles do not say, and a test environment applies no CSS
|
|
31
|
+
* at all, so each candidate is checked at the moment it is asked — a control that
|
|
32
|
+
* leaves `document.activeElement` where it was is passed over, instead of leaving
|
|
33
|
+
* the reader on the same control they pressed Tab from.
|
|
34
|
+
*/
|
|
35
|
+
export declare function focusFirst(candidates: readonly (HTMLElement | null | undefined)[]): void;
|
|
36
|
+
/**
|
|
37
|
+
* The Tab ring over the roots a surface owns, in the order it walks them.
|
|
38
|
+
*
|
|
39
|
+
* A root under a modal gate contributes nothing: none of its controls can take
|
|
40
|
+
* focus, so an edge of the ring that pointed into one would be a key the page
|
|
41
|
+
* had already swallowed with nowhere to go — a Tab that sticks.
|
|
42
|
+
*/
|
|
43
|
+
export declare function focusRing(roots: readonly (HTMLElement | null)[]): HTMLElement[];
|
|
44
|
+
/**
|
|
45
|
+
* Keep Tab inside the ring the surface painted, and let the reader out at
|
|
46
|
+
* neither edge.
|
|
47
|
+
*
|
|
48
|
+
* The ring is wider than `<main>`: a notice stack the surface paints in
|
|
49
|
+
* `document.body` sits after it in the page, so a Tab leaving the composer
|
|
50
|
+
* walks into the stack, and the edge where the key is caught and turned back is
|
|
51
|
+
* the stack's last button — not the last control inside `<main>`, which is where
|
|
52
|
+
* the ring used to stop the reader short of the notice. A key typed inside such
|
|
53
|
+
* a portal is trapped by the handler mounted on the portal: the `<main>` above
|
|
54
|
+
* it is not its ancestor and never hears the key.
|
|
55
|
+
*
|
|
56
|
+
* A ring with no controls in it answers nothing: there is nothing here to keep
|
|
57
|
+
* the reader inside, and a key prevented with nowhere to hand the focus is a key
|
|
58
|
+
* that sticks.
|
|
59
|
+
*
|
|
60
|
+
* The two ends the key is caught at are ends of the *walked* path, so a control
|
|
61
|
+
* the current width has switched off is neither of them: it holds no focus for
|
|
62
|
+
* the reader to stand on, and an edge drawn at it is an edge no Tab arrives at.
|
|
63
|
+
*/
|
|
64
|
+
export declare function trapKeys(event: KeyboardEvent<HTMLElement>, roots: readonly (HTMLElement | null)[]): void;
|
|
65
|
+
//# sourceMappingURL=focus-ring.d.ts.map
|
|
@@ -31,19 +31,9 @@ export interface SubagentNameCandidate {
|
|
|
31
31
|
/** The Host's own wording for the delegation; empty when it listed none. */
|
|
32
32
|
readonly label: string;
|
|
33
33
|
}
|
|
34
|
-
/** One durable delegation catalog entry, as the Host lists it. */
|
|
35
|
-
export interface SubagentCatalogEntry {
|
|
36
|
-
readonly kind?: string;
|
|
37
|
-
readonly id?: string;
|
|
38
|
-
readonly label?: string;
|
|
39
|
-
}
|
|
40
|
-
/** Direct delegation catalogs keyed by their parent chat. */
|
|
41
|
-
export type SubagentCatalogs = Readonly<Record<string, {
|
|
42
|
-
readonly entries?: readonly SubagentCatalogEntry[];
|
|
43
|
-
} | undefined>>;
|
|
44
34
|
/**
|
|
45
|
-
* Delegated sessions whose names a page may sign its notices with: the
|
|
46
|
-
*
|
|
35
|
+
* Delegated sessions whose names a page may sign its notices with: the children
|
|
36
|
+
* of the chats it lists, named by the row title the Host's session list carries.
|
|
47
37
|
*
|
|
48
38
|
* `chats` is the visible chat set — the account's own chats while accounts are
|
|
49
39
|
* on, and `undefined` for a deployment without accounts, where every chat on
|
|
@@ -53,5 +43,5 @@ export type SubagentCatalogs = Readonly<Record<string, {
|
|
|
53
43
|
* therefore contributes no id and no label — a foreign chat can neither sign
|
|
54
44
|
* a notice nor be named by one.
|
|
55
45
|
*/
|
|
56
|
-
export declare function visibleSubagentCandidates(byId: Readonly<Record<string, SessionSummary>>,
|
|
46
|
+
export declare function visibleSubagentCandidates(byId: Readonly<Record<string, SessionSummary>>, chats: ReadonlySet<string> | undefined): readonly SubagentNameCandidate[];
|
|
57
47
|
//# sourceMappingURL=lineage.d.ts.map
|
|
@@ -16,6 +16,15 @@
|
|
|
16
16
|
* delimiters stay literal text, exactly as the Host renders them. Footnote
|
|
17
17
|
* definitions (`[^id]: …`) are collected the way GitHub's dialect does, with
|
|
18
18
|
* lazy and indented continuation lines.
|
|
19
|
+
*
|
|
20
|
+
* A frame of a live stream is parsed with `streaming: true`, which says one
|
|
21
|
+
* thing only: the text may still grow. Block boundaries stay the business of
|
|
22
|
+
* this module — a caller that knows the answer is being written passes the
|
|
23
|
+
* flag, and nothing here is re-detected elsewhere. Two readings change with
|
|
24
|
+
* it: a block whose region runs to the end of the text has not met its
|
|
25
|
+
* terminator, so a fence or a `$$` block reports `pending`, and a table treats
|
|
26
|
+
* its live last line as still written (a delimiter row being typed opens the
|
|
27
|
+
* header, a row being typed stays out of the cells).
|
|
19
28
|
*/
|
|
20
29
|
/** `#`-through-`######` heading levels. */
|
|
21
30
|
export type HeadingDepth = 1 | 2 | 3 | 4 | 5 | 6;
|
|
@@ -39,6 +48,8 @@ export type MarkdownBlock = {
|
|
|
39
48
|
readonly kind: "code";
|
|
40
49
|
readonly text: string;
|
|
41
50
|
readonly lang?: string;
|
|
51
|
+
/** The fence has not met its closing marker: the stream is inside it. */
|
|
52
|
+
readonly pending?: true;
|
|
42
53
|
} | {
|
|
43
54
|
readonly kind: "quote";
|
|
44
55
|
readonly blocks: readonly MarkdownBlock[];
|
|
@@ -56,6 +67,8 @@ export type MarkdownBlock = {
|
|
|
56
67
|
} | {
|
|
57
68
|
readonly kind: "math";
|
|
58
69
|
readonly text: string;
|
|
70
|
+
/** The `$$` fence has not closed: the stream is still typing the TeX. */
|
|
71
|
+
readonly pending?: true;
|
|
59
72
|
} | {
|
|
60
73
|
readonly kind: "rule";
|
|
61
74
|
};
|
|
@@ -67,21 +80,36 @@ export interface ParsedMarkdown {
|
|
|
67
80
|
/** Footnote bodies by upper-cased identifier; first definition wins. */
|
|
68
81
|
readonly footnotes: ReadonlyMap<string, readonly MarkdownBlock[]>;
|
|
69
82
|
}
|
|
83
|
+
/** How to read the end of the text being parsed. */
|
|
84
|
+
export interface MarkdownParseOptions {
|
|
85
|
+
/**
|
|
86
|
+
* The text is a frame of a live stream, so its last content line may be
|
|
87
|
+
* half-typed: a block that reaches the end of the text is reported as
|
|
88
|
+
* `pending` instead of being treated as settled, and a table leaves an
|
|
89
|
+
* unfinished last row out of its cells. Omitted for a settled answer, which
|
|
90
|
+
* is where the two readings must not drift apart.
|
|
91
|
+
*/
|
|
92
|
+
readonly streaming?: boolean;
|
|
93
|
+
}
|
|
70
94
|
/** Split one table row into trimmed cells, honoring escaped pipes. */
|
|
71
95
|
export declare function splitTableRow(line: string): string[];
|
|
72
96
|
/**
|
|
73
97
|
* Parse a whole document.
|
|
74
98
|
* @param text - Markdown source with any line endings.
|
|
99
|
+
* @param options - How to read the end of the text; a live stream frame marks
|
|
100
|
+
* the block it stopped inside as pending.
|
|
75
101
|
* @returns Blocks plus the definitions the inline pass resolves against.
|
|
76
102
|
*/
|
|
77
|
-
export declare function parseMarkdown(text: string): ParsedMarkdown;
|
|
103
|
+
export declare function parseMarkdown(text: string, options?: MarkdownParseOptions): ParsedMarkdown;
|
|
78
104
|
/**
|
|
79
105
|
* Parse the blocks of one container (document, quote, or list item).
|
|
80
106
|
* @param lines - Container lines, already de-indented by the caller.
|
|
81
107
|
* @param definitions - Document-wide definition accumulator.
|
|
82
108
|
* @param footnotes - Document-wide footnote accumulator.
|
|
83
109
|
* @param depth - Container nesting depth.
|
|
110
|
+
* @param streaming - Whether the text is a live frame, so the container's last
|
|
111
|
+
* line may still be typed.
|
|
84
112
|
* @returns The container's blocks.
|
|
85
113
|
*/
|
|
86
|
-
export declare function parseBlocks(lines: readonly string[], definitions: Map<string, string>, footnotes: Map<string, readonly MarkdownBlock[]>, depth: number): MarkdownBlock[];
|
|
114
|
+
export declare function parseBlocks(lines: readonly string[], definitions: Map<string, string>, footnotes: Map<string, readonly MarkdownBlock[]>, depth: number, streaming?: boolean): MarkdownBlock[];
|
|
87
115
|
//# sourceMappingURL=blocks.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
+
import type { MarkdownParseOptions } from "./blocks.js";
|
|
2
3
|
import { type MarkdownSourceContext } from "./source-chip.js";
|
|
3
4
|
/**
|
|
4
5
|
* Render markdown source as semantic React elements. Raw HTML never enters the
|
|
@@ -7,8 +8,10 @@ import { type MarkdownSourceContext } from "./source-chip.js";
|
|
|
7
8
|
* instead of a plain link or code token.
|
|
8
9
|
* @param text - Assistant-authored markdown.
|
|
9
10
|
* @param context - Source resolution handed down by the owning message.
|
|
11
|
+
* @param options - How to read the end of the text; a live stream frame holds
|
|
12
|
+
* the block it stopped inside instead of rendering it as settled.
|
|
10
13
|
* @returns The document's blocks, plus the footnote section when the document
|
|
11
14
|
* references a defined footnote.
|
|
12
15
|
*/
|
|
13
|
-
export declare function renderMarkdown(text: string, context: MarkdownSourceContext): ReactNode[];
|
|
16
|
+
export declare function renderMarkdown(text: string, context: MarkdownSourceContext, options?: MarkdownParseOptions): ReactNode[];
|
|
14
17
|
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { QaTurnCompletion } from "./turn-completion-source.js";
|
|
2
|
+
import type { QaNoticeChannels } from "./preferences.js";
|
|
3
|
+
/** What the browser exposes of the desktop notification API. */
|
|
4
|
+
export type QaNotificationPermission = NotificationPermission | "unsupported";
|
|
5
|
+
/** One entry of the in-app stack. */
|
|
6
|
+
export interface QaTurnNoticeItem {
|
|
7
|
+
readonly key: string;
|
|
8
|
+
readonly sessionId: string;
|
|
9
|
+
readonly title: string;
|
|
10
|
+
}
|
|
11
|
+
/** A finished turn and the channels it takes. */
|
|
12
|
+
export interface PlannedTurnNotice {
|
|
13
|
+
readonly item: QaTurnNoticeItem;
|
|
14
|
+
/** Keep the line in this page, or send the fact to the desktop alone. */
|
|
15
|
+
readonly inApp: boolean;
|
|
16
|
+
/** Raise the desktop notice as well, or keep this one inside the page. */
|
|
17
|
+
readonly desktop: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface QaNoticeContext {
|
|
20
|
+
/** `config.notifications`: the deployment's switches over both channels. */
|
|
21
|
+
readonly switches: {
|
|
22
|
+
readonly enabled: boolean;
|
|
23
|
+
readonly allowOs: boolean;
|
|
24
|
+
};
|
|
25
|
+
/** The reader's own choice, from their account or from this browser. */
|
|
26
|
+
readonly channels: QaNoticeChannels;
|
|
27
|
+
readonly permission: QaNotificationPermission;
|
|
28
|
+
/** Whether this page is the one the person is looking at right now. */
|
|
29
|
+
readonly focused: boolean;
|
|
30
|
+
/** The chat the composer is showing. */
|
|
31
|
+
readonly activeSessionId: string | null;
|
|
32
|
+
}
|
|
33
|
+
/** Body text of every desktop notice: the fact, never the content. */
|
|
34
|
+
export declare const QA_TURN_NOTICE_BODY = "\u0425\u043E\u0434 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043D";
|
|
35
|
+
/**
|
|
36
|
+
* Decide what one finished turn is worth, if anything.
|
|
37
|
+
*
|
|
38
|
+
* A notice exists to say "this happened where you were not looking". The chat
|
|
39
|
+
* on screen answers itself — the reply arrives in front of the reader — so it
|
|
40
|
+
* gets nothing, while a background chat that settles under their eyes still
|
|
41
|
+
* gets the in-app line. Each channel then needs its own two answers: the
|
|
42
|
+
* deployment's and the reader's. The desktop additionally needs the browser's
|
|
43
|
+
* permission, which neither of those can grant on its behalf.
|
|
44
|
+
*/
|
|
45
|
+
export declare function planTurnNotice(completion: QaTurnCompletion, context: QaNoticeContext): PlannedTurnNotice | null;
|
|
46
|
+
/**
|
|
47
|
+
* Whether the person is looking at this page. A hidden tab and a visible tab
|
|
48
|
+
* behind another window both count as away: the notice is for the difference
|
|
49
|
+
* between "watching" and "not watching", not for the tab's own state.
|
|
50
|
+
*/
|
|
51
|
+
export declare function isPageFocused(documentState?: {
|
|
52
|
+
visibilityState: DocumentVisibilityState;
|
|
53
|
+
}, hasFocus?: () => boolean): boolean;
|
|
54
|
+
/** The desktop channel's current answer, or `unsupported` off a secure context. */
|
|
55
|
+
export declare function readNotificationPermission(): QaNotificationPermission;
|
|
56
|
+
/**
|
|
57
|
+
* Ask the browser for the desktop channel. Only ever called from a click: the
|
|
58
|
+
* permission prompt is the user's decision about this origin, and a page that
|
|
59
|
+
* asks on load — or once per finished turn — spends it on the wrong moment.
|
|
60
|
+
*/
|
|
61
|
+
export declare function requestNotificationPermission(): Promise<QaNotificationPermission>;
|
|
62
|
+
/**
|
|
63
|
+
* Hand one finished turn to the desktop. Returns false when the platform
|
|
64
|
+
* refuses: a notification that cannot be raised costs the reader nothing, and
|
|
65
|
+
* the in-app line is already on its way.
|
|
66
|
+
*/
|
|
67
|
+
export declare function raiseDesktopNotice(completion: QaTurnCompletion): boolean;
|
|
68
|
+
//# sourceMappingURL=notification-dispatcher.d.ts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { QaAccountNotifications } from "../../types.js";
|
|
2
|
+
import type { StorageLike } from "../types.js";
|
|
3
|
+
/** One reader's choice about the desktop channel. */
|
|
4
|
+
export interface QaNotificationPrefs {
|
|
5
|
+
/** Raise a desktop notice for a finished turn while this page is in the background. */
|
|
6
|
+
readonly osEnabled: boolean;
|
|
7
|
+
/** The offer was answered or waved off: a notice never asks a second time. */
|
|
8
|
+
readonly osOffered: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** The channels one finished turn may use, whoever decided them. */
|
|
11
|
+
export interface QaNoticeChannels {
|
|
12
|
+
readonly inApp: boolean;
|
|
13
|
+
readonly desktop: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare const QA_NOTIFICATION_DEFAULT_PREFS: QaNotificationPrefs;
|
|
16
|
+
/**
|
|
17
|
+
* Read the stored choice; a denied, full or foreign-shaped store falls back to
|
|
18
|
+
* the silent default rather than raising notices nobody asked for.
|
|
19
|
+
*
|
|
20
|
+
* What is left in this browser is what belongs to a browser: the answer to the
|
|
21
|
+
* desktop offer, and the desktop choice itself for as long as there is no
|
|
22
|
+
* account to hold it. Signed in, the account's {@link QaAccountNotifications}
|
|
23
|
+
* wins — see {@link resolveNoticeChannels} — because a preference that follows
|
|
24
|
+
* the person is the point of storing it on the account at all.
|
|
25
|
+
*/
|
|
26
|
+
export declare function readNotificationPrefs(storage: StorageLike | undefined, key: string): QaNotificationPrefs;
|
|
27
|
+
/** Persist the choice. A store that refuses only costs it across reloads. */
|
|
28
|
+
export declare function writeNotificationPrefs(storage: StorageLike | undefined, key: string, prefs: QaNotificationPrefs): void;
|
|
29
|
+
/**
|
|
30
|
+
* Which channels this reader may use for a finished turn.
|
|
31
|
+
*
|
|
32
|
+
* The account's answer wins once it exists, so the choice follows the person to
|
|
33
|
+
* another browser or another laptop. Without an account the browser's own
|
|
34
|
+
* answer stands: an anonymous stand is the common shape of a QA deployment, and
|
|
35
|
+
* a mute switch that only appeared once signed in would leave it with no switch
|
|
36
|
+
* at all. The in-page line has no browser-level switch of its own — a stand that
|
|
37
|
+
* wants it gone has `notifications.enabled`, and the offer this page makes is
|
|
38
|
+
* only ever about the desktop channel.
|
|
39
|
+
*/
|
|
40
|
+
export declare function resolveNoticeChannels(input: {
|
|
41
|
+
readonly account: QaAccountNotifications | undefined;
|
|
42
|
+
readonly prefs: QaNotificationPrefs;
|
|
43
|
+
}): QaNoticeChannels;
|
|
44
|
+
//# sourceMappingURL=preferences.d.ts.map
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/** One chat of this browser's own list, as the page currently sees it. */
|
|
2
|
+
export interface QaChatActivity {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
readonly title: string;
|
|
5
|
+
readonly running: boolean;
|
|
6
|
+
}
|
|
7
|
+
/** One turn that ended between two observations of the chat list. */
|
|
8
|
+
export interface QaTurnCompletion {
|
|
9
|
+
readonly sessionId: string;
|
|
10
|
+
/** The chat's own display title: the only text a notice may carry. */
|
|
11
|
+
readonly title: string;
|
|
12
|
+
readonly at: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* What this page last read about one chat's turn. Four readings, because two
|
|
16
|
+
* facts decide whether the end of a run is this reader's news: whether the chat
|
|
17
|
+
* was running, and whether the frame that said so was one the browser could
|
|
18
|
+
* vouch for. A frame read while the link was down settles neither fact, but the
|
|
19
|
+
* way `running` pointed in it still decides what this page is short of: the
|
|
20
|
+
* start of a run it cannot account for, or an idle reading it cannot yet trust.
|
|
21
|
+
*/
|
|
22
|
+
export type QaTurnSighting =
|
|
23
|
+
/**
|
|
24
|
+
* Not running, read while the link held — so a run seen next is one this
|
|
25
|
+
* page watches begin.
|
|
26
|
+
*/
|
|
27
|
+
"idle"
|
|
28
|
+
/**
|
|
29
|
+
* Running, and this page saw this very run begin: it held `idle` in the first
|
|
30
|
+
* frame that found the chat running. The frames after that keep the reading —
|
|
31
|
+
* the evidence is the witnessed start, so a run does not lose it by lasting
|
|
32
|
+
* longer than one frame.
|
|
33
|
+
*/
|
|
34
|
+
| "watched"
|
|
35
|
+
/**
|
|
36
|
+
* Running, with no evidence of where the run began: the page found the chat
|
|
37
|
+
* running without seeing it start — which is how the page opens, and how a run
|
|
38
|
+
* that outlived the link looks once the link is back. A run ending here is not
|
|
39
|
+
* this reader's news.
|
|
40
|
+
*/
|
|
41
|
+
| "unwatched"
|
|
42
|
+
/**
|
|
43
|
+
* Not running, but read only in frames the browser cannot vouch for: the link
|
|
44
|
+
* was down when this was read, or it has returned and the chat's row has not
|
|
45
|
+
* moved since. A row that has not moved is no news about now — it may well be
|
|
46
|
+
* the reading the gap left behind, and this page cannot tell the two apart —
|
|
47
|
+
* so it arms nothing, because a run that began inside the gap would leave it
|
|
48
|
+
* exactly as it is. Only the row moving ends it.
|
|
49
|
+
*/
|
|
50
|
+
| "stale";
|
|
51
|
+
export interface QaTurnCompletionOptions {
|
|
52
|
+
/**
|
|
53
|
+
* Re-project the baseline and report nothing. While the browser is
|
|
54
|
+
* reconnecting the list it holds is stale, and the first frame after the
|
|
55
|
+
* link returns would otherwise read as a batch of finished turns. This flag
|
|
56
|
+
* goes back off with the link, which is sooner than the host list is read
|
|
57
|
+
* again: the re-pull belongs to the host store and is not awaited, so a live
|
|
58
|
+
* frame can carry the rows the drop left. What a pause costs this page is
|
|
59
|
+
* therefore carried by the readings rather than by the flag — see `stale`. A
|
|
60
|
+
* gap that left no frame with this flag set is named as a rule of
|
|
61
|
+
* `docs/specs/owner-scoped-notifications.md` §12, not as a detail of this
|
|
62
|
+
* file.
|
|
63
|
+
*/
|
|
64
|
+
readonly paused?: boolean;
|
|
65
|
+
readonly now?: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Report the turns that ended since the previous observation of `chats`.
|
|
69
|
+
*
|
|
70
|
+
* The input is this reader's own rows — see {@link scopeNoticesToOwnChats},
|
|
71
|
+
* which is what keeps an admin's shared history out of them — because a notice
|
|
72
|
+
* is an outward report about the chat it names. The host list is the whole
|
|
73
|
+
* deployment's, so anything wider than these rows would tell one user that
|
|
74
|
+
* another user's turn had stopped.
|
|
75
|
+
*
|
|
76
|
+
* `seen` is the caller's per-page map of the last reading, and a chat is
|
|
77
|
+
* reported only when a `watched` run is seen ending in a frame the browser
|
|
78
|
+
* could vouch for. So the notice always tells the reader about a turn they were
|
|
79
|
+
* waiting for, and never about one that was already under way when they could
|
|
80
|
+
* not see it: a chat found running on the page's first frame, or in the frames
|
|
81
|
+
* around a reconnect, is `unwatched`, and its end passes in silence. Nor does a
|
|
82
|
+
* gap the page was shown spare a run it lands inside: the paused frame takes
|
|
83
|
+
* back the evidence that this page watched that run begin, because while the
|
|
84
|
+
* link was down the chat may have run another turn and the rows that come back
|
|
85
|
+
* name neither. The first run to end after a gap passes in silence too, in a
|
|
86
|
+
* chat whose row never moved across it — the only idle this page holds for that
|
|
87
|
+
* chat was read through the gap, and a run that began inside the gap would look
|
|
88
|
+
* exactly like it. That reading arms nothing until the chat's own row moves, and
|
|
89
|
+
* the move that arms it is a run ending: the very one this page then keeps
|
|
90
|
+
* silent about. So a turn is reported only when no gap falls between the idle
|
|
91
|
+
* reading that armed this page and the frame that sees the run end, which is why
|
|
92
|
+
* a run begun and finished on the recovered link can still pass unreported, and
|
|
93
|
+
* why a gap the page was shown costs a chat one turn — or two, where a turn
|
|
94
|
+
* ended inside the gap. A gap that reached no committed frame hands this function
|
|
95
|
+
* nothing to go silent about, and §12 of
|
|
96
|
+
* `docs/specs/owner-scoped-notifications.md` owns that case. The turn that a link
|
|
97
|
+
* which held carries from an armed idle to its end is the page's own, so a page
|
|
98
|
+
* that stays open notifies again once the turn paying for the gap has ended —
|
|
99
|
+
* once per turn from there.
|
|
100
|
+
*/
|
|
101
|
+
export declare function settleTurnCompletions(seen: Map<string, QaTurnSighting>, chats: readonly QaChatActivity[], options?: QaTurnCompletionOptions): QaTurnCompletion[];
|
|
102
|
+
/**
|
|
103
|
+
* Keep the rows a notice may be raised for: the sidebar's rows down to the
|
|
104
|
+
* chats this account owns outright.
|
|
105
|
+
*
|
|
106
|
+
* The sidebar is a *read* surface, and an admin's shared view is deliberately
|
|
107
|
+
* wider than ownership — the same opt-in that shows another account's chat
|
|
108
|
+
* must not decide whose activity this browser reports outward. A notice is
|
|
109
|
+
* that outward report, and it names a chat by title, so it takes the narrow
|
|
110
|
+
* list. `undefined` is the deployment with no accounts, where the browser's own
|
|
111
|
+
* index already is the owned set and there is nothing narrower to ask for.
|
|
112
|
+
*/
|
|
113
|
+
export declare function scopeNoticesToOwnChats(chats: readonly QaChatActivity[], ownIds: readonly string[] | undefined): readonly QaChatActivity[];
|
|
114
|
+
//# sourceMappingURL=turn-completion-source.d.ts.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { QaAccountNotifications, QaAccountNotificationsInput, ResolvedQaSurfaceConfig } from "../../types.js";
|
|
2
|
+
import type { StorageLike } from "../types.js";
|
|
3
|
+
import { type QaTurnNoticeItem } from "./notification-dispatcher.js";
|
|
4
|
+
import { type QaChatActivity } from "./turn-completion-source.js";
|
|
5
|
+
export interface QaTurnNotificationsInput {
|
|
6
|
+
/** The sidebar's rows: this browser's chats with their running state. */
|
|
7
|
+
readonly chats: readonly QaChatActivity[];
|
|
8
|
+
/**
|
|
9
|
+
* The chats this account owns outright, which is narrower than the rows: an
|
|
10
|
+
* admin's shared history lists chats it only reads, and the turn of such a
|
|
11
|
+
* chat is that other account's business. Absent where there is no account to
|
|
12
|
+
* be narrower than — a stand without accounts, whose rows are the browser's
|
|
13
|
+
* own index.
|
|
14
|
+
*/
|
|
15
|
+
readonly ownChatIds?: readonly string[];
|
|
16
|
+
readonly notifications: ResolvedQaSurfaceConfig["notifications"];
|
|
17
|
+
readonly storage: StorageLike | undefined;
|
|
18
|
+
readonly storageKey: string;
|
|
19
|
+
/**
|
|
20
|
+
* The signed-in reader's own channels and the write that changes them.
|
|
21
|
+
* Absent on a stand without accounts, where the browser's own answer is the
|
|
22
|
+
* only one there is to ask.
|
|
23
|
+
*/
|
|
24
|
+
readonly account?: {
|
|
25
|
+
readonly notifications: QaAccountNotifications;
|
|
26
|
+
readonly onSave: (input: QaAccountNotificationsInput) => Promise<string | null>;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* The link is down, so no run read among these rows is this reader's news. The
|
|
30
|
+
* flag says nothing about the rows: it goes back off with the link, while the
|
|
31
|
+
* host list is re-read after it and unawaited, so the reading named `stale` is
|
|
32
|
+
* what carries the gap over a live frame whose row has not moved since.
|
|
33
|
+
*/
|
|
34
|
+
readonly paused: boolean;
|
|
35
|
+
readonly activeSessionId: string | null;
|
|
36
|
+
readonly onSwitch: (sessionId: string) => void;
|
|
37
|
+
}
|
|
38
|
+
export interface QaTurnNotifications {
|
|
39
|
+
readonly items: readonly QaTurnNoticeItem[];
|
|
40
|
+
readonly onOpen: (sessionId: string) => void;
|
|
41
|
+
readonly onDismiss: (key: string) => void;
|
|
42
|
+
readonly onEnableDesktop?: () => void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Turn-completion notices for the chats this reader owns. Of the rows the
|
|
46
|
+
* sidebar shows, only the ones this account owns outright are watched, and when
|
|
47
|
+
* one of them stops running after this page watched that run begin, the reader
|
|
48
|
+
* is told in the channels they and the deployment allow.
|
|
49
|
+
*/
|
|
50
|
+
export declare function useQaTurnNotifications(input: QaTurnNotificationsInput): QaTurnNotifications;
|
|
51
|
+
//# sourceMappingURL=use-turn-notifications.d.ts.map
|
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
import type { SessionFace } from "@deepseek-ai/dsh-api-session-controller/client";
|
|
2
|
+
import type { UserMessage } from "@deepseek-ai/dsh-llm";
|
|
2
3
|
import type { ConversationSnapshot } from "@deepseek-ai/dsh-client-ui-conversation/client";
|
|
3
|
-
import type { QaPendingApproval, QaPendingQuestion, QaSessionState, QaSlashView, QaSubagentView, QaTurnSources, ResolvedQaSurfaceConfig } from "../types.js";
|
|
4
|
+
import type { QaPendingApproval, QaPendingQuestion, QaQueueStatus, QaSessionState, QaSlashView, QaSubagentView, QaTurnSources, ResolvedQaSurfaceConfig } from "../types.js";
|
|
4
5
|
/** Everything the bound-chat projection reads; the computation is pure. */
|
|
5
6
|
export interface QaBoundProjectionInput {
|
|
6
7
|
readonly connected: boolean;
|
|
7
8
|
readonly sessionId: string;
|
|
9
|
+
/** Chat identity from the controller; see `QaSessionState.chatKey`. */
|
|
10
|
+
readonly chatKey: number;
|
|
8
11
|
readonly sessionSnapshot: ReturnType<SessionFace["getSnapshot"]>;
|
|
12
|
+
/**
|
|
13
|
+
* The Host's Inbox projection for this session: the messages waiting for the
|
|
14
|
+
* agent's next turn. A projection key the Host has not published reads as an
|
|
15
|
+
* empty list, which is what a session with no queued work shows anyway.
|
|
16
|
+
*/
|
|
17
|
+
readonly queuedMessages: readonly UserMessage[];
|
|
18
|
+
/**
|
|
19
|
+
* Request ids this binding has already seen the Host name, out of
|
|
20
|
+
* {@link queuedMessages} and the transcript. The mask {@link projectQueue}
|
|
21
|
+
* draws with while the session library's echo retirement waits on a frame the
|
|
22
|
+
* surface may never get.
|
|
23
|
+
*/
|
|
24
|
+
readonly admittedSubmissions: ReadonlySet<string>;
|
|
9
25
|
readonly conversationSnapshot: ConversationSnapshot | undefined;
|
|
10
26
|
/** Turn bundles with the Host provenance already merged in (Host wins). */
|
|
11
27
|
readonly sourceBundles: readonly QaTurnSources[];
|
|
@@ -17,6 +33,13 @@ export interface QaBoundProjectionInput {
|
|
|
17
33
|
readonly approvals: readonly QaPendingApproval[];
|
|
18
34
|
readonly questions: readonly QaPendingQuestion[];
|
|
19
35
|
readonly operationError: string | null;
|
|
36
|
+
/**
|
|
37
|
+
* A send the stand had no room for. The dialog is the whole of what the
|
|
38
|
+
* visitor learns: the question never reached the Host, so the transcript has
|
|
39
|
+
* no row to carry the refusal on. Distinct from `queue`, the waiting rows of
|
|
40
|
+
* this chat.
|
|
41
|
+
*/
|
|
42
|
+
readonly requestQueue: QaQueueStatus | null;
|
|
20
43
|
readonly policyReady: boolean;
|
|
21
44
|
/** Historical binding retained for transcript access after policy drift. */
|
|
22
45
|
readonly compatibilityReadOnly?: boolean;
|
|
@@ -37,6 +60,17 @@ export interface QaBoundProjectionInput {
|
|
|
37
60
|
*/
|
|
38
61
|
readonly author?: string;
|
|
39
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* The request ids the Host has itself named for a send, out of the two lists it
|
|
65
|
+
* publishes: the messages waiting in its Inbox and the durable input rows of its
|
|
66
|
+
* transcript (`user` opens the turn that took the message, `steering` is one
|
|
67
|
+
* injected into the turn already running). Either is the server's own receipt
|
|
68
|
+
* that the message crossed, and reading both is what makes the receipt
|
|
69
|
+
* independent of which frame carried the news: a message the turn has claimed is
|
|
70
|
+
* gone from the Inbox yet stays in the transcript, so a send admitted and claimed
|
|
71
|
+
* between two notifications is still named by the next transcript frame.
|
|
72
|
+
*/
|
|
73
|
+
export declare function hostNamedSubmissionIds(queued: readonly UserMessage[], conversationSnapshot: ConversationSnapshot | undefined): Set<string>;
|
|
40
74
|
/**
|
|
41
75
|
* Project one bound chat into the observable surface state: phase, transcript
|
|
42
76
|
* with per-turn sources, footer sources, and the composer's capabilities.
|
|
@@ -15,10 +15,16 @@ export declare function QaRoleSelector(props: QaRoleSelectorProps): import("reac
|
|
|
15
15
|
* is hidden — the previewed profile need not be one the account holds — so
|
|
16
16
|
* without a control here the only exit was the browser's Back button, and a new
|
|
17
17
|
* chat meanwhile ran as the previewed profile instead of the account's default.
|
|
18
|
-
*
|
|
18
|
+
*
|
|
19
|
+
* Leaving is a new chat, so the way out waits for the same moments the header's
|
|
20
|
+
* "Новый чат" and the role selector wait for: while a chat is still being
|
|
21
|
+
* created, this click would take the screen from the question on its way in.
|
|
22
|
+
* @param props - the previewed role's name, how to leave the preview, and whether
|
|
23
|
+
* that way is currently blocked by a chat being created.
|
|
19
24
|
*/
|
|
20
25
|
export declare function QaAdminPreviewBanner(props: {
|
|
21
26
|
readonly role: string;
|
|
22
27
|
readonly onExit?: () => void;
|
|
28
|
+
readonly disabled?: boolean;
|
|
23
29
|
}): import("react/jsx-runtime").JSX.Element;
|
|
24
30
|
//# sourceMappingURL=RoleSelector.d.ts.map
|
|
@@ -8,16 +8,47 @@
|
|
|
8
8
|
* mutation; the status view re-reads the Remote while the card is visible, so
|
|
9
9
|
* a saved change is confirmed against the Host rather than against the form.
|
|
10
10
|
*/
|
|
11
|
-
import type {
|
|
11
|
+
import type { ConfigForm } from "@deepseek-ai/dsh-client-ui-settings/client";
|
|
12
12
|
import type { InjectFace, PropsRuntime } from "@deepseek-ai/dsh-client-ui-slots";
|
|
13
13
|
import type { RemoteResult } from "@deepseek-ai/dsh-typert-protocol";
|
|
14
14
|
import type { QaSurfaceConfig, ResolvedQaSurfaceConfig } from "../../types.js";
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* The face the row seat injects into this card.
|
|
17
|
+
*
|
|
18
|
+
* The live form is named `settingsForm`, not `form`: the seat hands its
|
|
19
|
+
* registrant a `form` of its own — the page's `ConfigPageForm`, which is only
|
|
20
|
+
* `{ state, mutate }` (`formFor` in
|
|
21
|
+
* `@deepseek-ai/dsh-client-ui-plugin-manager/lib/client.js` snapshots the same
|
|
22
|
+
* namespace's form and forwards `mutate` and nothing else), so it can neither be
|
|
23
|
+
* subscribed to nor written field by field, and which the page leaves
|
|
24
|
+
* `undefined` for a Config declaring no volatile field — and the renderer
|
|
25
|
+
* spreads that owner prop after this face. The card therefore keeps resolving
|
|
26
|
+
* the full `ConfigForm` of its own namespace through `ctx.configForms` and takes
|
|
27
|
+
* no copy of the page's view.
|
|
28
|
+
*/
|
|
16
29
|
export interface QaSettingsCardFace {
|
|
17
|
-
readonly
|
|
30
|
+
readonly settingsForm: ConfigForm<QaSurfaceConfig>;
|
|
18
31
|
describe(): Promise<RemoteResult<ResolvedQaSurfaceConfig>>;
|
|
19
32
|
}
|
|
20
|
-
type CardProps = PropsRuntime<"
|
|
21
|
-
export declare function QaSettingsCard({
|
|
33
|
+
type CardProps = PropsRuntime<"plugins.row.config"> & InjectFace<QaSettingsCardFace>;
|
|
34
|
+
export declare function QaSettingsCard({ settingsForm, describe }: CardProps): import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
/**
|
|
36
|
+
* The entry this plugin registers in the row's configuration seat.
|
|
37
|
+
*
|
|
38
|
+
* `RowDetail` in `@deepseek-ai/dsh-client-ui-plugin-manager/lib/client.js` can
|
|
39
|
+
* ask this seat for two shapes of the same entry: `view: 'summary'` as the row's
|
|
40
|
+
* one-liner and `view: 'page'` in the configuration column under the row's
|
|
41
|
+
* heading. Which of the two it asks for is the page's decision and §4.2 of
|
|
42
|
+
* `docs/DSH-0.1.7-MIGRATION.md` is where that is measured and stated — the row's
|
|
43
|
+
* description comes from the installed manifest, and the summary seat is the
|
|
44
|
+
* fallback for a row that declares none — so this bundle answers both without
|
|
45
|
+
* claiming either call is its own. The summary lands inside a line of the page's
|
|
46
|
+
* text, so it stays a sentence: a card seated there would draw a page within a
|
|
47
|
+
* line and start a second poll of the `qaSurface/describe` Remote. The page view
|
|
48
|
+
* is the body alone — the row's page already draws the card surface, the heading
|
|
49
|
+
* and the expand control, so a shell of ours would be a second frame inside the
|
|
50
|
+
* first (AGENTS.md, card-shell contract).
|
|
51
|
+
*/
|
|
52
|
+
export declare function QaSettingsCardEntry(props: CardProps): "A focused end-user QA surface backed by native DeepSeek Harness sessions" | import("react/jsx-runtime").JSX.Element;
|
|
22
53
|
export {};
|
|
23
54
|
//# sourceMappingURL=card.d.ts.map
|