@yadsh/dsh-qa-surface 0.8.0 → 0.10.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.
Files changed (242) hide show
  1. package/README.md +142 -4
  2. package/compatibility.json +5 -0
  3. package/lib/access/capability-catalog.js +32 -3
  4. package/lib/access/capability-catalog.js.map +1 -1
  5. package/lib/access/service.js +45 -17
  6. package/lib/access/service.js.map +1 -1
  7. package/lib/accounts/errors.js.map +1 -1
  8. package/lib/accounts/store.js +14 -0
  9. package/lib/accounts/store.js.map +1 -1
  10. package/lib/admin/permissions.js +4 -0
  11. package/lib/admin/permissions.js.map +1 -1
  12. package/lib/admin/quality-store.js +71 -0
  13. package/lib/admin/quality-store.js.map +1 -1
  14. package/lib/admin/service.js +113 -8
  15. package/lib/admin/service.js.map +1 -1
  16. package/lib/admin/session-log.js +66 -5
  17. package/lib/admin/session-log.js.map +1 -1
  18. package/lib/client/QaSessionController.js +371 -37
  19. package/lib/client/QaSessionController.js.map +1 -1
  20. package/lib/client/QaSurface.js +48 -8
  21. package/lib/client/QaSurface.js.map +1 -1
  22. package/lib/client/QaSurfaceGuard.js +12 -5
  23. package/lib/client/QaSurfaceGuard.js.map +1 -1
  24. package/lib/client/QaTranscriptAdapter.js +36 -0
  25. package/lib/client/QaTranscriptAdapter.js.map +1 -1
  26. package/lib/client/admin/QaAdmin.js +14 -2
  27. package/lib/client/admin/QaAdmin.js.map +1 -1
  28. package/lib/client/admin/pages/Conversations.js +33 -7
  29. package/lib/client/admin/pages/Conversations.js.map +1 -1
  30. package/lib/client/admin/pages/Users.js +9 -2
  31. package/lib/client/admin/pages/Users.js.map +1 -1
  32. package/lib/client/admin/shared.js +14 -1
  33. package/lib/client/admin/shared.js.map +1 -1
  34. package/lib/client/admin/styles.js +2 -0
  35. package/lib/client/admin/styles.js.map +1 -1
  36. package/lib/client/audit/QaAuditDialog.js +74 -0
  37. package/lib/client/audit/QaAuditDialog.js.map +1 -0
  38. package/lib/client/audit/QaAuditRowBadge.js +17 -0
  39. package/lib/client/audit/QaAuditRowBadge.js.map +1 -0
  40. package/lib/client/audit/controller.js +39 -0
  41. package/lib/client/audit/controller.js.map +1 -0
  42. package/lib/client/audit/types.js +36 -0
  43. package/lib/client/audit/types.js.map +1 -0
  44. package/lib/client/audit/use-chat-audits.js +139 -0
  45. package/lib/client/audit/use-chat-audits.js.map +1 -0
  46. package/lib/client/base64.js +22 -1
  47. package/lib/client/base64.js.map +1 -1
  48. package/lib/client/components/QaAgentsDrawer.js +9 -6
  49. package/lib/client/components/QaAgentsDrawer.js.map +1 -1
  50. package/lib/client/components/QaApproval.js +1 -1
  51. package/lib/client/components/QaApproval.js.map +1 -1
  52. package/lib/client/components/QaChangelog.js +72 -0
  53. package/lib/client/components/QaChangelog.js.map +1 -1
  54. package/lib/client/components/QaComposer.js +63 -3
  55. package/lib/client/components/QaComposer.js.map +1 -1
  56. package/lib/client/components/QaFilesPanel.js +17 -11
  57. package/lib/client/components/QaFilesPanel.js.map +1 -1
  58. package/lib/client/components/QaHeader.js +3 -11
  59. package/lib/client/components/QaHeader.js.map +1 -1
  60. package/lib/client/components/QaMessage.js +16 -0
  61. package/lib/client/components/QaMessage.js.map +1 -1
  62. package/lib/client/components/QaModal.js.map +1 -1
  63. package/lib/client/components/QaQuestions.js +5 -5
  64. package/lib/client/components/QaQuestions.js.map +1 -1
  65. package/lib/client/components/QaSidebar.js +22 -3
  66. package/lib/client/components/QaSidebar.js.map +1 -1
  67. package/lib/client/components/QaWidthHandle.js +111 -5
  68. package/lib/client/components/QaWidthHandle.js.map +1 -1
  69. package/lib/client/components/QaWorkspaceBrowser.js +231 -0
  70. package/lib/client/components/QaWorkspaceBrowser.js.map +1 -0
  71. package/lib/client/index.js +127 -51
  72. package/lib/client/index.js.map +1 -1
  73. package/lib/client/kiosk.js +51 -0
  74. package/lib/client/kiosk.js.map +1 -0
  75. package/lib/client/markdown/blocks.js +122 -7
  76. package/lib/client/markdown/blocks.js.map +1 -1
  77. package/lib/client/markdown/inline.js +108 -12
  78. package/lib/client/markdown/inline.js.map +1 -1
  79. package/lib/client/markdown/katex-css.js +12 -0
  80. package/lib/client/markdown/katex-css.js.map +1 -0
  81. package/lib/client/markdown/math.js +84 -0
  82. package/lib/client/markdown/math.js.map +1 -0
  83. package/lib/client/markdown/render.js +74 -5
  84. package/lib/client/markdown/render.js.map +1 -1
  85. package/lib/client/project-session-state.js +15 -2
  86. package/lib/client/project-session-state.js.map +1 -1
  87. package/lib/client/prompt-content.js +26 -0
  88. package/lib/client/prompt-content.js.map +1 -1
  89. package/lib/client/settings/card.js +2 -2
  90. package/lib/client/settings/card.js.map +1 -1
  91. package/lib/client/settings/sections/lockdown.js +1 -6
  92. package/lib/client/settings/sections/lockdown.js.map +1 -1
  93. package/lib/client/settings/sections/notes.js +46 -0
  94. package/lib/client/settings/sections/notes.js.map +1 -0
  95. package/lib/client/settings/sections/slash.js +57 -0
  96. package/lib/client/settings/sections/slash.js.map +1 -0
  97. package/lib/client/settings/sections/sources.js +4 -1
  98. package/lib/client/settings/sections/sources.js.map +1 -1
  99. package/lib/client/settings/sections/status.js +9 -1
  100. package/lib/client/settings/sections/status.js.map +1 -1
  101. package/lib/client/settings/sections.js +2 -0
  102. package/lib/client/settings/sections.js.map +1 -1
  103. package/lib/client/settlement.js +1 -1
  104. package/lib/client/settlement.js.map +1 -1
  105. package/lib/client/slash/SlashPalette.js +48 -0
  106. package/lib/client/slash/SlashPalette.js.map +1 -0
  107. package/lib/client/slash/copy.js +54 -0
  108. package/lib/client/slash/copy.js.map +1 -0
  109. package/lib/client/slash/slash-router.js +49 -0
  110. package/lib/client/slash/slash-router.js.map +1 -0
  111. package/lib/client/slash/useSlashNavigation.js +95 -0
  112. package/lib/client/slash/useSlashNavigation.js.map +1 -0
  113. package/lib/client/source-preview.js +3 -0
  114. package/lib/client/source-preview.js.map +1 -1
  115. package/lib/client/styles.js +145 -16
  116. package/lib/client/styles.js.map +1 -1
  117. package/lib/client/types.js +11 -0
  118. package/lib/client/types.js.map +1 -1
  119. package/lib/client.js +33548 -1876
  120. package/lib/client.js.map +1 -1
  121. package/lib/config-resolvers/basics.js +11 -2
  122. package/lib/config-resolvers/basics.js.map +1 -1
  123. package/lib/config-resolvers/defaults.js +32 -0
  124. package/lib/config-resolvers/defaults.js.map +1 -1
  125. package/lib/config-resolvers/lockdown.js +8 -2
  126. package/lib/config-resolvers/lockdown.js.map +1 -1
  127. package/lib/config-resolvers/notes.js +24 -0
  128. package/lib/config-resolvers/notes.js.map +1 -0
  129. package/lib/config-resolvers/slash-commands.js +60 -0
  130. package/lib/config-resolvers/slash-commands.js.map +1 -0
  131. package/lib/config-resolvers/sources.js +4 -0
  132. package/lib/config-resolvers/sources.js.map +1 -1
  133. package/lib/config.js +96 -2
  134. package/lib/config.js.map +1 -1
  135. package/lib/index.js +309 -11
  136. package/lib/index.js.map +1 -1
  137. package/lib/personal-skills/service.js +16 -3
  138. package/lib/personal-skills/service.js.map +1 -1
  139. package/lib/prompt-notes.js +45 -6
  140. package/lib/prompt-notes.js.map +1 -1
  141. package/lib/provenance/document-preview.js +51 -0
  142. package/lib/provenance/document-preview.js.map +1 -0
  143. package/lib/provenance/file-preview.js +191 -19
  144. package/lib/provenance/file-preview.js.map +1 -1
  145. package/lib/provenance/host-store.js +18 -1
  146. package/lib/provenance/host-store.js.map +1 -1
  147. package/lib/qa-tools/catalog.js +7 -1
  148. package/lib/qa-tools/catalog.js.map +1 -1
  149. package/lib/qa-tools/file-delete-gate.js +60 -0
  150. package/lib/qa-tools/file-delete-gate.js.map +1 -0
  151. package/lib/qa-tools/file-delete.js +156 -0
  152. package/lib/qa-tools/file-delete.js.map +1 -0
  153. package/lib/questions.js +90 -43
  154. package/lib/questions.js.map +1 -1
  155. package/lib/resolve-config.js +7 -0
  156. package/lib/resolve-config.js.map +1 -1
  157. package/lib/secure-session.js +24 -0
  158. package/lib/secure-session.js.map +1 -1
  159. package/lib/shared/documents.js +22 -0
  160. package/lib/shared/documents.js.map +1 -0
  161. package/lib/slash/catalog.js +77 -0
  162. package/lib/slash/catalog.js.map +1 -0
  163. package/lib/slash/matcher.js +100 -0
  164. package/lib/slash/matcher.js.map +1 -0
  165. package/lib/slash/parser.js +79 -0
  166. package/lib/slash/parser.js.map +1 -0
  167. package/lib/slash/policy.js +72 -0
  168. package/lib/slash/policy.js.map +1 -0
  169. package/lib/slash/remotes.js +272 -0
  170. package/lib/slash/remotes.js.map +1 -0
  171. package/lib/typert.host.js +544 -56
  172. package/lib/typert.remote-client.d.ts +13 -1
  173. package/lib/typert.remote-client.js +435 -53
  174. package/lib/types/access/capability-catalog.d.ts +28 -1
  175. package/lib/types/access/service.d.ts +33 -4
  176. package/lib/types/accounts/errors.d.ts +7 -1
  177. package/lib/types/accounts/store.d.ts +12 -0
  178. package/lib/types/admin/quality-store.d.ts +18 -0
  179. package/lib/types/admin/service.d.ts +34 -2
  180. package/lib/types/admin/session-log.d.ts +65 -1
  181. package/lib/types/client/QaSessionController.d.ts +84 -2
  182. package/lib/types/client/QaSurface.d.ts +14 -1
  183. package/lib/types/client/admin/pages/Conversations.d.ts +4 -0
  184. package/lib/types/client/admin/shared.d.ts +2 -0
  185. package/lib/types/client/audit/QaAuditDialog.d.ts +21 -0
  186. package/lib/types/client/audit/QaAuditRowBadge.d.ts +18 -0
  187. package/lib/types/client/audit/controller.d.ts +27 -0
  188. package/lib/types/client/audit/types.d.ts +72 -0
  189. package/lib/types/client/audit/use-chat-audits.d.ts +20 -0
  190. package/lib/types/client/base64.d.ts +13 -1
  191. package/lib/types/client/components/QaAgentsDrawer.d.ts +2 -1
  192. package/lib/types/client/components/QaComposer.d.ts +12 -2
  193. package/lib/types/client/components/QaFilesPanel.d.ts +16 -4
  194. package/lib/types/client/components/QaHeader.d.ts +9 -3
  195. package/lib/types/client/components/QaModal.d.ts +4 -3
  196. package/lib/types/client/components/QaQuestions.d.ts +7 -0
  197. package/lib/types/client/components/QaSidebar.d.ts +8 -0
  198. package/lib/types/client/components/QaWidthHandle.d.ts +48 -2
  199. package/lib/types/client/components/QaWorkspaceBrowser.d.ts +15 -0
  200. package/lib/types/client/index.d.ts +1 -1
  201. package/lib/types/client/kiosk.d.ts +34 -0
  202. package/lib/types/client/markdown/blocks.d.ts +14 -1
  203. package/lib/types/client/markdown/inline.d.ts +23 -7
  204. package/lib/types/client/markdown/katex-css.d.ts +11 -0
  205. package/lib/types/client/markdown/math.d.ts +23 -0
  206. package/lib/types/client/markdown/render.d.ts +2 -1
  207. package/lib/types/client/project-session-state.d.ts +3 -1
  208. package/lib/types/client/prompt-content.d.ts +9 -1
  209. package/lib/types/client/settings/sections/notes.d.ts +10 -0
  210. package/lib/types/client/settings/sections/slash.d.ts +16 -0
  211. package/lib/types/client/settings/sections.d.ts +2 -0
  212. package/lib/types/client/settlement.d.ts +4 -1
  213. package/lib/types/client/slash/SlashPalette.d.ts +24 -0
  214. package/lib/types/client/slash/copy.d.ts +30 -0
  215. package/lib/types/client/slash/slash-router.d.ts +67 -0
  216. package/lib/types/client/slash/useSlashNavigation.d.ts +47 -0
  217. package/lib/types/client/styles.d.ts +22 -0
  218. package/lib/types/client/types.d.ts +65 -1
  219. package/lib/types/config-resolvers/notes.d.ts +10 -0
  220. package/lib/types/config-resolvers/slash-commands.d.ts +20 -0
  221. package/lib/types/index.d.ts +116 -1
  222. package/lib/types/personal-skills/service.d.ts +5 -0
  223. package/lib/types/prompt-notes.d.ts +9 -0
  224. package/lib/types/provenance/document-preview.d.ts +24 -0
  225. package/lib/types/provenance/file-preview.d.ts +69 -2
  226. package/lib/types/provenance/host-store.d.ts +13 -0
  227. package/lib/types/qa-tools/catalog.d.ts +1 -1
  228. package/lib/types/qa-tools/file-delete-gate.d.ts +42 -0
  229. package/lib/types/qa-tools/file-delete.d.ts +32 -0
  230. package/lib/types/questions.d.ts +8 -0
  231. package/lib/types/shared/documents.d.ts +20 -0
  232. package/lib/types/slash/catalog.d.ts +56 -0
  233. package/lib/types/slash/matcher.d.ts +51 -0
  234. package/lib/types/slash/parser.d.ts +46 -0
  235. package/lib/types/slash/policy.d.ts +40 -0
  236. package/lib/types/slash/remotes.d.ts +35 -0
  237. package/lib/types/types.d.ts +293 -6
  238. package/lib/types/ui-mode.d.ts +18 -0
  239. package/lib/ui-mode.js +22 -0
  240. package/lib/ui-mode.js.map +1 -0
  241. package/package.json +15 -9
  242. package/scripts/attach-workspace-sessions.mjs +472 -0
