@yadsh/dsh-qa-surface 0.4.0 → 0.5.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 (89) hide show
  1. package/README.md +41 -5
  2. package/cordis.patch.yml +8 -0
  3. package/lib/accounts/credentials.js +12 -4
  4. package/lib/accounts/credentials.js.map +1 -1
  5. package/lib/accounts/store.js +16 -1
  6. package/lib/accounts/store.js.map +1 -1
  7. package/lib/approvals.js +179 -0
  8. package/lib/approvals.js.map +1 -0
  9. package/lib/cli.js +10 -0
  10. package/lib/cli.js.map +1 -1
  11. package/lib/client/QaSessionController.js +93 -0
  12. package/lib/client/QaSessionController.js.map +1 -1
  13. package/lib/client/QaSurface.js +14 -1
  14. package/lib/client/QaSurface.js.map +1 -1
  15. package/lib/client/approvals.js +104 -0
  16. package/lib/client/approvals.js.map +1 -0
  17. package/lib/client/attestation.js +3 -0
  18. package/lib/client/attestation.js.map +1 -1
  19. package/lib/client/components/QaApproval.js +23 -0
  20. package/lib/client/components/QaApproval.js.map +1 -0
  21. package/lib/client/components/QaChangelog.js +24 -0
  22. package/lib/client/components/QaChangelog.js.map +1 -1
  23. package/lib/client/components/QaQuestions.js +96 -0
  24. package/lib/client/components/QaQuestions.js.map +1 -0
  25. package/lib/client/index.js +11 -0
  26. package/lib/client/index.js.map +1 -1
  27. package/lib/client/project-session-state.js +5 -3
  28. package/lib/client/project-session-state.js.map +1 -1
  29. package/lib/client/questions.js +114 -0
  30. package/lib/client/questions.js.map +1 -0
  31. package/lib/client/settings/sections/sources.js +2 -0
  32. package/lib/client/settings/sections/sources.js.map +1 -1
  33. package/lib/client/styles.js +42 -0
  34. package/lib/client/styles.js.map +1 -1
  35. package/lib/client/types.js +2 -0
  36. package/lib/client/types.js.map +1 -1
  37. package/lib/client.js +1018 -56
  38. package/lib/client.js.map +1 -1
  39. package/lib/config-resolvers/basics.js +4 -2
  40. package/lib/config-resolvers/basics.js.map +1 -1
  41. package/lib/config-resolvers/defaults.js +4 -0
  42. package/lib/config-resolvers/defaults.js.map +1 -1
  43. package/lib/config-resolvers/lockdown.js +11 -0
  44. package/lib/config-resolvers/lockdown.js.map +1 -1
  45. package/lib/config-resolvers/session.js +2 -2
  46. package/lib/config-resolvers/session.js.map +1 -1
  47. package/lib/config-resolvers/shared.js +9 -0
  48. package/lib/config-resolvers/shared.js.map +1 -1
  49. package/lib/config-resolvers/sources.js +2 -0
  50. package/lib/config-resolvers/sources.js.map +1 -1
  51. package/lib/config.js +11 -2
  52. package/lib/config.js.map +1 -1
  53. package/lib/index.js +76 -6
  54. package/lib/index.js.map +1 -1
  55. package/lib/provenance/host-store.js +25 -9
  56. package/lib/provenance/host-store.js.map +1 -1
  57. package/lib/provenance/reported.js +37 -12
  58. package/lib/provenance/reported.js.map +1 -1
  59. package/lib/questions.js +185 -0
  60. package/lib/questions.js.map +1 -0
  61. package/lib/secure-session.js +69 -17
  62. package/lib/secure-session.js.map +1 -1
  63. package/lib/session-ownership.js +55 -0
  64. package/lib/session-ownership.js.map +1 -0
  65. package/lib/typert.host.js +357 -17
  66. package/lib/typert.remote-client.d.ts +11 -1
  67. package/lib/typert.remote-client.js +287 -14
  68. package/lib/types/accounts/credentials.d.ts +6 -0
  69. package/lib/types/accounts/store.d.ts +8 -0
  70. package/lib/types/approvals.d.ts +65 -0
  71. package/lib/types/client/QaSessionController.d.ts +38 -1
  72. package/lib/types/client/QaSurface.d.ts +8 -1
  73. package/lib/types/client/approvals.d.ts +39 -0
  74. package/lib/types/client/components/QaApproval.d.ts +13 -0
  75. package/lib/types/client/components/QaQuestions.d.ts +13 -0
  76. package/lib/types/client/project-session-state.d.ts +8 -1
  77. package/lib/types/client/questions.d.ts +45 -0
  78. package/lib/types/client/types.d.ts +48 -1
  79. package/lib/types/config-resolvers/shared.d.ts +7 -0
  80. package/lib/types/index.d.ts +29 -3
  81. package/lib/types/provenance/reported.d.ts +9 -1
  82. package/lib/types/questions.d.ts +83 -0
  83. package/lib/types/secure-session.d.ts +21 -2
  84. package/lib/types/session-ownership.d.ts +30 -0
  85. package/lib/types/types.d.ts +80 -4
  86. package/lib/types/user-workspace.d.ts +5 -1
  87. package/lib/user-workspace.js +21 -6
  88. package/lib/user-workspace.js.map +1 -1
  89. package/package.json +3 -3
