@yadsh/dsh-qa-surface 0.15.7 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/README.md +8 -0
  2. package/lib/access/capability-catalog.js +11 -4
  3. package/lib/access/capability-catalog.js.map +1 -1
  4. package/lib/access/service.js +46 -5
  5. package/lib/access/service.js.map +1 -1
  6. package/lib/accounts/store.js +2 -2
  7. package/lib/accounts/store.js.map +1 -1
  8. package/lib/admin/service.js +4 -2
  9. package/lib/admin/service.js.map +1 -1
  10. package/lib/admin/session-log.js +3 -0
  11. package/lib/admin/session-log.js.map +1 -1
  12. package/lib/agent-scope.js +9 -0
  13. package/lib/agent-scope.js.map +1 -0
  14. package/lib/chat-sharing/native-fence.js +111 -0
  15. package/lib/chat-sharing/native-fence.js.map +1 -0
  16. package/lib/chat-sharing/resources.js +57 -0
  17. package/lib/chat-sharing/resources.js.map +1 -0
  18. package/lib/chat-sharing/store.js +193 -0
  19. package/lib/chat-sharing/store.js.map +1 -0
  20. package/lib/chat-sharing/transport.js +274 -0
  21. package/lib/chat-sharing/transport.js.map +1 -0
  22. package/lib/chat-sharing/turn-guard.js +154 -0
  23. package/lib/chat-sharing/turn-guard.js.map +1 -0
  24. package/lib/chat-sharing/types.js +2 -0
  25. package/lib/chat-sharing/types.js.map +1 -0
  26. package/lib/chat-sharing/uploads.js +55 -0
  27. package/lib/chat-sharing/uploads.js.map +1 -0
  28. package/lib/client/QaAccountsController.js +29 -2
  29. package/lib/client/QaAccountsController.js.map +1 -1
  30. package/lib/client/QaConfigController.js +7 -12
  31. package/lib/client/QaConfigController.js.map +1 -1
  32. package/lib/client/QaSessionController.js +186 -19
  33. package/lib/client/QaSessionController.js.map +1 -1
  34. package/lib/client/QaSurface.js +110 -9
  35. package/lib/client/QaSurface.js.map +1 -1
  36. package/lib/client/QaSurfaceGuard.js +6 -1
  37. package/lib/client/QaSurfaceGuard.js.map +1 -1
  38. package/lib/client/QaTranscriptAdapter.js +13 -3
  39. package/lib/client/QaTranscriptAdapter.js.map +1 -1
  40. package/lib/client/account-conversation.js +33 -0
  41. package/lib/client/account-conversation.js.map +1 -0
  42. package/lib/client/account-sessions.js +106 -0
  43. package/lib/client/account-sessions.js.map +1 -0
  44. package/lib/client/account-upload.js +30 -0
  45. package/lib/client/account-upload.js.map +1 -0
  46. package/lib/client/chat-artifacts.js +17 -3
  47. package/lib/client/chat-artifacts.js.map +1 -1
  48. package/lib/client/chat-sharing-api.js +2 -0
  49. package/lib/client/chat-sharing-api.js.map +1 -0
  50. package/lib/client/components/QaChangelog.js +57 -3
  51. package/lib/client/components/QaChangelog.js.map +1 -1
  52. package/lib/client/components/QaChatSharing.js +92 -0
  53. package/lib/client/components/QaChatSharing.js.map +1 -0
  54. package/lib/client/components/QaComposer.js +8 -4
  55. package/lib/client/components/QaComposer.js.map +1 -1
  56. package/lib/client/components/QaFileAttachment.js +12 -3
  57. package/lib/client/components/QaFileAttachment.js.map +1 -1
  58. package/lib/client/components/QaFilesPanel.js +11 -4
  59. package/lib/client/components/QaFilesPanel.js.map +1 -1
  60. package/lib/client/components/QaHeader.js +3 -3
  61. package/lib/client/components/QaHeader.js.map +1 -1
  62. package/lib/client/components/QaMessage.js +34 -9
  63. package/lib/client/components/QaMessage.js.map +1 -1
  64. package/lib/client/components/QaSidebar.js +1 -1
  65. package/lib/client/components/QaSidebar.js.map +1 -1
  66. package/lib/client/components/QaSourcesPanel.js +12 -4
  67. package/lib/client/components/QaSourcesPanel.js.map +1 -1
  68. package/lib/client/components/QaWorkspaceBrowser.js +28 -7
  69. package/lib/client/components/QaWorkspaceBrowser.js.map +1 -1
  70. package/lib/client/components/source-refs.js +42 -23
  71. package/lib/client/components/source-refs.js.map +1 -1
  72. package/lib/client/index.js +60 -6
  73. package/lib/client/index.js.map +1 -1
  74. package/lib/client/lineage.js +4 -3
  75. package/lib/client/lineage.js.map +1 -1
  76. package/lib/client/markdown/katex-css.js +1 -1
  77. package/lib/client/markdown/render.js +3 -4
  78. package/lib/client/markdown/render.js.map +1 -1
  79. package/lib/client/markdown/source-chip.js +4 -1
  80. package/lib/client/markdown/source-chip.js.map +1 -1
  81. package/lib/client/notifications/notification-dispatcher.js +50 -11
  82. package/lib/client/notifications/notification-dispatcher.js.map +1 -1
  83. package/lib/client/notifications/use-turn-notifications.js +107 -18
  84. package/lib/client/notifications/use-turn-notifications.js.map +1 -1
  85. package/lib/client/project-session-state.js +28 -13
  86. package/lib/client/project-session-state.js.map +1 -1
  87. package/lib/client/session-admission.js +9 -1
  88. package/lib/client/session-admission.js.map +1 -1
  89. package/lib/client/session-sources.js +44 -3
  90. package/lib/client/session-sources.js.map +1 -1
  91. package/lib/client/slash/useSlashNavigation.js +8 -5
  92. package/lib/client/slash/useSlashNavigation.js.map +1 -1
  93. package/lib/client/source-preview.js +1 -1
  94. package/lib/client/source-preview.js.map +1 -1
  95. package/lib/client/styles.js +9 -2
  96. package/lib/client/styles.js.map +1 -1
  97. package/lib/client/turn-sources.js +2 -1
  98. package/lib/client/turn-sources.js.map +1 -1
  99. package/lib/client/types.js.map +1 -1
  100. package/lib/client/workspace-download.js +42 -2
  101. package/lib/client/workspace-download.js.map +1 -1
  102. package/lib/client.js +3329 -947
  103. package/lib/client.js.map +1 -1
  104. package/lib/enforcement/skill-policy.js +29 -4
  105. package/lib/enforcement/skill-policy.js.map +1 -1
  106. package/lib/enforcement/skill-resource-paths.js +32 -0
  107. package/lib/enforcement/skill-resource-paths.js.map +1 -0
  108. package/lib/enforcement/structured-result.js +38 -0
  109. package/lib/enforcement/structured-result.js.map +1 -0
  110. package/lib/enforcement/tool-grants.js +3 -1
  111. package/lib/enforcement/tool-grants.js.map +1 -1
  112. package/lib/index.js +397 -14
  113. package/lib/index.js.map +1 -1
  114. package/lib/prompt-notes.js +18 -1
  115. package/lib/prompt-notes.js.map +1 -1
  116. package/lib/provenance/collector.js +13 -1
  117. package/lib/provenance/collector.js.map +1 -1
  118. package/lib/provenance/connectors.js +32 -8
  119. package/lib/provenance/connectors.js.map +1 -1
  120. package/lib/provenance/dedupe.js +8 -1
  121. package/lib/provenance/dedupe.js.map +1 -1
  122. package/lib/provenance/document-preview.js +19 -1
  123. package/lib/provenance/document-preview.js.map +1 -1
  124. package/lib/provenance/extractors.js +67 -1
  125. package/lib/provenance/extractors.js.map +1 -1
  126. package/lib/provenance/file-download.js +56 -0
  127. package/lib/provenance/file-download.js.map +1 -0
  128. package/lib/provenance/file-preview.js +12 -1
  129. package/lib/provenance/file-preview.js.map +1 -1
  130. package/lib/provenance/host-store.js +59 -10
  131. package/lib/provenance/host-store.js.map +1 -1
  132. package/lib/provenance/integration-extractor.js +63 -0
  133. package/lib/provenance/integration-extractor.js.map +1 -0
  134. package/lib/qa-tools/docs-tools.js +14 -0
  135. package/lib/qa-tools/docs-tools.js.map +1 -1
  136. package/lib/secure-session.js +9 -3
  137. package/lib/secure-session.js.map +1 -1
  138. package/lib/session-fork-host.js +157 -0
  139. package/lib/session-fork-host.js.map +1 -0
  140. package/lib/session-fork.js +34 -0
  141. package/lib/session-fork.js.map +1 -0
  142. package/lib/session-ownership.js +5 -1
  143. package/lib/session-ownership.js.map +1 -1
  144. package/lib/shared/session-lineage.js +6 -0
  145. package/lib/shared/session-lineage.js.map +1 -0
  146. package/lib/slash/draft-target.js +21 -0
  147. package/lib/slash/draft-target.js.map +1 -0
  148. package/lib/slash/remotes.js +39 -4
  149. package/lib/slash/remotes.js.map +1 -1
  150. package/lib/typert.host.js +1633 -236
  151. package/lib/typert.remote-client.d.ts +48 -1
  152. package/lib/typert.remote-client.js +1477 -234
  153. package/lib/types/access/capability-catalog.d.ts +1 -1
  154. package/lib/types/access/service.d.ts +7 -0
  155. package/lib/types/access.js +2 -0
  156. package/lib/types/access.js.map +1 -0
  157. package/lib/types/accounts/store.d.ts +1 -1
  158. package/lib/types/accounts.js +2 -0
  159. package/lib/types/accounts.js.map +1 -0
  160. package/lib/types/admin/session-log.d.ts +2 -0
  161. package/lib/types/admin.js +2 -0
  162. package/lib/types/admin.js.map +1 -0
  163. package/lib/types/agent-scope.d.ts +4 -0
  164. package/lib/types/capability.js +2 -0
  165. package/lib/types/capability.js.map +1 -0
  166. package/lib/types/chat-sharing/native-fence.d.ts +11 -0
  167. package/lib/types/chat-sharing/resources.d.ts +5 -0
  168. package/lib/types/chat-sharing/store.d.ts +28 -0
  169. package/lib/types/chat-sharing/transport.d.ts +31 -0
  170. package/lib/types/chat-sharing/turn-guard.d.ts +21 -0
  171. package/lib/types/chat-sharing/types.d.ts +25 -0
  172. package/lib/types/chat-sharing/uploads.d.ts +5 -0
  173. package/lib/types/client/QaAccountsController.d.ts +3 -0
  174. package/lib/types/client/QaConfigController.d.ts +3 -2
  175. package/lib/types/client/QaSessionController.d.ts +17 -3
  176. package/lib/types/client/QaSurface.d.ts +6 -1
  177. package/lib/types/client/account-conversation.d.ts +6 -0
  178. package/lib/types/client/account-sessions.d.ts +7 -0
  179. package/lib/types/client/account-upload.d.ts +15 -0
  180. package/lib/types/client/chat-sharing-api.d.ts +35 -0
  181. package/lib/types/client/components/QaChatSharing.d.ts +10 -0
  182. package/lib/types/client/components/QaComposer.d.ts +2 -0
  183. package/lib/types/client/components/QaFileAttachment.d.ts +3 -2
  184. package/lib/types/client/components/QaFilesPanel.d.ts +4 -1
  185. package/lib/types/client/components/QaMessage.d.ts +5 -2
  186. package/lib/types/client/components/QaWorkspaceBrowser.d.ts +8 -1
  187. package/lib/types/client/components/source-refs.d.ts +1 -0
  188. package/lib/types/client/lineage.d.ts +2 -2
  189. package/lib/types/client/notifications/notification-dispatcher.d.ts +10 -6
  190. package/lib/types/client/notifications/use-turn-notifications.d.ts +4 -0
  191. package/lib/types/client/project-session-state.d.ts +1 -0
  192. package/lib/types/client/session-admission.d.ts +2 -0
  193. package/lib/types/client/session-sources.d.ts +1 -0
  194. package/lib/types/client/turn-sources.d.ts +1 -1
  195. package/lib/types/client/types.d.ts +8 -1
  196. package/lib/types/client/workspace-download.d.ts +9 -1
  197. package/lib/types/config.js +2 -0
  198. package/lib/types/config.js.map +1 -0
  199. package/lib/types/documents.js +2 -0
  200. package/lib/types/documents.js.map +1 -0
  201. package/lib/types/enforcement/skill-resource-paths.d.ts +5 -0
  202. package/lib/types/enforcement/structured-result.d.ts +11 -0
  203. package/lib/types/expert-memory.js +2 -0
  204. package/lib/types/expert-memory.js.map +1 -0
  205. package/lib/types/index.d.ts +35 -1
  206. package/lib/types/policy.js +2 -0
  207. package/lib/types/policy.js.map +1 -0
  208. package/lib/types/prompt-notes.d.ts +2 -0
  209. package/lib/types/provenance/connectors.d.ts +4 -1
  210. package/lib/types/provenance/document-preview.d.ts +2 -0
  211. package/lib/types/provenance/extractors.d.ts +2 -0
  212. package/lib/types/provenance/file-download.d.ts +10 -0
  213. package/lib/types/provenance/host-store.d.ts +2 -0
  214. package/lib/types/provenance/integration-extractor.d.ts +5 -0
  215. package/lib/types/provenance/types.d.ts +2 -0
  216. package/lib/types/qa-tools/docs-tools.d.ts +2 -0
  217. package/lib/types/quality.js +7 -0
  218. package/lib/types/quality.js.map +1 -0
  219. package/lib/types/session-fork-host.d.ts +27 -0
  220. package/lib/types/session-fork.d.ts +7 -0
  221. package/lib/types/session.js +2 -0
  222. package/lib/types/session.js.map +1 -0
  223. package/lib/types/shared/session-lineage.d.ts +7 -0
  224. package/lib/types/skills.js +2 -0
  225. package/lib/types/skills.js.map +1 -0
  226. package/lib/types/slash/draft-target.d.ts +7 -0
  227. package/lib/types/slash/remotes.d.ts +7 -0
  228. package/lib/types/slash.js +2 -0
  229. package/lib/types/slash.js.map +1 -0
  230. package/lib/types/types/access.d.ts +43 -0
  231. package/lib/types/types/accounts.d.ts +173 -0
  232. package/lib/types/types/admin.d.ts +286 -0
  233. package/lib/types/types/capability.d.ts +230 -0
  234. package/lib/types/types/config.d.ts +594 -0
  235. package/lib/types/types/documents.d.ts +34 -0
  236. package/lib/types/types/expert-memory.d.ts +35 -0
  237. package/lib/types/types/policy.d.ts +54 -0
  238. package/lib/types/types/quality.d.ts +100 -0
  239. package/lib/types/types/session.d.ts +382 -0
  240. package/lib/types/types/skills.d.ts +143 -0
  241. package/lib/types/types/slash.d.ts +159 -0
  242. package/lib/types/types.d.ts +13 -2180
  243. package/package.json +8 -7
