@yadsh/dsh-qa-surface 0.20.0 → 0.21.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 (60) hide show
  1. package/README.md +54 -0
  2. package/lib/client/QaTranscriptAdapter.js +36 -1
  3. package/lib/client/QaTranscriptAdapter.js.map +1 -1
  4. package/lib/client/chat-artifacts.js +1 -0
  5. package/lib/client/chat-artifacts.js.map +1 -1
  6. package/lib/client/components/QaArtifactAttachment.js +12 -0
  7. package/lib/client/components/QaArtifactAttachment.js.map +1 -0
  8. package/lib/client/components/QaChangelog.js +25 -0
  9. package/lib/client/components/QaChangelog.js.map +1 -1
  10. package/lib/client/components/QaFilesPanel.js +2 -8
  11. package/lib/client/components/QaFilesPanel.js.map +1 -1
  12. package/lib/client/components/QaMessage.js +3 -8
  13. package/lib/client/components/QaMessage.js.map +1 -1
  14. package/lib/client/components/QaWorkGroup.js +1 -3
  15. package/lib/client/components/QaWorkGroup.js.map +1 -1
  16. package/lib/client/settings/card.js +2 -2
  17. package/lib/client/settings/card.js.map +1 -1
  18. package/lib/client/settings/sections/file-writes.js +15 -0
  19. package/lib/client/settings/sections/file-writes.js.map +1 -0
  20. package/lib/client/settings/sections.js +1 -0
  21. package/lib/client/settings/sections.js.map +1 -1
  22. package/lib/client/tool-presentation.js +21 -3
  23. package/lib/client/tool-presentation.js.map +1 -1
  24. package/lib/client.js +8 -8
  25. package/lib/client.js.map +1 -1
  26. package/lib/config-resolvers/defaults.js +2 -0
  27. package/lib/config-resolvers/defaults.js.map +1 -1
  28. package/lib/config-resolvers/tools.js +2 -0
  29. package/lib/config-resolvers/tools.js.map +1 -1
  30. package/lib/config.js +26 -1
  31. package/lib/config.js.map +1 -1
  32. package/lib/index.js +13 -0
  33. package/lib/index.js.map +1 -1
  34. package/lib/prompt-notes.js +6 -2
  35. package/lib/prompt-notes.js.map +1 -1
  36. package/lib/qa-tools/catalog.js +16 -1
  37. package/lib/qa-tools/catalog.js.map +1 -1
  38. package/lib/qa-tools/file-write-gate.js +47 -0
  39. package/lib/qa-tools/file-write-gate.js.map +1 -0
  40. package/lib/qa-tools/index.js +6 -0
  41. package/lib/qa-tools/index.js.map +1 -1
  42. package/lib/qa-tools/subagent-tools.js +159 -0
  43. package/lib/qa-tools/subagent-tools.js.map +1 -0
  44. package/lib/shared/file-write-policy.js +29 -0
  45. package/lib/shared/file-write-policy.js.map +1 -0
  46. package/lib/typert.host.js +124 -116
  47. package/lib/typert.remote-client.js +119 -115
  48. package/lib/types/client/components/QaArtifactAttachment.d.ts +8 -0
  49. package/lib/types/client/settings/sections/file-writes.d.ts +4 -0
  50. package/lib/types/client/settings/sections.d.ts +1 -0
  51. package/lib/types/client/tool-presentation.d.ts +1 -0
  52. package/lib/types/prompt-notes.d.ts +1 -1
  53. package/lib/types/qa-tools/catalog.d.ts +3 -1
  54. package/lib/types/qa-tools/file-write-gate.d.ts +6 -0
  55. package/lib/types/qa-tools/index.d.ts +1 -0
  56. package/lib/types/qa-tools/subagent-tools.d.ts +40 -0
  57. package/lib/types/shared/file-write-policy.d.ts +10 -0
  58. package/lib/types/types/config.d.ts +3 -0
  59. package/lib/types/types/documents.d.ts +2 -0
  60. package/package.json +5 -5