@@ -0,0 +1,20 @@
1
+ import type { QaAuditApi, QaSessionAudit, QaAuditSummary } from "./types.js";
2
+ /** How often the chat list re-asks which chats have an audit. */
3
+ export declare const AUDIT_POLL_MS = 30000;
4
+ /**
5
+ * Poll the audit summary for every chat id.
6
+ *
7
+ * @param api - the Remote facade, or `null` when the audit plugin is absent.
8
+ * @param sessionIds - the chats currently listed.
9
+ */
10
+ export declare function useChatAudits(api: QaAuditApi | null, sessionIds: readonly string[]): ReadonlyMap<string, QaAuditSummary>;
11
+ /** The dialog's own load: one audit's documents, fetched when it opens. */
12
+ export interface QaAuditLoad {
13
+ readonly loading: boolean;
14
+ readonly audit: QaSessionAudit | null;
15
+ readonly error: string | null;
16
+ }
17
+ export declare function useSessionAuditDocument(api: QaAuditApi | null, sessionId: string | null, open: boolean,
18
+ /** Reload key; the summary's `modifiedAt` changes exactly when bytes do. */
19
+ modifiedAt: string | null): QaAuditLoad;
20
+ //# sourceMappingURL=use-chat-audits.d.ts.map
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Browser-side binary-to-base64. Chunked so `String.fromCharCode` never
2
+ * Browser-side base64. Encoding is chunked so `String.fromCharCode` never
3
3
  * crosses the engine's argument limit on large attachments.