@@ -0,0 +1,54 @@
1
+ export type QaSessionPolicy = "browser-persistent" | "new-on-load" | "fixed";
2
+ export type QaSandboxMode = "read-only" | "workspace-write";
3
+ export type QaApprovalPolicy = "never";
4
+ export type QaToolPolicyMode = "allow-list";
5
+ /**
6
+ * How the QA tool catalog is attached. `all` attaches the whole catalog once
7
+ * the activation skill loads; the field is reserved so a future grouped or
8
+ * searched mode needs no config redesign.
9
+ */
10
+ export type QaToolActivationMode = "all";
11
+ /**
12
+ * How a tool policy `ask` resolves on an attested QA agent. `blocked` refuses
13
+ * the call with the surface's own reason; `interactive` parks it until the
14
+ * operator answers in the QA view.
15
+ */
16
+ export type QaApprovalInteraction = "blocked" | "interactive";
17
+ /**
18
+ * How a user-questions request resolves on an attested QA agent. `unsupported`
19
+ * refuses the ask outright; `interactive` answers it from the QA view.
20
+ */
21
+ export type QaQuestionInteraction = "unsupported" | "interactive";
22
+ /**
23
+ * What a deployment may write for the question seam. `enabled` is accepted as
24
+ * the spelling of `interactive` a feature request asked for; the resolved
25
+ * config carries one name only.
26
+ */
27
+ export type QaQuestionInteractionInput = QaQuestionInteraction | "enabled";
28
+ /** The operator's answer to one parked tool call. */
29
+ export type QaApprovalDecision = "allowed-once" | "rejected";
30
+ /** One answered question; `custom` is free text, and may accompany `selected`. */
31
+ export interface QaQuestionAnswerItem {
32
+ readonly id: string;
33
+ readonly selected: readonly string[];
34
+ readonly custom?: string;
35
+ }
36
+ /**
37
+ * Authorization inside QA Surface. It is deliberately independent of a QA
38
+ * subrole: an admin may work as any analyst profile while still holding the
39
+ * administrative permissions, and a reviewer answers conversations without
40
+ * being able to manage accounts.
41
+ */
42
+ export type QaAccountRole = "user" | "reviewer" | "admin";
43
+ /** Administrative permissions a role grants; see `admin/permissions.ts`. */
44
+ export type QaPermission = "users.read" | "users.manage" | "roles.read" | "roles.manage" | "conversations.read.all" | "conversations.read.own" | "conversations.delete" | "reviews.read" | "reviews.write" | "analytics.read" | "audit.read" | "settings.manage"
45
+ /** Write access to skill files, personal and deployment-wide. */
46
+ | "skills.manage"
47
+ /**
48
+ * What the domain experts wrote into their durable memory. Reading is split
49
+ * from correcting because a reviewer is the one who notices a remembered
50
+ * inaccuracy in an answer, and an answer the expert keeps getting wrong is
51
+ * the reviewer's business even though the fix is not.
52
+ */
53
+ | "memory.read" | "memory.manage";
54
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1,100 @@
1
+ /** A user's verdict on one assistant message. Binary by design. */
2
+ export type QaFeedbackRating = "positive" | "negative";
3
+ /**
4
+ * Optional negative-feedback reasons. The list is short on purpose: asking for
5
+ * a precise cause at rating time costs more answers than it buys insight, and
6
+ * a reviewer classifies the hard cases afterwards.
7
+ */
8
+ export type QaFeedbackReason = "incorrect" | "instruction_not_followed" | "missing_information" | "outdated_information" | "tool_issue" | "too_verbose" | "too_short" | "other";
9
+ /** One user's rating of one assistant message. */
10
+ export interface QaMessageFeedback {
11
+ readonly id: string;
12
+ readonly conversationId: string;
13
+ readonly messageId: string;
14
+ readonly userId: string;
15
+ readonly rating: QaFeedbackRating;
16
+ readonly reasons?: readonly QaFeedbackReason[];
17
+ readonly comment?: string;
18
+ readonly createdAt: string;
19
+ readonly updatedAt?: string;
20
+ }
21
+ /** The rating fields a browser may write; identity and time are Host-owned. */
22
+ export interface QaMessageFeedbackInput {
23
+ readonly rating: QaFeedbackRating;
24
+ readonly reasons?: readonly QaFeedbackReason[];
25
+ readonly comment?: string;
26
+ }
27
+ /**
28
+ * One rating a browser still holds locally: a verdict given while the surface
29
+ * had no way to file it, replayed by the harvest. Reasons never ride along —
30
+ * the browser's map only ever stored the thumbs.
31
+ */
32
+ export interface QaFeedbackHarvestEntry {
33
+ readonly conversationId: string;
34
+ /** The durable log position, exactly as a live rating carries it. */
35
+ readonly messageId: string;
36
+ readonly rating: QaFeedbackRating;
37
+ }
38
+ /** What one harvest write did; the counts answer for the whole batch. */
39
+ export interface QaFeedbackHarvestResult {
40
+ /** Ratings the Host stored now. Replaying the same batch stores none. */
41
+ readonly recorded: number;
42
+ /** Entries the Host already held a rating for, left as they were. */
43
+ readonly present: number;
44
+ /** Entries refused: not the caller's conversation, or unusable. */
45
+ readonly rejected: number;
46
+ }
47
+ /** Review workflow state of a conversation or one of its messages. */
48
+ export type QaReviewStatus = "unreviewed" | "in_review" | "reviewed" | "needs_followup";
49
+ /**
50
+ * Reviewer taxonomy, grouped the way the spec groups it. Issue ids stay flat so
51
+ * aggregations never depend on walking a tree in the browser.
52
+ */
53
+ export type QaQualityIssueType = "answer.incorrect" | "answer.incomplete" | "answer.hallucination" | "answer.request_not_followed" | "answer.poor_formatting" | "answer.communication" | "context.missing_conversation" | "context.missing_knowledge" | "context.outdated_knowledge" | "tool.wrong_selection" | "tool.should_have_been_used" | "tool.bad_arguments" | "tool.failure" | "tool.unavailable" | "skill.missing" | "skill.wrong" | "skill.not_followed" | "skill.prompt_policy" | "access.missing_capability" | "access.excessive_capability" | "other";
54
+ export type QaQualitySeverity = "minor" | "major" | "critical";
55
+ /** Where a reviewer thinks the fix belongs; the loop's change target. */
56
+ export type QaRemediationTarget = "prompt" | "skill" | "tool" | "knowledge" | "role" | "model" | "product_ux" | "user_misunderstanding" | "unknown";
57
+ /** One reviewer result. `needs_followup` keeps the item in the queue. */
58
+ export interface QaConversationReview {
59
+ readonly id: string;
60
+ readonly conversationId: string;
61
+ readonly messageId?: string;
62
+ readonly reviewerId: string;
63
+ readonly status: "reviewed" | "needs_followup";
64
+ readonly issues: readonly QaQualityIssueType[];
65
+ readonly severity: QaQualitySeverity;
66
+ readonly notes?: string;
67
+ readonly target?: QaRemediationTarget;
68
+ readonly suggestedAction?: string;
69
+ readonly createdAt: string;
70
+ readonly updatedAt?: string;
71
+ }
72
+ /** A reviewer's write; ids, author and first-seen time are Host-owned. */
73
+ export interface QaConversationReviewInput {
74
+ readonly conversationId: string;
75
+ readonly messageId?: string;
76
+ readonly status: "reviewed" | "needs_followup";
77
+ readonly issues: readonly QaQualityIssueType[];
78
+ readonly severity: QaQualitySeverity;
79
+ readonly notes?: string;
80
+ readonly target?: QaRemediationTarget;
81
+ readonly suggestedAction?: string;
82
+ }
83
+ /** Why a conversation entered the review queue. */
84
+ export type QaReviewReason = "negative_feedback" | "manual" | "tool_failure" | "automatic";
85
+ export type QaReviewPriority = "low" | "normal" | "high";
86
+ /** One queue row: a conversation needing attention, with its derived state. */
87
+ export interface QaReviewQueueItem {
88
+ readonly conversationId: string;
89
+ readonly messageId?: string;
90
+ readonly reason: QaReviewReason;
91
+ readonly priority: QaReviewPriority;
92
+ readonly status: QaReviewStatus;
93
+ readonly assignedReviewerId?: string;
94
+ /** ISO time of the signal that put the item in the queue. */
95
+ readonly raisedAt: string;
96
+ readonly reviewerId?: string;
97
+ readonly reviewId?: string;
98
+ readonly feedbackId?: string;
99
+ }
100
+ //# sourceMappingURL=quality.d.ts.map
@@ -0,0 +1,382 @@
1
+ import type { QaTurnSources } from "../provenance/types.js";
2
+ import type { QaArtifactView } from "./documents.js";
3
+ import type { QaCommandActivity, QaSlashView } from "./slash.js";
4
+ export interface QaSourceFilePreview {
5
+ readonly path: string;
6
+ readonly content: string;
7
+ readonly size: number;
8
+ readonly truncated: boolean;
9
+ readonly markdown: boolean;
10
+ readonly renderableMarkdown: boolean;
11
+ readonly document?: QaDocumentPreview;
12
+ }
13
+ /**
14
+ * A file the panel renders by conversion rather than by bytes: the document
15
+ * pipeline turned a Word file into PDF, and the browser shows that PDF.
16
+ */
17
+ export interface QaDocumentPreview {
18
+ readonly kind: "pdf";
19
+ readonly base64: string;
20
+ readonly mime: "application/pdf";
21
+ readonly name: string;
22
+ readonly bytes: number;
23
+ }
24
+ /** One directory entry of a chat's own workspace, as the files panel browses it. */
25
+ export interface QaWorkspaceEntry {
26
+ readonly name: string;
27
+ readonly type: "file" | "directory";
28
+ readonly size: number | null;
29
+ }
30
+ /**
31
+ * One directory of the chat's workspace. `path` is the canonical form of the
32
+ * directory as requested — the chat root itself is the empty string — so the
33
+ * panel can build a breadcrumb without another round trip.
34
+ */
35
+ export interface QaWorkspaceListing {
36
+ readonly path: string;
37
+ readonly entries: readonly QaWorkspaceEntry[];
38
+ /** More children existed than one listing carries. */
39
+ readonly truncated: boolean;
40
+ }
41
+ /**
42
+ * One file of the chat's workspace: decoded text when it reads as UTF-8, base64
43
+ * bytes when it does not. The panel needs both — documents the agent produced
44
+ * are binary, while notes and transcripts preview as text.
45
+ */
46
+ export interface QaWorkspaceFileChunk {
47
+ readonly path: string;
48
+ readonly size: number;
49
+ readonly offset: number;
50
+ readonly version: string;
51
+ readonly base64: string;
52
+ readonly done: boolean;
53
+ }
54
+ export interface QaWorkspaceFile {
55
+ readonly path: string;
56
+ readonly size: number;
57
+ readonly truncated: boolean;
58
+ readonly markdown: boolean;
59
+ readonly renderableMarkdown: boolean;
60
+ readonly mime: string;
61
+ /** Present when the file decoded as text; absent for binary content. */
62
+ readonly text?: string;
63
+ /** Present when the file is not text; base64 of at most the byte cap. */
64
+ readonly base64?: string;
65
+ }
66
+ /** Host-attested facts required before the QA composer may become writable. */
67
+ export interface QaLockdownProof {
68
+ readonly chatAccess?: import("../chat-sharing/types.js").QaChatAccess;
69
+ readonly sessionId: string;
70
+ /** Last inherited event in an ordinary fork; absent on an original chat. */
71
+ readonly inheritedThroughSeq?: number;
72
+ readonly enabled: boolean;
73
+ readonly agentPresetMatches: boolean;
74
+ readonly workspaceMatches: boolean;
75
+ readonly modelMatches: boolean;
76
+ readonly sandboxModeMatches: boolean;
77
+ readonly approvalIsNever: boolean;
78
+ readonly permissionPreset: string;
79
+ readonly toolPolicyLoaded: boolean;
80
+ readonly toolAllowList: readonly string[];
81
+ }
82
+ export interface QaUserMessage {
83
+ readonly id: string;
84
+ readonly role: "user";
85
+ readonly text: string;
86
+ /** `pending` is a browser-only optimistic row until the Host emits it. */
87
+ readonly status: "pending" | "committed";
88
+ readonly timestamp?: number;
89
+ readonly images?: readonly QaImageView[];
90
+ /** Durable files the user attached to this message, in prompt order. */
91
+ readonly files?: readonly QaFileView[];
92
+ /**
93
+ * Chat owner's display name, set only for an admin reading a foreign
94
+ * chat; the owner themself sees their messages unlabeled.
95
+ */
96
+ readonly author?: string;
97
+ }
98
+ /** Browser-only user row shown while the Host prepares the accepted turn. */
99
+ export type QaPendingUserMessage = Omit<QaUserMessage, "status"> & {
100
+ readonly status: "pending";
101
+ };
102
+ export type QaMessage = QaUserMessage | {
103
+ readonly id: string;
104
+ readonly role: "assistant";
105
+ readonly text: string;
106
+ readonly status: "streaming" | "committed" | "failed";
107
+ readonly timestamp?: number;
108
+ /**
109
+ * Position of this answer in the session's durable event log. Feedback is
110
+ * keyed to it: a rating survives a replay, a reload and a role change,
111
+ * while the browser's own message id does not.
112
+ */
113
+ readonly seq?: number;
114
+ /** Final text of a completed turn with a durable fork boundary. */
115
+ readonly forkable?: boolean;
116
+ /** Host turn this answer belongs to; groups regenerations into variants. */
117
+ readonly turn?: number;
118
+ /**
119
+ * Files this turn produced, in the order the tools reported them. The
120
+ * answer is the place a produced document is handed over: without these
121
+ * cards the file exists only as a path in a paragraph, and a reader who
122
+ * does not know the files tab concludes nothing was made.
123
+ */
124
+ readonly artifacts?: readonly QaArtifactView[];
125
+ /** Canonical evidence snapshot shared with this answer's source drawer. */
126
+ readonly sources?: readonly QaSource[];
127
+ readonly sourcesComplete?: boolean;
128
+ readonly incompleteSourceOrigins?: QaTurnSources["incompleteOrigins"];
129
+ /** Host-recorded response timing, present on finalized messages only. */
130
+ readonly stats?: {
131
+ /** step start → final message. */
132
+ readonly durationMs: number;
133
+ /** step start → first token; null when no token delta was recorded. */
134
+ readonly ttftMs: number | null;
135
+ /** Estimated from visible text (≈4 chars/token) over the generation window. */
136
+ readonly tokensPerSecond: number | null;
137
+ };
138
+ } | {
139
+ readonly id: string;
140
+ readonly role: "system";
141
+ readonly text: string;
142
+ readonly status: "info" | "error";
143
+ readonly timestamp?: number;
144
+ /**
145
+ * Set on a human command row. Commands stay out of the model
146
+ * conversation, so this projection is the only trace the user sees.
147
+ */
148
+ readonly command?: QaCommandActivity;
149
+ /** Collapsible settlement row (subagent finished/stopped/failed). */
150
+ readonly notice?: {
151
+ readonly title: string;
152
+ readonly body: string;
153
+ /** Muted correlation line above the body (task name, session id). */
154
+ readonly meta?: string;
155
+ };
156
+ } | {
157
+ readonly id: string;
158
+ readonly role: "work";
159
+ readonly turn: number;
160
+ /**
161
+ * "error" marks a turn the host ended with a provider failure; "stopped"
162
+ * marks one the user ended, whose answer is a prefix rather than a reply.
163
+ */
164
+ readonly status: "running" | "complete" | "error" | "stopped";
165
+ readonly startedAt?: number;
166
+ readonly endedAt?: number;
167
+ readonly items: readonly QaWorkItem[];
168
+ };
169
+ export type QaWorkItem = {
170
+ readonly id: string;
171
+ readonly kind: "reasoning" | "progress";
172
+ readonly text: string;
173
+ readonly status: "running" | "complete";
174
+ } | {
175
+ readonly id: string;
176
+ readonly kind: "tool";
177
+ readonly name: string;
178
+ readonly label: string;
179
+ readonly summary: string;
180
+ readonly input: string | null;
181
+ readonly output: string | null;
182
+ readonly status: "running" | "ok" | "error" | "stopped";
183
+ /** Durable child id, present on subagent launch calls that started one. */
184
+ readonly subagentId?: string;
185
+ readonly startedAt?: number;
186
+ readonly endedAt?: number;
187
+ };
188
+ export type QaSessionPhase = "idle" | "creating" | "ready" | "running" | "reconnecting" | "blocked" | "error";
189
+ /** Transitional UI name; the drawer now consumes the canonical source object. */
190
+ export type QaSource = import("../provenance/types.js").QaSourceReference;
191
+ /** Raster formats the attachment path accepts (mirrors the host contract). */
192
+ export type QaImageMediaType = "image/png" | "image/jpeg" | "image/webp" | "image/gif";
193
+ /** One image pending in the composer, browser-owned until the prompt lands. */
194
+ export interface QaImageDraft {
195
+ readonly kind: "image";
196
+ readonly id: string;
197
+ readonly mediaType: QaImageMediaType;
198
+ readonly name: string;
199
+ /** Canonical base64 of the image bytes, without the data: URL prefix. */
200
+ readonly data: string;
201
+ /** Local object URL for the preview thumbnail. */
202
+ readonly previewUrl: string;
203
+ }
204
+ /**
205
+ * One file pending in the composer. The bytes stay in the browser until the
206
+ * prompt is sent: an image can ride the prompt inline, but a file must be
207
+ * staged through the Host upload route first and then cited by its receipt.
208
+ */
209
+ export interface QaFileDraft {
210
+ readonly kind: "file";
211
+ readonly id: string;
212
+ readonly name: string;
213
+ readonly bytes: number;
214
+ /** Verbatim payload; a pasted blob is a File built from the pasted text. */
215
+ readonly blob: Blob;
216
+ }
217
+ /** Anything the composer may hold before the prompt is sent. */
218
+ export type QaAttachmentDraft = QaImageDraft | QaFileDraft;
219
+ /** A durable image attached to a sent message. */
220
+ export interface QaImageView {
221
+ readonly attachmentId: string;
222
+ readonly mediaType: QaImageMediaType;
223
+ /** Browser-local thumbnail URL, present only on an optimistic message. */
224
+ readonly previewUrl?: string;
225
+ }
226
+ /**
227
+ * A durable file attached to a sent message. The browser never reads these
228
+ * bytes back (the attachment route serves images); the row shows the handle
229
+ * the model resolves, and the Host keeps the verbatim copy.
230
+ */
231
+ export interface QaFileView {
232
+ readonly attachmentId: string;
233
+ readonly name: string;
234
+ readonly bytes: number;
235
+ }
236
+ /** A subagent transcript opened read-only from the agents panel. */
237
+ export interface QaSubagentView {
238
+ readonly id: string;
239
+ readonly title: string;
240
+ }
241
+ /**
242
+ * One tool call waiting for the operator. The browser lists these over its own
243
+ * remote and answers them one by one; nothing here is answered automatically.
244
+ */
245
+ export interface QaPendingApproval {
246
+ readonly id: string;
247
+ /** The chat the request belongs to: a delegated child asks under its root. */
248
+ readonly sessionId: string;
249
+ readonly toolName: string;
250
+ /** The reason the composed gate gave for asking, when it gave one. */
251
+ readonly reason: string | null;
252
+ readonly createdAt: number;
253
+ /** True when a delegated child of the chat made the call. */
254
+ readonly delegated: boolean;
255
+ }
256
+ /**
257
+ * One question waiting for the operator, normalized for the form the QA view
258
+ * renders. The protocol fields are the harness user-questions contract; absent
259
+ * ones become explicit nulls so the browser never branches on undefined.
260
+ */
261
+ export interface QaPendingQuestionItem {
262
+ readonly id: string;
263
+ readonly question: string;
264
+ readonly header: string | null;
265
+ readonly detail: string | null;
266
+ readonly options: readonly QaPendingQuestionOption[];
267
+ readonly multiSelect: boolean;
268
+ }
269
+ export interface QaPendingQuestionOption {
270
+ readonly label: string;
271
+ readonly description: string | null;
272
+ }
273
+ /**
274
+ * One user-questions request parked for the operator. A single request carries
275
+ * every question the model asked in one call, so the card is a form with a
276
+ * pager, not a list of independent prompts.
277
+ */
278
+ export interface QaPendingQuestion {
279
+ readonly id: string;
280
+ /** The chat the request belongs to. */
281
+ readonly sessionId: string;
282
+ readonly questions: readonly QaPendingQuestionItem[];
283
+ readonly createdAt: number;
284
+ }
285
+ /**
286
+ * One message that waits for the agent's next turn. Rows the Host already
287
+ * admitted carry their durable occurrence id, which is what a queue operation
288
+ * addresses; a row still in flight carries a browser id and edits nothing.
289
+ */
290
+ export interface QaQueueRow {
291
+ readonly id: string;
292
+ /** Short single-line text for the strip; newlines are folded away. */
293
+ readonly preview: string;
294
+ /** Full text to edit, or null when the row is not plain text. */
295
+ readonly text: string | null;
296
+ /** Attachments the row carries besides its text. */
297
+ readonly attachments: number;
298
+ /** Set for a local row the Host queue has not echoed back yet. */
299
+ readonly sending: boolean;
300
+ }
301
+ /** What the queue strip may ask the Host to do with one waiting message. */
302
+ export type QaQueueOperation = "edit" | "remove" | "steer";
303
+ /**
304
+ * What `qaSurface/queueStatus` answers: how much of the deployment's request
305
+ * ceiling is in use right now. The Host counts the chats whose agent is running
306
+ * a turn, so the load is read where the whole of it is visible rather than
307
+ * guessed from one browser's view of the stand.
308
+ */
309
+ export interface QaQueueStatus {
310
+ /** The configured ceiling; 0 means the deployment sets none. */
311
+ readonly limit: number;
312
+ /**
313
+ * Turns answering at the moment of the read, this visitor's own included —
314
+ * the stand cannot tell a place it owes someone from one it owes you.
315
+ */
316
+ readonly active: number;
317
+ /** Whether one more turn fits; false while no ceiling is set. */
318
+ readonly full: boolean;
319
+ }
320
+ export interface QaSessionState {
321
+ readonly chatAccess?: import("../chat-sharing/types.js").QaChatAccess;
322
+ readonly phase: QaSessionPhase;
323
+ readonly sessionId: string | null;
324
+ /**
325
+ * Identity of the chat the surface is showing. Unique across every chat the
326
+ * page has opened — a controller that is re-created for a new chat is handed
327
+ * a new identity, so a component keyed by it cannot carry one chat's composer
328
+ * text into another. It is taken only when the chat changes: a draft that
329
+ * creates its session on the first prompt keeps its key, because the composer
330
+ * holds an unsent question in component state, and remounting it on the new
331
+ * session id would throw that text away before the Host has accepted
332
+ * anything. `0` means no chat — see `QA_SESSION_IDLE_STATE`.
333
+ */
334
+ readonly chatKey: number;
335
+ readonly messages: readonly QaMessage[];
336
+ /** Immediate send feedback, kept outside the durable transcript. */
337
+ readonly pendingMessage: QaPendingUserMessage | null;
338
+ readonly error: string | null;
339
+ /**
340
+ * An owner-authorized historical chat whose recorded composition no longer
341
+ * matches the deployment. Its transcript remains visible, but no Host
342
+ * operation may be issued through this binding.
343
+ */
344
+ readonly compatibilityReadOnly?: boolean;
345
+ readonly canSend: boolean;
346
+ readonly canStop: boolean;
347
+ /**
348
+ * Messages waiting for the next turn, oldest first. Sending while the agent
349
+ * runs lands here instead of in the transcript, so the strip beside the
350
+ * composer is the only place the user can still see them.
351
+ */
352
+ readonly queue: readonly QaQueueRow[];
353
+ /** Whether a queue operation may be issued on this binding right now. */
354
+ readonly canEditQueue: boolean;
355
+ /** Bumped whenever this browser's chat index changes (add/forget). */
356
+ readonly chatsRevision: number;
357
+ /** Tool-derived sources of the current chat (web targets and files read). */
358
+ readonly sources: readonly QaSource[];
359
+ readonly sourcesComplete: boolean;
360
+ readonly incompleteSourceOrigins: QaTurnSources["incompleteOrigins"];
361
+ /** Set while the bound session is a subagent watched from the panel. */
362
+ readonly viewingSubagent: QaSubagentView | null;
363
+ /** Tool calls parked for the operator's answer, oldest first. */
364
+ readonly approvals: readonly QaPendingApproval[];
365
+ /** Question requests parked for the operator's answer, oldest first. */
366
+ readonly questions: readonly QaPendingQuestion[];
367
+ /**
368
+ * Set when a send was held back because the stand is already answering as
369
+ * many questions as it allows. The question never left the browser, so this
370
+ * is the whole of what the visitor is told about it; the surface answers with
371
+ * the request-ceiling dialog and the composer keeps the draft. Named apart
372
+ * from `queue`, which is the same chat's list of waiting messages.
373
+ */
374
+ readonly requestQueue: QaQueueStatus | null;
375
+ /** Slash palette state, keyed to the chat this snapshot describes. */
376
+ readonly slash: QaSlashView;
377
+ }
378
+ /** Minimal server-trusted identity exposed to principal-scoped plugins. */
379
+ export interface QaPrincipal {
380
+ readonly userId: string;
381
+ }
382
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Why one skill draft cannot be saved, or why it saves with a caveat. Codes
3
+ * stay stable on the wire; the browser owns the Russian copy.
4
+ */
5
+ export type QaSkillDiagnosticCode = "name-required" | "name-invalid" | "name-mismatch" | "description-required" | "description-too-long" | "when-to-use-too-long" | "field-type-invalid" | "invocation-never" | "invocation-invalid" | "invocation-legacy-key" | "allowed-tools-invalid" | "tool-name-invalid" | "tool-unavailable" | "tools-too-many" | "file-too-large" | "frontmatter-missing" | "skill-file-missing" | "skill-file-truncated" | "frontmatter-invalid" | "unknown-field" | "resource-unsupported";
6
+ /** One finding about a skill file or an editor draft. */
7
+ export interface QaSkillDiagnostic {
8
+ readonly code: QaSkillDiagnosticCode;
9
+ readonly severity: "error" | "warning";
10
+ /** The editor field the message belongs to, or null for a file-wide one. */
11
+ readonly field: string | null;
12
+ /** The offending value: a tool name, a frontmatter key, a limit. */
13
+ readonly detail: string | null;
14
+ }
15
+ /**
16
+ * A JSON-representable frontmatter value. The editor receives the preserved
17
+ * foreign fields verbatim over the Host bridge, which carries JSON only, so
18
+ * the parser drops anything a YAML document can hold but JSON cannot.
19
+ */
20
+ export type QaSkillJsonValue = string | number | boolean | null | readonly QaSkillJsonValue[] | {
21
+ readonly [key: string]: QaSkillJsonValue;
22
+ };
23
+ /** One personal skill as the catalog list renders it. */
24
+ /**
25
+ * One administrator write to a skill somebody else owns.
26
+ *
27
+ * The record exists so a personal skill cannot be changed behind its owner's
28
+ * back: it is written beside the skill and reported on every read, and the
29
+ * owner sees the badge in their own catalog.
30
+ */
31
+ export interface QaSkillAdminEdit {
32
+ /** Administrator account id; the owner is told a role, not a colleague. */
33
+ readonly actorId: string;
34
+ /** ISO timestamp of that write. */
35
+ readonly at: string;
36
+ }
37
+ /**
38
+ * Which skill store an administrator is editing: the deployment-wide shared
39
+ * root every account may read, or one account's own directory.
40
+ */
41
+ export type QaAdminSkillScope = {
42
+ readonly kind: "shared";
43
+ } | {
44
+ readonly kind: "user";
45
+ readonly userId: string;
46
+ };
47
+ /** The account a personal skill scope belongs to, for the console's header. */
48
+ export interface QaAdminSkillOwner {
49
+ readonly userId: string;
50
+ readonly email: string;
51
+ readonly displayName: string;
52
+ }
53
+ /** One scope's catalog plus the facts the console names it by. */
54
+ export interface QaAdminSkillsView {
55
+ readonly scope: QaAdminSkillScope;
56
+ /** The account of a personal scope; null for the shared root. */
57
+ readonly owner: QaAdminSkillOwner | null;
58
+ readonly skills: readonly QaSkillSummary[];
59
+ /** Absolute directory this scope reads and writes, rendered read-only. */
60
+ readonly rootPath: string;
61
+ }
62
+ export interface QaSkillSummary {
63
+ readonly name: string;
64
+ readonly description: string;
65
+ readonly whenToUse: string | null;
66
+ readonly modelInvocable: boolean;
67
+ readonly userInvocable: boolean;
68
+ /** Declared tools, in canonical order; unknown ones included. */
69
+ readonly allowedTools: readonly string[];
70
+ /** Declared tools the current QA scope cannot use; still stored as declared. */
71
+ readonly unavailableTools: readonly string[];
72
+ /** Entries in the skill directory besides SKILL.md (references, assets, …). */
73
+ readonly resourceCount: number;
74
+ readonly valid: boolean;
75
+ readonly diagnostics: readonly QaSkillDiagnostic[];
76
+ readonly updatedAt: string | null;
77
+ /** sha256 of the stored bytes; an update must echo the revision it read. */
78
+ readonly revision: string;
79
+ /**
80
+ * The administrator write that produced the stored revision, or null. A
81
+ * record whose revision no longer matches is stale and reports as null: the
82
+ * badge answers "did an administrator write what I am looking at", not
83
+ * "was this skill ever touched by an administrator".
84
+ */
85
+ readonly adminEdit: QaSkillAdminEdit | null;
86
+ }
87
+ /** One personal skill with everything the editor needs. */
88
+ export interface QaSkillDocument extends QaSkillSummary {
89
+ readonly body: string;
90
+ /** Frontmatter the editor preserves but does not own. */
91
+ readonly extraFrontmatter: Readonly<Record<string, QaSkillJsonValue>>;
92
+ /** Absolute SKILL.md path; rendered read-only for advanced users. */
93
+ readonly sourcePath: string;
94
+ /** The canonical file the serializer writes, built from the parsed content. */
95
+ readonly preview: string;
96
+ /**
97
+ * True when the stored file is larger than the Host's read ceiling, so `body`
98
+ * and `preview` describe its head only. A save over such a document erases
99
+ * the unread tail, and the Host refuses it until the client confirms.
100
+ */
101
+ readonly truncated: boolean;
102
+ }
103
+ /** One tool the picker can offer, with this deployment's availability. */
104
+ export interface QaSkillToolDescriptor {
105
+ readonly name: string;
106
+ readonly description: string;
107
+ /** False when the QA session's own scope cannot use the tool. */
108
+ readonly available: boolean;
109
+ }
110
+ /** The editor's save payload. */
111
+ export interface QaSkillDraftInput {
112
+ readonly name: string;
113
+ readonly description: string;
114
+ readonly whenToUse: string | null;
115
+ readonly modelInvocable: boolean;
116
+ readonly userInvocable: boolean;
117
+ readonly allowedTools: readonly string[];
118
+ readonly body: string;
119
+ /** Echo of the revision the editor read; a stale one is refused. */
120
+ readonly expectedRevision: string | null;
121
+ /**
122
+ * The client's acknowledgement that it is saving from an incomplete copy: the
123
+ * stored `SKILL.md` is over the read ceiling, so the draft carries the head
124
+ * of the file and a save would drop everything the read never loaded. A write
125
+ * without it is refused.
126
+ */
127
+ readonly confirmPartialOverwrite?: boolean;
128
+ }
129
+ /**
130
+ * The Host's answer about one unsaved draft: the file a save would write and
131
+ * the diagnostics it found. The editor shows its own subset immediately and
132
+ * this authoritative set as soon as it arrives.
133
+ */
134
+ export interface QaSkillValidation {
135
+ readonly preview: string;
136
+ readonly diagnostics: readonly QaSkillDiagnostic[];
137
+ }
138
+ /** What one delete did: v1 keeps the directory recoverable. */
139
+ export interface QaSkillRemoval {
140
+ readonly name: string;
141
+ readonly trashed: boolean;
142
+ }
143
+ //# sourceMappingURL=skills.d.ts.map