@@ -0,0 +1,8 @@
1
+ import type { QaArtifactView } from "../../types.js";
2
+ export declare function QaArtifactAttachment({ artifact, onOpen, onDownload, onApprove, }: {
3
+ readonly artifact: QaArtifactView;
4
+ readonly onOpen?: (file: QaArtifactView) => void;
5
+ readonly onDownload?: (file: QaArtifactView) => void;
6
+ readonly onApprove?: (file: QaArtifactView) => Promise<void>;
7
+ }): import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=QaArtifactAttachment.d.ts.map
@@ -0,0 +1,4 @@
1
+ import { type ConfigProps } from "./common.js";
2
+ /** The operator's refusal is returned to the model before any native write. */
3
+ export declare function FileWritesSection(props: ConfigProps): import("react/jsx-runtime").JSX.Element;
4
+ //# sourceMappingURL=file-writes.d.ts.map
@@ -16,6 +16,7 @@ export { AccountsSection } from "./sections/accounts.js";
16
16
  export { AttachmentsSection } from "./sections/attachments.js";
17
17
  export { BrandingSection } from "./sections/branding.js";
18
18
  export { DocsSection } from "./sections/docs.js";
19
+ export { FileWritesSection } from "./sections/file-writes.js";
19
20
  export { EmbeddingSection } from "./sections/embedding.js";
20
21
  export { InterfaceSection } from "./sections/interface.js";
21
22
  export { LockdownSection } from "./sections/lockdown.js";
@@ -1,6 +1,7 @@
1
1
  import type { ToolResultNode } from "@deepseek-ai/dsh-client-ui-conversation/client";
2
2
  import type { QaWorkItem } from "../types.js";
3
3
  export declare function flattenToolOutput(node: ToolResultNode): string | null;
4
+ export declare function isDelegationTool(name: string): boolean;
4
5
  export declare function toolStatus(node: ToolResultNode): "ok" | "error" | "stopped";
5
6
  export declare function workTool(callId: string, name: string, argsRaw: string, status: "running" | "ok" | "error" | "stopped", startedAt: number | undefined, endedAt: number | undefined, output: string | null): QaWorkItem;
6
7
  //# sourceMappingURL=tool-presentation.d.ts.map
@@ -41,7 +41,7 @@ export declare const QA_CODE_SOURCES_NOTE = "dsh-qa-surface:code-sources";
41
41
  export declare const QA_IDENTITY_NOTE_TEMPLATE = "{identity}\n\n{instructions}";
42
42
  export declare const QA_SOURCES_NOTE_TEMPLATE = "Source provenance is collected automatically from your tool calls; the QA surface lists what it collected beside the answer. Do not append a manual Sources/\u0418\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0438 bibliography of your own.";
43
43
  export declare const QA_SOURCES_FALLBACK_TEMPLATE = "A delegated run whose provider cannot expose tool events must call {reportTool} before finishing.";
44
- export declare const QA_DELEGATION_NOTE_TEMPLATE = "When you start a background subagent, give the delegation a short vivid name in its description field: two or three words in the user's language that say what the run is for (\u00AB\u0421\u0432\u0435\u0440\u043A\u0430 \u043E\u0442\u0447\u0451\u0442\u043E\u0432\u00BB, \"Log triage\"). The QA surface shows that description as the subagent's display name in the operator's panel and completion notices.";
44
+ export declare const QA_DELEGATION_NOTE_TEMPLATE: string;
45
45
  export declare const QA_DOCUMENTS_NOTE_TEMPLATE: string;
46
46
  export declare const QA_SOURCE_PRIORITY_NOTE_TEMPLATE = "Answer from the source that owns the question: read what the conversation and its attachments already carry, then search the product documentation and ask the domain expert, and only then look in memory. Recalled memory is background from earlier sessions \u2014 a miss there is not evidence that no source exists, and it is not where a document, a page or a product fact should be looked up.";
