@yadsh/dsh-qa-surface 0.18.0 → 0.20.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 +201 -22
  2. package/lib/access/model-choices.js +103 -0
  3. package/lib/access/model-choices.js.map +1 -0
  4. package/lib/access/model-policy.js +79 -7
  5. package/lib/access/model-policy.js.map +1 -1
  6. package/lib/access/model.js +29 -1
  7. package/lib/access/model.js.map +1 -1
  8. package/lib/access/queue-policy.js +36 -0
  9. package/lib/access/queue-policy.js.map +1 -0
  10. package/lib/access/service.js +124 -7
  11. package/lib/access/service.js.map +1 -1
  12. package/lib/account-remotes.js +10 -1
  13. package/lib/account-remotes.js.map +1 -1
  14. package/lib/accounts/database.js +44 -3
  15. package/lib/accounts/database.js.map +1 -1
  16. package/lib/accounts/store.js +28 -0
  17. package/lib/accounts/store.js.map +1 -1
  18. package/lib/admin/service.js +6 -1
  19. package/lib/admin/service.js.map +1 -1
  20. package/lib/attachment-access.js +147 -0
  21. package/lib/attachment-access.js.map +1 -0
  22. package/lib/chat-sharing/search.js +89 -0
  23. package/lib/chat-sharing/search.js.map +1 -0
  24. package/lib/chat-sharing/transport.js +8 -9
  25. package/lib/chat-sharing/transport.js.map +1 -1
  26. package/lib/client/QaAccountsController.js +43 -8
  27. package/lib/client/QaAccountsController.js.map +1 -1
  28. package/lib/client/QaSessionController.js +106 -32
  29. package/lib/client/QaSessionController.js.map +1 -1
  30. package/lib/client/QaSurface.js +64 -5
  31. package/lib/client/QaSurface.js.map +1 -1
  32. package/lib/client/admin/ModelPolicyEditor.js +28 -2
  33. package/lib/client/admin/ModelPolicyEditor.js.map +1 -1
  34. package/lib/client/admin/RoleEditor.js +18 -1
  35. package/lib/client/admin/RoleEditor.js.map +1 -1
  36. package/lib/client/admin/pages/SkillFiles.js +1 -1
  37. package/lib/client/admin/pages/SkillFiles.js.map +1 -1
  38. package/lib/client/admin/pages/Users.js +36 -16
  39. package/lib/client/admin/pages/Users.js.map +1 -1
  40. package/lib/client/admin/styles.js +3 -0
  41. package/lib/client/admin/styles.js.map +1 -1
  42. package/lib/client/code-source-styles.js +12 -0
  43. package/lib/client/code-source-styles.js.map +1 -0
  44. package/lib/client/components/QaChangelog.js +96 -0
  45. package/lib/client/components/QaChangelog.js.map +1 -1
  46. package/lib/client/components/QaChatActions.js +36 -14
  47. package/lib/client/components/QaChatActions.js.map +1 -1
  48. package/lib/client/components/QaCodeSourcePicker.js +18 -0
  49. package/lib/client/components/QaCodeSourcePicker.js.map +1 -0
  50. package/lib/client/components/QaComposer.js +11 -12
  51. package/lib/client/components/QaComposer.js.map +1 -1
  52. package/lib/client/components/QaComposerSettings.js +202 -0
  53. package/lib/client/components/QaComposerSettings.js.map +1 -0
  54. package/lib/client/components/QaFormItem.js +74 -38
  55. package/lib/client/components/QaFormItem.js.map +1 -1
  56. package/lib/client/components/QaHistoryCatalog.js +261 -0
  57. package/lib/client/components/QaHistoryCatalog.js.map +1 -0
  58. package/lib/client/components/QaInputForm.js +115 -32
  59. package/lib/client/components/QaInputForm.js.map +1 -1
  60. package/lib/client/components/QaModelSelector.js +21 -0
  61. package/lib/client/components/QaModelSelector.js.map +1 -0
  62. package/lib/client/components/QaRequestWait.js +15 -0
  63. package/lib/client/components/QaRequestWait.js.map +1 -0
  64. package/lib/client/components/QaSidebar.js +25 -24
  65. package/lib/client/components/QaSidebar.js.map +1 -1
  66. package/lib/client/composer-settings-styles.js +21 -0
  67. package/lib/client/composer-settings-styles.js.map +1 -0
  68. package/lib/client/forms-styles.js +35 -11
  69. package/lib/client/forms-styles.js.map +1 -1
  70. package/lib/client/history-organization-styles.js +31 -0
  71. package/lib/client/history-organization-styles.js.map +1 -0
  72. package/lib/client/history-organization.js +155 -0
  73. package/lib/client/history-organization.js.map +1 -0
  74. package/lib/client/index.js +13 -2
  75. package/lib/client/index.js.map +1 -1
  76. package/lib/client/project-session-state.js.map +1 -1
  77. package/lib/client/request-wait-styles.js +7 -0
  78. package/lib/client/request-wait-styles.js.map +1 -0
  79. package/lib/client/settings/sections/attachments.js +7 -1
  80. package/lib/client/settings/sections/attachments.js.map +1 -1
  81. package/lib/client/settings/sections/session.js +1 -1
  82. package/lib/client/settings/sections/session.js.map +1 -1
  83. package/lib/client/styles.js +20 -1
  84. package/lib/client/styles.js.map +1 -1
  85. package/lib/client/types.js.map +1 -1
  86. package/lib/client/use-chat-code-source.js +156 -0
  87. package/lib/client/use-chat-code-source.js.map +1 -0
  88. package/lib/client/use-history-organization.js +48 -0
  89. package/lib/client/use-history-organization.js.map +1 -0
  90. package/lib/client/use-model-selection.js +96 -0
  91. package/lib/client/use-model-selection.js.map +1 -0
  92. package/lib/client/use-qa-file-drop.js +81 -0
  93. package/lib/client/use-qa-file-drop.js.map +1 -0
  94. package/lib/client/user-settings/IntegrationTokensPage.js +42 -6
  95. package/lib/client/user-settings/IntegrationTokensPage.js.map +1 -1
  96. package/lib/client/user-settings/UserSettingsDialog.js +1 -1
  97. package/lib/client/user-settings/UserSettingsDialog.js.map +1 -1
  98. package/lib/client.js +131 -27
  99. package/lib/client.js.map +1 -1
  100. package/lib/code-source-selection.js +102 -0
  101. package/lib/code-source-selection.js.map +1 -0
  102. package/lib/config-resolvers/accounts.js +26 -1
  103. package/lib/config-resolvers/accounts.js.map +1 -1
  104. package/lib/config-resolvers/defaults.js +5 -0
  105. package/lib/config-resolvers/defaults.js.map +1 -1
  106. package/lib/config-resolvers/integration.js +8 -1
  107. package/lib/config-resolvers/integration.js.map +1 -1
  108. package/lib/config-resolvers/session.js +2 -0
  109. package/lib/config-resolvers/session.js.map +1 -1
  110. package/lib/config.js +51 -3
  111. package/lib/config.js.map +1 -1
  112. package/lib/enforcement/skill-policy.js +37 -2
  113. package/lib/enforcement/skill-policy.js.map +1 -1
  114. package/lib/filesystem-intent.js +39 -0
  115. package/lib/filesystem-intent.js.map +1 -0
  116. package/lib/forms/attachments.js +18 -2
  117. package/lib/forms/attachments.js.map +1 -1
  118. package/lib/forms/errors.js +6 -1
  119. package/lib/forms/errors.js.map +1 -1
  120. package/lib/forms/gate.js +28 -2
  121. package/lib/forms/gate.js.map +1 -1
  122. package/lib/forms/schema-errors.js +47 -0
  123. package/lib/forms/schema-errors.js.map +1 -0
  124. package/lib/forms/schema.js +29 -20
  125. package/lib/forms/schema.js.map +1 -1
  126. package/lib/index.js +189 -84
  127. package/lib/index.js.map +1 -1
  128. package/lib/integration/http.js +9 -10
  129. package/lib/integration/http.js.map +1 -1
  130. package/lib/integration/service.js +9 -0
  131. package/lib/integration/service.js.map +1 -1
  132. package/lib/personal-skills/provider.js +9 -1
  133. package/lib/personal-skills/provider.js.map +1 -1
  134. package/lib/personal-skills/service.js +4 -0
  135. package/lib/personal-skills/service.js.map +1 -1
  136. package/lib/personal-skills/shared-seed.js +65 -0
  137. package/lib/personal-skills/shared-seed.js.map +1 -0
  138. package/lib/prompt-notes.js +19 -1
  139. package/lib/prompt-notes.js.map +1 -1
  140. package/lib/provenance/collector.js +1 -0
  141. package/lib/provenance/collector.js.map +1 -1
  142. package/lib/provenance/extractors.js +6 -1
  143. package/lib/provenance/extractors.js.map +1 -1
  144. package/lib/qa-tools/catalog.js +18 -1
  145. package/lib/qa-tools/catalog.js.map +1 -1
  146. package/lib/qa-tools/code-files.js +207 -0
  147. package/lib/qa-tools/code-files.js.map +1 -0
  148. package/lib/qa-tools/code-tools.js +158 -0
  149. package/lib/qa-tools/code-tools.js.map +1 -0
  150. package/lib/qa-tools/docs-tools.js +49 -12
  151. package/lib/qa-tools/docs-tools.js.map +1 -1
  152. package/lib/qa-tools/index.js +4 -0
  153. package/lib/qa-tools/index.js.map +1 -1
  154. package/lib/qa-tools/request-user-form.js +27 -7
  155. package/lib/qa-tools/request-user-form.js.map +1 -1
  156. package/lib/request-scheduler.js +262 -0
  157. package/lib/request-scheduler.js.map +1 -0
  158. package/lib/resolve-config.js +9 -1
  159. package/lib/resolve-config.js.map +1 -1
  160. package/lib/secure-session.js +62 -56
  161. package/lib/secure-session.js.map +1 -1
  162. package/lib/session-create.js +125 -0
  163. package/lib/session-create.js.map +1 -0
  164. package/lib/session-model.js +43 -1
  165. package/lib/session-model.js.map +1 -1
  166. package/lib/shared/history-folder.js +18 -0
  167. package/lib/shared/history-folder.js.map +1 -0
  168. package/lib/typert.host.js +793 -159
  169. package/lib/typert.remote-client.d.ts +19 -7
  170. package/lib/typert.remote-client.js +726 -148
  171. package/lib/types/access/model-choices.d.ts +16 -0
  172. package/lib/types/access/model-policy.d.ts +13 -7
  173. package/lib/types/access/model.d.ts +9 -0
  174. package/lib/types/access/queue-policy.d.ts +30 -0
  175. package/lib/types/access/service.d.ts +27 -0
  176. package/lib/types/account-remotes.d.ts +5 -4
  177. package/lib/types/accounts/database.d.ts +5 -0
  178. package/lib/types/accounts/store.d.ts +6 -0
  179. package/lib/types/attachment-access.d.ts +29 -0
  180. package/lib/types/chat-sharing/search.d.ts +5 -0
  181. package/lib/types/chat-sharing/transport.d.ts +1 -1
  182. package/lib/types/client/QaAccountsController.d.ts +3 -1
  183. package/lib/types/client/QaSessionController.d.ts +31 -14
  184. package/lib/types/client/QaSurface.d.ts +2 -0
  185. package/lib/types/client/admin/ModelPolicyEditor.d.ts +2 -0
  186. package/lib/types/client/code-source-styles.d.ts +2 -0
  187. package/lib/types/client/components/QaChatActions.d.ts +3 -1
  188. package/lib/types/client/components/QaCodeSourcePicker.d.ts +9 -0
  189. package/lib/types/client/components/QaComposer.d.ts +2 -0
  190. package/lib/types/client/components/QaComposerSettings.d.ts +16 -0
  191. package/lib/types/client/components/QaFormItem.d.ts +4 -2
  192. package/lib/types/client/components/QaHistoryCatalog.d.ts +19 -0
  193. package/lib/types/client/components/QaInputForm.d.ts +3 -2
  194. package/lib/types/client/components/QaModelSelector.d.ts +4 -0
  195. package/lib/types/client/components/QaRequestWait.d.ts +6 -0
  196. package/lib/types/client/components/QaSidebar.d.ts +3 -0
  197. package/lib/types/client/composer-settings-styles.d.ts +2 -0
  198. package/lib/types/client/forms-styles.d.ts +1 -1
  199. package/lib/types/client/history-organization-styles.d.ts +3 -0
  200. package/lib/types/client/history-organization.d.ts +38 -0
  201. package/lib/types/client/project-session-state.d.ts +2 -4
  202. package/lib/types/client/request-wait-styles.d.ts +2 -0
  203. package/lib/types/client/types.d.ts +15 -7
  204. package/lib/types/client/use-chat-code-source.d.ts +20 -0
  205. package/lib/types/client/use-history-organization.d.ts +8 -0
  206. package/lib/types/client/use-model-selection.d.ts +24 -0
  207. package/lib/types/client/use-qa-file-drop.d.ts +12 -0
  208. package/lib/types/code-source-selection.d.ts +28 -0
  209. package/lib/types/code-sources.js +2 -0
  210. package/lib/types/code-sources.js.map +1 -0
  211. package/lib/types/config-resolvers/integration.d.ts +7 -1
  212. package/lib/types/filesystem-intent.d.ts +12 -0
  213. package/lib/types/forms/attachments.d.ts +5 -2
  214. package/lib/types/forms/errors.d.ts +3 -2
  215. package/lib/types/forms/gate.d.ts +4 -2
  216. package/lib/types/forms/schema-errors.d.ts +7 -0
  217. package/lib/types/forms/types.d.ts +14 -0
  218. package/lib/types/index.d.ts +41 -15
  219. package/lib/types/integration/http.d.ts +1 -3
  220. package/lib/types/integration/service.d.ts +2 -0
  221. package/lib/types/personal-skills/shared-seed.d.ts +12 -0
  222. package/lib/types/prompt-notes.d.ts +5 -1
  223. package/lib/types/qa-tools/catalog.d.ts +4 -3
  224. package/lib/types/qa-tools/code-files.d.ts +59 -0
  225. package/lib/types/qa-tools/code-tools.d.ts +7 -0
  226. package/lib/types/qa-tools/docs-tools.d.ts +4 -0
  227. package/lib/types/qa-tools/index.d.ts +3 -1
  228. package/lib/types/qa-tools/request-user-form.d.ts +1 -1
  229. package/lib/types/request-scheduler.d.ts +47 -0
  230. package/lib/types/secure-session.d.ts +12 -26
  231. package/lib/types/session-create.d.ts +29 -0
  232. package/lib/types/session-model.d.ts +11 -2
  233. package/lib/types/shared/history-folder.d.ts +4 -0
  234. package/lib/types/types/accounts.d.ts +11 -0
  235. package/lib/types/types/capability.d.ts +31 -4
  236. package/lib/types/types/code-sources.d.ts +12 -0
  237. package/lib/types/types/config.d.ts +20 -0
  238. package/lib/types/types/session.d.ts +8 -0
  239. package/lib/types/types.d.ts +1 -0
  240. package/lib/types/user-workspace.d.ts +4 -6
  241. package/lib/user-workspace.js +20 -71
  242. package/lib/user-workspace.js.map +1 -1
  243. package/package.json +13 -10
