@yadsh/dsh-qa-surface 0.2.0 → 0.4.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 +236 -20
- package/compatibility.json +11 -3
- package/lib/account-remotes.js +100 -0
- package/lib/account-remotes.js.map +1 -0
- package/lib/accounts/credentials.js +27 -0
- package/lib/accounts/credentials.js.map +1 -0
- package/lib/accounts/errors.js +9 -0
- package/lib/accounts/errors.js.map +1 -0
- package/lib/accounts/file.js +101 -0
- package/lib/accounts/file.js.map +1 -0
- package/lib/accounts/index.js +2 -0
- package/lib/accounts/index.js.map +1 -0
- package/lib/accounts/store.js +461 -0
- package/lib/accounts/store.js.map +1 -0
- package/lib/accounts/token.js +61 -0
- package/lib/accounts/token.js.map +1 -0
- package/lib/attachment-rules.js +111 -0
- package/lib/attachment-rules.js.map +1 -0
- package/lib/attestation.js.map +1 -1
- package/lib/cli.js +256 -0
- package/lib/cli.js.map +1 -0
- package/lib/client/QaAccountsController.js +359 -0
- package/lib/client/QaAccountsController.js.map +1 -0
- package/lib/client/QaSessionController.js +238 -180
- package/lib/client/QaSessionController.js.map +1 -1
- package/lib/client/QaSurface.js +281 -105
- package/lib/client/QaSurface.js.map +1 -1
- package/lib/client/QaTranscriptAdapter.js +95 -244
- package/lib/client/QaTranscriptAdapter.js.map +1 -1
- package/lib/client/attachments.js +150 -0
- package/lib/client/attachments.js.map +1 -0
- package/lib/client/attestation.js +7 -1
- package/lib/client/attestation.js.map +1 -1
- package/lib/client/base64.js +16 -0
- package/lib/client/base64.js.map +1 -0
- package/lib/client/chat-files.js +48 -0
- package/lib/client/chat-files.js.map +1 -0
- package/lib/client/components/Markdown.js +54 -13
- package/lib/client/components/Markdown.js.map +1 -1
- package/lib/client/components/QaAuthGate.js +40 -0
- package/lib/client/components/QaAuthGate.js.map +1 -0
- package/lib/client/components/QaChangelog.js +131 -0
- package/lib/client/components/QaChangelog.js.map +1 -0
- package/lib/client/components/QaComposer.js +56 -74
- package/lib/client/components/QaComposer.js.map +1 -1
- package/lib/client/components/QaFileAttachment.js +19 -0
- package/lib/client/components/QaFileAttachment.js.map +1 -0
- package/lib/client/components/QaFilesPanel.js +45 -0
- package/lib/client/components/QaFilesPanel.js.map +1 -0
- package/lib/client/components/QaHeader.js +34 -0
- package/lib/client/components/QaHeader.js.map +1 -0
- package/lib/client/components/QaMessage.js +61 -18
- package/lib/client/components/QaMessage.js.map +1 -1
- package/lib/client/components/QaModal.js +31 -0
- package/lib/client/components/QaModal.js.map +1 -0
- package/lib/client/components/QaProfile.js +64 -0
- package/lib/client/components/QaProfile.js.map +1 -0
- package/lib/client/components/QaRightRail.js +15 -0
- package/lib/client/components/QaRightRail.js.map +1 -0
- package/lib/client/components/QaSidebar.js +68 -20
- package/lib/client/components/QaSidebar.js.map +1 -1
- package/lib/client/components/QaSourcesPanel.js +127 -0
- package/lib/client/components/QaSourcesPanel.js.map +1 -0
- package/lib/client/components/QaTurnRail.js +296 -0
- package/lib/client/components/QaTurnRail.js.map +1 -0
- package/lib/client/components/QaWelcomeNotice.js +125 -0
- package/lib/client/components/QaWelcomeNotice.js.map +1 -0
- package/lib/client/components/QaWidthHandle.js +147 -0
- package/lib/client/components/QaWidthHandle.js.map +1 -0
- package/lib/client/components/QaWorkGroup.js +19 -20
- package/lib/client/components/QaWorkGroup.js.map +1 -1
- package/lib/client/components/source-refs.js +78 -0
- package/lib/client/components/source-refs.js.map +1 -0
- package/lib/client/components/surface-utils.js +28 -0
- package/lib/client/components/surface-utils.js.map +1 -0
- package/lib/client/components/thinking-phrases.js +24 -0
- package/lib/client/components/thinking-phrases.js.map +1 -0
- package/lib/client/create-session.js +26 -0
- package/lib/client/create-session.js.map +1 -0
- package/lib/client/failure-copy.js +63 -0
- package/lib/client/failure-copy.js.map +1 -0
- package/lib/client/index.js +135 -16
- package/lib/client/index.js.map +1 -1
- package/lib/client/project-session-state.js +78 -0
- package/lib/client/project-session-state.js.map +1 -0
- package/lib/client/prompt-content.js +54 -0
- package/lib/client/prompt-content.js.map +1 -0
- package/lib/client/session-admission.js +38 -0
- package/lib/client/session-admission.js.map +1 -0
- package/lib/client/session-assets.js +52 -0
- package/lib/client/session-assets.js.map +1 -0
- package/lib/client/session-sources.js +61 -0
- package/lib/client/session-sources.js.map +1 -0
- package/lib/client/settings/card.js +143 -0
- package/lib/client/settings/card.js.map +1 -0
- package/lib/client/settings/fields.js +145 -0
- package/lib/client/settings/fields.js.map +1 -0
- package/lib/client/settings/format.js +255 -0
- package/lib/client/settings/format.js.map +1 -0
- package/lib/client/settings/sections/access.js +25 -0
- package/lib/client/settings/sections/access.js.map +1 -0
- package/lib/client/settings/sections/accounts.js +47 -0
- package/lib/client/settings/sections/accounts.js.map +1 -0
- package/lib/client/settings/sections/attachments.js +46 -0
- package/lib/client/settings/sections/attachments.js.map +1 -0
- package/lib/client/settings/sections/branding.js +28 -0
- package/lib/client/settings/sections/branding.js.map +1 -0
- package/lib/client/settings/sections/common.js +20 -0
- package/lib/client/settings/sections/common.js.map +1 -0
- package/lib/client/settings/sections/embedding.js +19 -0
- package/lib/client/settings/sections/embedding.js.map +1 -0
- package/lib/client/settings/sections/interface.js +60 -0
- package/lib/client/settings/sections/interface.js.map +1 -0
- package/lib/client/settings/sections/lockdown.js +82 -0
- package/lib/client/settings/sections/lockdown.js.map +1 -0
- package/lib/client/settings/sections/session.js +53 -0
- package/lib/client/settings/sections/session.js.map +1 -0
- package/lib/client/settings/sections/sources.js +72 -0
- package/lib/client/settings/sections/sources.js.map +1 -0
- package/lib/client/settings/sections/status.js +37 -0
- package/lib/client/settings/sections/status.js.map +1 -0
- package/lib/client/settings/sections.js +23 -0
- package/lib/client/settings/sections.js.map +1 -0
- package/lib/client/settings/styles.js +57 -0
- package/lib/client/settings/styles.js.map +1 -0
- package/lib/client/settlement.js +24 -0
- package/lib/client/settlement.js.map +1 -0
- package/lib/client/stream-publisher.js +47 -0
- package/lib/client/stream-publisher.js.map +1 -0
- package/lib/client/styles.js +225 -17
- package/lib/client/styles.js.map +1 -1
- package/lib/client/tool-presentation.js +102 -0
- package/lib/client/tool-presentation.js.map +1 -0
- package/lib/client/turn-sources.js +98 -0
- package/lib/client/turn-sources.js.map +1 -0
- package/lib/client/types.js +2 -0
- package/lib/client/types.js.map +1 -1
- package/lib/client/use-right-rail.js +96 -0
- package/lib/client/use-right-rail.js.map +1 -0
- package/lib/client/use-session-ui-state.js +75 -0
- package/lib/client/use-session-ui-state.js.map +1 -0
- package/lib/client/use-transcript-view.js +44 -0
- package/lib/client/use-transcript-view.js.map +1 -0
- package/lib/client.js +9052 -1345
- package/lib/client.js.map +1 -1
- package/lib/config-resolvers/accounts.js +60 -0
- package/lib/config-resolvers/accounts.js.map +1 -0
- package/lib/config-resolvers/attachments.js +28 -0
- package/lib/config-resolvers/attachments.js.map +1 -0
- package/lib/config-resolvers/basics.js +59 -0
- package/lib/config-resolvers/basics.js.map +1 -0
- package/lib/config-resolvers/defaults.js +132 -0
- package/lib/config-resolvers/defaults.js.map +1 -0
- package/lib/config-resolvers/lockdown.js +79 -0
- package/lib/config-resolvers/lockdown.js.map +1 -0
- package/lib/config-resolvers/session.js +42 -0
- package/lib/config-resolvers/session.js.map +1 -0
- package/lib/config-resolvers/shared.js +42 -0
- package/lib/config-resolvers/shared.js.map +1 -0
- package/lib/config-resolvers/sources.js +81 -0
- package/lib/config-resolvers/sources.js.map +1 -0
- package/lib/config-resolvers/ui.js +20 -0
- package/lib/config-resolvers/ui.js.map +1 -0
- package/lib/config.js +279 -102
- package/lib/config.js.map +1 -1
- package/lib/entry-redirect.js +45 -0
- package/lib/entry-redirect.js.map +1 -0
- package/lib/host-route.js +25 -1
- package/lib/host-route.js.map +1 -1
- package/lib/index.js +258 -23
- package/lib/index.js.map +1 -1
- package/lib/launch-token.js +42 -0
- package/lib/launch-token.js.map +1 -0
- package/lib/profile.js +214 -0
- package/lib/profile.js.map +1 -0
- package/lib/prompt-notes.js +231 -0
- package/lib/prompt-notes.js.map +1 -0
- package/lib/provenance/collector.js +40 -0
- package/lib/provenance/collector.js.map +1 -0
- package/lib/provenance/connectors.js +147 -0
- package/lib/provenance/connectors.js.map +1 -0
- package/lib/provenance/dedupe.js +89 -0
- package/lib/provenance/dedupe.js.map +1 -0
- package/lib/provenance/extractors.js +340 -0
- package/lib/provenance/extractors.js.map +1 -0
- package/lib/provenance/file-preview.js +39 -0
- package/lib/provenance/file-preview.js.map +1 -0
- package/lib/provenance/host-store.js +387 -0
- package/lib/provenance/host-store.js.map +1 -0
- package/lib/provenance/index.js +9 -0
- package/lib/provenance/index.js.map +1 -0
- package/lib/provenance/normalize.js +128 -0
- package/lib/provenance/normalize.js.map +1 -0
- package/lib/provenance/reported.js +53 -0
- package/lib/provenance/reported.js.map +1 -0
- package/lib/provenance/types.js +2 -0
- package/lib/provenance/types.js.map +1 -0
- package/lib/resolve-config.js +35 -249
- package/lib/resolve-config.js.map +1 -1
- package/lib/secure-session.js +122 -14
- package/lib/secure-session.js.map +1 -1
- package/lib/shared/session-key.js +18 -0
- package/lib/shared/session-key.js.map +1 -0
- package/lib/shared/settings.js +10 -0
- package/lib/shared/settings.js.map +1 -0
- package/lib/thinking-phrases.js +68 -0
- package/lib/thinking-phrases.js.map +1 -0
- package/lib/typert.host.js +749 -11
- package/lib/typert.remote-client.d.ts +23 -3
- package/lib/typert.remote-client.js +593 -6
- package/lib/types/account-remotes.d.ts +42 -0
- package/lib/types/accounts/credentials.d.ts +14 -0
- package/lib/types/accounts/errors.d.ts +11 -0
- package/lib/types/accounts/file.d.ts +82 -0
- package/lib/types/accounts/index.d.ts +2 -0
- package/lib/types/accounts/store.d.ts +144 -0
- package/lib/types/accounts/token.d.ts +31 -0
- package/lib/types/attachment-rules.d.ts +44 -0
- package/lib/types/attestation.d.ts +1 -1
- package/lib/types/cli.d.ts +9 -0
- package/lib/types/client/QaAccountsController.d.ts +102 -0
- package/lib/types/client/QaConfigController.d.ts +1 -1
- package/lib/types/client/QaSessionController.d.ts +61 -22
- package/lib/types/client/QaSurface.d.ts +14 -3
- package/lib/types/client/QaTranscriptAdapter.d.ts +5 -10
- package/lib/types/client/attachments.d.ts +54 -0
- package/lib/types/client/base64.d.ts +10 -0
- package/lib/types/client/chat-files.d.ts +30 -0
- package/lib/types/client/components/Markdown.d.ts +11 -1
- package/lib/types/client/components/QaAgentsDrawer.d.ts +1 -1
- package/lib/types/client/components/QaAuthGate.d.ts +15 -0
- package/lib/types/client/components/QaChangelog.d.ts +21 -0
- package/lib/types/client/components/QaComposer.d.ts +8 -4
- package/lib/types/client/components/QaFileAttachment.d.ts +14 -0
- package/lib/types/client/components/QaFilesPanel.d.ts +15 -0
- package/lib/types/client/components/QaHeader.d.ts +41 -0
- package/lib/types/client/components/QaMessage.d.ts +12 -3
- package/lib/types/client/components/QaModal.d.ts +26 -0
- package/lib/types/client/components/QaProfile.d.ts +25 -0
- package/lib/types/client/components/QaRightRail.d.ts +23 -0
- package/lib/types/client/components/QaSidebar.d.ts +44 -2
- package/lib/types/client/components/QaSourcesPanel.d.ts +23 -0
- package/lib/types/client/components/QaTurnRail.d.ts +65 -0
- package/lib/types/client/components/QaWelcomeNotice.d.ts +27 -0
- package/lib/types/client/components/QaWidthHandle.d.ts +43 -0
- package/lib/types/client/components/QaWorkGroup.d.ts +5 -3
- package/lib/types/client/components/source-refs.d.ts +16 -0
- package/lib/types/client/components/surface-utils.d.ts +11 -0
- package/lib/types/client/components/thinking-phrases.d.ts +9 -0
- package/lib/types/client/create-session.d.ts +13 -0
- package/lib/types/client/failure-copy.d.ts +19 -0
- package/lib/types/client/index.d.ts +1 -0
- package/lib/types/client/project-session-state.d.ts +30 -0
- package/lib/types/client/prompt-content.d.ts +30 -0
- package/lib/types/client/session-admission.d.ts +23 -0
- package/lib/types/client/session-assets.d.ts +20 -0
- package/lib/types/client/session-sources.d.ts +28 -0
- package/lib/types/client/settings/card.d.ts +23 -0
- package/lib/types/client/settings/fields.d.ts +139 -0
- package/lib/types/client/settings/format.d.ts +108 -0
- package/lib/types/client/settings/sections/access.d.ts +9 -0
- package/lib/types/client/settings/sections/accounts.d.ts +9 -0
- package/lib/types/client/settings/sections/attachments.d.ts +15 -0
- package/lib/types/client/settings/sections/branding.d.ts +8 -0
- package/lib/types/client/settings/sections/common.d.ts +28 -0
- package/lib/types/client/settings/sections/embedding.d.ts +8 -0
- package/lib/types/client/settings/sections/interface.d.ts +9 -0
- package/lib/types/client/settings/sections/lockdown.d.ts +9 -0
- package/lib/types/client/settings/sections/session.d.ts +9 -0
- package/lib/types/client/settings/sections/sources.d.ts +9 -0
- package/lib/types/client/settings/sections/status.d.ts +22 -0
- package/lib/types/client/settings/sections.d.ts +25 -0
- package/lib/types/client/settings/styles.d.ts +8 -0
- package/lib/types/client/settlement.d.ts +6 -0
- package/lib/types/client/stream-publisher.d.ts +28 -0
- package/lib/types/client/tool-presentation.d.ts +6 -0
- package/lib/types/client/turn-sources.d.ts +14 -0
- package/lib/types/client/types.d.ts +101 -9
- package/lib/types/client/use-right-rail.d.ts +56 -0
- package/lib/types/client/use-session-ui-state.d.ts +41 -0
- package/lib/types/client/use-transcript-view.d.ts +20 -0
- package/lib/types/config-resolvers/accounts.d.ts +15 -0
- package/lib/types/config-resolvers/attachments.d.ts +6 -0
- package/lib/types/config-resolvers/basics.d.ts +8 -0
- package/lib/types/config-resolvers/defaults.d.ts +4 -0
- package/lib/types/config-resolvers/lockdown.d.ts +10 -0
- package/lib/types/config-resolvers/session.d.ts +6 -0
- package/lib/types/config-resolvers/shared.d.ts +16 -0
- package/lib/types/config-resolvers/sources.d.ts +6 -0
- package/lib/types/config-resolvers/ui.d.ts +6 -0
- package/lib/types/entry-redirect.d.ts +20 -0
- package/lib/types/host-route.d.ts +14 -1
- package/lib/types/index.d.ts +54 -3
- package/lib/types/launch-token.d.ts +21 -0
- package/lib/types/profile.d.ts +76 -0
- package/lib/types/prompt-notes.d.ts +110 -0
- package/lib/types/provenance/collector.d.ts +26 -0
- package/lib/types/provenance/connectors.d.ts +11 -0
- package/lib/types/provenance/dedupe.d.ts +6 -0
- package/lib/types/provenance/extractors.d.ts +14 -0
- package/lib/types/provenance/file-preview.d.ts +10 -0
- package/lib/types/provenance/host-store.d.ts +54 -0
- package/lib/types/provenance/index.d.ts +10 -0
- package/lib/types/provenance/normalize.d.ts +13 -0
- package/lib/types/provenance/reported.d.ts +5 -0
- package/lib/types/provenance/types.d.ts +78 -0
- package/lib/types/resolve-config.d.ts +8 -3
- package/lib/types/secure-session.d.ts +36 -2
- package/lib/types/shared/session-key.d.ts +23 -0
- package/lib/types/shared/settings.d.ts +10 -0
- package/lib/types/thinking-phrases.d.ts +17 -0
- package/lib/types/types.d.ts +290 -16
- package/lib/types/user-workspace.d.ts +38 -0
- package/lib/user-workspace.js +231 -0
- package/lib/user-workspace.js.map +1 -0
- package/package.json +71 -47
- package/CHANGELOG.md +0 -93
- package/SPEC-dsh-qa-surface.md +0 -2425
- package/docs/ARCHITECTURE.md +0 -66
- package/docs/COMPATIBILITY.md +0 -14
- package/docs/CONFIGURATION.md +0 -112
- package/docs/EMBEDDING.md +0 -13
- package/lib/client/components/QaSourcesDrawer.js +0 -46
- package/lib/client/components/QaSourcesDrawer.js.map +0 -1
- package/lib/types/client/components/QaSourcesDrawer.d.ts +0 -8
package/lib/resolve-config.js
CHANGED
|
@@ -1,255 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
workspaceId: null,
|
|
17
|
-
fixedSessionId: null,
|
|
18
|
-
agentPreset: null,
|
|
19
|
-
provider: null,
|
|
20
|
-
model: null,
|
|
21
|
-
reasoningEffort: null,
|
|
22
|
-
}),
|
|
23
|
-
ui: Object.freeze({
|
|
24
|
-
showHeader: true,
|
|
25
|
-
showReset: false,
|
|
26
|
-
showStop: true,
|
|
27
|
-
showTimestamps: false,
|
|
28
|
-
showToolActivity: false,
|
|
29
|
-
showReasoning: false,
|
|
30
|
-
renderMarkdown: true,
|
|
31
|
-
maxContentWidth: 900,
|
|
32
|
-
showSessionList: false,
|
|
33
|
-
}),
|
|
34
|
-
suggestedQuestions: Object.freeze([
|
|
35
|
-
"Что ты умеешь?",
|
|
36
|
-
"С чего начать?",
|
|
37
|
-
"Помоги разобраться с ошибкой",
|
|
38
|
-
]),
|
|
39
|
-
interaction: Object.freeze({
|
|
40
|
-
approvals: "blocked",
|
|
41
|
-
questions: "unsupported",
|
|
42
|
-
}),
|
|
43
|
-
lockdown: Object.freeze({
|
|
44
|
-
enabled: true,
|
|
45
|
-
enforceFixedAgentPreset: true,
|
|
46
|
-
enforceFixedWorkspace: true,
|
|
47
|
-
enforceFixedModel: true,
|
|
48
|
-
sandboxMode: "read-only",
|
|
49
|
-
approvalPolicy: "never",
|
|
50
|
-
permissionPreset: "qa-read-only",
|
|
51
|
-
allowPermissionChanges: false,
|
|
52
|
-
allowSlashCommands: false,
|
|
53
|
-
allowSettingsMutation: false,
|
|
54
|
-
allowSessionReset: false,
|
|
55
|
-
allowSessionRename: false,
|
|
56
|
-
allowSessionDelete: false,
|
|
57
|
-
allowArbitrarySessionOpen: false,
|
|
58
|
-
toolPolicy: Object.freeze({
|
|
59
|
-
mode: "allow-list",
|
|
60
|
-
allow: Object.freeze([]),
|
|
61
|
-
}),
|
|
62
|
-
}),
|
|
63
|
-
embedding: Object.freeze({ frameAncestors: null }),
|
|
64
|
-
});
|
|
65
|
-
function optionalText(value) {
|
|
66
|
-
const trimmed = value?.trim() ?? "";
|
|
67
|
-
return trimmed === "" ? null : trimmed;
|
|
68
|
-
}
|
|
69
|
-
export function normalizeRoutePath(value) {
|
|
70
|
-
const trimmed = value.trim();
|
|
71
|
-
if (trimmed === "" || !trimmed.startsWith("/")) {
|
|
72
|
-
throw new TypeError("dsh-qa-surface: route.path must start with /");
|
|
73
|
-
}
|
|
74
|
-
const path = trimmed.length > 1 ? trimmed.replace(/\/+$/u, "") : trimmed;
|
|
75
|
-
if (path === "/") {
|
|
76
|
-
throw new TypeError("dsh-qa-surface: route.path cannot replace the operator root");
|
|
77
|
-
}
|
|
78
|
-
if (path === "/api" || path.startsWith("/api/")) {
|
|
79
|
-
throw new TypeError("dsh-qa-surface: route.path cannot claim /api");
|
|
80
|
-
}
|
|
81
|
-
if (path === "/plugins" || path.startsWith("/plugins/")) {
|
|
82
|
-
throw new TypeError("dsh-qa-surface: route.path cannot claim /plugins");
|
|
83
|
-
}
|
|
84
|
-
return path;
|
|
85
|
-
}
|
|
86
|
-
function uniqueQuestions(values) {
|
|
87
|
-
const questions = [
|
|
88
|
-
...new Set(values.map((value) => value.trim()).filter(Boolean)),
|
|
89
|
-
];
|
|
90
|
-
if (questions.some((value) => value.length > 500)) {
|
|
91
|
-
throw new TypeError("dsh-qa-surface: suggested questions must be at most 500 characters");
|
|
92
|
-
}
|
|
93
|
-
return Object.freeze(questions);
|
|
94
|
-
}
|
|
95
|
-
function uniqueToolNames(values) {
|
|
96
|
-
const names = [
|
|
97
|
-
...new Set(values.map((value) => value.trim()).filter(Boolean)),
|
|
98
|
-
];
|
|
99
|
-
if (names.some((value) => value.length > 200)) {
|
|
100
|
-
throw new TypeError("dsh-qa-surface: lockdown.toolPolicy.allow names must be at most 200 characters");
|
|
101
|
-
}
|
|
102
|
-
return Object.freeze(names);
|
|
103
|
-
}
|
|
104
|
-
/** Materialize defaults and enforce route/session/model safety constraints. */
|
|
1
|
+
import { resolveAccounts } from "./config-resolvers/accounts.js";
|
|
2
|
+
import { resolveAttachments } from "./config-resolvers/attachments.js";
|
|
3
|
+
import { normalizeRoutePath, resolveBasics, } from "./config-resolvers/basics.js";
|
|
4
|
+
import { DEFAULT_QA_SURFACE_CONFIG } from "./config-resolvers/defaults.js";
|
|
5
|
+
import { resolveLockdown } from "./config-resolvers/lockdown.js";
|
|
6
|
+
import { resolveSession } from "./config-resolvers/session.js";
|
|
7
|
+
import { resolveSources } from "./config-resolvers/sources.js";
|
|
8
|
+
import { uniquePhrases, uniqueQuestions } from "./config-resolvers/shared.js";
|
|
9
|
+
import { resolveUi } from "./config-resolvers/ui.js";
|
|
10
|
+
export { DEFAULT_QA_SURFACE_CONFIG, normalizeRoutePath };
|
|
11
|
+
/**
|
|
12
|
+
* Materialize defaults and enforce route/session/model safety constraints by
|
|
13
|
+
* running one resolver per config domain — in the order the checks have
|
|
14
|
+
* always fired — and assembling the frozen result.
|
|
15
|
+
*/
|
|
105
16
|
export function resolveConfig(input = {}) {
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
// session to one directory, so together they are a configuration error.
|
|
114
|
-
const cwd = optionalText(input.session?.cwd);
|
|
115
|
-
if (cwd !== null && !/^([a-zA-Z]:[/\\]|\/)/u.test(cwd)) {
|
|
116
|
-
throw new TypeError("dsh-qa-surface: session.cwd must be an absolute directory path");
|
|
117
|
-
}
|
|
118
|
-
const workspaceId = optionalText(input.session?.workspaceId);
|
|
119
|
-
if (workspaceId !== null && cwd !== null) {
|
|
120
|
-
throw new TypeError("dsh-qa-surface: session.workspaceId and session.cwd are mutually exclusive");
|
|
121
|
-
}
|
|
122
|
-
const provider = optionalText(input.session?.provider);
|
|
123
|
-
const model = optionalText(input.session?.model);
|
|
124
|
-
if ((provider === null) !== (model === null)) {
|
|
125
|
-
throw new TypeError("dsh-qa-surface: session.provider and session.model must be set together");
|
|
126
|
-
}
|
|
127
|
-
const storageKey = input.session?.storageKey?.trim() ??
|
|
128
|
-
DEFAULT_QA_SURFACE_CONFIG.session.storageKey;
|
|
129
|
-
if (storageKey === "") {
|
|
130
|
-
throw new TypeError("dsh-qa-surface: session.storageKey cannot be empty");
|
|
131
|
-
}
|
|
132
|
-
const maxContentWidth = input.ui?.maxContentWidth ?? DEFAULT_QA_SURFACE_CONFIG.ui.maxContentWidth;
|
|
133
|
-
if (!Number.isSafeInteger(maxContentWidth) ||
|
|
134
|
-
maxContentWidth < 480 ||
|
|
135
|
-
maxContentWidth > 1600) {
|
|
136
|
-
throw new TypeError("dsh-qa-surface: ui.maxContentWidth must be an integer from 480 to 1600");
|
|
137
|
-
}
|
|
138
|
-
const lockdownEnabled = input.lockdown?.enabled ?? DEFAULT_QA_SURFACE_CONFIG.lockdown.enabled;
|
|
139
|
-
const rawLockdown = input.lockdown;
|
|
140
|
-
const forbiddenCapabilityFlags = [
|
|
141
|
-
["allowPermissionChanges", rawLockdown?.allowPermissionChanges],
|
|
142
|
-
["allowSlashCommands", rawLockdown?.allowSlashCommands],
|
|
143
|
-
["allowSettingsMutation", rawLockdown?.allowSettingsMutation],
|
|
144
|
-
["allowSessionRename", rawLockdown?.allowSessionRename],
|
|
145
|
-
["allowSessionDelete", rawLockdown?.allowSessionDelete],
|
|
146
|
-
["allowArbitrarySessionOpen", rawLockdown?.allowArbitrarySessionOpen],
|
|
147
|
-
];
|
|
148
|
-
const weakenedFlag = forbiddenCapabilityFlags.find(([, value]) => value === true);
|
|
149
|
-
if (weakenedFlag !== undefined) {
|
|
150
|
-
throw new TypeError(`dsh-qa-surface: lockdown.${weakenedFlag[0]} cannot be enabled`);
|
|
151
|
-
}
|
|
152
|
-
if (input.lockdown?.sandboxMode !== undefined &&
|
|
153
|
-
input.lockdown.sandboxMode !== "read-only") {
|
|
154
|
-
throw new TypeError("dsh-qa-surface: lockdown.sandboxMode must be read-only");
|
|
155
|
-
}
|
|
156
|
-
if (input.lockdown?.approvalPolicy !== undefined &&
|
|
157
|
-
input.lockdown.approvalPolicy !== "never") {
|
|
158
|
-
throw new TypeError("dsh-qa-surface: lockdown.approvalPolicy must be never");
|
|
159
|
-
}
|
|
160
|
-
if (input.lockdown?.toolPolicy?.mode !== undefined &&
|
|
161
|
-
input.lockdown.toolPolicy.mode !== "allow-list") {
|
|
162
|
-
throw new TypeError("dsh-qa-surface: lockdown.toolPolicy.mode must be allow-list");
|
|
163
|
-
}
|
|
164
|
-
const permissionPreset = input.lockdown?.permissionPreset?.trim() ??
|
|
165
|
-
DEFAULT_QA_SURFACE_CONFIG.lockdown.permissionPreset;
|
|
166
|
-
if (lockdownEnabled && permissionPreset === "") {
|
|
167
|
-
throw new TypeError("dsh-qa-surface: lockdown.permissionPreset is required when lockdown is enabled");
|
|
168
|
-
}
|
|
169
|
-
const allowSessionReset = input.lockdown?.allowSessionReset ??
|
|
170
|
-
DEFAULT_QA_SURFACE_CONFIG.lockdown.allowSessionReset;
|
|
171
|
-
if (lockdownEnabled &&
|
|
172
|
-
(input.ui?.showReset ?? DEFAULT_QA_SURFACE_CONFIG.ui.showReset) &&
|
|
173
|
-
!allowSessionReset) {
|
|
174
|
-
throw new TypeError("dsh-qa-surface: ui.showReset requires lockdown.allowSessionReset");
|
|
175
|
-
}
|
|
17
|
+
const basics = resolveBasics(input);
|
|
18
|
+
const session = resolveSession(input);
|
|
19
|
+
const ui = resolveUi(input);
|
|
20
|
+
const lockdown = resolveLockdown(input, ui);
|
|
21
|
+
const sources = resolveSources(input);
|
|
22
|
+
const attachments = resolveAttachments(input);
|
|
23
|
+
const accounts = resolveAccounts(input, { session, lockdown });
|
|
176
24
|
return Object.freeze({
|
|
177
|
-
enabled:
|
|
178
|
-
route:
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}),
|
|
183
|
-
branding: Object.freeze({
|
|
184
|
-
title: input.branding?.title?.trim() ||
|
|
185
|
-
DEFAULT_QA_SURFACE_CONFIG.branding.title,
|
|
186
|
-
subtitle: input.branding?.subtitle?.trim() ?? "",
|
|
187
|
-
welcomeMessage: input.branding?.welcomeMessage?.trim() ??
|
|
188
|
-
DEFAULT_QA_SURFACE_CONFIG.branding.welcomeMessage,
|
|
189
|
-
placeholder: input.branding?.placeholder?.trim() ||
|
|
190
|
-
DEFAULT_QA_SURFACE_CONFIG.branding.placeholder,
|
|
191
|
-
logoUrl: optionalText(input.branding?.logoUrl),
|
|
192
|
-
// Undefined falls back to the default notice; an explicit null or
|
|
193
|
-
// empty string hides the plate entirely.
|
|
194
|
-
disclaimer: input.branding?.disclaimer === undefined
|
|
195
|
-
? DEFAULT_QA_SURFACE_CONFIG.branding.disclaimer
|
|
196
|
-
: (optionalText(input.branding.disclaimer) ?? ""),
|
|
197
|
-
}),
|
|
198
|
-
session: Object.freeze({
|
|
199
|
-
policy,
|
|
200
|
-
storageKey,
|
|
201
|
-
cwd,
|
|
202
|
-
workspaceId: optionalText(input.session?.workspaceId),
|
|
203
|
-
fixedSessionId,
|
|
204
|
-
agentPreset: optionalText(input.session?.agentPreset),
|
|
205
|
-
provider,
|
|
206
|
-
model,
|
|
207
|
-
reasoningEffort: optionalText(input.session?.reasoningEffort),
|
|
208
|
-
}),
|
|
209
|
-
ui: Object.freeze({
|
|
210
|
-
showHeader: input.ui?.showHeader ?? DEFAULT_QA_SURFACE_CONFIG.ui.showHeader,
|
|
211
|
-
showReset: input.ui?.showReset ?? DEFAULT_QA_SURFACE_CONFIG.ui.showReset,
|
|
212
|
-
showStop: input.ui?.showStop ?? DEFAULT_QA_SURFACE_CONFIG.ui.showStop,
|
|
213
|
-
showTimestamps: input.ui?.showTimestamps ?? DEFAULT_QA_SURFACE_CONFIG.ui.showTimestamps,
|
|
214
|
-
showToolActivity: input.ui?.showToolActivity ??
|
|
215
|
-
DEFAULT_QA_SURFACE_CONFIG.ui.showToolActivity,
|
|
216
|
-
showReasoning: input.ui?.showReasoning ?? DEFAULT_QA_SURFACE_CONFIG.ui.showReasoning,
|
|
217
|
-
renderMarkdown: input.ui?.renderMarkdown ?? DEFAULT_QA_SURFACE_CONFIG.ui.renderMarkdown,
|
|
218
|
-
maxContentWidth,
|
|
219
|
-
showSessionList: input.ui?.showSessionList ??
|
|
220
|
-
DEFAULT_QA_SURFACE_CONFIG.ui.showSessionList,
|
|
221
|
-
}),
|
|
25
|
+
enabled: basics.enabled,
|
|
26
|
+
route: basics.route,
|
|
27
|
+
branding: basics.branding,
|
|
28
|
+
session,
|
|
29
|
+
ui,
|
|
222
30
|
suggestedQuestions: uniqueQuestions(input.suggestedQuestions ?? DEFAULT_QA_SURFACE_CONFIG.suggestedQuestions),
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
enforceFixedWorkspace: input.lockdown?.enforceFixedWorkspace ??
|
|
232
|
-
DEFAULT_QA_SURFACE_CONFIG.lockdown.enforceFixedWorkspace,
|
|
233
|
-
enforceFixedModel: input.lockdown?.enforceFixedModel ??
|
|
234
|
-
DEFAULT_QA_SURFACE_CONFIG.lockdown.enforceFixedModel,
|
|
235
|
-
sandboxMode: "read-only",
|
|
236
|
-
approvalPolicy: "never",
|
|
237
|
-
permissionPreset,
|
|
238
|
-
allowPermissionChanges: false,
|
|
239
|
-
allowSlashCommands: false,
|
|
240
|
-
allowSettingsMutation: false,
|
|
241
|
-
allowSessionReset,
|
|
242
|
-
allowSessionRename: false,
|
|
243
|
-
allowSessionDelete: false,
|
|
244
|
-
allowArbitrarySessionOpen: false,
|
|
245
|
-
toolPolicy: Object.freeze({
|
|
246
|
-
mode: "allow-list",
|
|
247
|
-
allow: uniqueToolNames(input.lockdown?.toolPolicy?.allow ?? []),
|
|
248
|
-
}),
|
|
249
|
-
}),
|
|
250
|
-
embedding: Object.freeze({
|
|
251
|
-
frameAncestors: optionalText(input.embedding?.frameAncestors),
|
|
252
|
-
}),
|
|
31
|
+
thinkingPhrases: uniquePhrases(input.thinkingPhrases ?? DEFAULT_QA_SURFACE_CONFIG.thinkingPhrases),
|
|
32
|
+
interaction: basics.interaction,
|
|
33
|
+
lockdown,
|
|
34
|
+
embedding: basics.embedding,
|
|
35
|
+
accounts,
|
|
36
|
+
entry: basics.entry,
|
|
37
|
+
sources,
|
|
38
|
+
attachments,
|
|
253
39
|
});
|
|
254
40
|
}
|
|
255
41
|
//# sourceMappingURL=resolve-config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-config.js","sourceRoot":"","sources":["../src/resolve-config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve-config.js","sourceRoot":"","sources":["../src/resolve-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EACL,kBAAkB,EAClB,aAAa,GACd,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAGrD,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,CAAC;AAEzD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAK,GAAoB,EAAE;IAE3B,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5B,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,WAAW,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC/D,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,OAAO;QACP,EAAE;QACF,kBAAkB,EAAE,eAAe,CACjC,KAAK,CAAC,kBAAkB,IAAI,yBAAyB,CAAC,kBAAkB,CACzE;QACD,eAAe,EAAE,aAAa,CAC5B,KAAK,CAAC,eAAe,IAAI,yBAAyB,CAAC,eAAe,CACnE;QACD,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,QAAQ;QACR,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,QAAQ;QACR,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO;QACP,WAAW;KACZ,CAAC,CAAC;AACL,CAAC"}
|
package/lib/secure-session.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
// The `types` subpath keeps the client ISessions Context merge authoritative;
|
|
2
|
+
// the package root merges a conflicting host `sessions` service type.
|
|
3
|
+
import { SessionId } from "@deepseek-ai/dsh-session/types";
|
|
2
4
|
import { WorkspaceId } from "@deepseek-ai/dsh-workspace";
|
|
5
|
+
import { QaAccountsError } from "./accounts/store.js";
|
|
3
6
|
import { QaAttestationError } from "./attestation.js";
|
|
4
7
|
import { qaToolDenial, qaToolPolicyPlan } from "./lockdown-policy.js";
|
|
8
|
+
import { QA_REPORT_SOURCES_TOOL } from "./provenance/host-store.js";
|
|
9
|
+
import { qaUserWorkspaceDenial } from "./user-workspace.js";
|
|
5
10
|
/** Grace period in which a fresh session may still be pinned to the QA preset. */
|
|
6
11
|
const FRESH_SESSION_BOOTSTRAP_WINDOW_MS = 120_000;
|
|
7
12
|
/**
|
|
@@ -31,22 +36,83 @@ export class QaPolicyAdmission {
|
|
|
31
36
|
ctx;
|
|
32
37
|
config;
|
|
33
38
|
logger;
|
|
39
|
+
accounts;
|
|
34
40
|
appliedPolicies = new Map();
|
|
35
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Sessions the QA surface has attested. The provenance note is written for
|
|
43
|
+
* exactly these, and a delegated child resolves through its root session, so
|
|
44
|
+
* one set answers for the whole chat.
|
|
45
|
+
*/
|
|
46
|
+
attested = new Set();
|
|
47
|
+
workspaceRoots = new Map();
|
|
48
|
+
disposeWorkspaceGuard;
|
|
49
|
+
constructor(ctx, config, logger, accounts) {
|
|
36
50
|
this.ctx = ctx;
|
|
37
51
|
this.config = config;
|
|
38
52
|
this.logger = logger;
|
|
53
|
+
this.accounts = accounts;
|
|
54
|
+
this.disposeWorkspaceGuard = ctx.tools.guard((execution) => {
|
|
55
|
+
const session = execution.agent?.session;
|
|
56
|
+
if (session === undefined)
|
|
57
|
+
return undefined;
|
|
58
|
+
const root = this.workspaceRoots.get(String(session.id));
|
|
59
|
+
if (root === undefined)
|
|
60
|
+
return undefined;
|
|
61
|
+
if (!cwdMatches(session.header.cwd, root)) {
|
|
62
|
+
return "QA workspace boundary: session cwd is outside this user's directory.";
|
|
63
|
+
}
|
|
64
|
+
return qaUserWorkspaceDenial(execution, root, this.attachmentRoot());
|
|
65
|
+
});
|
|
66
|
+
ctx.on("session/created", (session) => {
|
|
67
|
+
const parent = session.header.parentSession;
|
|
68
|
+
if (parent === undefined)
|
|
69
|
+
return;
|
|
70
|
+
const root = this.workspaceRoots.get(String(parent));
|
|
71
|
+
if (root !== undefined)
|
|
72
|
+
this.workspaceRoots.set(String(session.id), root);
|
|
73
|
+
});
|
|
39
74
|
ctx.on("agent/disposed", ({ agent }) => {
|
|
40
75
|
this.appliedPolicies.delete(agent);
|
|
76
|
+
this.workspaceRoots.delete(String(agent.session.id));
|
|
41
77
|
});
|
|
42
78
|
}
|
|
43
|
-
|
|
79
|
+
/**
|
|
80
|
+
* The mounted attachment store's verbatim root, when the backend exposes
|
|
81
|
+
* one. It sits outside every workspace, so the per-user fence would
|
|
82
|
+
* otherwise deny the model the exact file an upload produced and the prompt
|
|
83
|
+
* points it at. A backend without a resolvable root simply keeps the fence
|
|
84
|
+
* closed — attachments then only work where reads are not fenced per user.
|
|
85
|
+
*/
|
|
86
|
+
attachmentRoot() {
|
|
87
|
+
const store = this.ctx.get("attachments");
|
|
88
|
+
return typeof store?.root === "string" ? store.root : undefined;
|
|
89
|
+
}
|
|
90
|
+
secureSession(token, sessionId) {
|
|
44
91
|
const config = this.config();
|
|
45
92
|
const lockdown = config.lockdown;
|
|
93
|
+
// Account identity is checked before any policy work: an invalid token
|
|
94
|
+
// must not learn whether a session exists or how the deployment composes.
|
|
95
|
+
// Independent of lockdown — a deployment may gate users without pinning
|
|
96
|
+
// the policy, and the gate itself no-ops while accounts are disabled.
|
|
97
|
+
let sessionOwner;
|
|
98
|
+
if (this.accounts !== undefined) {
|
|
99
|
+
try {
|
|
100
|
+
sessionOwner = this.accounts.enforceSessionAccess(token, sessionId);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if (error instanceof QaAccountsError) {
|
|
104
|
+
throw new QaAttestationError(error.reason === "session-owned-elsewhere"
|
|
105
|
+
? "session-owned-elsewhere"
|
|
106
|
+
: "auth-required", error.message);
|
|
107
|
+
}
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
46
111
|
const agent = this.ctx.agents.get(SessionId(sessionId));
|
|
47
112
|
if (agent === undefined) {
|
|
48
113
|
throw new QaAttestationError("agent-unavailable", "agent is unavailable");
|
|
49
114
|
}
|
|
115
|
+
this.attested.add(sessionId);
|
|
50
116
|
if (!lockdown.enabled) {
|
|
51
117
|
return {
|
|
52
118
|
sessionId,
|
|
@@ -54,7 +120,7 @@ export class QaPolicyAdmission {
|
|
|
54
120
|
agentPresetMatches: true,
|
|
55
121
|
workspaceMatches: true,
|
|
56
122
|
modelMatches: true,
|
|
57
|
-
|
|
123
|
+
sandboxModeMatches: false,
|
|
58
124
|
approvalIsNever: false,
|
|
59
125
|
permissionPreset: "",
|
|
60
126
|
toolPolicyLoaded: false,
|
|
@@ -71,13 +137,28 @@ export class QaPolicyAdmission {
|
|
|
71
137
|
if (expectedWorkspace !== null && pinnedWorkspace === undefined) {
|
|
72
138
|
throw new QaAttestationError("workspace-unavailable", `workspace ${expectedWorkspace} is not registered`);
|
|
73
139
|
}
|
|
140
|
+
let expectedUserRoot;
|
|
141
|
+
if (config.accounts.perUserWorkspace) {
|
|
142
|
+
if (sessionOwner === undefined || pinnedWorkspace === undefined) {
|
|
143
|
+
throw new QaAttestationError("workspace-unavailable", "per-user workspace identity is unavailable");
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
expectedUserRoot = this.accounts?.userWorkspace(sessionOwner.id, pinnedWorkspace.path);
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
throw new QaAttestationError("workspace-unavailable", error instanceof Error ? error.message : String(error));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
74
152
|
const expectedPreset = config.session.agentPreset;
|
|
75
153
|
const agentPresetMatches = !lockdown.enforceFixedAgentPreset ||
|
|
76
154
|
expectedPreset === null ||
|
|
77
155
|
this.ctx.agentPresets.composedPreset(agent.ctx) === expectedPreset;
|
|
78
156
|
const workspaceMatches = !lockdown.enforceFixedWorkspace ||
|
|
79
157
|
(expectedWorkspace === null && config.session.cwd === null) ||
|
|
80
|
-
(
|
|
158
|
+
(expectedUserRoot !== undefined &&
|
|
159
|
+
cwdMatches(agent.session.header.cwd, expectedUserRoot)) ||
|
|
160
|
+
(!config.accounts.perUserWorkspace &&
|
|
161
|
+
pinnedWorkspace !== undefined &&
|
|
81
162
|
cwdMatches(agent.session.header.cwd, pinnedWorkspace.path)) ||
|
|
82
163
|
(expectedWorkspace === null &&
|
|
83
164
|
config.session.cwd !== null &&
|
|
@@ -95,17 +176,25 @@ export class QaPolicyAdmission {
|
|
|
95
176
|
const permission = this.ctx.permissionPresets.resolve(lockdown.permissionPreset);
|
|
96
177
|
if (permission.sandbox !== lockdown.sandboxMode ||
|
|
97
178
|
permission.approval !== lockdown.approvalPolicy) {
|
|
98
|
-
throw new QaAttestationError("permission-preset", `permission preset ${lockdown.permissionPreset} does not resolve to
|
|
179
|
+
throw new QaAttestationError("permission-preset", `permission preset ${lockdown.permissionPreset} does not resolve to ${lockdown.sandboxMode}/never`);
|
|
99
180
|
}
|
|
100
|
-
const currentPermission = this.ctx.permissionPresets.current(agent.session
|
|
101
|
-
|
|
181
|
+
const currentPermission = this.ctx.permissionPresets.current(agent.session);
|
|
182
|
+
// History check over the model-visible surface: `user/message` is a
|
|
183
|
+
// surface event, so any adopted conversation shows up here regardless of
|
|
184
|
+
// window pagination.
|
|
185
|
+
const hasUserHistory = agent.session.surface.nodes.some((seq) => agent.session.eventAt(seq)?.type === "user/message");
|
|
102
186
|
if (currentPermission !== lockdown.permissionPreset &&
|
|
103
187
|
(hasUserHistory ||
|
|
104
188
|
Date.now() - agent.session.header.createdAt >
|
|
105
189
|
FRESH_SESSION_BOOTSTRAP_WINDOW_MS)) {
|
|
106
190
|
throw new QaAttestationError("adoption-refused", "existing non-QA session cannot be adopted");
|
|
107
191
|
}
|
|
108
|
-
const
|
|
192
|
+
const policyAllow = config.sources.enabled &&
|
|
193
|
+
config.sources.subagents.enableReportToolFallback &&
|
|
194
|
+
!lockdown.toolPolicy.allow.includes(QA_REPORT_SOURCES_TOOL)
|
|
195
|
+
? [...lockdown.toolPolicy.allow, QA_REPORT_SOURCES_TOOL]
|
|
196
|
+
: lockdown.toolPolicy.allow;
|
|
197
|
+
const policy = qaToolPolicyPlan(policyAllow, (toolName) => this.ctx.tools.get(toolName, agent) !== undefined);
|
|
109
198
|
if (policy.unknown.length > 0) {
|
|
110
199
|
throw new QaAttestationError("unknown-tools", `unknown QA tool(s): ${policy.unknown.join(", ")}`);
|
|
111
200
|
}
|
|
@@ -132,14 +221,20 @@ export class QaPolicyAdmission {
|
|
|
132
221
|
}
|
|
133
222
|
}
|
|
134
223
|
this.ctx.permissionPresets.set(agent.session, lockdown.permissionPreset);
|
|
135
|
-
const effectivePermission = this.ctx.permissionPresets.current(agent.session
|
|
136
|
-
const
|
|
224
|
+
const effectivePermission = this.ctx.permissionPresets.current(agent.session);
|
|
225
|
+
const sandboxModeMatches = permission.sandbox === lockdown.sandboxMode;
|
|
137
226
|
const approvalIsNever = permission.approval === "never";
|
|
138
227
|
if (effectivePermission !== lockdown.permissionPreset ||
|
|
139
|
-
!
|
|
228
|
+
!sandboxModeMatches ||
|
|
140
229
|
!approvalIsNever) {
|
|
141
230
|
throw new QaAttestationError("attestation-failed", "permission attestation failed");
|
|
142
231
|
}
|
|
232
|
+
if (expectedUserRoot !== undefined) {
|
|
233
|
+
this.workspaceRoots.set(sessionId, expectedUserRoot);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
this.workspaceRoots.delete(sessionId);
|
|
237
|
+
}
|
|
143
238
|
this.logger.debug("lockdown.attested", {
|
|
144
239
|
sessionId,
|
|
145
240
|
permissionPreset: lockdown.permissionPreset,
|
|
@@ -151,13 +246,23 @@ export class QaPolicyAdmission {
|
|
|
151
246
|
agentPresetMatches,
|
|
152
247
|
workspaceMatches,
|
|
153
248
|
modelMatches,
|
|
154
|
-
|
|
249
|
+
sandboxModeMatches,
|
|
155
250
|
approvalIsNever,
|
|
156
251
|
permissionPreset: lockdown.permissionPreset,
|
|
157
252
|
toolPolicyLoaded: true,
|
|
158
|
-
|
|
253
|
+
// The fallback reporter is an internal read-only provenance capability,
|
|
254
|
+
// not an operator-configured QA tool grant.
|
|
255
|
+
toolAllowList: lockdown.toolPolicy.allow,
|
|
159
256
|
};
|
|
160
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* Whether one session went through this boundary. The provenance note is
|
|
260
|
+
* written only for attested sessions, which is what keeps a deployment's
|
|
261
|
+
* source rules out of unrelated chats served by the same process.
|
|
262
|
+
*/
|
|
263
|
+
knowsSession(sessionId) {
|
|
264
|
+
return this.attested.has(sessionId);
|
|
265
|
+
}
|
|
161
266
|
/** Detach every pinned tool policy; wired as a disposal effect by the entry. */
|
|
162
267
|
dispose() {
|
|
163
268
|
for (const policy of this.appliedPolicies.values()) {
|
|
@@ -165,6 +270,9 @@ export class QaPolicyAdmission {
|
|
|
165
270
|
policy.disposeGuard();
|
|
166
271
|
}
|
|
167
272
|
this.appliedPolicies.clear();
|
|
273
|
+
this.attested.clear();
|
|
274
|
+
this.workspaceRoots.clear();
|
|
275
|
+
this.disposeWorkspaceGuard();
|
|
168
276
|
}
|
|
169
277
|
}
|
|
170
278
|
//# sourceMappingURL=secure-session.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secure-session.js","sourceRoot":"","sources":["../src/secure-session.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"secure-session.js","sourceRoot":"","sources":["../src/secure-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The browser-local key namespace every QA-side index derives from: the
|
|
3
|
+
* configured storage key pinned to the served route, versioned once so the
|
|
4
|
+
* Host's head-script injection and the client bundle cannot drift apart.
|
|
5
|
+
*
|
|
6
|
+
* Dependency-free like every `src/shared` module: both bundles inline it.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* The versioned key prefix for browser-local QA state of one deployment.
|
|
10
|
+
* Callers append their own scope suffix (`:account-token`, `:welcome-notice`,
|
|
11
|
+
* `:chat:<id>`, …).
|
|
12
|
+
* @param config - configuration holding the storage key and the route path.
|
|
13
|
+
* @returns the versioned prefix, e.g. `dsh-qa-surface.session:v1:/qa`.
|
|
14
|
+
*/
|
|
15
|
+
export function qaStorageNamespace(config) {
|
|
16
|
+
return `${config.session.storageKey}:v1:${config.route.path}`;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=session-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-key.js","sourceRoot":"","sources":["../../src/shared/session-key.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAGE;IAEF,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity shared by the Host plugin and its browser settings card.
|
|
3
|
+
*
|
|
4
|
+
* This module must stay dependency-free: the card bundle inlines it, and a
|
|
5
|
+
* browser build must not pull the Host config surface (schemastery) into the
|
|
6
|
+
* page just to learn the namespace name.
|
|
7
|
+
*/
|
|
8
|
+
/** Settings namespace the QA surface owns and its card binds to. */
|
|
9
|
+
export const QA_SURFACE_SETTINGS_NAMESPACE = "qa-surface";
|
|
10
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/shared/settings.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,oEAAoE;AACpE,MAAM,CAAC,MAAM,6BAA6B,GAAG,YAAY,CAAC"}
|