47
47
  export interface QaIdentityRenderInput {
@@ -2,6 +2,7 @@ import type { CodeFilesOptions } from "./code-files.js";
2
2
  import type { Agent } from "@deepseek-ai/dsh-agent";
3
3
  import type { QaToolDescriptor } from "./types.js";
4
4
  import type { QaFormGate } from "../forms/gate.js";
5
+ import { type QaSubagentToolsOptions } from "./subagent-tools.js";
5
6
  /**
6
7
  * Deterministic catalog identity. The durable activation marker is derived from
7
8
  * the session log rather than stored, so this version is not compared against a
@@ -10,9 +11,10 @@ import type { QaFormGate } from "../forms/gate.js";
10
11
  *
11
12
  * Bump it whenever the catalog's tool set or their schemas change.
12
13
  */
13
- export declare const QA_TOOL_CATALOG_VERSION = "5";
14
+ export declare const QA_TOOL_CATALOG_VERSION = "6";
14
15
  /** What the catalog's definitions read, beyond the execution record. */
15
16
  export interface QaToolsSelfcheckDeps extends CodeFilesOptions {
17
+ readonly subagents?: QaSubagentToolsOptions;
16
18
  readonly forms?: QaFormGate;
17
19
  readonly formProjection?: (submission: import("../forms/types.js").QaFormSubmission, sessionId: string) => Promise<unknown>;
18
20
  readonly catalogVersion: string;
@@ -0,0 +1,6 @@
1
+ import type { Context } from "@deepseek-ai/cordis";
2
+ import type { QaSessionOwnership } from "../session-ownership.js";
3
+ import type { QaFileWritePolicy } from "../shared/file-write-policy.js";
4
+ /** Global monotonic guard: covers attested roots, children and nested dispatch. */
5
+ export declare function installQaFileWriteGate(ctx: Context, ownership: QaSessionOwnership, policy: () => QaFileWritePolicy): () => void;
6
+ //# sourceMappingURL=file-write-gate.d.ts.map
@@ -3,6 +3,7 @@ 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 subagents?: import("./subagent-tools.js").QaSubagentToolsOptions;
6
7
  readonly codeSources?: import("./code-files.js").CodeFilesOptions["codeSources"];
7
8
  readonly codeReadRoots?: () => readonly string[];
8
9
  readonly forms?: import("../forms/gate.js").QaFormGate;
@@ -0,0 +1,40 @@
1
+ import type { Context } from "@deepseek-ai/cordis";
2
+ import type { Agent, AgentOptions } from "@deepseek-ai/dsh-agent";
3
+ import { type ContentBlock } from "@deepseek-ai/dsh-llm";
4
+ import type { ToolDefinition } from "@deepseek-ai/dsh-tools";
5
+ import { type QaSessionModelPolicy } from "../access/model-policy.js";
6
+ /** Optional Host service: loading QA does not require a subagent backend. */
7
+ export interface QaSubagentsFace {
8
+ getProvider(name: string): {
9
+ readonly capabilities: {
10
+ readonly agentOptions: boolean;
11
+ readonly depthLimit: boolean;
12
+ };
13
+ } | undefined;
14
+ resolveMaxDepth(value: undefined): number | undefined;
15
+ startActivation(spec: {
16
+ readonly provider: string;
17
+ readonly label: string;
18
+ readonly signal: AbortSignal;
19
+ readonly delivery: "parent";
20
+ readonly request: {
21
+ readonly parent: Agent;
22
+ readonly prompt: ContentBlock[];
23
+ readonly agentOptions: AgentOptions;
24
+ readonly maxDepth?: number;
25
+ };
26
+ }): Promise<{
27
+ readonly childId: string;
28
+ }>;
29
+ }
30
+ export interface QaSubagentToolsOptions {
31
+ readonly ctx: Context;
32
+ /** Must reject a caller outside an attested QA conversation. */
33
+ readonly policy: (agent: Agent) => QaSessionModelPolicy;
34
+ readonly runtime: () => QaSubagentsFace | undefined;
35
+ }
36
+ /** Only live catalog entries covered by the owner's current model grants. */
37
+ export declare function createQaListSubagentModelsTool(options: QaSubagentToolsOptions): ToolDefinition;
38
+ /** Start a fresh native child, with route authority supplied by QA ownership. */
39
+ export declare function createQaSubagentTool(options: QaSubagentToolsOptions): ToolDefinition;
40
+ //# sourceMappingURL=subagent-tools.d.ts.map
@@ -0,0 +1,10 @@
1
+ /** Operator-owned policy, shared by the Host resolver and settings controls. */
2
+ export interface QaFileWritePolicy {
3
+ readonly blockedExtensions: readonly string[];
4
+ readonly message: string;
5
+ }
6
+ export declare const QA_FILE_WRITE_EXTENSION_PATTERN: RegExp;
7
+ export declare const DEFAULT_QA_FILE_WRITE_POLICY: QaFileWritePolicy;
8
+ /** Normalize exact suffixes; wildcard and path rules are deliberately unsupported. */
9
+ export declare function resolveFileWritePolicy(input?: Partial<QaFileWritePolicy>): QaFileWritePolicy;
10
+ //# sourceMappingURL=file-write-policy.d.ts.map
@@ -167,6 +167,8 @@ export interface QaSurfaceConfig {
167
167
  * model request until the activation skill has actually been loaded.
168
168
  */
169
169
  readonly tools?: {
170
+ /** Deny native file writes by suffix; an empty list disables this policy. */
171
+ readonly fileWritePolicy?: Partial<import("../shared/file-write-policy.js").QaFileWritePolicy>;
170
172
  /**
171
173
  * `true` attaches the QA tools only after the activation skill loads;
172
174
  * `false` attaches them to every managed agent at creation.
@@ -511,6 +513,7 @@ export interface ResolvedQaSurfaceConfig {
511
513
  readonly allowOs: boolean;
512
514
  };
513
515
  readonly tools: {
516
+ readonly fileWritePolicy: import("../shared/file-write-policy.js").QaFileWritePolicy;
514
517
  readonly dynamicActivation: boolean;
515
518
  readonly activationSkill: string;
516
519
  readonly activationMode: QaToolActivationMode;
@@ -8,6 +8,8 @@
8
8
  * this account's workspace in.
9
9
  */
10
10
  export interface QaArtifactView {
11
+ /** Other outputs of the same spreadsheet edit in this turn, newest first. */
12
+ readonly earlierEdits?: readonly QaArtifactView[];
11
13
  readonly workflow?: {
12
14
  readonly id: string;
13
15
  readonly revision: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yadsh/dsh-qa-surface",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "A focused end-user QA surface backed by native DeepSeek Harness sessions",
5
5
  "repository": {
6
6
  "type": "git",
@@ -137,11 +137,11 @@
137
137
  "openid-client": "6.8.8",
138
138
  "yaml": "^2.9.0",
139
139
  "zod": "^4.4.3",
140
- "@yadsh/dsh-audit-core": "^0.1.3",
141
- "@yadsh/dsh-plugin-log": "^0.4.3",
140
+ "@yadsh/dsh-audit-ui": "^0.1.4",
141
+ "@yadsh/dsh-documents": "^0.9.0",
142
142
  "@yadsh/dsh-plugin-kit": "^0.8.0",
143
- "@yadsh/dsh-documents": "^0.8.3",
144
- "@yadsh/dsh-audit-ui": "^0.1.4"
143
+ "@yadsh/dsh-plugin-log": "^0.4.3",
144
+ "@yadsh/dsh-audit-core": "^0.1.3"
145
145
  },
146
146
  "devDependencies": {
147
147
  "@deepseek-ai/cordis": "4.0.5",