@@ -1,6 +1,6 @@
1
1
  import type { SessionFace } from "@deepseek-ai/dsh-api-session-controller/client";
2
2
  import type { ConversationSnapshot } from "@deepseek-ai/dsh-client-ui-conversation/client";
3
- import type { QaSessionState, QaSubagentView, QaTurnSources, ResolvedQaSurfaceConfig } from "../types.js";
3
+ import type { QaPendingApproval, QaPendingQuestion, QaSessionState, QaSubagentView, QaTurnSources, ResolvedQaSurfaceConfig } from "../types.js";
4
4
  /** Everything the bound-chat projection reads; the computation is pure. */
5
5
  export interface QaBoundProjectionInput {
6
6
  readonly connected: boolean;
@@ -9,6 +9,13 @@ export interface QaBoundProjectionInput {
9
9
  readonly conversationSnapshot: ConversationSnapshot | undefined;
10
10
  /** Turn bundles with the Host provenance already merged in (Host wins). */
11
11
  readonly sourceBundles: readonly QaTurnSources[];
12
+ /**
13
+ * Tool calls and questions the Host parked for the operator. They are
14
+ * host-side state, not part of the session snapshot, so the controller polls
15
+ * them separately.
16
+ */
17
+ readonly approvals: readonly QaPendingApproval[];
18
+ readonly questions: readonly QaPendingQuestion[];
12
19
  readonly operationError: string | null;
13
20
  readonly policyReady: boolean;
14
21
  readonly admissionPending: boolean;
@@ -0,0 +1,45 @@
1
+ import type { QaPendingQuestion, QaQuestionAnswerItem } from "../types.js";
2
+ import type { QaQuestionApi } from "./types.js";
3
+ /**
4
+ * The operator's side of a parked `ask_user_question` call.
5
+ *
6
+ * Like a parked approval, the request lives on the Host: it survives a reload,
7
+ * and the surface learns about it by asking while a turn runs. Unlike an
8
+ * approval, an answer is a whole form — every question of the request, with the
9
+ * operator's selections and free text — so the bridge forwards the form and
10
+ * re-reads the list afterwards.
11
+ */
12
+ export declare class QaHostQuestionBridge {
13
+ private readonly questionApi;
14
+ private questions;
15
+ private signature;
16
+ private refreshing;
17
+ private answering;
18
+ /** Bumped on reset so a stale in-flight response never lands. */
19
+ private generation;
20
+ constructor(questionApi: QaQuestionApi | undefined);
21
+ /** Leave the chat: a chat switch drops the previous chat's requests. */
22
+ reset(): void;
23
+ /** The last list this bridge saw; empty when the deployment refuses them. */
24
+ list(): readonly QaPendingQuestion[];
25
+ /** Whether this page can ask the Host about questions at all. */
26
+ get available(): boolean;
27
+ /**
28
+ * Re-read the chat's pending questions; a changed list republishes through
29
+ * the callback. Overlapping calls coalesce, and a response that outlives its
30
+ * chat is dropped.
31
+ */
32
+ refresh(sessionId: string, token: string, onChanged: () => void): Promise<void>;
33
+ /** Send the operator's answers to one request and re-read the list. */
34
+ answer(sessionId: string, token: string, requestId: string, answers: readonly QaQuestionAnswerItem[]): Promise<void>;
35
+ /** Close one request without answering it. */
36
+ cancel(sessionId: string, token: string, requestId: string): Promise<void>;
37
+ /**
38
+ * Run one write against a request, then re-read the list it belonged to. A
39
+ * refusal is not an error: the request was already settled (the turn was
40
+ * stopped, the call went away), so the refresh — not the write — is what the
41
+ * surface shows.
42
+ */
43
+ private settle;
44
+ }
45
+ //# sourceMappingURL=questions.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import type { ClientRemote } from "@deepseek-ai/dsh-api-gateway/client";
2
2
  import type { ISessions, SessionFace } from "@deepseek-ai/dsh-api-session-controller/client";
3
3
  import type { UiConversation } from "@deepseek-ai/dsh-client-ui-conversation/client";
4
- import type { QaAccountProfileInput, QaAccountSession, QaAccountUserPublic, QaClaimResult, QaLockdownProof, QaOwnershipEntry, QaSessionState, QaSourceFilePreview, QaTurnSources, QaWhoamiResult } from "../types.js";
4
+ import type { QaAccountProfileInput, QaAccountSession, QaAccountUserPublic, QaApprovalDecision, QaClaimResult, QaLockdownProof, QaOwnershipEntry, QaPendingApproval, QaPendingQuestion, QaQuestionAnswerItem, QaSessionState, QaSourceFilePreview, QaTurnSources, QaWhoamiResult } from "../types.js";
5
5
  /** Wire content one prompt carries: text plus base64 image uploads. */
6
6
  export type QaPromptContent = Parameters<SessionFace["prompt"]>[0];
7
7
  /** DSH session runtime surface the QA controller is allowed to touch. */
@@ -87,6 +87,53 @@ export type QaBoundSourceApi = {
87
87
  readonly error: unknown;
88
88
  }>;
89
89
  };
90
+ /**
91
+ * Approval remotes of this plugin's namespace. Read-only listing plus the one
92
+ * write: the operator's answer to a parked tool call.
93
+ */
94
+ export interface QaApprovalApi {
95
+ pendingApprovals(token: string, sessionId: string): Promise<{
96
+ readonly ok: true;
97
+ readonly value: readonly QaPendingApproval[];
98
+ } | {
99
+ readonly ok: false;
100
+ readonly error: unknown;
101
+ }>;
102
+ answerApproval(token: string, sessionId: string, requestId: string, decision: QaApprovalDecision): Promise<{
103
+ readonly ok: true;
104
+ readonly value: boolean;
105
+ } | {
106
+ readonly ok: false;
107
+ readonly error: unknown;
108
+ }>;
109
+ }
110
+ /**
111
+ * Question remotes of this plugin's namespace: the parked `ask_user_question`
112
+ * requests of one chat, the operator's answers, and closing one unanswered.
113
+ */
114
+ export interface QaQuestionApi {
115
+ pendingQuestions(token: string, sessionId: string): Promise<{
116
+ readonly ok: true;
117
+ readonly value: readonly QaPendingQuestion[];
118
+ } | {
119
+ readonly ok: false;
120
+ readonly error: unknown;
121
+ }>;
122
+ answerQuestion(token: string, sessionId: string, requestId: string, answers: readonly QaQuestionAnswerItem[]): Promise<{
123
+ readonly ok: true;
124
+ readonly value: boolean;
125
+ } | {
126
+ readonly ok: false;
127
+ readonly error: unknown;
128
+ }>;
129
+ cancelQuestion(token: string, sessionId: string, requestId: string): Promise<{
130
+ readonly ok: true;
131
+ readonly value: boolean;
132
+ } | {
133
+ readonly ok: false;
134
+ readonly error: unknown;
135
+ }>;
136
+ }
90
137
  /** Account remotes exposed by the plugin's own typert namespace. */
91
138
  export interface QaAccountsApi {
92
139
  accountsWhoami(token: string): Promise<RemoteResult<QaWhoamiResult>>;
@@ -1,5 +1,12 @@
1
1
  /** Trim an optional string; a blank value collapses to null. */
2
2
  export declare function optionalText(value: string | null | undefined): string | null;
3
+ /**
4
+ * Whether a configured directory is absolute. The rule reads a drive-letter
5
+ * path as absolute on every platform, like `session.cwd` does: a deployment
6
+ * profile is authored on one machine and may be read on another, so a
7
+ * Windows-style root is not a mistake to reject on a POSIX host.
8
+ */
9
+ export declare function isAbsoluteDirectoryPath(value: string): boolean;
3
10
  /**
4
11
  * Shared numeric guard for operator-tuned limits: the value has to be a safe
5
12
  * integer inside [min, max], and every rejection carries the same message.
@@ -1,7 +1,7 @@
1
1
  import { TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
2
2
  import type { Context } from "@deepseek-ai/cordis";
3
3
  import type { QaTurnSources } from "./provenance/types.js";
4
- import type { QaAccountProfileInput, QaAccountSession, QaAccountUserPublic, QaClaimResult, QaLockdownProof, QaOwnershipEntry, QaSurfaceConfig, ResolvedQaSurfaceConfig, QaSourceFilePreview, QaWhoamiResult } from "./types.js";
4
+ import type { QaAccountProfileInput, QaAccountSession, QaAccountUserPublic, QaApprovalDecision, QaClaimResult, QaLockdownProof, QaOwnershipEntry, QaPendingApproval, QaPendingQuestion, QaQuestionAnswerItem, QaSurfaceConfig, ResolvedQaSurfaceConfig, QaSourceFilePreview, QaWhoamiResult } from "./types.js";
5
5
  export declare const name = "qa-surface";
6
6
  export declare const inject: string[];
7
7
  import { QA_SURFACE_SETTINGS_NAMESPACE } from "./shared/settings.js";
@@ -19,6 +19,8 @@ export declare class QaSurface extends TypertRemoteService {
19
19
  private source;
20
20
  private readonly logger;
21
21
  private readonly admission;
22
+ private readonly approvals;
23
+ private readonly userQuestions;
22
24
  private readonly provenance;
23
25
  private readonly notes;
24
26
  /** Account-remote bodies; the wire signatures stay on this class. */
@@ -74,9 +76,33 @@ export declare class QaSurface extends TypertRemoteService {
74
76
  */
75
77
  createSession(token: string): Promise<string>;
76
78
  /** Pin and attest the effective policy. The browser supplies identity only. */
77
- secureSession(token: string, sessionId: string): QaLockdownProof;
79
+ secureSession(token: string, sessionId: string): Promise<QaLockdownProof>;
78
80
  /** Return canonical Host snapshots; replay is rebuilt from qa/sources events. */
79
- sources(token: string, sessionId: string): readonly QaTurnSources[];
81
+ sources(token: string, sessionId: string): Promise<readonly QaTurnSources[]>;
82
+ /**
83
+ * The tool calls of one chat that wait for the operator. Read-only: a
84
+ * deployment with blocked approvals answers with an empty list.
85
+ */
86
+ pendingApprovals(token: string, sessionId: string): Promise<readonly QaPendingApproval[]>;
87
+ /**
88
+ * Apply the operator's answer to one parked call. The id must belong to a
89
+ * request of this chat; an answer that lost the race (the turn was stopped,
90
+ * the agent went away) is refused with `false`.
91
+ */
92
+ answerApproval(token: string, sessionId: string, requestId: string, decision: QaApprovalDecision): Promise<boolean>;
93
+ /**
94
+ * The questions of one chat that wait for the operator. Read-only: a
95
+ * deployment with unsupported questions answers with an empty list.
96
+ */
97
+ pendingQuestions(token: string, sessionId: string): Promise<readonly QaPendingQuestion[]>;
98
+ /**
99
+ * Apply the operator's answers to one parked question request. Every question
100
+ * of the request must be present in `answers`; one the browser omits reads as
101
+ * a skip.
102
+ */
103
+ answerQuestion(token: string, sessionId: string, requestId: string, answers: readonly QaQuestionAnswerItem[]): Promise<boolean>;
104
+ /** Close a parked question request without answering it. */
105
+ cancelQuestion(token: string, sessionId: string, requestId: string): Promise<boolean>;
80
106
  /** Narrow read-only preview capability for files already present as sources. */
81
107
  readSourceFile(token: string, sessionId: string, sourcePath: string): Promise<QaSourceFilePreview>;
82
108
  private refreshRoute;
@@ -1,5 +1,13 @@
1
1
  import { canonicalizeUrl } from "./normalize.js";
2
2
  import type { QaReportedSource, QaSourceOrigin, QaSourceReference } from "./types.js";
3
+ export interface ReportedSourceOptions {
4
+ /**
5
+ * Whether a reported source must carry an address to be recorded. With
6
+ * `false`, a source the model wrote without a usable path or URL keeps its
7
+ * own type, title and snippet instead of being dropped.
8
+ */
9
+ readonly validate?: boolean;
10
+ }
3
11
  /** Normalize a source explicitly reported by a delegated provider. */
4
- export declare function normalizeReportedSource(source: QaReportedSource, origin: QaSourceOrigin, workspaceRoot?: string, urlOptions?: Parameters<typeof canonicalizeUrl>[1]): QaSourceReference | null;
12
+ export declare function normalizeReportedSource(source: QaReportedSource, origin: QaSourceOrigin, workspaceRoot?: string, urlOptions?: Parameters<typeof canonicalizeUrl>[1], options?: ReportedSourceOptions): QaSourceReference | null;
5
13
  //# sourceMappingURL=reported.d.ts.map
@@ -0,0 +1,83 @@
1
+ import type { Agent } from "@deepseek-ai/dsh-agent";
2
+ import type { Context } from "@deepseek-ai/cordis";
3
+ import type { PluginLogger } from "@yadsh/dsh-plugin-log";
4
+ import type { QaSessionOwnership } from "./session-ownership.js";
5
+ import type { QaPendingQuestion, QaQuestionAnswerItem } from "./types.js";
6
+ /**
7
+ * The harness user-questions contract this seam reads and writes, declared
8
+ * structurally on purpose: the plugin neither mounts the service nor depends on
9
+ * its package, so it stays loadable in a deployment that composes no questions
10
+ * at all. Shapes follow `@deepseek-ai/dsh-user-questions` `src/types.ts` at the
11
+ * tested harness release (`AskUserQuestionItem` / `AskUserQuestionAnswer`).
12
+ */
13
+ export interface QaQuestionOption {
14
+ readonly label: string;
15
+ readonly description?: string;
16
+ }
17
+ export interface QaQuestionItem {
18
+ readonly id: string;
19
+ readonly question: string;
20
+ readonly detail?: string;
21
+ readonly header?: string;
22
+ readonly options?: readonly QaQuestionOption[];
23
+ readonly multiSelect?: boolean;
24
+ }
25
+ export interface QaQuestionRequest {
26
+ readonly questions: readonly QaQuestionItem[];
27
+ readonly agent?: Agent;
28
+ readonly signal?: AbortSignal;
29
+ }
30
+ /** What the answerer waterfall accepts as its value. */
31
+ export interface QaQuestionAnswer {
32
+ readonly answers: readonly QaQuestionAnswerItem[];
33
+ }
34
+ /** What the model reads when the deployment does not answer questions. */
35
+ export declare const QA_QUESTIONS_UNSUPPORTED = "questions are not answered in this assistant view; ask the user in plain text instead";
36
+ /**
37
+ * User questions in the QA view.
38
+ *
39
+ * `ask_user_question` reaches the browser through the harness answerer
40
+ * waterfall, and the stock DSH web bundle mounts its own answerer in every
41
+ * page. Behind the QA overlay that answerer is unreachable, so a question asked
42
+ * of a QA chat would sit in front of nobody. This gate claims the request for
43
+ * attested chats before the generic browser bridge sees it:
44
+ *
45
+ * - `interaction.questions: interactive` parks the request until the operator
46
+ * answers or closes it in the QA view, and the answer becomes the waterfall's
47
+ * value.
48
+ * - `unsupported` (default) refuses with a reason the model can act on, rather
49
+ * than letting the turn stall on a card no one can see.
50
+ *
51
+ * Nothing is ever answered on the operator's behalf, and a request from a
52
+ * session this deployment did not attest is handed back to the chain untouched.
53
+ */
54
+ export declare class QaQuestionGate {
55
+ private readonly ctx;
56
+ private readonly interactive;
57
+ private readonly ownership;
58
+ private readonly logger;
59
+ private readonly pending;
60
+ private readonly disposers;
61
+ constructor(ctx: Context, interactive: () => boolean, ownership: QaSessionOwnership, logger: PluginLogger);
62
+ /** Claim question requests for the chats this deployment answers. */
63
+ install(): void;
64
+ /** Questions of one chat, oldest first: what the QA view renders. */
65
+ list(sessionId: string): readonly QaPendingQuestion[];
66
+ /**
67
+ * Apply the operator's answers; an unknown or foreign id is refused. The
68
+ * parked request is authoritative: a label the question never offered is
69
+ * dropped, and a free-text answer replaces the choice in a single-select
70
+ * rather than accompanying it, so the model only ever reads a real answer.
71
+ */
72
+ answer(sessionId: string, requestId: string, answers: readonly QaQuestionAnswerItem[]): boolean;
73
+ /** Close a request without answering it. */
74
+ cancel(sessionId: string, requestId: string): boolean;
75
+ /** Detach the listener and fail every parked request. Wired as an effect. */
76
+ dispose(): void;
77
+ private handle;
78
+ /** Park one request until the operator answers it, or the turn ends. */
79
+ private park;
80
+ /** Fail the questions one session's agent owns; a disposed agent cannot ask. */
81
+ private settleOwner;
82
+ }
83
+ //# sourceMappingURL=questions.d.ts.map
@@ -32,7 +32,7 @@ export declare class QaPolicyAdmission {
32
32
  * one set answers for the whole chat.
33
33
  */
34
34
  private readonly attested;
35
- private readonly workspaceRoots;
35
+ private readonly workspaceAccess;
36
36
  private readonly disposeWorkspaceGuard;
37
37
  constructor(ctx: Context, config: () => ResolvedQaSurfaceConfig, logger: PluginLogger, accounts?: QaAccountsGate | undefined);
38
38
  /**
@@ -43,7 +43,26 @@ export declare class QaPolicyAdmission {
43
43
  * closed — attachments then only work where reads are not fenced per user.
44
44
  */
45
45
  private attachmentRoot;
46
- secureSession(token: string, sessionId: string): QaLockdownProof;
46
+ /**
47
+ * The live agent for one session, resuming a Session the Host has not
48
+ * materialized in this process.
49
+ *
50
+ * DSH builds an agent on demand: a session's journal opens straight from
51
+ * persistence (`session/page` reads the durable log), and only Agent-bound
52
+ * operations — a prompt, a model selection, renaming, an upload — resolve or
53
+ * resume one. So a chat from an earlier Host run has a readable transcript
54
+ * and no agent at all, and attestation, which pins the tool policy ON that
55
+ * agent, is the first thing here that needs one. Refusing instead would make
56
+ * every restored chat unopenable until something else in the Host happened
57
+ * to wake it.
58
+ *
59
+ * The resume composes the session's OWN recorded preset — the same
60
+ * composition a stock prompt would produce — so a session composed outside
61
+ * the QA preset still lands on the mismatch refusals below ("composition
62
+ * mismatch"), and the adoption and permission checks stay the gate.
63
+ */
64
+ private liveAgent;
65
+ secureSession(token: string, sessionId: string): Promise<QaLockdownProof>;
47
66
  /**
48
67
  * Whether one session went through this boundary. The provenance note is
49
68
  * written only for attested sessions, which is what keeps a deployment's
@@ -0,0 +1,30 @@
1
+ import type { Context } from "@deepseek-ai/cordis";
2
+ /**
3
+ * Which sessions belong to this deployment.
4
+ *
5
+ * The admission boundary attests chat roots. A delegated child never appears
6
+ * there — its scope chain does not reach the chat's own agent context — so it
7
+ * inherits its chat from the session that created it. Both interactive seams
8
+ * (tool approvals and user questions) read ownership from here, which is what
9
+ * keeps one chat answered by exactly one surface.
10
+ */
11
+ export declare class QaSessionOwnership {
12
+ private readonly isAttested;
13
+ /** Child session → the attested chat that owns it. */
14
+ private readonly inherited;
15
+ private disposeListener;
16
+ private installed;
17
+ constructor(isAttested: (sessionId: string) => boolean);
18
+ /** Listen for the children of an attested chat; safe to call from each seam. */
19
+ install(ctx: Context): void;
20
+ /** The attested chat behind a session: itself, or the root it inherited. */
21
+ rootOf(sessionId: string): string | undefined;
22
+ /**
23
+ * Drop one session's inheritance. Called when its agent is gone; the chat's
24
+ * own claim needs no bookkeeping here, because it resolves through the
25
+ * admission's attested set, which owns that lifetime.
26
+ */
27
+ forget(sessionId: string): void;
28
+ dispose(): void;
29
+ }
30
+ //# sourceMappingURL=session-ownership.d.ts.map
@@ -3,6 +3,25 @@ export type QaSessionPolicy = "browser-persistent" | "new-on-load" | "fixed";
3
3
  export type QaSandboxMode = "read-only" | "workspace-write";
4
4
  export type QaApprovalPolicy = "never";
5
5
  export type QaToolPolicyMode = "allow-list";
6
+ /**
7
+ * How a tool policy `ask` resolves on an attested QA agent. `blocked` refuses
8
+ * the call with the surface's own reason; `interactive` parks it until the
9
+ * operator answers in the QA view.
10
+ */
11
+ export type QaApprovalInteraction = "blocked" | "interactive";
12
+ /**
13
+ * How a user-questions request resolves on an attested QA agent. `unsupported`
14
+ * refuses the ask outright; `interactive` answers it from the QA view.
15
+ */
16
+ export type QaQuestionInteraction = "unsupported" | "interactive";
17
+ /** The operator's answer to one parked tool call. */
18
+ export type QaApprovalDecision = "allowed-once" | "rejected";
19
+ /** One answered question; `custom` is free text, and may accompany `selected`. */
20
+ export interface QaQuestionAnswerItem {
21
+ readonly id: string;
22
+ readonly selected: readonly string[];
23
+ readonly custom?: string;
24
+ }
6
25
  export type QaAccountRole = "user" | "admin";
7
26
  /** The account fields projected to browsers; never includes credentials. */
8
27
  export interface QaAccountUserPublic {
@@ -107,6 +126,11 @@ export interface QaSourcesConfig {
107
126
  readonly inheritSources?: boolean;
108
127
  readonly enableReportToolFallback?: boolean;
109
128
  readonly markIncompleteOpaqueRuns?: boolean;
129
+ /**
130
+ * Whether a source the model writes into `qa_report_sources` must carry a
131
+ * usable path or URL. Off records the model's own type, title and snippet.
132
+ */
133
+ readonly validateReportedSources?: boolean;
110
134
  };
111
135
  readonly legacy?: {
112
136
  readonly parseAssistantSourcesBlock?: boolean;
@@ -158,8 +182,8 @@ export interface QaSurfaceConfig {
158
182
  */
159
183
  readonly thinkingPhrases?: readonly string[];
160
184
  readonly interaction?: {
161
- readonly approvals?: "blocked";
162
- readonly questions?: "unsupported";
185
+ readonly approvals?: QaApprovalInteraction;
186
+ readonly questions?: QaQuestionInteraction;
163
187
  };
164
188
  readonly lockdown?: {
165
189
  readonly enabled?: boolean;
@@ -180,6 +204,8 @@ export interface QaSurfaceConfig {
180
204
  readonly mode?: QaToolPolicyMode;
181
205
  readonly allow?: readonly string[];
182
206
  };
207
+ /** Shared directories available to read-only filesystem tools. */
208
+ readonly sharedReadOnlyRoots?: readonly string[];
183
209
  };
184
210
  readonly embedding?: {
185
211
  readonly frameAncestors?: string | null;
@@ -277,8 +303,8 @@ export interface ResolvedQaSurfaceConfig {
277
303
  readonly suggestedQuestions: readonly string[];
278
304
  readonly thinkingPhrases: readonly string[];
279
305
  readonly interaction: {
280
- readonly approvals: "blocked";
281
- readonly questions: "unsupported";
306
+ readonly approvals: QaApprovalInteraction;
307
+ readonly questions: QaQuestionInteraction;
282
308
  };
283
309
  readonly lockdown: {
284
310
  readonly enabled: boolean;
@@ -299,6 +325,7 @@ export interface ResolvedQaSurfaceConfig {
299
325
  readonly mode: QaToolPolicyMode;
300
326
  readonly allow: readonly string[];
301
327
  };
328
+ readonly sharedReadOnlyRoots: readonly string[];
302
329
  };
303
330
  readonly embedding: {
304
331
  readonly frameAncestors: string | null;
@@ -355,6 +382,7 @@ export interface ResolvedQaSurfaceConfig {
355
382
  readonly inheritSources: boolean;
356
383
  readonly enableReportToolFallback: boolean;
357
384
  readonly markIncompleteOpaqueRuns: boolean;
385
+ readonly validateReportedSources: boolean;
358
386
  };
359
387
  readonly legacy: {
360
388
  readonly parseAssistantSourcesBlock: boolean;
@@ -516,6 +544,50 @@ export interface QaSubagentView {
516
544
  readonly id: string;
517
545
  readonly title: string;
518
546
  }
547
+ /**
548
+ * One tool call waiting for the operator. The browser lists these over its own
549
+ * remote and answers them one by one; nothing here is answered automatically.
550
+ */
551
+ export interface QaPendingApproval {
552
+ readonly id: string;
553
+ /** The chat the request belongs to: a delegated child asks under its root. */
554
+ readonly sessionId: string;
555
+ readonly toolName: string;
556
+ /** The reason the composed gate gave for asking, when it gave one. */
557
+ readonly reason: string | null;
558
+ readonly createdAt: number;
559
+ /** True when a delegated child of the chat made the call. */
560
+ readonly delegated: boolean;
561
+ }
562
+ /**
563
+ * One question waiting for the operator, normalized for the form the QA view
564
+ * renders. The protocol fields are the harness user-questions contract; absent
565
+ * ones become explicit nulls so the browser never branches on undefined.
566
+ */
567
+ export interface QaPendingQuestionItem {
568
+ readonly id: string;
569
+ readonly question: string;
570
+ readonly header: string | null;
571
+ readonly detail: string | null;
572
+ readonly options: readonly QaPendingQuestionOption[];
573
+ readonly multiSelect: boolean;
574
+ }
575
+ export interface QaPendingQuestionOption {
576
+ readonly label: string;
577
+ readonly description: string | null;
578
+ }
579
+ /**
580
+ * One user-questions request parked for the operator. A single request carries
581
+ * every question the model asked in one call, so the card is a form with a
582
+ * pager, not a list of independent prompts.
583
+ */
584
+ export interface QaPendingQuestion {
585
+ readonly id: string;
586
+ /** The chat the request belongs to. */
587
+ readonly sessionId: string;
588
+ readonly questions: readonly QaPendingQuestionItem[];
589
+ readonly createdAt: number;
590
+ }
519
591
  export interface QaSessionState {
520
592
  readonly phase: QaSessionPhase;
521
593
  readonly sessionId: string | null;
@@ -531,5 +603,9 @@ export interface QaSessionState {
531
603
  readonly incompleteSourceOrigins: QaTurnSources["incompleteOrigins"];
532
604
  /** Set while the bound session is a subagent watched from the panel. */
533
605
  readonly viewingSubagent: QaSubagentView | null;
606
+ /** Tool calls parked for the operator's answer, oldest first. */
607
+ readonly approvals: readonly QaPendingApproval[];
608
+ /** Question requests parked for the operator's answer, oldest first. */
609
+ readonly questions: readonly QaPendingQuestion[];
534
610
  }
535
611
  //# sourceMappingURL=types.d.ts.map
@@ -7,6 +7,10 @@ export interface QaToolExecutionLike {
7
7
  readonly name: string;
8
8
  readonly arguments: unknown;
9
9
  }
10
+ export interface QaUserWorkspaceReadPolicy {
11
+ /** Shared directories exposed only to read-only filesystem tools. */
12
+ readonly sharedReadOnlyRoots?: readonly string[];
13
+ }
10
14
  export declare function pathIsInside(target: string, root: string): boolean;
11
15
  /**
12
16
  * Resolve the deepest existing ancestor, preserving the missing suffix. This
@@ -34,5 +38,5 @@ export declare function existingQaUserWorkspace(workspaceRoot: string, userId: s
34
38
  * directory-wide tools stay confined because the store is shared by every
35
39
  * account, and writes are never exempted.
36
40
  */
37
- export declare function qaUserWorkspaceDenial(execution: QaToolExecutionLike, root: string, attachmentRoot?: string): string | undefined;
41
+ export declare function qaUserWorkspaceDenial(execution: QaToolExecutionLike, root: string, attachmentRoot?: string, readPolicy?: QaUserWorkspaceReadPolicy): string | undefined;
38
42
  //# sourceMappingURL=user-workspace.d.ts.map
@@ -132,7 +132,17 @@ function requestedPaths(execution) {
132
132
  * for reads: the attachment store is shared by every account, and only the
133
133
  * exact file an upload produced is meant to be reachable.
134
134
  */
135
- function isReadOnlyPathTool(execution) {
135
+ function readsSharedRoot(execution) {
136
+ if (execution.name === "read" ||
137
+ execution.name === "read_image" ||
138
+ execution.name === "glob" ||
139
+ execution.name === "grep") {
140
+ return true;
141
+ }
142
+ return (execution.name === "str_replace_editor" &&
143
+ record(execution.arguments)?.command === "view");
144
+ }
145
+ function readsSingleFile(execution) {
136
146
  if (execution.name === "read" || execution.name === "read_image")
137
147
  return true;
138
148
  return (execution.name === "str_replace_editor" &&
@@ -176,7 +186,7 @@ function requestedWriteBytes(execution) {
176
186
  * directory-wide tools stay confined because the store is shared by every
177
187
  * account, and writes are never exempted.
178
188
  */
179
- export function qaUserWorkspaceDenial(execution, root, attachmentRoot) {
189
+ export function qaUserWorkspaceDenial(execution, root, attachmentRoot, readPolicy = {}) {
180
190
  const args = record(execution.arguments);
181
191
  if (args?.sandbox_permissions !== undefined ||
182
192
  (execution.name === "edit" &&
@@ -189,12 +199,13 @@ export function qaUserWorkspaceDenial(execution, root, attachmentRoot) {
189
199
  execution.name.startsWith("job_") ||
190
200
  execution.name === "run_code" ||
191
201
  execution.name === "lsp" ||
192
- execution.name === "apply_patch" ||
193
- execution.name.startsWith("dsh_git_")) {
202
+ execution.name === "apply_patch") {
194
203
  return PATH_DENIAL;
195
204
  }
196
- const readsOnly = isReadOnlyPathTool(execution);
205
+ const readsShared = readsSharedRoot(execution);
206
+ const readsOneFile = readsSingleFile(execution);
197
207
  try {
208
+ const sharedReadOnlyRoots = (readPolicy.sharedReadOnlyRoots ?? []).map(canonicalCandidate);
198
209
  for (const requested of requestedPaths(execution)) {
199
210
  const absolute = path.isAbsolute(requested)
200
211
  ? requested
@@ -202,9 +213,13 @@ export function qaUserWorkspaceDenial(execution, root, attachmentRoot) {
202
213
  const canonical = canonicalCandidate(absolute);
203
214
  if (pathIsInside(canonical, root))
204
215
  continue;
216
+ if (readsShared &&
217
+ sharedReadOnlyRoots.some((readRoot) => pathIsInside(canonical, readRoot))) {
218
+ continue;
219
+ }
205
220
  // Resolved only for a path the fence would otherwise refuse, so the
206
221
  // common case pays no extra filesystem walk.
207
- if (readsOnly &&
222
+ if (readsOneFile &&
208
223
  attachmentRoot !== undefined &&
209
224
  pathIsInside(canonical, canonicalCandidate(attachmentRoot))) {
210
225
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"user-workspace.js","sourceRoot":"","sources":["../src/user-workspace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"user-workspace.js","sourceRoot":"","sources":["../src/user-workspace.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yadsh/dsh-qa-surface",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "A focused end-user QA surface backed by native DeepSeek Harness sessions",
5
5
  "repository": {
6
6
  "type": "git",
@@ -162,8 +162,8 @@
162
162
  "typescript": "^7.0.2",
163
163
  "vitest": "^4.1.11",
164
164
  "@yadsh/dsh-config": "^0.0.0",
165
- "@yadsh/dsh-plugin-scripts": "^0.0.0",
166
- "@yadsh/dsh-plugin-kit": "^0.1.0"
165
+ "@yadsh/dsh-plugin-kit": "^0.1.0",
166
+ "@yadsh/dsh-plugin-scripts": "^0.0.0"
167
167
  },
168
168
  "publishConfig": {
169
169
  "access": "public",