4
4
  */
5
5
  /**
@@ -7,4 +7,16 @@
7
7
  * @returns the canonical base64 text (no `data:` prefix, no padding tricks).
8
8
  */
9
9
  export declare function bytesToBase64(bytes: Uint8Array): string;
10
+ /**
11
+ * Decode base64 the Host sent for a file the panel could not read as text.
12
+ *
13
+ * A malformed body is tolerated rather than thrown on: the caller is about to
14
+ * hand the bytes to a download or an image tag, and a partial file is a better
15
+ * outcome than losing the panel to an exception. `atob` still rejects input
16
+ * that is not base64 at all; the caller keeps that refusal.
17
+ *
18
+ * @param value - base64 text, with or without a data-URL prefix.
19
+ * @returns the decoded bytes.
20
+ */
21
+ export declare function base64ToBytes(value: string): Uint8Array;
10
22
  //# sourceMappingURL=base64.d.ts.map
@@ -5,7 +5,8 @@ export interface QaSubagentRow {
5
5
  readonly title: string;
6
6
  readonly running: boolean;
7
7
  readonly completed: boolean;
8
- readonly meta: string;
8
+ /** Muted facts rendered after the title, one span per part. */
9
+ readonly meta: readonly string[];
9
10
  }
10
11
  /**
11
12
  * Direct subagent children of the open chat, running first. Reads the host
@@ -1,4 +1,4 @@
1
- import type { QaAttachmentDraft } from "../../types.js";
1
+ import type { QaAttachmentDraft, QaSlashView, ResolvedQaSlashCommands } from "../../types.js";
2
2
  import { type QaAttachmentLimits } from "../attachments.js";
3
3
  import type { QaQuickQuestion } from "../types.js";
4
4
  export interface QaComposerProps {
@@ -13,8 +13,18 @@ export interface QaComposerProps {
13
13
  readonly attachments: readonly QaAttachmentDraft[];
14
14
  /** Deployment policy: accepted kinds, ceilings and the paste threshold. */
15
15
  readonly limits: QaAttachmentLimits;