@@ -1,3 +1,4 @@
1
+ import type { CodeFilesOptions } from "./code-files.js";
1
2
  import type { Agent } from "@deepseek-ai/dsh-agent";
2
3
  import type { QaToolDescriptor } from "./types.js";
3
4
  import type { QaFormGate } from "../forms/gate.js";
@@ -9,11 +10,11 @@ import type { QaFormGate } from "../forms/gate.js";
9
10
  *
10
11
  * Bump it whenever the catalog's tool set or their schemas change.
11
12
  */
12
- export declare const QA_TOOL_CATALOG_VERSION = "4";
13
+ export declare const QA_TOOL_CATALOG_VERSION = "5";
13
14
  /** What the catalog's definitions read, beyond the execution record. */
14
- export interface QaToolsSelfcheckDeps {
15
+ export interface QaToolsSelfcheckDeps extends CodeFilesOptions {
15
16
  readonly forms?: QaFormGate;
16
- readonly formProjection?: (submission: import("../forms/types.js").QaFormSubmission) => Promise<unknown>;
17
+ readonly formProjection?: (submission: import("../forms/types.js").QaFormSubmission, sessionId: string) => Promise<unknown>;
17
18
  readonly catalogVersion: string;
18
19
  readonly activationMode: string;
19
20
  /** Names the catalog contributes, in catalog order. */
@@ -0,0 +1,59 @@
1
+ import { type CodeSource, type CodeSourcesCatalog } from "@yadsh/dsh-plugin-kit/code-sources";
2
+ export interface CodeExecution {
3
+ readonly agent?: {
4
+ readonly session?: {
5
+ readonly id?: unknown;
6
+ readonly header?: {
7
+ readonly cwd?: unknown;
8
+ };
9
+ };
10
+ };
11
+ }
12
+ export interface CodeFilesOptions {
13
+ readonly codeSources?: ((exec?: CodeExecution) => CodeSourcesCatalog) | undefined;
14
+ readonly codeReadRoots?: (() => readonly string[]) | undefined;
15
+ }
16
+ export interface CodeScope {
17
+ readonly source: CodeSource;
18
+ readonly root: string;
19
+ }
20
+ /** Selection and authorization are separate, including after following root links. */
21
+ export declare function codeScope(options: CodeFilesOptions, exec: CodeExecution, requested?: unknown): Promise<CodeScope>;
22
+ export declare function boundedInteger(value: unknown, fallback: number, max: number): number;
23
+ /** Read a bounded window, with the selected identity on every result. */
24
+ export declare function readCode(scope: CodeScope, args: {
25
+ path?: unknown;
26
+ from?: unknown;
27
+ lines?: unknown;
28
+ }): Promise<{
29
+ source: string;
30
+ label: string;
31
+ root: string;
32
+ path: string;
33
+ absolutePath: string;
34
+ from: number;
35
+ to: number;
36
+ totalLines: number;
37
+ text: string;
38
+ truncated: boolean;
39
+ }>;
40
+ /** Literal search in one tree; entry, file, content, time and output budgets are fixed. */
41
+ export declare function searchCode(scope: CodeScope, args: {
42
+ query?: unknown;
43
+ path?: unknown;
44
+ limit?: unknown;
45
+ }): Promise<{
46
+ source: string;
47
+ label: string;
48
+ root: string;
49
+ query: string;
50
+ hits: {
51
+ path: string;
52
+ line: number;
53
+ text: string;
54
+ }[];
55
+ filesScanned: number;
56
+ skipped: number;
57
+ truncated: boolean;
58
+ }>;
59
+ //# sourceMappingURL=code-files.d.ts.map
@@ -0,0 +1,7 @@
1
+ import { type ToolDefinition } from "@deepseek-ai/dsh-tools";
2
+ import { type CodeFilesOptions } from "./code-files.js";
3
+ /** Discovery reports availability in this session without granting new roots. */
4
+ export declare function createCodeSourcesTool(options: CodeFilesOptions): ToolDefinition;
5
+ export declare function createCodeReadTool(options: CodeFilesOptions): ToolDefinition;
6
+ export declare function createCodeSearchTool(options: CodeFilesOptions): ToolDefinition;
7
+ //# sourceMappingURL=code-tools.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import type { ToolDefinition } from "@deepseek-ai/dsh-tools";
2
+ import { type CodeSourcesCatalog } from "@yadsh/dsh-plugin-kit/code-sources";
2
3
  /**
3
4
  * `docs_search` and `docs_read` — the documentation surface of the QA catalog.
4
5
  *
@@ -73,6 +74,7 @@ interface QaDocsExecution {
73
74
  * comes from configuration instead of from the calling chat.
74
75
  */
75
76
  export interface QaDocsOptions {
77
+ readonly codeSources?: ((exec?: import("./code-files.js").CodeExecution) => CodeSourcesCatalog) | undefined;
76
78
  /** Absolute documentation root, or `""` for `<chat workspace>/docs`. */
77
79
  readonly root?: string;
78
80
  /**
@@ -112,6 +114,7 @@ export interface QaDocsHit extends QaDocsIdentity {
112
114
  }
113
115
  /** The outcome of one documentation search. */
114
116
  export interface QaDocsSearchResult extends QaDocsIdentity {
117
+ readonly source?: string;
115
118
  readonly query: string;
116
119
  /** The directory documentation is read from, relative to the workspace. */
117
120
  readonly root: string;
@@ -122,6 +125,7 @@ export interface QaDocsSearchResult extends QaDocsIdentity {
122
125
  }
123
126
  /** The outcome of one documentation read. */
124
127
  export interface QaDocsReadResult extends QaDocsIdentity {
128
+ readonly source?: string;
125
129
  readonly path: string;
126
130
  /** Actual read target, kept out of the model-facing rendering. */
127
131
  readonly absolutePath: string;
@@ -3,9 +3,11 @@ import type { Context } from "@deepseek-ai/cordis";
3
3
  import type { PluginLogger } from "@yadsh/dsh-plugin-log";
4
4
  import type { QaToolActivation } from "./types.js";
5
5
  export interface QaToolsOptions {
6
+ readonly codeSources?: import("./code-files.js").CodeFilesOptions["codeSources"];
7
+ readonly codeReadRoots?: () => readonly string[];
6
8
  readonly forms?: import("../forms/gate.js").QaFormGate;
7
9
  readonly formsEnabled?: () => boolean;
8
- readonly formProjection?: (submission: import("../forms/types.js").QaFormSubmission) => Promise<unknown>;
10
+ readonly formProjection?: (submission: import("../forms/types.js").QaFormSubmission, sessionId: string) => Promise<unknown>;
9
11
  readonly logger: PluginLogger;
10
12
  readonly dynamicActivation: boolean;
11
13
  readonly activationSkill: string;
@@ -1,5 +1,5 @@
1
1
  import type { ToolDefinition } from "@deepseek-ai/dsh-tools";
2
2
  import type { QaFormGate } from "../forms/gate.js";
3
3
  /** Build only; the QA activation manager owns registration and role admission. */
4
- export declare function createRequestUserFormTool(gate: QaFormGate, project?: (submission: import("../forms/types.js").QaFormSubmission) => Promise<unknown>): ToolDefinition;
4
+ export declare function createRequestUserFormTool(gate: QaFormGate, project?: (submission: import("../forms/types.js").QaFormSubmission, sessionId: string) => Promise<unknown>): ToolDefinition;
5
5
  //# sourceMappingURL=request-user-form.d.ts.map
@@ -0,0 +1,47 @@
1
+ import type { Context } from "@deepseek-ai/cordis";
2
+ import type { Agent } from "@deepseek-ai/dsh-agent";
3
+ import type { QaQueueStatus } from "./types.js";
4
+ /** A FIFO admission lease covers a complete root turn, including its experts. */
5
+ export declare class QaRequestScheduler {
6
+ private readonly limit;
7
+ private readonly roots;
8
+ private readonly now;
9
+ private readonly familyBusy;
10
+ private readonly overrideLimit;
11
+ private readonly active;
12
+ private readonly waiting;
13
+ private readonly completed;
14
+ private readonly retiring;
15
+ private closed;
16
+ /**
17
+ * @param limit - the deployment's ceiling, the chain's last layer.
18
+ * @param roots - the root agents the queue gates.
19
+ * @param now - the clock, injectable for the wait estimate's tests.
20
+ * @param familyBusy - whether a root's descendants still answer.
21
+ * @param overrideLimit - the ceiling one specific turn fills against, when
22
+ * its role or account overrides the deployment's number. `undefined`
23
+ * defers to `limit`; this is read per admission, so a settings write is
24
+ * visible to the next turn without reloading the plugin.
25
+ */
26
+ constructor(limit: () => number, roots: () => readonly Agent[], now?: () => number, familyBusy?: (agent: Agent) => boolean, overrideLimit?: (agent: Agent) => number | undefined);
27
+ /** The effective ceiling one arriving turn is measured against. */
28
+ private limitFor;
29
+ install(ctx: Context): () => void;
30
+ acquire(agent: Agent, signal: AbortSignal): Promise<void>;
31
+ release(agent: Agent, completed?: boolean): void;
32
+ private pump;
33
+ /**
34
+ * Report admission as one read sees it.
35
+ * @param sessionId - the chat whose FIFO position is asked, if any.
36
+ * @param ceiling - the effective ceiling of the principal this read is for,
37
+ * when the caller has resolved it; the deployment's number otherwise.
38
+ */
39
+ status(sessionId?: string, ceiling?: number): QaQueueStatus;
40
+ private estimate;
41
+ dispose(): void;
42
+ }
43
+ /** Include background descendants whose root has already ended its own turn. */
44
+ export declare function qaRequestFamilyBusy(ctx: Context, root: Agent): boolean;
45
+ /** Older optional compositions may lack the registry, but cannot enforce a cap. */
46
+ export declare function qaRequestRoots(ctx: Context, required: boolean): readonly Agent[];
47
+ //# sourceMappingURL=request-scheduler.d.ts.map
@@ -1,5 +1,6 @@
1
1
  import type { Agent } from "@deepseek-ai/dsh-agent";
2
2
  import type { Context } from "@deepseek-ai/cordis";
3
+ import { type QaAttachmentRecovery } from "./attachment-access.js";
3
4
  import type { PluginLogger } from "@yadsh/dsh-plugin-log";
4
5
  import { type QaSessionFacts } from "./accounts/store.js";
5
6
  import type { QaIntegrationPrincipalBindings } from "./integration-principals.js";
@@ -71,13 +72,10 @@ export declare class QaPolicyAdmission {
71
72
  * one set answers for the whole chat.
72
73
  */
73
74
  private readonly attested;
75
+ private readonly rejected;
74
76
  private readonly questionWarnings;
75
77
  private readonly workspaceAccess;
76
- /**
77
- * Removers of the document input roots granted per session, so a grant lives
78
- * exactly as long as the workspace access that justified it.
79
- */
80
- private readonly documentInputRoots;
78
+ private readonly attachmentAccess;
81
79
  /**
82
80
  * Every name reachable anywhere in one QA conversation, keyed by session id.
83
81
  *
@@ -116,7 +114,7 @@ export declare class QaPolicyAdmission {
116
114
  * deliberately not a delegation); {@link secureSessionForUser} has no token
117
115
  * to compare, so it fills it here, against the ownership record it checked.
118
116
  */
119
- principals?: QaIntegrationPrincipalBindings | undefined);
117
+ principals?: QaIntegrationPrincipalBindings | undefined, attachmentRecovery?: QaAttachmentRecovery);
120
118
  /**
121
119
  * Add tools whose own executor resolves the QA principal server-side.
122
120
  * Enabling the contributing plugin is the operator decision; model arguments
@@ -130,29 +128,17 @@ export declare class QaPolicyAdmission {
130
128
  * newly-created, permanently unusable chat behind.
131
129
  */
132
130
  preflightDeployment(): void;
131
+ /** Keep a failed creation fenced even when its Host teardown cannot finish. */
132
+ rejectSession(sessionId: string): void;
133
+ /** Called only after failed creation confirms resource and ownership cleanup. */
134
+ forgetRejectedSession(sessionId: string): void;
133
135
  /**
134
- * The mounted attachment store's verbatim root, when the backend exposes
135
- * one. It sits outside every workspace, so the per-user fence would
136
- * otherwise deny the model the exact file an upload produced and the prompt
137
- * points it at. A backend without a resolvable root simply keeps the fence
138
- * closed — attachments then only work where reads are not fenced per user.
139
- * Source preview asks for the same root, so one upload is readable by both.
136
+ * The backend location used to validate exact file capabilities. The root
137
+ * itself grants no read access; only this conversation's Host-admitted
138
+ * user-message references and verified submitted form resources do.
140
139
  */
141
140
  attachmentRoot(): string | undefined;
142
- /**
143
- * Carry the fence's attachment exemption into the document pipeline.
144
- *
145
- * The guard above lets a single-file read reach the mounted store: an upload
146
- * is content-addressed, immutable, outside every workspace, and the prompt
147
- * hands the model exactly that path. The document pipeline keeps its own
148
- * read scope and knew nothing about the store, so `document_*` refused the
149
- * very file the model was allowed to read — the panel's own Word preview hit
150
- * the same wall. The grant is the missing hand-over, made where the access it
151
- * mirrors is made: per admitted session, and revoked with it.
152
- */
153
- private grantDocumentInputRoots;
154
- /** Drop one session's document grant, if the pipeline still holds it. */
155
- private revokeDocumentInputRoots;
141
+ grantAttachmentFile(sessionId: string, file: string): void;
156
142
  /**
157
143
  * The live agent for one session, resuming a Session the Host has not
158
144
  * materialized in this process.
@@ -0,0 +1,29 @@
1
+ import type { Context } from "@deepseek-ai/cordis";
2
+ import type { PluginLogger } from "@yadsh/dsh-plugin-log";
3
+ import type { QaStoredSessionEraser } from "./admin/session-log.js";
4
+ import type { QaSessionModelPolicy } from "./access/model-policy.js";
5
+ import type { ResolvedQaSurfaceConfig } from "./types.js";
6
+ export interface QaSessionCreateOptions {
7
+ readonly ctx: Context;
8
+ readonly config: ResolvedQaSurfaceConfig;
9
+ readonly logger: PluginLogger;
10
+ readonly sessionFiles: QaStoredSessionEraser;
11
+ reserve(id: string): {
12
+ readonly id: string;
13
+ } | undefined;
14
+ release(owner: string, id: string): void;
15
+ modelPolicy(id: string): QaSessionModelPolicy;
16
+ preflight(): void;
17
+ admit(id: string): Promise<unknown>;
18
+ attest(id: string, owner: string | undefined): void;
19
+ reject(id: string): void;
20
+ /** Drop failure-only metadata after resource and ownership cleanup succeeds. */
21
+ forget(id: string): void;
22
+ }
23
+ /**
24
+ * Admit inside the native factory's serial publication callback. A failure is
25
+ * rolled back by the Host's lifecycle owner before we erase this UUID's log;
26
+ * native preset composition and dynamic default-model hooks stay intact.
27
+ */
28
+ export declare function createQaSession(options: QaSessionCreateOptions): Promise<string>;
29
+ //# sourceMappingURL=session-create.d.ts.map
@@ -1,8 +1,11 @@
1
1
  import type { Context } from "@deepseek-ai/cordis";
2
+ import type { Agent } from "@deepseek-ai/dsh-agent";
2
3
  import type { SessionId } from "@deepseek-ai/dsh-session/types";
3
4
  import type { PluginLogger } from "@yadsh/dsh-plugin-log";
4
- import { type QaSessionModelPolicy } from "./access/model-policy.js";
5
- import type { QaModelPair } from "./types.js";
5
+ import { type ModelSelectionFacts, type QaSessionModelPolicy } from "./access/model-policy.js";
6
+ import type { QaModelPair, QaModelReplacement } from "./types.js";
7
+ /** Host selection is durable and can differ from immutable agent creation options. */
8
+ export declare function sessionModelSelection(ctx: Context, agent: Pick<Agent, "session" | "options">): ModelSelectionFacts;
6
9
  /**
7
10
  * Put one fresh session on the pair its model policy names.
8
11
  *
@@ -21,4 +24,10 @@ import type { QaModelPair } from "./types.js";
21
24
  * @returns the pair the session was put on, or `undefined` when none applied.
22
25
  */
23
26
  export declare function applySessionModelPolicy(ctx: Context, sessionId: SessionId, policy: QaSessionModelPolicy, logger: PluginLogger): Promise<QaModelPair | undefined>;
27
+ /** Migrate an idle owned chat only along an explicit redirect to its exact policy. */
28
+ export declare function reconcileSessionModelPolicy(ctx: Context, sessionId: SessionId, policy: QaSessionModelPolicy, current: {
29
+ readonly status: string;
30
+ readonly options: ModelSelectionFacts;
31
+ readonly runMaintenance?: Agent["runMaintenance"];
32
+ }, replacements: readonly QaModelReplacement[], logger: PluginLogger): Promise<boolean>;
24
33
  //# sourceMappingURL=session-model.d.ts.map
@@ -0,0 +1,4 @@
1
+ import type { QaHistoryFolderTarget } from "../types/accounts.js";
2
+ /** Bound both fields at the server boundary; identifiers are opaque UI keys. */
3
+ export declare function normalizeHistoryFolder(input: unknown): QaHistoryFolderTarget | null;
4
+ //# sourceMappingURL=history-folder.d.ts.map
@@ -128,12 +128,22 @@ export interface QaClaimResult {
128
128
  * questions cannot read back conversations it was never given.
129
129
  */
130
130
  export type QaServiceTokenScope = "ask" | "sessions:read";
131
+ /** Virtual UI destination, never a workspace or filesystem path. */
132
+ export interface QaHistoryFolderTarget {
133
+ readonly id: string;
134
+ readonly name: string;
135
+ }
136
+ export interface QaOwnedSessionsResult {
137
+ readonly ids: readonly string[];
138
+ readonly integrationFolders?: Readonly<Record<string, QaHistoryFolderTarget>>;
139
+ }
131
140
  /**
132
141
  * What an account asks a new integration token to be. The credential is always
133
142
  * issued to the caller: nothing a browser sends may name another account, so
134
143
  * this shape has no owner field and the administrative path keeps its own.
135
144
  */
136
145
  export interface QaServiceTokenCreateInput {
146
+ readonly historyFolder?: QaHistoryFolderTarget | null;
137
147
  /** A note the operator's list shows; empty becomes a generic label. */
138
148
  readonly label?: string;
139
149
  /** Requested scopes; unknown ones are dropped, explicit empty grants none. */
@@ -149,6 +159,7 @@ export interface QaServiceTokenCreateInput {
149
159
  * that could repeat it would be a list that leaks it.
150
160
  */
151
161
  export interface QaServiceTokenSummary {
162
+ readonly historyFolder?: QaHistoryFolderTarget | null;
152
163
  readonly id: string;
153
164
  readonly label: string;
154
165
  readonly scopes: readonly QaServiceTokenScope[];
@@ -120,8 +120,7 @@ export interface QaSkillActivationRecord {
120
120
  readonly reason?: string;
121
121
  }
122
122
  /**
123
- * One provider and model pair, fixed by policy rather than chosen in the
124
- * interface. `provider` and `model` are named together or not at all, because
123
+ * One provider and model pair. `provider` and `model` are named together, because
125
124
  * the Host refuses either of them alone.
126
125
  */
127
126
  export interface QaModelPair {
@@ -129,6 +128,11 @@ export interface QaModelPair {
129
128
  readonly model: string;
130
129
  readonly reasoningEffort?: string;
131
130
  }
131
+ /** Operator-defined replacement of one exact provider/model pair. */
132
+ export interface QaModelReplacement {
133
+ readonly from: QaModelPair;
134
+ readonly to: QaModelPair;
135
+ }
132
136
  /** One agent capability profile. It never grants administrative access. */
133
137
  export interface QaSubrole {
134
138
  readonly id: string;
@@ -137,11 +141,19 @@ export interface QaSubrole {
137
141
  readonly enabled: boolean;
138
142
  readonly capabilities: QaCapabilitySelection;
139
143
  /**
140
- * The pair every chat of this role is opened on, whatever the visitor picks
141
- * in the interface. Absent means the role keeps no opinion and the
144
+ * The default pair every new chat of this role opens on.
145
+ * Absent means the role keeps no opinion and the
142
146
  * deployment's pair serves it.
143
147
  */
144
148
  readonly model?: QaModelPair;
149
+ /** Additional user-selectable pairs. The default model stays available. */
150
+ readonly allowedModels?: readonly QaModelPair[];
151
+ /**
152
+ * How many of the stand's slots this role's turns may fill at once, ahead of
153
+ * the deployment's `session.maxActiveRequests`. 0 lifts the ceiling for this
154
+ * role's turns; absent keeps the deployment's number.
155
+ */
156
+ readonly maxActiveRequests?: number;
145
157
  readonly ui?: {
146
158
  readonly icon?: string;
147
159
  readonly accent?: string;
@@ -178,6 +190,21 @@ export interface QaUserAccess {
178
190
  * deployment shares. Absent means the account keeps no opinion.
179
191
  */
180
192
  readonly model?: QaModelPair;
193
+ /** Overrides the role's alternatives; [] permits only the default model. */
194
+ readonly allowedModels?: readonly QaModelPair[];
195
+ /**
196
+ * How many of the stand's slots this account's turns may fill at once,
197
+ * ahead of what its role says. 0 lifts the ceiling for this account's
198
+ * turns; absent keeps the role's or the deployment's number.
199
+ */
200
+ readonly maxActiveRequests?: number;
201
+ }
202
+ /** Filtered model choices for one owned chat or the caller's next chat. */
203
+ export interface QaModelOptions {
204
+ readonly models: readonly QaModelCatalogEntry[];
205
+ readonly choices: readonly QaModelPair[];
206
+ readonly defaultModel?: QaModelPair;
207
+ readonly selected?: QaModelPair;
181
208
  }
182
209
  export type QaCapabilitySourceKind = "core" | "plugin" | "mcp" | "filesystem" | "runtime";
183
210
  /** One capability currently installed, or retained as a missing selection. */
@@ -0,0 +1,12 @@
1
+ /** Browser-safe source selection state; filesystem access is configured separately. */
2
+ export interface QaChatCodeSources {
3
+ readonly selectedSource: string | null;
4
+ readonly effectiveSource: string | null;
5
+ readonly entries: readonly {
6
+ readonly id: string;
7
+ readonly label: string;
8
+ }[];
9
+ readonly writable: boolean;
10
+ readonly unavailable: boolean;
11
+ }
12
+ //# sourceMappingURL=code-sources.d.ts.map
@@ -1,4 +1,6 @@
1
1
  import type { QaAccountIdentityField } from "./accounts.js";
2
+ import type { QaModelReplacement } from "./capability.js";
3
+ import type { CodeSourcesConfig, CodeSourcesCatalog } from "@yadsh/dsh-plugin-kit/code-sources";
2
4
  import type { QaApprovalInteraction, QaApprovalPolicy, QaQuestionInteraction, QaQuestionInteractionInput, QaSandboxMode, QaSessionPolicy, QaToolActivationMode, QaToolPolicyMode } from "./policy.js";
3
5
  import type { QaSlashCommandsConfig, ResolvedQaSlashCommands } from "./slash.js";
4
6
  export interface QaSourcesConfig {
@@ -94,6 +96,8 @@ export interface QaNotesConfig {
94
96
  };
95
97
  }
96
98
  export interface QaSurfaceConfig {
99
+ /** Named code trees shared with Git; access is granted separately. */
100
+ readonly codeSources?: CodeSourcesConfig;
97
101
  readonly forms?: Partial<import("../forms/types.js").QaFormPolicy>;
98
102
  readonly enabled?: boolean;
99
103
  readonly route?: {
@@ -120,6 +124,8 @@ export interface QaSurfaceConfig {
120
124
  readonly provider?: string | null;
121
125
  readonly model?: string | null;
122
126
  readonly reasoningEffort?: string | null;
127
+ /** Exact central redirects applied after account/role/deployment precedence. */
128
+ readonly modelReplacements?: readonly QaModelReplacement[];
123
129
  /**
124
130
  * How many chat turns the deployment answers at once. A ceiling is what a
125
131
  * locally hosted model needs: the card runs out long before the queue does,
@@ -274,6 +280,11 @@ export interface QaSurfaceConfig {
274
280
  readonly enabled?: boolean;
275
281
  /** Directory below the personal root; relative, never escaping it. */
276
282
  readonly relativeRoot?: string;
283
+ /** Copy only these deployment skills into shared storage once. */
284
+ readonly sharedSeed?: {
285
+ readonly root: string;
286
+ readonly names: readonly string[];
287
+ } | null;
277
288
  /** Follow manual file edits and refresh the DSH catalog. */
278
289
  readonly watch?: boolean;
279
290
  readonly maxSkillBytes?: number;
@@ -347,6 +358,8 @@ export interface QaIntegrationConfig {
347
358
  readonly maxRequestBytes?: number;
348
359
  /** Ceiling on one inline image attachment, in bytes. */
349
360
  readonly maxAttachmentBytes?: number;
361
+ /** Files per integration request; 0 inherits attachments.maxPending. */
362
+ readonly maxAttachments?: number;
350
363
  /**
351
364
  * Ceiling on the published answer, in characters. The caller posts it into a
352
365
  * ticket comment, whose own budget is smaller than a model's answer, and a
@@ -375,6 +388,7 @@ export interface QaAttachmentsConfig {
375
388
  readonly extensions?: readonly string[];
376
389
  }
377
390
  export interface ResolvedQaSurfaceConfig {
391
+ readonly codeSources: CodeSourcesCatalog;
378
392
  readonly forms: Readonly<import("../forms/types.js").QaFormPolicy>;
379
393
  readonly enabled: boolean;
380
394
  readonly route: {
@@ -399,6 +413,7 @@ export interface ResolvedQaSurfaceConfig {
399
413
  readonly provider: string | null;
400
414
  readonly model: string | null;
401
415
  readonly reasoningEffort: string | null;
416
+ readonly modelReplacements: readonly QaModelReplacement[];
402
417
  readonly maxActiveRequests: number;
403
418
  };
404
419
  readonly ui: {
@@ -477,6 +492,10 @@ export interface ResolvedQaSurfaceConfig {
477
492
  skills: {
478
493
  readonly enabled: boolean;
479
494
  readonly relativeRoot: string;
495
+ readonly sharedSeed: {
496
+ readonly root: string;
497
+ readonly names: readonly string[];
498
+ } | null;
480
499
  readonly watch: boolean;
481
500
  readonly maxSkillBytes: number;
482
501
  readonly allowResourceEditing: boolean;
@@ -597,6 +616,7 @@ export interface ResolvedQaSurfaceConfig {
597
616
  readonly requestsPerMinute: number;
598
617
  readonly maxRequestBytes: number;
599
618
  readonly maxAttachmentBytes: number;
619
+ readonly maxAttachments: number;
600
620
  readonly maxAnswerCharacters: number;
601
621
  };
602
622
  }
@@ -331,6 +331,14 @@ export interface QaQueueStatus {
331
331
  readonly active: number;
332
332
  /** Whether one more turn fits; false while no ceiling is set. */
333
333
  readonly full: boolean;
334
+ /** The Host enforces admission and starts queued turns automatically. */
335
+ readonly managed?: boolean;
336
+ readonly queued?: number;
337
+ /** Present only for the authorized chat whose status was requested. */
338
+ readonly waiting?: boolean;
339
+ readonly position?: number | null;
340
+ /** Approximate delay derived from completed turns, or null without a sample. */
341
+ readonly estimatedWaitMs?: number | null;
334
342
  }
335
343
  export interface QaSessionState {
336
344
  readonly chatAccess?: import("../chat-sharing/types.js").QaChatAccess;
@@ -10,6 +10,7 @@ export type * from "./types/config.js";
10
10
  export type * from "./types/slash.js";
11
11
  export type * from "./types/documents.js";
12
12
  export type * from "./types/session.js";
13
+ export type * from "./types/code-sources.js";
13
14
  export type * from "./types/answer-review.js";
14
15
  export type * from "./types/quality.js";
15
16
  export type * from "./types/admin.js";
@@ -10,6 +10,8 @@ export interface QaToolExecutionLike {
10
10
  export interface QaUserWorkspaceReadPolicy {
11
11
  /** Shared directories exposed only to read-only filesystem tools. */
12
12
  readonly sharedReadOnlyRoots?: readonly string[];
13
+ /** Exact canonical files derived from this conversation's trusted references. */
14
+ readonly attachmentFiles?: readonly string[];
13
15
  }
14
16
  export declare function pathIsInside(target: string, root: string): boolean;
15
17
  /**
@@ -31,12 +33,8 @@ export declare function existingQaUserWorkspace(workspaceRoot: string, userId: s
31
33
  * fences model-controlled file paths for both reads and writes, rejects tools
32
34
  * whose implementation can walk above cwd, and enforces bounded scratch use.
33
35
  *
34
- * `attachmentRoot` is the one deliberate read exemption: an uploaded file is
35
- * an immutable content-addressed copy the deployment stores outside every
36
- * workspace, and the model reaches it exactly as the harness intends (the
37
- * prompt carries the stored path). Reads of a single such file are allowed;
38
- * directory-wide tools stay confined because the store is shared by every
39
- * account, and writes are never exempted.
36
+ * `attachmentRoot` identifies the storage backend, never authority to read it.
37
+ * Only regular files in `attachmentFiles` may cross the workspace boundary.
40
38
  */
41
39
  export declare function qaUserWorkspaceDenial(execution: QaToolExecutionLike, root: string, attachmentRoot?: string, readPolicy?: QaUserWorkspaceReadPolicy): string | undefined;
42
40
  //# sourceMappingURL=user-workspace.d.ts.map