@yadsh/dsh-qa-surface 0.11.0 → 0.11.2
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 +81 -58
- package/lib/client/QaSessionController.js +24 -2
- package/lib/client/QaSessionController.js.map +1 -1
- package/lib/client/components/QaChangelog.js +31 -0
- package/lib/client/components/QaChangelog.js.map +1 -1
- package/lib/client/slash/SlashPalette.js +4 -13
- package/lib/client/slash/SlashPalette.js.map +1 -1
- package/lib/client/slash/palette-rows.js +45 -0
- package/lib/client/slash/palette-rows.js.map +1 -0
- package/lib/client/slash/useSlashNavigation.js +8 -2
- package/lib/client/slash/useSlashNavigation.js.map +1 -1
- package/lib/client/turn-sources.js +20 -0
- package/lib/client/turn-sources.js.map +1 -1
- package/lib/client.js +192 -98
- package/lib/client.js.map +1 -1
- package/lib/config-resolvers/defaults.js +3 -0
- package/lib/config-resolvers/defaults.js.map +1 -1
- package/lib/config-resolvers/integration.js +9 -3
- package/lib/config-resolvers/integration.js.map +1 -1
- package/lib/config-resolvers/shared.js +12 -0
- package/lib/config-resolvers/shared.js.map +1 -1
- package/lib/config-resolvers/tools.js +1 -0
- package/lib/config-resolvers/tools.js.map +1 -1
- package/lib/config.js +6 -0
- package/lib/config.js.map +1 -1
- package/lib/index.js +5 -2
- package/lib/index.js.map +1 -1
- package/lib/integration/attachments.js +16 -1
- package/lib/integration/attachments.js.map +1 -1
- package/lib/integration/http.js +59 -21
- package/lib/integration/http.js.map +1 -1
- package/lib/integration/service.js +42 -0
- package/lib/integration/service.js.map +1 -1
- package/lib/launch-token.js +22 -17
- package/lib/launch-token.js.map +1 -1
- package/lib/qa-tools/catalog.js +2 -2
- package/lib/qa-tools/catalog.js.map +1 -1
- package/lib/qa-tools/docs-tools.js +66 -9
- package/lib/qa-tools/docs-tools.js.map +1 -1
- package/lib/qa-tools/index.js +1 -0
- package/lib/qa-tools/index.js.map +1 -1
- package/lib/secure-session.js +14 -4
- package/lib/secure-session.js.map +1 -1
- package/lib/typert.host.js +69 -68
- package/lib/typert.remote-client.js +68 -67
- package/lib/types/client/QaSessionController.d.ts +14 -0
- package/lib/types/client/components/QaWidthHandle.d.ts +0 -1
- package/lib/types/client/slash/palette-rows.d.ts +43 -0
- package/lib/types/client/turn-sources.d.ts +14 -0
- package/lib/types/config-resolvers/integration.d.ts +7 -1
- package/lib/types/config-resolvers/shared.d.ts +8 -0
- package/lib/types/launch-token.d.ts +10 -3
- package/lib/types/qa-tools/catalog.d.ts +6 -1
- package/lib/types/qa-tools/docs-tools.d.ts +23 -5
- package/lib/types/qa-tools/index.d.ts +2 -0
- package/lib/types/types.d.ts +12 -0
- package/package.json +3 -3
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grouping for the palette's rows.
|
|
3
|
+
*
|
|
4
|
+
* Ranking is global: skills and commands are scored and sorted together, so
|
|
5
|
+
* `/tkp` can put a command between two skills and a palette that captioned
|
|
6
|
+
* every neighbouring run would draw «Навыки» twice over one group of rows.
|
|
7
|
+
*
|
|
8
|
+
* This module is the translation between the two: it buckets the ranked rows
|
|
9
|
+
* by kind, keeps each bucket in ranked order, and puts the bucket whose best
|
|
10
|
+
* row ranked highest first. The palette's first row is therefore still the
|
|
11
|
+
* best match — which is the row Enter picks when the user types nothing else.
|
|
12
|
+
*
|
|
13
|
+
* A row keeps its `index` from the ranked list, so what the keyboard moves
|
|
14
|
+
* through is the order the palette draws: the navigation hook publishes the
|
|
15
|
+
* flattened groups rather than the raw ranking.
|
|
16
|
+
*
|
|
17
|
+
* Pure on purpose: the hook and the component both need the same grouping, and
|
|
18
|
+
* the tests drive it with plain arrays.
|
|
19
|
+
*/
|
|
20
|
+
import type { QaSlashCatalogEntry } from "../../types.js";
|
|
21
|
+
/** One palette row: the entry, and where it sat in the ranked list. */
|
|
22
|
+
export interface QaSlashPaletteRow {
|
|
23
|
+
readonly entry: QaSlashCatalogEntry;
|
|
24
|
+
/** Position in the ranked list these groups were built from. */
|
|
25
|
+
readonly index: number;
|
|
26
|
+
}
|
|
27
|
+
/** One titled group of the palette: exactly one per kind that was ranked. */
|
|
28
|
+
export interface QaSlashPaletteGroup {
|
|
29
|
+
readonly kind: QaSlashCatalogEntry["kind"];
|
|
30
|
+
readonly rows: readonly QaSlashPaletteRow[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Bucket ranked rows by kind, one group per kind.
|
|
34
|
+
*
|
|
35
|
+
* A kind with no row contributes no group, and the group order follows the
|
|
36
|
+
* ranking (the best row's own kind leads) rather than a fixed
|
|
37
|
+
* skill-then-command order, so the top of the list never disagrees with the
|
|
38
|
+
* ranking above it.
|
|
39
|
+
*/
|
|
40
|
+
export declare function groupPaletteRows(rows: readonly QaSlashCatalogEntry[]): readonly QaSlashPaletteGroup[];
|
|
41
|
+
/** The entries of every group, in the order the palette draws them. */
|
|
42
|
+
export declare function flattenPaletteGroups(groups: readonly QaSlashPaletteGroup[]): readonly QaSlashCatalogEntry[];
|
|
43
|
+
//# sourceMappingURL=palette-rows.d.ts.map
|
|
@@ -9,6 +9,20 @@ export declare function chatLegacyOf(snapshot: ConversationSnapshot | undefined)
|
|
|
9
9
|
* and replay and requires no assistant-authored bibliography.
|
|
10
10
|
*/
|
|
11
11
|
export declare function projectTurnSources(snapshot: ConversationSnapshot | undefined, sessionId?: string, workspaceRoot?: string): readonly QaTurnSources[];
|
|
12
|
+
/**
|
|
13
|
+
* The directory a projected source path is anchored on: the chat's own cwd.
|
|
14
|
+
*
|
|
15
|
+
* Both channels read the same durable tool results, and the Host's evidence —
|
|
16
|
+
* the set the source preview checks a request against — canonicalizes every
|
|
17
|
+
* recorded path against the session's own cwd. A projection anchored on
|
|
18
|
+
* anything else splits one file into two spellings the moment the two
|
|
19
|
+
* directories differ (an adopted chat, a chat whose cwd was pinned under an
|
|
20
|
+
* older configuration): the rail then shows a path the Host does not hold, and
|
|
21
|
+
* the detailed view refuses a source the answer just cited as no longer
|
|
22
|
+
* evidence until the rail is rebuilt from the Host's own bundles. The
|
|
23
|
+
* configured pin stays the fallback for a chat the browser cannot place yet.
|
|
24
|
+
*/
|
|
25
|
+
export declare function sourceAnchorRoot(chatCwd: string | undefined, configuredCwd: string | null): string | undefined;
|
|
12
26
|
/** Visible evidence sources for the latest turn, shared by the drawer/footer. */
|
|
13
27
|
export declare function projectSources(snapshot: ConversationSnapshot | undefined, sessionId?: string, workspaceRoot?: string): readonly QaSource[];
|
|
14
28
|
//# sourceMappingURL=turn-sources.d.ts.map
|
|
@@ -3,8 +3,14 @@ type ResolvedIntegration = ResolvedQaSurfaceConfig["integration"];
|
|
|
3
3
|
/** Operator-tunable bounds; the values the settings card shows as hard limits. */
|
|
4
4
|
export declare const QA_INTEGRATION_TTL_DAYS_MIN = 1;
|
|
5
5
|
export declare const QA_INTEGRATION_TTL_DAYS_MAX = 3650;
|
|
6
|
+
/**
|
|
7
|
+
* Floor only: how long an integration may wait for its answer is the operator's
|
|
8
|
+
* call. The deployment spends no budget of its own by waiting, and the ceiling
|
|
9
|
+
* this constant used to carry (10 minutes) truncated exactly the long questions
|
|
10
|
+
* an integration exists for — a nineteen-minute analysis came back as
|
|
11
|
+
* "escalate" while the answer was still being written.
|
|
12
|
+
*/
|
|
6
13
|
export declare const QA_INTEGRATION_TIMEOUT_MS_MIN = 5000;
|
|
7
|
-
export declare const QA_INTEGRATION_TIMEOUT_MS_MAX = 600000;
|
|
8
14
|
export declare const QA_INTEGRATION_CONCURRENCY_MIN = 1;
|
|
9
15
|
export declare const QA_INTEGRATION_CONCURRENCY_MAX = 16;
|
|
10
16
|
export declare const QA_INTEGRATION_RATE_MIN = 1;
|
|
@@ -7,6 +7,14 @@ export declare function optionalText(value: string | null | undefined): string |
|
|
|
7
7
|
* Windows-style root is not a mistake to reject on a POSIX host.
|
|
8
8
|
*/
|
|
9
9
|
export declare function isAbsoluteDirectoryPath(value: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Shared numeric guard for a limit with a floor but no honest ceiling: the value
|
|
12
|
+
* has to be a safe integer of at least `min`. A ceiling belongs on a budget the
|
|
13
|
+
* deployment itself spends (bytes, parallel calls); a wait it merely allows is
|
|
14
|
+
* the operator's call, and a ceiling there only ever truncated a legitimate long
|
|
15
|
+
* answer.
|
|
16
|
+
*/
|
|
17
|
+
export declare function assertIntAtLeast(name: string, value: number, min: number): void;
|
|
10
18
|
/**
|
|
11
19
|
* Shared numeric guard for operator-tuned limits: the value has to be a safe
|
|
12
20
|
* integer inside [min, max], and every rejection carries the same message.
|
|
@@ -12,9 +12,16 @@ interface AuthenticatedUrlFace {
|
|
|
12
12
|
authenticatedUrl?(baseUrl: string): string;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
* Resolve the launch token
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* Resolve the launch token lazily, on the navigations that need it.
|
|
16
|
+
*
|
|
17
|
+
* A token that resolved is cached — it is stable for the process lifetime, so
|
|
18
|
+
* the host is asked once. A failure is **not** cached: the first `/qa` request
|
|
19
|
+
* can arrive while the plugin tree is still starting, when `connection` is not
|
|
20
|
+
* answerable yet, and treating that single early answer as final used to leave
|
|
21
|
+
* every later cookie-less browser on the marker hand-off, which dead-ends at
|
|
22
|
+
* the host's token screen until the next restart. The failure is reported once
|
|
23
|
+
* per reason and retried quietly afterwards, so the retry costs a service
|
|
24
|
+
* lookup and never a log flood.
|
|
18
25
|
*/
|
|
19
26
|
export declare function makeLaunchTokenSource(getConnection: () => AuthenticatedUrlFace | undefined, warn: (message: string) => void): LaunchTokenSource;
|
|
20
27
|
export {};
|
|
@@ -9,7 +9,7 @@ import type { QaToolDescriptor } from "./types.js";
|
|
|
9
9
|
* Bump it whenever the catalog's tool set or their schemas change.
|
|
10
10
|
*/
|
|
11
11
|
export declare const QA_TOOL_CATALOG_VERSION = "3";
|
|
12
|
-
/**
|
|
12
|
+
/** What the catalog's definitions read, beyond the execution record. */
|
|
13
13
|
export interface QaToolsSelfcheckDeps {
|
|
14
14
|
readonly catalogVersion: string;
|
|
15
15
|
readonly activationMode: string;
|
|
@@ -19,6 +19,11 @@ export interface QaToolsSelfcheckDeps {
|
|
|
19
19
|
readonly activeTools: (agent: Agent) => readonly string[];
|
|
20
20
|
/** Whether the calling agent's session shows the activation skill was loaded. */
|
|
21
21
|
readonly skillLoaded: (agent: Agent) => boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Documentation root the two readers use, or `""` for the `docs/` directory
|
|
24
|
+
* inside each chat's own workspace.
|
|
25
|
+
*/
|
|
26
|
+
readonly docsRoot?: string;
|
|
22
27
|
}
|
|
23
28
|
/**
|
|
24
29
|
* Build the shipped QA tool catalog.
|
|
@@ -54,11 +54,25 @@ interface QaDocsExecution {
|
|
|
54
54
|
};
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Where this deployment publishes its documentation.
|
|
59
|
+
*
|
|
60
|
+
* A deployment that hands every chat its own workspace publishes documentation
|
|
61
|
+
* inside it, and an empty `root` keeps that layout. One that publishes the
|
|
62
|
+
* corpus once — outside every per-user directory — names it here, and the tools
|
|
63
|
+
* read it exactly as they read a per-chat tree: same fence, same reported paths
|
|
64
|
+
* (`docs/<module>/<version>/…`), only the directory that contains the tree
|
|
65
|
+
* comes from configuration instead of from the calling chat.
|
|
66
|
+
*/
|
|
67
|
+
export interface QaDocsOptions {
|
|
68
|
+
/** Absolute documentation root, or `""` for `<chat workspace>/docs`. */
|
|
69
|
+
readonly root?: string;
|
|
70
|
+
}
|
|
57
71
|
/** The resolved documentation root of one call. */
|
|
58
72
|
export interface QaDocsRoot {
|
|
59
|
-
/** Canonical
|
|
73
|
+
/** Canonical directory the tree sits in: the chat's workspace, or the configured root's parent. */
|
|
60
74
|
readonly workspace: string;
|
|
61
|
-
/** Canonical
|
|
75
|
+
/** Canonical directory documentation is read from. */
|
|
62
76
|
readonly docs: string;
|
|
63
77
|
}
|
|
64
78
|
/**
|
|
@@ -116,8 +130,12 @@ export declare function docsIdentityOf(pathFromDocsRoot: string): QaDocsIdentity
|
|
|
116
130
|
* The root is a real directory inside the canonical workspace: a `docs` entry
|
|
117
131
|
* that is a link or a file is refused rather than followed, because the fence
|
|
118
132
|
* is the point of the tool and a link is how a fence is left.
|
|
133
|
+
*
|
|
134
|
+
* A deployment that names its corpus once (`QaDocsOptions.root`) skips the
|
|
135
|
+
* per-chat lookup entirely — that layout is exactly why it configures the root —
|
|
136
|
+
* and is held to the same rules: absolute, a real directory, no links.
|
|
119
137
|
*/
|
|
120
|
-
export declare function docsRootOf(exec: QaDocsExecution): Promise<QaDocsRoot>;
|
|
138
|
+
export declare function docsRootOf(exec: QaDocsExecution, options?: QaDocsOptions): Promise<QaDocsRoot>;
|
|
121
139
|
export interface QaDocsSearchRequest {
|
|
122
140
|
readonly query: string;
|
|
123
141
|
readonly version?: string | undefined;
|
|
@@ -153,8 +171,8 @@ export declare function readDocumentation(root: QaDocsRoot, request: QaDocsReadR
|
|
|
153
171
|
* version/module facets exist so a model that has been told "3.8" stops
|
|
154
172
|
* sweeping the whole tree.
|
|
155
173
|
*/
|
|
156
|
-
export declare function createDocsSearchTool(): ToolDefinition;
|
|
174
|
+
export declare function createDocsSearchTool(options?: QaDocsOptions): ToolDefinition;
|
|
157
175
|
/** `docs_read` — open one documentation file at a bounded window of lines. */
|
|
158
|
-
export declare function createDocsReadTool(): ToolDefinition;
|
|
176
|
+
export declare function createDocsReadTool(options?: QaDocsOptions): ToolDefinition;
|
|
159
177
|
export {};
|
|
160
178
|
//# sourceMappingURL=docs-tools.d.ts.map
|
|
@@ -8,6 +8,8 @@ export interface QaToolsOptions {
|
|
|
8
8
|
readonly activationSkill: string;
|
|
9
9
|
readonly activationMode: string;
|
|
10
10
|
readonly activationPresets: readonly string[];
|
|
11
|
+
/** Documentation root the readers use; `""` reads each chat's own `docs/`. */
|
|
12
|
+
readonly docsRoot: string;
|
|
11
13
|
}
|
|
12
14
|
/**
|
|
13
15
|
* The QA tool subsystem: one catalog, one per-agent activation manager, and the
|
package/lib/types/types.d.ts
CHANGED
|
@@ -714,6 +714,13 @@ export interface QaSurfaceConfig {
|
|
|
714
714
|
* name the QA preset in any deployment that composes more than one.
|
|
715
715
|
*/
|
|
716
716
|
readonly activationPresets?: readonly string[];
|
|
717
|
+
/**
|
|
718
|
+
* Absolute path of the documentation tree `docs_search`/`docs_read` read.
|
|
719
|
+
* Leave it empty when the deployment publishes `docs/` inside each chat's
|
|
720
|
+
* own workspace; name it when the corpus is published once, outside every
|
|
721
|
+
* per-user directory, which is otherwise unreadable to those tools.
|
|
722
|
+
*/
|
|
723
|
+
readonly docsRoot?: string;
|
|
717
724
|
};
|
|
718
725
|
readonly lockdown?: {
|
|
719
726
|
readonly enabled?: boolean;
|
|
@@ -990,6 +997,11 @@ export interface ResolvedQaSurfaceConfig {
|
|
|
990
997
|
readonly activationSkill: string;
|
|
991
998
|
readonly activationMode: QaToolActivationMode;
|
|
992
999
|
readonly activationPresets: readonly string[];
|
|
1000
|
+
/**
|
|
1001
|
+
* Absolute documentation root the QA catalogue reads, or `""` for the
|
|
1002
|
+
* `docs/` directory inside each chat's own workspace.
|
|
1003
|
+
*/
|
|
1004
|
+
readonly docsRoot: string;
|
|
993
1005
|
};
|
|
994
1006
|
readonly sources: {
|
|
995
1007
|
readonly enabled: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yadsh/dsh-qa-surface",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.2",
|
|
4
4
|
"description": "A focused end-user QA surface backed by native DeepSeek Harness sessions",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -134,9 +134,9 @@
|
|
|
134
134
|
"yaml": "^2.9.0",
|
|
135
135
|
"zod": "^4.4.3",
|
|
136
136
|
"@yadsh/dsh-audit-core": "^0.1.0",
|
|
137
|
-
"@yadsh/dsh-
|
|
138
|
-
"@yadsh/dsh-documents": "^0.5.0",
|
|
137
|
+
"@yadsh/dsh-documents": "^0.5.1",
|
|
139
138
|
"@yadsh/dsh-plugin-log": "^0.4.0",
|
|
139
|
+
"@yadsh/dsh-audit-ui": "^0.1.1",
|
|
140
140
|
"@yadsh/dsh-plugin-kit": "^0.3.0"
|
|
141
141
|
},
|
|
142
142
|
"devDependencies": {
|