16
+ /** Slash catalog of this chat; inert while the master switch is off. */
17
+ readonly slash: QaSlashView;
18
+ readonly slashPolicy: ResolvedQaSlashCommands["palette"];
16
19
  readonly onAttachmentsChange: (attachments: readonly QaAttachmentDraft[]) => void;
17
- readonly onSend: (text: string, attachments: readonly QaAttachmentDraft[]) => Promise<boolean>;
20
+ /**
21
+ * `pick` names the entry the user chose in the palette, while the draft
22
+ * still reads as its invocation. It is what disambiguates a skill and a
23
+ * command that share a name; `null` means the draft alone decides.
24
+ */
25
+ readonly onSend: (text: string, attachments: readonly QaAttachmentDraft[], pick: string | null) => Promise<boolean>;
26
+ /** Called when the palette opens, so the caller can revalidate the catalog. */
27
+ readonly onSlashOpen: () => void;
18
28
  readonly onStop: () => Promise<void>;
19
29
  }
20
30
  /**
@@ -1,15 +1,27 @@
1
1
  import type { QaChatFileGroup } from "../chat-files.js";
2
+ import type { QaBoundSourceApi } from "../types.js";
2
3
  export interface QaFilesPanelProps {
3
4
  readonly groups: readonly QaChatFileGroup[];
4
5
  /** Resolve an image attachment to an object URL; images render inert without it. */
5
6
  readonly resolveImage?: (attachmentId: string) => Promise<string>;
6
7
  /** Scroll the transcript to the group's user message. */
7
8
  readonly onJumpToMessage: (messageId: string) => void;
9
+ /**
10
+ * The chat whose workspace the panel browses. Both this and `api` are absent
11
+ * in hosts that only render the attachment roster, where the workspace
12
+ * section is left out rather than shown as a refusal.
13
+ */
14
+ readonly sessionId?: string;
15
+ readonly api?: QaBoundSourceApi;
8
16
  }
9
17
  /**
10
- * The chat's attachment roster: one section per sending message, newest
11
- * first. Rows mirror the transcript's handles — the browser never reads a
12
- * file back, and the images are the same object URLs the message showed.
18
+ * The chat's attachment roster plus, when the Host is reachable, the chat's
19
+ * own workspace: one section per sending message, newest first, and above it
20
+ * the file browser the conversation worked in.
21
+ *
22
+ * Rows mirror the transcript's handles — the browser never reads an attachment
23
+ * back, and the images are the same object URLs the message showed — while the
24
+ * workspace section reads through the Host's fenced listing and file reads.
13
25
  */
14
- export declare function QaFilesPanel({ groups, resolveImage, onJumpToMessage, }: QaFilesPanelProps): import("react/jsx-runtime").JSX.Element;
26
+ export declare function QaFilesPanel({ groups, resolveImage, onJumpToMessage, sessionId, api, }: QaFilesPanelProps): import("react/jsx-runtime").JSX.Element;
15
27
  //# sourceMappingURL=QaFilesPanel.d.ts.map
