@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.
- package/README.md +41 -5
- package/cordis.patch.yml +8 -0
- package/lib/accounts/credentials.js +12 -4
- package/lib/accounts/credentials.js.map +1 -1
- package/lib/accounts/store.js +16 -1
- package/lib/accounts/store.js.map +1 -1
- package/lib/approvals.js +179 -0
- package/lib/approvals.js.map +1 -0
- package/lib/cli.js +10 -0
- package/lib/cli.js.map +1 -1
- package/lib/client/QaSessionController.js +93 -0
- package/lib/client/QaSessionController.js.map +1 -1
- package/lib/client/QaSurface.js +14 -1
- package/lib/client/QaSurface.js.map +1 -1
- package/lib/client/approvals.js +104 -0
- package/lib/client/approvals.js.map +1 -0
- package/lib/client/attestation.js +3 -0
- package/lib/client/attestation.js.map +1 -1
- package/lib/client/components/QaApproval.js +23 -0
- package/lib/client/components/QaApproval.js.map +1 -0
- package/lib/client/components/QaChangelog.js +24 -0
- package/lib/client/components/QaChangelog.js.map +1 -1
- package/lib/client/components/QaQuestions.js +96 -0
- package/lib/client/components/QaQuestions.js.map +1 -0
- package/lib/client/index.js +11 -0
- package/lib/client/index.js.map +1 -1
- package/lib/client/project-session-state.js +5 -3
- package/lib/client/project-session-state.js.map +1 -1
- package/lib/client/questions.js +114 -0
- package/lib/client/questions.js.map +1 -0
- package/lib/client/settings/sections/sources.js +2 -0
- package/lib/client/settings/sections/sources.js.map +1 -1
- package/lib/client/styles.js +42 -0
- package/lib/client/styles.js.map +1 -1
- package/lib/client/types.js +2 -0
- package/lib/client/types.js.map +1 -1
- package/lib/client.js +1018 -56
- package/lib/client.js.map +1 -1
- package/lib/config-resolvers/basics.js +4 -2
- package/lib/config-resolvers/basics.js.map +1 -1
- package/lib/config-resolvers/defaults.js +4 -0
- package/lib/config-resolvers/defaults.js.map +1 -1
- package/lib/config-resolvers/lockdown.js +11 -0
- package/lib/config-resolvers/lockdown.js.map +1 -1
- package/lib/config-resolvers/session.js +2 -2
- package/lib/config-resolvers/session.js.map +1 -1
- package/lib/config-resolvers/shared.js +9 -0
- package/lib/config-resolvers/shared.js.map +1 -1
- package/lib/config-resolvers/sources.js +2 -0
- package/lib/config-resolvers/sources.js.map +1 -1
- package/lib/config.js +11 -2
- package/lib/config.js.map +1 -1
- package/lib/index.js +76 -6
- package/lib/index.js.map +1 -1
- package/lib/provenance/host-store.js +25 -9
- package/lib/provenance/host-store.js.map +1 -1
- package/lib/provenance/reported.js +37 -12
- package/lib/provenance/reported.js.map +1 -1
- package/lib/questions.js +185 -0
- package/lib/questions.js.map +1 -0
- package/lib/secure-session.js +69 -17
- package/lib/secure-session.js.map +1 -1
- package/lib/session-ownership.js +55 -0
- package/lib/session-ownership.js.map +1 -0
- package/lib/typert.host.js +357 -17
- package/lib/typert.remote-client.d.ts +11 -1
- package/lib/typert.remote-client.js +287 -14
- package/lib/types/accounts/credentials.d.ts +6 -0
- package/lib/types/accounts/store.d.ts +8 -0
- package/lib/types/approvals.d.ts +65 -0
- package/lib/types/client/QaSessionController.d.ts +38 -1
- package/lib/types/client/QaSurface.d.ts +8 -1
- package/lib/types/client/approvals.d.ts +39 -0
- package/lib/types/client/components/QaApproval.d.ts +13 -0
- package/lib/types/client/components/QaQuestions.d.ts +13 -0
- package/lib/types/client/project-session-state.d.ts +8 -1
- package/lib/types/client/questions.d.ts +45 -0
- package/lib/types/client/types.d.ts +48 -1
- package/lib/types/config-resolvers/shared.d.ts +7 -0
- package/lib/types/index.d.ts +29 -3
- package/lib/types/provenance/reported.d.ts +9 -1
- package/lib/types/questions.d.ts +83 -0
- package/lib/types/secure-session.d.ts +21 -2
- package/lib/types/session-ownership.d.ts +30 -0
- package/lib/types/types.d.ts +80 -4
- package/lib/types/user-workspace.d.ts +5 -1
- package/lib/user-workspace.js +21 -6
- package/lib/user-workspace.js.map +1 -1
- 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.
|
package/lib/types/index.d.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
package/lib/types/types.d.ts
CHANGED
|
@@ -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?:
|
|
162
|
-
readonly questions?:
|
|
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:
|
|
281
|
-
readonly questions:
|
|
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
|
package/lib/user-workspace.js
CHANGED
|
@@ -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
|
|
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
|
|
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 (
|
|
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":"AAAA,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,WAAW,EACX,YAAY,EACZ,QAAQ,GACT,MAAM,SAAS,CAAC;AACjB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,iFAAiF;AACjF,MAAM,CAAC,MAAM,4BAA4B,GAAG,WAAW,CAAC;AAExD,6EAA6E;AAC7E,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAC7D,MAAM,CAAC,MAAM,iCAAiC,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAElE,MAAM,eAAe,GACnB,6EAA6E,CAAC;AAChF,MAAM,WAAW,GACf,+DAA+D,CAAC;AAClE,MAAM,YAAY,GAAG,gDAAgD,CAAC;
|
|
1
|
+
{"version":3,"file":"user-workspace.js","sourceRoot":"","sources":["../src/user-workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,WAAW,EACX,YAAY,EACZ,QAAQ,GACT,MAAM,SAAS,CAAC;AACjB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,iFAAiF;AACjF,MAAM,CAAC,MAAM,4BAA4B,GAAG,WAAW,CAAC;AAExD,6EAA6E;AAC7E,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAC7D,MAAM,CAAC,MAAM,iCAAiC,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAElE,MAAM,eAAe,GACnB,6EAA6E,CAAC;AAChF,MAAM,WAAW,GACf,+DAA+D,CAAC;AAClE,MAAM,YAAY,GAAG,gDAAgD,CAAC;AAYtE,SAAS,QAAQ,CAAC,IAAY,EAAE,KAAa;IAC3C,OAAO,OAAO,CAAC,QAAQ,KAAK,OAAO;QACjC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,WAAW,EAAE;QAC5C,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,IAAY;IACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7C,OAAO,CACL,QAAQ,KAAK,EAAE;QACf,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;YACpC,QAAQ,KAAK,IAAI;YACjB,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAC9B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,MAAM,GAAG,QAAQ,CAAC;IACtB,SAAS,CAAC;QACR,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,KAAK,CAAC;YACpE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,MAAM,KAAK,MAAM;gBAAE,MAAM,KAAK,CAAC;YACnC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACtC,MAAM,GAAG,MAAM,CAAC;QAClB,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAa;IACzC,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9B,IAAI,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,+CAA+C,KAAK,EAAE,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,aAAqB,EACrB,MAAc;IAEd,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IACD,MAAM,kBAAkB,GAAG,YAAY,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,4BAA4B,CAAC,CAAC;IAC9E,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACvD,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAChC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC9D,MAAM,kBAAkB,GAAG,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC1D,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;IACvD,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC/B,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC7D,MAAM,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACxD,IACE,CAAC,YAAY,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;QACpD,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,kBAAkB,CAAC,EAC9D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,uBAAuB,CACrC,aAAqB,EACrB,MAAc;IAEd,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IACD,MAAM,kBAAkB,GAAG,YAAY,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,4BAA4B,CAAC,CAAC;IAC9E,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC9C,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAChC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC/B,MAAM,kBAAkB,GAAG,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC1D,MAAM,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACxD,IACE,CAAC,YAAY,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;QACrD,CAAC,YAAY,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;QACpD,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,kBAAkB,CAAC,EAC9D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACzE,CAAC,CAAE,KAAiC;QACpC,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,SAAS,cAAc,CAAC,SAA8B;IACpD,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACzC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAClC,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC;QACZ,KAAK,YAAY,CAAC;QAClB,KAAK,OAAO,CAAC;QACb,KAAK,MAAM,EAAE,CAAC;YACZ,OAAO,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,CAAC;QACD,KAAK,MAAM,CAAC;QACZ,KAAK,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC3D,CAAC;QACD,KAAK,oBAAoB,EAAE,CAAC;YAC1B,OAAO,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,CAAC;QACD;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,SAA8B;IACrD,IACE,SAAS,CAAC,IAAI,KAAK,MAAM;QACzB,SAAS,CAAC,IAAI,KAAK,YAAY;QAC/B,SAAS,CAAC,IAAI,KAAK,MAAM;QACzB,SAAS,CAAC,IAAI,KAAK,MAAM,EACzB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CACL,SAAS,CAAC,IAAI,KAAK,oBAAoB;QACvC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,MAAM,CAChD,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,SAA8B;IACrD,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,SAAS,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IAC9E,OAAO,CACL,SAAS,CAAC,IAAI,KAAK,oBAAoB;QACvC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,MAAM,CAChD,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,SAAiB;IACrD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,IAAI,SAAS,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAG,CAAC;QAC/B,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YAClE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACjD,IAAI,KAAK,CAAC,cAAc,EAAE;gBAAE,SAAS;YACrC,IAAI,KAAK,CAAC,WAAW,EAAE;gBAAE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;iBAC5C,IAAI,KAAK,CAAC,MAAM,EAAE;gBAAE,KAAK,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC;YAC3D,IAAI,KAAK,GAAG,SAAS;gBAAE,MAAM;QAC/B,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,mBAAmB,CAAC,SAA8B;IACzD,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACzC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7D,OAAO,MAAM,CAAC,MAAM,CAClB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CACf,KAAK,GAAG,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACpE,CAAC,CACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB,CACnC,SAA8B,EAC9B,IAAY,EACZ,cAAuB,EACvB,UAAU,GAA8B,EAAE;IAE1C,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACzC,IACE,IAAI,EAAE,mBAAmB,KAAK,SAAS;QACvC,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM;YACxB,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,IAAI,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC,CAAC,EAC5D,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,IACE,SAAS,CAAC,IAAI,KAAK,MAAM;QACzB,SAAS,CAAC,IAAI,KAAK,OAAO;QAC1B,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QACtC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QACjC,SAAS,CAAC,IAAI,KAAK,UAAU;QAC7B,SAAS,CAAC,IAAI,KAAK,KAAK;QACxB,SAAS,CAAC,IAAI,KAAK,aAAa,EAChC,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,MAAM,WAAW,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAC/C,MAAM,YAAY,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAChD,IAAI,CAAC;QACH,MAAM,mBAAmB,GAAG,CAAC,UAAU,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC,GAAG,CACpE,kBAAkB,CACnB,CAAC;QACF,KAAK,MAAM,SAAS,IAAI,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC;YAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;gBACzC,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAClC,MAAM,SAAS,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAC/C,IAAI,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC;gBAAE,SAAS;YAC5C,IACE,WAAW;gBACX,mBAAmB,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CACpC,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,CAClC,EACD,CAAC;gBACD,SAAS;YACX,CAAC;YACD,oEAAoE;YACpE,6CAA6C;YAC7C,IACE,YAAY;gBACZ,cAAc,KAAK,SAAS;gBAC5B,YAAY,CAAC,SAAS,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC,EAC3D,CAAC;gBACD,SAAS;YACX,CAAC;YACD,OAAO,WAAW,CAAC;QACrB,CAAC;QACD,IACE,SAAS,CAAC,IAAI,KAAK,OAAO;YAC1B,SAAS,CAAC,IAAI,KAAK,MAAM;YACzB,CAAC,SAAS,CAAC,IAAI,KAAK,oBAAoB;gBACtC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC,EAClD,CAAC;YACD,MAAM,SAAS,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;YACjD,IACE,SAAS,GAAG,iCAAiC;gBAC7C,cAAc,CAAC,IAAI,EAAE,2BAA2B,CAAC,GAAG,SAAS;oBAC3D,2BAA2B,EAC7B,CAAC;gBACD,OAAO,YAAY,CAAC;YACtB,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yadsh/dsh-qa-surface",
|
|
3
|
-
"version": "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-
|
|
166
|
-
"@yadsh/dsh-plugin-
|
|
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",
|