@@ -17,10 +17,9 @@ export interface QaHeaderProps {
17
17
  readonly logoUrl: string | null;
18
18
  /** The derived conversation title; null hides the heading. */
19
19
  readonly title: string | null;
20
- /** A subagent view replaces the mode caption with its return control. */
20
+ /** A subagent view shows its return control in the title row. */
21
21
  readonly viewingSubagent: boolean;
22
22
  readonly onCloseSubagent: () => void;
23
- readonly agentPreset: string | null;
24
23
  readonly roleSelector?: ReactNode;
25
24
  readonly administration?: {
26
25
  readonly onOpen: () => void;
@@ -36,6 +35,13 @@ export interface QaHeaderProps {
36
35
  readonly sourcesOpen: boolean;
37
36
  readonly onOpenSources: () => void;
38
37
  readonly fileCount: number;
38
+ /**
39
+ * Whether the files tab has anything to open: attachments, or the chat's own
40
+ * workspace when the deployment lets the panel read files. The count stays
41
+ * the attachment number, so an empty chat with a readable workspace shows no
42
+ * badge but still opens.
43
+ */
44
+ readonly filesEnabled: boolean;
39
45
  readonly filesOpen: boolean;
40
46
  readonly onOpenFiles: () => void;
41
47
  /**
@@ -53,5 +59,5 @@ export interface QaHeaderProps {
53
59
  readonly resetDisabled: boolean;
54
60
  readonly onReset: () => void;
55
61
  }
56
- export declare function QaHeader({ logoUrl, title, viewingSubagent, onCloseSubagent, agentPreset, roleSelector, administration, agentCount, agentsOpen, onToggleAgents, sourcesVisible, sourcesCount, sourcesComplete, sourcesOpen, onOpenSources, fileCount, filesOpen, onOpenFiles, settings, panelLauncher, showReset, resetDisabled, onReset, }: QaHeaderProps): import("react/jsx-runtime").JSX.Element;
62
+ export declare function QaHeader({ logoUrl, title, viewingSubagent, onCloseSubagent, roleSelector, administration, agentCount, agentsOpen, onToggleAgents, sourcesVisible, sourcesCount, sourcesComplete, sourcesOpen, onOpenSources, fileCount, filesEnabled, filesOpen, onOpenFiles, settings, panelLauncher, showReset, resetDisabled, onReset, }: QaHeaderProps): import("react/jsx-runtime").JSX.Element;
57
63
  //# sourceMappingURL=QaHeader.d.ts.map
@@ -11,11 +11,12 @@ export interface QaModalProps {
11
11
  readonly footer?: ReactNode;
12
12
  readonly wide?: boolean;
13
13
  /**
14
- * Panel size: `wide` fits prose that must not wrap mid-sentence, and
14
+ * Panel size: `wide` fits prose that must not wrap mid-sentence,
15
15
  * `settings` the sectioned user-settings dialog, which needs both a
16
- * comfortable height and a two-column body.
16
+ * comfortable height and a two-column body, and `document` a file
17
+ * preview the reader expanded out of the rail.
17
18
  */
18
- readonly size?: "default" | "wide" | "settings";
19
+ readonly size?: "default" | "wide" | "settings" | "document";
19
20
  }
20
21
  /**
21
22
  * The shared QA dialog shell: backdrop, panel, head with the close control,
@@ -3,6 +3,13 @@ export interface QaQuestionsProps {
3
3
  readonly questions: readonly QaPendingQuestion[];
4
4
  readonly onAnswer: (requestId: string, answers: readonly QaQuestionAnswerItem[]) => Promise<void>;
5
5
  readonly onCancel: (requestId: string) => Promise<void>;
6
+ /**
7
+ * Stop the turn the questions belong to. The form takes the composer's
8
+ * place, so the run's own stop action moves here: an operator who does not
9
+ * want to answer must still be able to end the turn instead.
10
+ */
11
+ readonly onStop?: () => Promise<void>;
12
+ readonly canStop?: boolean;
6
13
  }
7
14
  /**
8
15
  * The questions a running turn waits on. Answers are the operator's own: the
@@ -1,4 +1,5 @@
1
1
  import type { SessionSummary } from "@deepseek-ai/dsh-api-session-controller/client";
2
+ import { type QaAuditSummary } from "../audit/types.js";
2
3
  /** One renderable row of the chat-history sidebar. */
3
4
  export interface QaChatRow {
4
5
  readonly id: string;
@@ -53,6 +54,13 @@ export interface QaSidebarProps {
53
54
  readonly onNewChat: () => void;
54
55
  /** Removes a chat from this browser's index; omit to hide the control. */
55
56
  readonly onDelete?: (sessionId: string) => void;
57
+ /**
58
+ * Audit summaries by chat id, for the row badge. Empty when the audit plugin
59
+ * is not installed — the badge is then absent rather than empty.
60
+ */
61
+ readonly audits?: ReadonlyMap<string, QaAuditSummary>;
62
+ /** Opens the audit dialog for a chat; omit when audits are unavailable. */
63
+ readonly onAudit?: (sessionId: string) => void;
56
64
  /** The signed-in account; omit when accounts are disabled. */
57
65
  readonly account?: {
58
66
  readonly email: string;
@@ -19,8 +19,12 @@ export declare const QA_HANDLE_FREE_BAND = 40;
19
19
  * at every width; the stylesheet caps it once more by the live side gutter.
20
20
  */
21
21
  export declare const QA_BLEED_MAX_WIDTH: number;
22
- export declare function readQaContentWidth(storage: Pick<Storage, "getItem">, key: string): number | null;
23
- export declare function writeQaContentWidth(storage: Pick<Storage, "setItem">, key: string, width: number): void;
22
+ /**
23
+ * A stored positive width, or null when the browser has none (first visit,
24
+ * denied storage, corrupt value). Shared by every draggable width.
25
+ */
26
+ export declare function readQaStoredWidth(storage: Pick<Storage, "getItem">, key: string): number | null;
27
+ export declare function writeQaStoredWidth(storage: Pick<Storage, "setItem">, key: string, width: number): void;
24
28
  /**
25
29
  * Resolve the centered content width for the currently available column. The
26
30
  * operator sets only the floor; the column is the ceiling, so the content may
@@ -52,5 +56,47 @@ export declare function useQaContentWidth({ active, root, storage, storageKey, m
52
56
  readonly onEnd: () => void;
53
57
  };
54
58
  export type UseQaContentWidthResult = ReturnType<typeof useQaContentWidth>;
59
+ /** Drag clamp for the chat-list sidebar, borrowed from the DSH frame. */
60
+ export declare const QA_SIDEBAR_MIN_WIDTH = 264;
61
+ export declare const QA_SIDEBAR_MAX_WIDTH = 420;
62
+ /** The width the sidebar keeps until its first drag: today's fixed width. */
63
+ export declare const QA_SIDEBAR_DEFAULT_WIDTH = 264;
64
+ /** Integer pixels, no snapping and no step, like the DSH frame clamp. */
65
+ export declare function clampQaSidebarWidth(px: number): number;
66
+ /** Resolve the sidebar width for this browser: the stored drag or the default. */
67
+ export declare function resolveQaSidebarWidth(stored: number | null): number;
68
+ interface QaSidebarHandleProps {
69
+ readonly onStart: () => number;
70
+ readonly onDrag: (width: number) => void;
71
+ readonly onCommit: (width: number) => void;
72
+ readonly onEnd: () => void;
73
+ }
74
+ /**
75
+ * The invisible strip on the sidebar's border, like the DSH frame's handle: an
76
+ * 8px hit target straddling the edge, found by the cursor alone. One-sided —
77
+ * the pointer delta is the width delta — and pointer-captured, so the drag
78
+ * keeps tracking outside the strip and never selects text.
79
+ */
80
+ export declare function QaSidebarHandle(props: QaSidebarHandleProps): import("react/jsx-runtime").JSX.Element;
81
+ interface UseQaSidebarWidthOptions {
82
+ /** Whether the expanded sidebar is mounted (the collapsed rail has none). */
83
+ readonly active: boolean;
84
+ readonly root: RefObject<HTMLElement | null>;
85
+ readonly storage: Pick<Storage, "getItem" | "setItem">;
86
+ readonly storageKey: string;
87
+ }
88
+ /**
89
+ * Sidebar counterpart of `useQaContentWidth`: the width never enters React
90
+ * state — the drag writes the custom property straight onto the nav element,
91
+ * so the memoized sidebar does not re-render per frame — and only the
92
+ * committed value reaches storage, which the next mount restores.
93
+ */
94
+ export declare function useQaSidebarWidth({ active, root, storage, storageKey, }: UseQaSidebarWidthOptions): {
95
+ readonly onStart: () => number;
96
+ readonly onDrag: (width: number) => void;
97
+ readonly onCommit: (width: number) => void;
98
+ readonly onEnd: () => void;
99
+ };
100
+ export type UseQaSidebarWidthResult = ReturnType<typeof useQaSidebarWidth>;
55
101
  export {};
56
102
  //# sourceMappingURL=QaWidthHandle.d.ts.map
@@ -0,0 +1,15 @@
1
+ import type { QaBoundSourceApi } from "../types.js";
2
+ export interface QaWorkspaceBrowserProps {
3
+ readonly sessionId: string;
4
+ readonly api: QaBoundSourceApi;
5
+ }
6
+ /**
7
+ * The chat's own workspace, browsable from the files rail.
8
+ *
9
+ * One directory at a time: the Host lists a directory, the panel descends into
10
+ * its children and never travels by path, so a link in a listing cannot walk
11
+ * the visitor out of the chat's tree. Opening a file reads exactly that file —
12
+ * text inline, anything else as a downloadable handle.
13
+ */
14
+ export declare function QaWorkspaceBrowser({ sessionId, api, }: QaWorkspaceBrowserProps): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=QaWorkspaceBrowser.d.ts.map
@@ -6,7 +6,7 @@ declare module "@deepseek-ai/cordis" {
6
6
  }
7
7
  }
8
8
  export declare const inject: string[];
9
- /** Register the route-aware, full-frame QA entry in the additive overlay slot. */
9
+ /** Register the route-aware, full-frame QA entry: root owner in the kiosk, additive overlay slot otherwise. */
10
10
  export declare function apply(ctx: Context): Promise<() => Promise<void>>;
11
11
  export { QaConfigController } from "./QaConfigController.js";
12
12
  export { QaAccountsController } from "./QaAccountsController.js";
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The QA kiosk presentation mode, as the client half of the plugin sees it.
3
+ *
4
+ * The harness publishes the deployment's UI mode into every served document
5
+ * ahead of the first application script (the index prelude injected for
6
+ * `DSH_UI_MODE=qa`): `window.DSH_UI_MODE` and, alongside it, the QA base path
7
+ * the server-side route policy serves the application under. The mode — not
8
+ * `location.pathname` — is what the client branches on: the route policy owns
9
+ * which paths carry a document at all, and a client that keyed off the
10
+ * pathname would re-introduce exactly the paths the policy closed.
11
+ *
12
+ * A document without the globals (a host without the kiosk patches, a plugin
13
+ * bundle served into an overlay deployment) reads as the overlay
14
+ * presentation: the `shell.overlay` registration this plugin has always
15
+ * used. That keeps one plugin build compatible with both compositions.
16
+ */
17
+ /**
18
+ * Whether one URL pathname lives on a surface: the surface path itself or any
19
+ * child of it. A plain prefix check would also match `/qadmin` or `/qa-test`.
20
+ */
21
+ export declare function matchesSurface(pathname: string, surface: string): boolean;
22
+ /**
23
+ * Whether this browser was served by a QA kiosk deployment.
24
+ * @param target - the global object; overridable for tests.
25
+ */
26
+ export declare function qaKioskMode(target?: Readonly<Record<string, unknown>>): boolean;
27
+ /**
28
+ * The QA surface's base path of a kiosk deployment, normalized: single
29
+ * leading slash, no trailing slash. A malformed value falls back to the
30
+ * default rather than disabling the mode.
31
+ * @param target - the global object; overridable for tests.
32
+ */
33
+ export declare function qaKioskBasePath(target?: Readonly<Record<string, unknown>>): string;
34
+ //# sourceMappingURL=kiosk.d.ts.map
@@ -9,6 +9,13 @@
9
9
  * blocks, setext inside lists, link reference definitions spanning lines) stay
10
10
  * out. Raw HTML never becomes a block: a tag line is a paragraph whose inline
11
11
  * pass leaves the tag as literal text.
12
+ *
13
+ * Math follows the Host transcript's settled grammar: display TeX is a
14
+ * `$$`-delimited block (a fence on its own lines or one line
15
+ * `$$…$$`) or a ```math fence, and nothing else — the `\(…\)` and `\[…\]`
16
+ * delimiters stay literal text, exactly as the Host renders them. Footnote
17
+ * definitions (`[^id]: …`) are collected the way GitHub's dialect does, with
18
+ * lazy and indented continuation lines.
12
19
  */
13
20
  /** `#`-through-`######` heading levels. */
14
21
  export type HeadingDepth = 1 | 2 | 3 | 4 | 5 | 6;
@@ -46,6 +53,9 @@ export type MarkdownBlock = {
46
53
  readonly align: readonly TableAlign[];
47
54
  readonly head: readonly string[];
48
55
  readonly rows: readonly (readonly string[])[];
56
+ } | {
57
+ readonly kind: "math";
58
+ readonly text: string;
49
59
  } | {
50
60
  readonly kind: "rule";
51
61
  };
@@ -54,6 +64,8 @@ export interface ParsedMarkdown {
54
64
  readonly blocks: readonly MarkdownBlock[];
55
65
  /** Link/image definitions by upper-cased identifier. */
56
66
  readonly definitions: ReadonlyMap<string, string>;
67
+ /** Footnote bodies by upper-cased identifier; first definition wins. */
68
+ readonly footnotes: ReadonlyMap<string, readonly MarkdownBlock[]>;
57
69
  }
58
70
  /** Split one table row into trimmed cells, honoring escaped pipes. */
59
71
  export declare function splitTableRow(line: string): string[];
@@ -67,8 +79,9 @@ export declare function parseMarkdown(text: string): ParsedMarkdown;
67
79
  * Parse the blocks of one container (document, quote, or list item).
68
80
  * @param lines - Container lines, already de-indented by the caller.
69
81
  * @param definitions - Document-wide definition accumulator.
82
+ * @param footnotes - Document-wide footnote accumulator.
70
83
  * @param depth - Container nesting depth.
71
84
  * @returns The container's blocks.
72
85
  */
73
- export declare function parseBlocks(lines: readonly string[], definitions: Map<string, string>, depth: number): MarkdownBlock[];
86
+ export declare function parseBlocks(lines: readonly string[], definitions: Map<string, string>, footnotes: Map<string, readonly MarkdownBlock[]>, depth: number): MarkdownBlock[];
74
87
  //# sourceMappingURL=blocks.d.ts.map
@@ -1,10 +1,13 @@
1
1
  /**
2
2
  * GFM inline grammar for the chat renderer: code spans, emphasis, links,
3
- * images, autolinks, and the two line-break flavors. Emphasis follows the
4
- * CommonMark intent (a closer must match its opener's delimiter run, `_` never
5
- * opens inside a word) rather than the full delimiter-stack algorithm — the
6
- * shapes this grammar cannot express are the pathological ones, and they
7
- * degrade to literal text instead of mangling the sentence.
3
+ * images, autolinks, TeX math, footnotes, and the two line-break flavors.
4
+ * Emphasis follows the CommonMark intent (a closer must match its opener's
5
+ * delimiter run, `_` never opens inside a word) rather than the full
6
+ * delimiter-stack algorithm — the shapes this grammar cannot express are the
7
+ * pathological ones, and they degrade to literal text instead of mangling the
8
+ * sentence. Math follows the Host transcript: `$…$` and `$$…$$` spans, with
9
+ * maximal-munch dollar runs and whitespace padding stripped only when both
10
+ * ends carry it.
8
11
  */
9
12
  /** One inline node; `children` nodes nest. */
10
13
  export type MarkdownInline = {
@@ -28,13 +31,26 @@ export type MarkdownInline = {
28
31
  readonly kind: "image";
29
32
  readonly src: string;
30
33
  readonly alt: string;
34
+ } | {
35
+ readonly kind: "inlineMath";
36
+ readonly value: string;
37
+ } | {
38
+ readonly kind: "footnoteRef";
39
+ readonly id: string;
31
40
  };
41
+ /** The reference targets one inline pass resolves against. */
42
+ export interface InlineTargets {
43
+ /** Link/image definitions by upper-cased identifier. */
44
+ readonly definitions: ReadonlyMap<string, string>;
45
+ /** Footnote identifiers that have a definition, by upper-cased label. */
46
+ readonly footnotes: ReadonlyMap<string, unknown>;
47
+ }
32
48
  /**
33
49
  * Parse the inline content of one leaf block.
34
50
  * @param text - Raw inline Markdown, newlines included.
35
- * @param definitions - Link/image definitions collected by the block pass.
51
+ * @param targets - The definitions and footnotes this pass resolves against.
36
52
  * @param depth - Inline nesting depth.
37
53
  * @returns The inline nodes in document order.
38
54
  */
39
- export declare function parseInline(text: string, definitions: ReadonlyMap<string, string>, depth?: number): MarkdownInline[];
55
+ export declare function parseInline(text: string, targets: ReadonlyMap<string, string> | InlineTargets, depth?: number): MarkdownInline[];
40
56
  //# sourceMappingURL=inline.d.ts.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * `katex/dist/katex.min.css` with every font inlined as a woff2 data URI.
3
+ * Generated by `scripts/generate-katex-css.mjs` from the pinned `katex`
4
+ * devDependency — do not edit by hand; regenerate after a `katex` upgrade.
5
+ *
6
+ * The QA overlay is a self-contained client bundle, so the math styles and
7
+ * their fonts travel inside it: nothing here may reference an external file,
8
+ * and a data URI cannot collide with the Host's own KaTeX font declarations.
9
+ */
10
+ export declare const KATEX_CSS: string;
11
+ //# sourceMappingURL=katex-css.d.ts.map
@@ -0,0 +1,23 @@
1
+ /**
2
+ * TeX-to-React via KaTeX, mirroring the Host transcript's math pipeline: the
3
+ * same two-arm error chain (strict render, `strict: 'ignore'` retry, error
4
+ * span) so a formula renders identically here and in DSH's own message. KaTeX
5
+ * emits an HTML string; the browser's HTML parser turns it into a tree this
6
+ * module maps onto React elements — the output is a static span/MathML/SVG
7
+ * vocabulary with no raw author HTML, the same trust the fenced-code
8
+ * highlighter's tree gets.
9
+ *
10
+ * React has no MathML support, so the `.katex-mathml` subtree's elements land
11
+ * in the HTML namespace; the visual arm is the `.katex-html` span tree and
12
+ * the MathML arm serves assistive technology, which reads it by tag name.
13
+ */
14
+ import type { ReactNode } from "react";
15
+ /**
16
+ * Render TeX source to React elements through KaTeX.
17
+ * @param value - The TeX source (a math node's raw content).
18
+ * @param displayMode - Display (block) versus inline rendering.
19
+ * @returns KaTeX's element tree, or the error span when the source does not
20
+ * parse even under `strict: 'ignore'`.
21
+ */
22
+ export declare function renderTexToReact(value: string, displayMode: boolean): ReactNode;
23
+ //# sourceMappingURL=math.d.ts.map
@@ -7,7 +7,8 @@ import { type MarkdownSourceContext } from "./source-chip.js";
7
7
  * instead of a plain link or code token.
8
8
  * @param text - Assistant-authored markdown.
9
9
  * @param context - Source resolution handed down by the owning message.
10
- * @returns The document's blocks.
10
+ * @returns The document's blocks, plus the footnote section when the document
11
+ * references a defined footnote.
11
12
  */
12
13
  export declare function renderMarkdown(text: string, context: MarkdownSourceContext): ReactNode[];
13
14
  //# sourceMappingURL=render.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import type { SessionFace } from "@deepseek-ai/dsh-api-session-controller/client";
2
2
  import type { ConversationSnapshot } from "@deepseek-ai/dsh-client-ui-conversation/client";
3
- import type { QaPendingApproval, QaPendingQuestion, QaSessionState, QaSubagentView, QaTurnSources, ResolvedQaSurfaceConfig } from "../types.js";
3
+ import type { QaPendingApproval, QaPendingQuestion, QaSessionState, QaSlashView, QaSubagentView, QaTurnSources, ResolvedQaSurfaceConfig } from "../types.js";
4
4
  /** Everything the bound-chat projection reads; the computation is pure. */
5
5
  export interface QaBoundProjectionInput {
6
6
  readonly connected: boolean;
@@ -23,6 +23,8 @@ export interface QaBoundProjectionInput {
23
23
  readonly admissionPending: boolean;
24
24
  readonly chatsRevision: number;
25
25
  readonly viewingSubagent: QaSubagentView | null;
26
+ /** Slash catalog state of this chat; the controller owns its lifetime. */
27
+ readonly slash: QaSlashView;
26
28
  readonly config: ResolvedQaSurfaceConfig;
27
29
  /**
28
30
  * The chat's subagent display names keyed by session id, read from the
@@ -1,5 +1,5 @@
1
1
  import type { SessionFace } from "@deepseek-ai/dsh-api-session-controller/client";
2
- import type { QaAttachmentDraft, QaFileDraft } from "../types.js";
2
+ import type { QaAttachmentDraft, QaFileDraft, QaSlashSubmitAttachment } from "../types.js";
3
3
  import type { QaFileUpload, QaPromptContent } from "./types.js";
4
4
  /**
5
5
  * Stage every pending file on the Host and collect the receipts the prompt
@@ -26,5 +26,13 @@ export declare function stageQaFiles(service: QaFileUpload | undefined, session:
26
26
  * staging failed elsewhere) degrades to an empty receipt rather than
27
27
  * dropping the attachment.
28
28
  */
29
+ /**
30
+ * The same two shapes for a human command, which admits attachments through
31
+ * the shared store rather than through the prompt: an image rides encoded, a
32
+ * file rides the receipt its staging minted. An attachment whose staging
33
+ * failed is dropped instead of being sent as an empty receipt — the command
34
+ * would otherwise read a handle that resolves to nothing.
35
+ */
36
+ export declare function buildQaSlashAttachments(attachments: readonly QaAttachmentDraft[], receipts: ReadonlyMap<string, string>): readonly QaSlashSubmitAttachment[];
29
37
  export declare function buildQaPromptContent(prompt: string, attachments: readonly QaAttachmentDraft[], receipts: ReadonlyMap<string, string>): QaPromptContent;
30
38
  //# sourceMappingURL=prompt-content.d.ts.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Model notes: the ambient plugin messages the injector writes into a QA chat
3
+ * (who the user is, the source-provenance rules, delegation naming). Each note
4
+ * has a switch and an optional wording override; an empty template keeps the
5
+ * built-in text, so the fields double as a wording editor and a mute switch.
6
+ */
7
+ import { type ConfigProps } from "./common.js";
8
+ /** The ambient notes the Host writes into QA chats as hidden user messages. */
9
+ export declare function NotesSection(props: ConfigProps): import("react/jsx-runtime").JSX.Element;
10
+ //# sourceMappingURL=notes.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Slash interface: the master switch, the two admission policies and the
3
+ * palette itself.
4
+ *
5
+ * The allow lists stay name-based, which is what the deployment config stores
6
+ * — an operator writes `generate-tkp`, never an id. They are plain lists
7
+ * rather than checkboxes over a discovered catalog because the two halves are
8
+ * discovered differently and only one of them can be enumerated here at all:
9
+ * skills are a registry lookup, while a command is only resolvable against a
10
+ * live chat's agent, so this card could not honestly offer a fixed list of
11
+ * command names to tick.
12
+ */
13
+ import { type ConfigProps } from "./common.js";
14
+ /** Master switch, per-kind admission policy and palette presentation. */
15
+ export declare function SlashSection(props: ConfigProps): import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=slash.d.ts.map
@@ -18,7 +18,9 @@ export { BrandingSection } from "./sections/branding.js";
18
18
  export { EmbeddingSection } from "./sections/embedding.js";
19
19
  export { InterfaceSection } from "./sections/interface.js";
20
20
  export { LockdownSection } from "./sections/lockdown.js";
21
+ export { NotesSection } from "./sections/notes.js";
21
22
  export { SessionSection } from "./sections/session.js";
23
+ export { SlashSection } from "./sections/slash.js";
22
24
  export { SourcesSection } from "./sections/sources.js";
23
25
  export { StatusSection } from "./sections/status.js";
24
26
  export type { StatusProps } from "./sections/status.js";
@@ -13,7 +13,10 @@ export declare function parseSettlement(text: string): SettledSubagent | undefin
13
13
  export interface SettlementView {
14
14
  readonly title: string;
15
15
  readonly body: string;
16
- /** Muted correlation line above the body; absent when the title says it all. */
16
+ /**
17
+ * Muted correlation lines above the body, one fact per line; absent when
18
+ * the title says it all.
19
+ */
17
20
  readonly meta?: string;
18
21
  }
19
22
  /**
@@ -0,0 +1,24 @@
1
+ import type { QaSlashCatalogEntry, QaSlashCommandSurface, QaSlashView } from "../../types.js";
2
+ export interface QaSlashPaletteProps {
3
+ readonly rows: readonly QaSlashCatalogEntry[];
4
+ readonly activeId: string | null;
5
+ readonly state: QaSlashView["state"];
6
+ readonly error: string | null;
7
+ readonly commandSurface: QaSlashCommandSurface;
8
+ readonly showDescriptions: boolean;
9
+ readonly showKindBadge: boolean;
10
+ readonly idPrefix: string;
11
+ readonly onHover: (index: number) => void;
12
+ readonly onPick: (entry: QaSlashCatalogEntry) => void;
13
+ }
14
+ /**
15
+ * The palette itself: a listbox over rows the composer has already filtered
16
+ * and ranked. It owns no state — an empty list means "nothing matches", and
17
+ * the surface line says why when the catalog could not be read at all.
18
+ *
19
+ * Options are picked on `click` and never take focus (`onMouseDown` prevents
20
+ * the default) so the caret stays in the textarea: the keyboard keeps working
21
+ * straight after a click, and Escape still closes what the mouse opened.
22
+ */
23
+ export declare const QaSlashPalette: import("react").MemoExoticComponent<(props: QaSlashPaletteProps) => import("react/jsx-runtime").JSX.Element>;
24
+ //# sourceMappingURL=SlashPalette.d.ts.map
@@ -0,0 +1,30 @@
1
+ import type { QaSlashCatalogEntry, QaSlashExecution } from "../../types.js";
2
+ import type { QaSlashRoute } from "./slash-router.js";
3
+ /**
4
+ * The user-facing copy of every slash decision. One module because these
5
+ * strings are the whole interface between a refusal and the person reading it:
6
+ * a refusal that does not say what to do next is indistinguishable from a bug.
7
+ */
8
+ /** The refusal that predates the feature; unchanged, so nothing regresses. */
9
+ export declare const SLASH_DISABLED_COPY = "\u041A\u043E\u043C\u0430\u043D\u0434\u044B \u0441\u043E \u0441\u043B\u0435\u0448\u0435\u043C \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B \u0432 \u0440\u0435\u0436\u0438\u043C\u0435 \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A\u0430.";
10
+ export declare function slashRefusalCopy(route: Extract<QaSlashRoute, {
11
+ kind: "unknown" | "ambiguous" | "unavailable";
12
+ }>): string;
13
+ /**
14
+ * A gesture inside an ordinary prompt that this deployment withholds. Stated
15
+ * as a fact about the deployment, not as a fault of the message, because the
16
+ * message itself is fine — it is one word of it that will not take effect.
17
+ */
18
+ export declare function slashWithheldCopy(names: readonly string[]): string;
19
+ export declare function slashExecuteFailureCopy(entry: QaSlashCatalogEntry): string;
20
+ /** Copy for a refusal the Host decided, keyed by its reason. */
21
+ export declare function slashHostRefusalCopy(refusal: Extract<QaSlashExecution, {
22
+ kind: "refused";
23
+ }>): string;
24
+ /**
25
+ * Attachments the chosen command refuses. Checked before dispatch so the
26
+ * composer keeps the draft and the files; the Host checks it again and stays
27
+ * the authority.
28
+ */
29
+ export declare function slashAttachmentsCopy(entry: QaSlashCatalogEntry): string;
30
+ //# sourceMappingURL=copy.d.ts.map