@yadsh/dsh-qa-surface 0.9.0 → 0.11.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 +269 -2
- package/lib/access/service.js +49 -10
- package/lib/access/service.js.map +1 -1
- package/lib/account-remotes.js +41 -0
- package/lib/account-remotes.js.map +1 -1
- package/lib/accounts/database.js +140 -0
- package/lib/accounts/database.js.map +1 -1
- package/lib/accounts/errors.js.map +1 -1
- package/lib/accounts/service-token.js +103 -0
- package/lib/accounts/service-token.js.map +1 -0
- package/lib/accounts/store.js +291 -5
- package/lib/accounts/store.js.map +1 -1
- package/lib/admin/conversation-log.js +14 -8
- package/lib/admin/conversation-log.js.map +1 -1
- package/lib/admin/permissions.js +5 -0
- package/lib/admin/permissions.js.map +1 -1
- package/lib/admin/quality-store.js +4 -0
- package/lib/admin/quality-store.js.map +1 -1
- package/lib/admin/service.js +180 -7
- package/lib/admin/service.js.map +1 -1
- package/lib/admin/session-log.js +39 -8
- package/lib/admin/session-log.js.map +1 -1
- package/lib/attachment-rules.js +39 -6
- package/lib/attachment-rules.js.map +1 -1
- package/lib/cli.js +83 -1
- package/lib/cli.js.map +1 -1
- package/lib/client/QaAccountsController.js +213 -4
- package/lib/client/QaAccountsController.js.map +1 -1
- package/lib/client/QaSessionController.js +49 -21
- package/lib/client/QaSessionController.js.map +1 -1
- package/lib/client/QaSurface.js +51 -9
- package/lib/client/QaSurface.js.map +1 -1
- package/lib/client/QaSurfaceGuard.js +12 -5
- package/lib/client/QaSurfaceGuard.js.map +1 -1
- package/lib/client/admin/QaAdmin.js +14 -2
- package/lib/client/admin/QaAdmin.js.map +1 -1
- package/lib/client/admin/pages/SkillFiles.js +78 -0
- package/lib/client/admin/pages/SkillFiles.js.map +1 -0
- package/lib/client/admin/pages/Users.js +74 -3
- package/lib/client/admin/pages/Users.js.map +1 -1
- package/lib/client/admin/routes.js +8 -1
- package/lib/client/admin/routes.js.map +1 -1
- package/lib/client/admin/shared.js +5 -1
- package/lib/client/admin/shared.js.map +1 -1
- package/lib/client/admin/styles.js +2 -0
- package/lib/client/admin/styles.js.map +1 -1
- package/lib/client/attachments.js +41 -11
- package/lib/client/attachments.js.map +1 -1
- package/lib/client/base64.js +22 -1
- package/lib/client/base64.js.map +1 -1
- package/lib/client/components/QaAgentsDrawer.js +9 -6
- package/lib/client/components/QaAgentsDrawer.js.map +1 -1
- package/lib/client/components/QaApproval.js +1 -1
- package/lib/client/components/QaApproval.js.map +1 -1
- package/lib/client/components/QaAuthGate.js +19 -10
- package/lib/client/components/QaAuthGate.js.map +1 -1
- package/lib/client/components/QaChangelog.js +56 -0
- package/lib/client/components/QaChangelog.js.map +1 -1
- package/lib/client/components/QaFilesPanel.js +17 -11
- package/lib/client/components/QaFilesPanel.js.map +1 -1
- package/lib/client/components/QaHeader.js +3 -11
- package/lib/client/components/QaHeader.js.map +1 -1
- package/lib/client/components/QaModal.js.map +1 -1
- package/lib/client/components/QaQuestions.js +4 -4
- package/lib/client/components/QaQuestions.js.map +1 -1
- package/lib/client/components/QaSidebar.js +10 -2
- package/lib/client/components/QaSidebar.js.map +1 -1
- package/lib/client/components/QaWidthHandle.js +111 -5
- package/lib/client/components/QaWidthHandle.js.map +1 -1
- package/lib/client/components/QaWorkspaceBrowser.js +231 -0
- package/lib/client/components/QaWorkspaceBrowser.js.map +1 -0
- package/lib/client/index.js +122 -53
- package/lib/client/index.js.map +1 -1
- package/lib/client/kiosk.js +51 -0
- package/lib/client/kiosk.js.map +1 -0
- package/lib/client/lineage.js +64 -0
- package/lib/client/lineage.js.map +1 -1
- package/lib/client/markdown/blocks.js +122 -7
- package/lib/client/markdown/blocks.js.map +1 -1
- package/lib/client/markdown/inline.js +108 -12
- package/lib/client/markdown/inline.js.map +1 -1
- package/lib/client/markdown/katex-css.js +12 -0
- package/lib/client/markdown/katex-css.js.map +1 -0
- package/lib/client/markdown/math.js +84 -0
- package/lib/client/markdown/math.js.map +1 -0
- package/lib/client/markdown/render.js +74 -5
- package/lib/client/markdown/render.js.map +1 -1
- package/lib/client/settings/card.js +2 -2
- package/lib/client/settings/card.js.map +1 -1
- package/lib/client/settings/sections/attachments.js +6 -5
- package/lib/client/settings/sections/attachments.js.map +1 -1
- package/lib/client/settings/sections/notes.js +64 -0
- package/lib/client/settings/sections/notes.js.map +1 -0
- package/lib/client/settings/sections/sources.js +4 -1
- package/lib/client/settings/sections/sources.js.map +1 -1
- package/lib/client/settings/sections.js +1 -0
- package/lib/client/settings/sections.js.map +1 -1
- package/lib/client/settlement.js +1 -1
- package/lib/client/settlement.js.map +1 -1
- package/lib/client/source-preview.js +3 -0
- package/lib/client/source-preview.js.map +1 -1
- package/lib/client/styles.js +106 -18
- package/lib/client/styles.js.map +1 -1
- package/lib/client/types.js.map +1 -1
- package/lib/client/user-settings/IntegrationTokensPage.js +150 -0
- package/lib/client/user-settings/IntegrationTokensPage.js.map +1 -0
- package/lib/client/user-settings/PasswordSettingsPage.js +48 -0
- package/lib/client/user-settings/PasswordSettingsPage.js.map +1 -0
- package/lib/client/user-settings/SkillCatalog.js +2 -2
- package/lib/client/user-settings/SkillCatalog.js.map +1 -1
- package/lib/client/user-settings/UserSettingsDialog.js +17 -2
- package/lib/client/user-settings/UserSettingsDialog.js.map +1 -1
- package/lib/client/user-settings/copy.js +20 -0
- package/lib/client/user-settings/copy.js.map +1 -1
- package/lib/client.js +31007 -686
- package/lib/client.js.map +1 -1
- package/lib/config-resolvers/attachments.js +6 -5
- package/lib/config-resolvers/attachments.js.map +1 -1
- package/lib/config-resolvers/defaults.js +33 -2
- package/lib/config-resolvers/defaults.js.map +1 -1
- package/lib/config-resolvers/integration.js +94 -0
- package/lib/config-resolvers/integration.js.map +1 -0
- package/lib/config-resolvers/notes.js +26 -0
- package/lib/config-resolvers/notes.js.map +1 -0
- package/lib/config-resolvers/sources.js +4 -0
- package/lib/config-resolvers/sources.js.map +1 -1
- package/lib/config.js +107 -0
- package/lib/config.js.map +1 -1
- package/lib/index.js +348 -12
- package/lib/index.js.map +1 -1
- package/lib/integration/answer.js +100 -0
- package/lib/integration/answer.js.map +1 -0
- package/lib/integration/attachments.js +231 -0
- package/lib/integration/attachments.js.map +1 -0
- package/lib/integration/contract.js +53 -0
- package/lib/integration/contract.js.map +1 -0
- package/lib/integration/host-runner.js +243 -0
- package/lib/integration/host-runner.js.map +1 -0
- package/lib/integration/http.js +538 -0
- package/lib/integration/http.js.map +1 -0
- package/lib/integration/service.js +331 -0
- package/lib/integration/service.js.map +1 -0
- package/lib/integration/transcript-reader.js +202 -0
- package/lib/integration/transcript-reader.js.map +1 -0
- package/lib/integration/transcript.js +148 -0
- package/lib/integration/transcript.js.map +1 -0
- package/lib/personal-skills/index.js +2 -2
- package/lib/personal-skills/index.js.map +1 -1
- package/lib/personal-skills/paths.js +14 -8
- package/lib/personal-skills/paths.js.map +1 -1
- package/lib/personal-skills/provider.js +16 -4
- package/lib/personal-skills/provider.js.map +1 -1
- package/lib/personal-skills/service.js +240 -30
- package/lib/personal-skills/service.js.map +1 -1
- package/lib/prompt-notes.js +103 -6
- package/lib/prompt-notes.js.map +1 -1
- package/lib/provenance/document-preview.js +60 -0
- package/lib/provenance/document-preview.js.map +1 -0
- package/lib/provenance/file-preview.js +191 -19
- package/lib/provenance/file-preview.js.map +1 -1
- package/lib/qa-tools/catalog.js +18 -1
- package/lib/qa-tools/catalog.js.map +1 -1
- package/lib/qa-tools/docs-tools.js +563 -0
- package/lib/qa-tools/docs-tools.js.map +1 -0
- package/lib/qa-tools/file-delete-gate.js +60 -0
- package/lib/qa-tools/file-delete-gate.js.map +1 -0
- package/lib/qa-tools/file-delete.js +156 -0
- package/lib/qa-tools/file-delete.js.map +1 -0
- package/lib/resolve-config.js +6 -0
- package/lib/resolve-config.js.map +1 -1
- package/lib/secure-session.js +83 -3
- package/lib/secure-session.js.map +1 -1
- package/lib/shared/documents.js +22 -0
- package/lib/shared/documents.js.map +1 -0
- package/lib/shared/integration-tokens.js +23 -0
- package/lib/shared/integration-tokens.js.map +1 -0
- package/lib/typert.host.js +1320 -134
- package/lib/typert.remote-client.d.ts +33 -1
- package/lib/typert.remote-client.js +1102 -74
- package/lib/types/access/service.d.ts +33 -2
- package/lib/types/account-remotes.d.ts +30 -1
- package/lib/types/accounts/database.d.ts +53 -0
- package/lib/types/accounts/errors.d.ts +5 -1
- package/lib/types/accounts/service-token.d.ts +70 -0
- package/lib/types/accounts/store.d.ts +131 -1
- package/lib/types/admin/conversation-log.d.ts +12 -0
- package/lib/types/admin/service.d.ts +56 -1
- package/lib/types/admin/session-log.d.ts +21 -0
- package/lib/types/attachment-rules.d.ts +26 -3
- package/lib/types/client/QaAccountsController.d.ts +64 -5
- package/lib/types/client/QaSessionController.d.ts +24 -2
- package/lib/types/client/admin/pages/SkillFiles.d.ts +17 -0
- package/lib/types/client/admin/routes.d.ts +2 -0
- package/lib/types/client/admin/shared.d.ts +2 -0
- package/lib/types/client/attachments.d.ts +21 -4
- package/lib/types/client/base64.d.ts +13 -1
- package/lib/types/client/components/QaAgentsDrawer.d.ts +2 -1
- package/lib/types/client/components/QaFilesPanel.d.ts +16 -4
- package/lib/types/client/components/QaHeader.d.ts +9 -3
- package/lib/types/client/components/QaModal.d.ts +4 -3
- package/lib/types/client/components/QaWidthHandle.d.ts +48 -2
- package/lib/types/client/components/QaWorkspaceBrowser.d.ts +15 -0
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/kiosk.d.ts +34 -0
- package/lib/types/client/lineage.d.ts +42 -0
- package/lib/types/client/markdown/blocks.d.ts +14 -1
- package/lib/types/client/markdown/inline.d.ts +23 -7
- package/lib/types/client/markdown/katex-css.d.ts +11 -0
- package/lib/types/client/markdown/math.d.ts +23 -0
- package/lib/types/client/markdown/render.d.ts +2 -1
- package/lib/types/client/settings/sections/notes.d.ts +12 -0
- package/lib/types/client/settings/sections.d.ts +1 -0
- package/lib/types/client/settlement.d.ts +4 -1
- package/lib/types/client/styles.d.ts +15 -2
- package/lib/types/client/types.d.ts +120 -1
- package/lib/types/client/user-settings/IntegrationTokensPage.d.ts +21 -0
- package/lib/types/client/user-settings/PasswordSettingsPage.d.ts +19 -0
- package/lib/types/client/user-settings/UserSettingsDialog.d.ts +11 -2
- package/lib/types/client/user-settings/copy.d.ts +10 -1
- package/lib/types/config-resolvers/integration.d.ts +47 -0
- package/lib/types/config-resolvers/notes.d.ts +10 -0
- package/lib/types/config.d.ts +10 -0
- package/lib/types/index.d.ts +111 -1
- package/lib/types/integration/answer.d.ts +65 -0
- package/lib/types/integration/attachments.d.ts +85 -0
- package/lib/types/integration/contract.d.ts +196 -0
- package/lib/types/integration/host-runner.d.ts +44 -0
- package/lib/types/integration/http.d.ts +79 -0
- package/lib/types/integration/service.d.ts +120 -0
- package/lib/types/integration/transcript-reader.d.ts +100 -0
- package/lib/types/integration/transcript.d.ts +59 -0
- package/lib/types/personal-skills/index.d.ts +2 -2
- package/lib/types/personal-skills/paths.d.ts +15 -3
- package/lib/types/personal-skills/provider.d.ts +14 -2
- package/lib/types/personal-skills/service.d.ts +89 -14
- package/lib/types/prompt-notes.d.ts +37 -0
- package/lib/types/provenance/document-preview.d.ts +28 -0
- package/lib/types/provenance/file-preview.d.ts +69 -2
- package/lib/types/qa-tools/catalog.d.ts +1 -1
- package/lib/types/qa-tools/docs-tools.d.ts +160 -0
- package/lib/types/qa-tools/file-delete-gate.d.ts +42 -0
- package/lib/types/qa-tools/file-delete.d.ts +32 -0
- package/lib/types/secure-session.d.ts +52 -1
- package/lib/types/shared/documents.d.ts +20 -0
- package/lib/types/shared/integration-tokens.d.ts +24 -0
- package/lib/types/types.d.ts +263 -3
- package/lib/types/ui-mode.d.ts +18 -0
- package/lib/ui-mode.js +22 -0
- package/lib/ui-mode.js.map +1 -0
- package/package.json +12 -10
package/lib/index.js
CHANGED
|
@@ -37,7 +37,7 @@ import { Remote, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
|
|
|
37
37
|
import { SessionId } from "@deepseek-ai/dsh-session/types";
|
|
38
38
|
import { WorkspaceId } from "@deepseek-ai/dsh-workspace";
|
|
39
39
|
import { createHostLoggerSink, getPluginLogger, } from "@yadsh/dsh-plugin-log";
|
|
40
|
-
import { ConfigSchema, resolveConfig } from "./config.js";
|
|
40
|
+
import { ConfigSchema, qaSurfaceVersion, resolveConfig } from "./config.js";
|
|
41
41
|
import { createQaAccountRemotes } from "./account-remotes.js";
|
|
42
42
|
import { QaAdminService } from "./admin/service.js";
|
|
43
43
|
import { QaQualityStore } from "./admin/quality-store.js";
|
|
@@ -45,12 +45,17 @@ import { createSessionEraser, createSessionLogReader, } from "./admin/session-lo
|
|
|
45
45
|
import { createQaPersonalSkillRemotes, QaPersonalSkillsHost, } from "./personal-skills/index.js";
|
|
46
46
|
import { QaApprovalGate } from "./approvals.js";
|
|
47
47
|
import { QaAttestationError, qaAttestationFailureMessage, } from "./attestation.js";
|
|
48
|
+
import { QaFileDeleteGate } from "./qa-tools/file-delete-gate.js";
|
|
48
49
|
import { QaQuestionGate } from "./questions.js";
|
|
49
50
|
import { QaSessionOwnership } from "./session-ownership.js";
|
|
50
51
|
import { entryRedirectRow } from "./entry-redirect.js";
|
|
52
|
+
import { qaKioskDeployment } from "./ui-mode.js";
|
|
51
53
|
import { registerQaNavigationRoute } from "./host-route.js";
|
|
52
54
|
import { makeLaunchTokenSource } from "./launch-token.js";
|
|
53
55
|
import { QaIntegrationPrincipalBindings } from "./integration-principals.js";
|
|
56
|
+
import { registerQaIntegrationRoutes } from "./integration/http.js";
|
|
57
|
+
import { createQaIntegrationRunner } from "./integration/host-runner.js";
|
|
58
|
+
import { QaIntegrationService } from "./integration/service.js";
|
|
54
59
|
import { QaPolicyAdmission } from "./secure-session.js";
|
|
55
60
|
import { QaAccessService } from "./access/service.js";
|
|
56
61
|
import { createQaSlashRemotes } from "./slash/remotes.js";
|
|
@@ -58,7 +63,8 @@ import { QaPromptNotes } from "./prompt-notes.js";
|
|
|
58
63
|
import { QaTools } from "./qa-tools/index.js";
|
|
59
64
|
import { QaProvenanceHost } from "./provenance/host-store.js";
|
|
60
65
|
import { defaultLegacyProvenanceFilePath, defaultQaProvenanceDirectoryPath, FileQaProvenanceSnapshotStore, } from "./provenance/snapshot-store.js";
|
|
61
|
-
import {
|
|
66
|
+
import { previewConvertibleDocument } from "./provenance/document-preview.js";
|
|
67
|
+
import { listWorkspaceDirectory, readSourceFilePreview, readWorkspaceFile, QaSourcePreviewError, } from "./provenance/file-preview.js";
|
|
62
68
|
import { existingQaUserWorkspace, prepareQaUserWorkspace, } from "./user-workspace.js";
|
|
63
69
|
export const name = "qa-surface";
|
|
64
70
|
export const inject = [
|
|
@@ -90,12 +96,17 @@ let QaSurface = (() => {
|
|
|
90
96
|
let _instanceExtraInitializers = [];
|
|
91
97
|
let _accountsRegister_decorators;
|
|
92
98
|
let _accountsLogin_decorators;
|
|
99
|
+
let _accountsChangePassword_decorators;
|
|
100
|
+
let _accountsRequestPasswordReset_decorators;
|
|
93
101
|
let _accountsWhoami_decorators;
|
|
94
102
|
let _accountsClaimSessions_decorators;
|
|
95
103
|
let _accountsOwnedSessions_decorators;
|
|
96
104
|
let _accountsListOwnership_decorators;
|
|
97
105
|
let _accountsUpdateProfile_decorators;
|
|
98
106
|
let _accountsUpdateStarters_decorators;
|
|
107
|
+
let _accountsListServiceTokens_decorators;
|
|
108
|
+
let _accountsCreateServiceToken_decorators;
|
|
109
|
+
let _accountsRevokeServiceToken_decorators;
|
|
99
110
|
let _describe_decorators;
|
|
100
111
|
let _createSession_decorators;
|
|
101
112
|
let _accessCurrent_decorators;
|
|
@@ -108,10 +119,18 @@ let QaSurface = (() => {
|
|
|
108
119
|
let _accessUpdateAssignment_decorators;
|
|
109
120
|
let _accessUpdateSkillOverride_decorators;
|
|
110
121
|
let _accessSkillActivations_decorators;
|
|
122
|
+
let _adminSkills_decorators;
|
|
123
|
+
let _adminSkill_decorators;
|
|
124
|
+
let _adminSkillSave_decorators;
|
|
125
|
+
let _adminSkillDelete_decorators;
|
|
126
|
+
let _adminSkillValidate_decorators;
|
|
127
|
+
let _adminSkillTools_decorators;
|
|
111
128
|
let _adminOverview_decorators;
|
|
112
129
|
let _adminUsers_decorators;
|
|
113
130
|
let _adminUser_decorators;
|
|
114
131
|
let _adminUpdateUser_decorators;
|
|
132
|
+
let _adminPasswordResetRequests_decorators;
|
|
133
|
+
let _adminResetPassword_decorators;
|
|
115
134
|
let _adminConversations_decorators;
|
|
116
135
|
let _adminConversation_decorators;
|
|
117
136
|
let _adminDeleteConversation_decorators;
|
|
@@ -130,6 +149,9 @@ let QaSurface = (() => {
|
|
|
130
149
|
let _answerQuestion_decorators;
|
|
131
150
|
let _cancelQuestion_decorators;
|
|
132
151
|
let _readSourceFile_decorators;
|
|
152
|
+
let _listWorkspaceFiles_decorators;
|
|
153
|
+
let _readWorkspaceFile_decorators;
|
|
154
|
+
let _previewWorkspaceDocument_decorators;
|
|
133
155
|
let _skillsList_decorators;
|
|
134
156
|
let _skillsGet_decorators;
|
|
135
157
|
let _skillsCreate_decorators;
|
|
@@ -144,12 +166,17 @@ let QaSurface = (() => {
|
|
|
144
166
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
145
167
|
_accountsRegister_decorators = [Remote("accountsRegister")];
|
|
146
168
|
_accountsLogin_decorators = [Remote("accountsLogin")];
|
|
169
|
+
_accountsChangePassword_decorators = [Remote("accountsChangePassword")];
|
|
170
|
+
_accountsRequestPasswordReset_decorators = [Remote("accountsRequestPasswordReset")];
|
|
147
171
|
_accountsWhoami_decorators = [Remote("accountsWhoami")];
|
|
148
172
|
_accountsClaimSessions_decorators = [Remote("accountsClaimSessions")];
|
|
149
173
|
_accountsOwnedSessions_decorators = [Remote("accountsOwnedSessions")];
|
|
150
174
|
_accountsListOwnership_decorators = [Remote("accountsListOwnership")];
|
|
151
175
|
_accountsUpdateProfile_decorators = [Remote("accountsUpdateProfile")];
|
|
152
176
|
_accountsUpdateStarters_decorators = [Remote("accountsUpdateStarters")];
|
|
177
|
+
_accountsListServiceTokens_decorators = [Remote("accountsListServiceTokens")];
|
|
178
|
+
_accountsCreateServiceToken_decorators = [Remote("accountsCreateServiceToken")];
|
|
179
|
+
_accountsRevokeServiceToken_decorators = [Remote("accountsRevokeServiceToken")];
|
|
153
180
|
_describe_decorators = [Remote("describe")];
|
|
154
181
|
_createSession_decorators = [Remote("createSession")];
|
|
155
182
|
_accessCurrent_decorators = [Remote("accessCurrent")];
|
|
@@ -162,10 +189,18 @@ let QaSurface = (() => {
|
|
|
162
189
|
_accessUpdateAssignment_decorators = [Remote("accessUpdateAssignment")];
|
|
163
190
|
_accessUpdateSkillOverride_decorators = [Remote("accessUpdateSkillOverride")];
|
|
164
191
|
_accessSkillActivations_decorators = [Remote("accessSkillActivations")];
|
|
192
|
+
_adminSkills_decorators = [Remote("adminSkills")];
|
|
193
|
+
_adminSkill_decorators = [Remote("adminSkill")];
|
|
194
|
+
_adminSkillSave_decorators = [Remote("adminSkillSave")];
|
|
195
|
+
_adminSkillDelete_decorators = [Remote("adminSkillDelete")];
|
|
196
|
+
_adminSkillValidate_decorators = [Remote("adminSkillValidate")];
|
|
197
|
+
_adminSkillTools_decorators = [Remote("adminSkillTools")];
|
|
165
198
|
_adminOverview_decorators = [Remote("adminOverview")];
|
|
166
199
|
_adminUsers_decorators = [Remote("adminUsers")];
|
|
167
200
|
_adminUser_decorators = [Remote("adminUser")];
|
|
168
201
|
_adminUpdateUser_decorators = [Remote("adminUpdateUser")];
|
|
202
|
+
_adminPasswordResetRequests_decorators = [Remote("adminPasswordResetRequests")];
|
|
203
|
+
_adminResetPassword_decorators = [Remote("adminResetPassword")];
|
|
169
204
|
_adminConversations_decorators = [Remote("adminConversations")];
|
|
170
205
|
_adminConversation_decorators = [Remote("adminConversation")];
|
|
171
206
|
_adminDeleteConversation_decorators = [Remote("adminDeleteConversation")];
|
|
@@ -184,6 +219,9 @@ let QaSurface = (() => {
|
|
|
184
219
|
_answerQuestion_decorators = [Remote("answerQuestion")];
|
|
185
220
|
_cancelQuestion_decorators = [Remote("cancelQuestion")];
|
|
186
221
|
_readSourceFile_decorators = [Remote("readSourceFile")];
|
|
222
|
+
_listWorkspaceFiles_decorators = [Remote("listWorkspaceFiles")];
|
|
223
|
+
_readWorkspaceFile_decorators = [Remote("readWorkspaceFile")];
|
|
224
|
+
_previewWorkspaceDocument_decorators = [Remote("previewWorkspaceDocument")];
|
|
187
225
|
_skillsList_decorators = [Remote("skillsList")];
|
|
188
226
|
_skillsGet_decorators = [Remote("skillsGet")];
|
|
189
227
|
_skillsCreate_decorators = [Remote("skillsCreate")];
|
|
@@ -195,12 +233,17 @@ let QaSurface = (() => {
|
|
|
195
233
|
_slashExecute_decorators = [Remote("slashExecute")];
|
|
196
234
|
__esDecorate(this, null, _accountsRegister_decorators, { kind: "method", name: "accountsRegister", static: false, private: false, access: { has: obj => "accountsRegister" in obj, get: obj => obj.accountsRegister }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
197
235
|
__esDecorate(this, null, _accountsLogin_decorators, { kind: "method", name: "accountsLogin", static: false, private: false, access: { has: obj => "accountsLogin" in obj, get: obj => obj.accountsLogin }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
236
|
+
__esDecorate(this, null, _accountsChangePassword_decorators, { kind: "method", name: "accountsChangePassword", static: false, private: false, access: { has: obj => "accountsChangePassword" in obj, get: obj => obj.accountsChangePassword }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
237
|
+
__esDecorate(this, null, _accountsRequestPasswordReset_decorators, { kind: "method", name: "accountsRequestPasswordReset", static: false, private: false, access: { has: obj => "accountsRequestPasswordReset" in obj, get: obj => obj.accountsRequestPasswordReset }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
198
238
|
__esDecorate(this, null, _accountsWhoami_decorators, { kind: "method", name: "accountsWhoami", static: false, private: false, access: { has: obj => "accountsWhoami" in obj, get: obj => obj.accountsWhoami }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
199
239
|
__esDecorate(this, null, _accountsClaimSessions_decorators, { kind: "method", name: "accountsClaimSessions", static: false, private: false, access: { has: obj => "accountsClaimSessions" in obj, get: obj => obj.accountsClaimSessions }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
200
240
|
__esDecorate(this, null, _accountsOwnedSessions_decorators, { kind: "method", name: "accountsOwnedSessions", static: false, private: false, access: { has: obj => "accountsOwnedSessions" in obj, get: obj => obj.accountsOwnedSessions }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
201
241
|
__esDecorate(this, null, _accountsListOwnership_decorators, { kind: "method", name: "accountsListOwnership", static: false, private: false, access: { has: obj => "accountsListOwnership" in obj, get: obj => obj.accountsListOwnership }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
202
242
|
__esDecorate(this, null, _accountsUpdateProfile_decorators, { kind: "method", name: "accountsUpdateProfile", static: false, private: false, access: { has: obj => "accountsUpdateProfile" in obj, get: obj => obj.accountsUpdateProfile }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
203
243
|
__esDecorate(this, null, _accountsUpdateStarters_decorators, { kind: "method", name: "accountsUpdateStarters", static: false, private: false, access: { has: obj => "accountsUpdateStarters" in obj, get: obj => obj.accountsUpdateStarters }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
244
|
+
__esDecorate(this, null, _accountsListServiceTokens_decorators, { kind: "method", name: "accountsListServiceTokens", static: false, private: false, access: { has: obj => "accountsListServiceTokens" in obj, get: obj => obj.accountsListServiceTokens }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
245
|
+
__esDecorate(this, null, _accountsCreateServiceToken_decorators, { kind: "method", name: "accountsCreateServiceToken", static: false, private: false, access: { has: obj => "accountsCreateServiceToken" in obj, get: obj => obj.accountsCreateServiceToken }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
246
|
+
__esDecorate(this, null, _accountsRevokeServiceToken_decorators, { kind: "method", name: "accountsRevokeServiceToken", static: false, private: false, access: { has: obj => "accountsRevokeServiceToken" in obj, get: obj => obj.accountsRevokeServiceToken }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
204
247
|
__esDecorate(this, null, _describe_decorators, { kind: "method", name: "describe", static: false, private: false, access: { has: obj => "describe" in obj, get: obj => obj.describe }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
205
248
|
__esDecorate(this, null, _createSession_decorators, { kind: "method", name: "createSession", static: false, private: false, access: { has: obj => "createSession" in obj, get: obj => obj.createSession }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
206
249
|
__esDecorate(this, null, _accessCurrent_decorators, { kind: "method", name: "accessCurrent", static: false, private: false, access: { has: obj => "accessCurrent" in obj, get: obj => obj.accessCurrent }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
@@ -213,10 +256,18 @@ let QaSurface = (() => {
|
|
|
213
256
|
__esDecorate(this, null, _accessUpdateAssignment_decorators, { kind: "method", name: "accessUpdateAssignment", static: false, private: false, access: { has: obj => "accessUpdateAssignment" in obj, get: obj => obj.accessUpdateAssignment }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
214
257
|
__esDecorate(this, null, _accessUpdateSkillOverride_decorators, { kind: "method", name: "accessUpdateSkillOverride", static: false, private: false, access: { has: obj => "accessUpdateSkillOverride" in obj, get: obj => obj.accessUpdateSkillOverride }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
215
258
|
__esDecorate(this, null, _accessSkillActivations_decorators, { kind: "method", name: "accessSkillActivations", static: false, private: false, access: { has: obj => "accessSkillActivations" in obj, get: obj => obj.accessSkillActivations }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
259
|
+
__esDecorate(this, null, _adminSkills_decorators, { kind: "method", name: "adminSkills", static: false, private: false, access: { has: obj => "adminSkills" in obj, get: obj => obj.adminSkills }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
260
|
+
__esDecorate(this, null, _adminSkill_decorators, { kind: "method", name: "adminSkill", static: false, private: false, access: { has: obj => "adminSkill" in obj, get: obj => obj.adminSkill }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
261
|
+
__esDecorate(this, null, _adminSkillSave_decorators, { kind: "method", name: "adminSkillSave", static: false, private: false, access: { has: obj => "adminSkillSave" in obj, get: obj => obj.adminSkillSave }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
262
|
+
__esDecorate(this, null, _adminSkillDelete_decorators, { kind: "method", name: "adminSkillDelete", static: false, private: false, access: { has: obj => "adminSkillDelete" in obj, get: obj => obj.adminSkillDelete }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
263
|
+
__esDecorate(this, null, _adminSkillValidate_decorators, { kind: "method", name: "adminSkillValidate", static: false, private: false, access: { has: obj => "adminSkillValidate" in obj, get: obj => obj.adminSkillValidate }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
264
|
+
__esDecorate(this, null, _adminSkillTools_decorators, { kind: "method", name: "adminSkillTools", static: false, private: false, access: { has: obj => "adminSkillTools" in obj, get: obj => obj.adminSkillTools }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
216
265
|
__esDecorate(this, null, _adminOverview_decorators, { kind: "method", name: "adminOverview", static: false, private: false, access: { has: obj => "adminOverview" in obj, get: obj => obj.adminOverview }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
217
266
|
__esDecorate(this, null, _adminUsers_decorators, { kind: "method", name: "adminUsers", static: false, private: false, access: { has: obj => "adminUsers" in obj, get: obj => obj.adminUsers }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
218
267
|
__esDecorate(this, null, _adminUser_decorators, { kind: "method", name: "adminUser", static: false, private: false, access: { has: obj => "adminUser" in obj, get: obj => obj.adminUser }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
219
268
|
__esDecorate(this, null, _adminUpdateUser_decorators, { kind: "method", name: "adminUpdateUser", static: false, private: false, access: { has: obj => "adminUpdateUser" in obj, get: obj => obj.adminUpdateUser }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
269
|
+
__esDecorate(this, null, _adminPasswordResetRequests_decorators, { kind: "method", name: "adminPasswordResetRequests", static: false, private: false, access: { has: obj => "adminPasswordResetRequests" in obj, get: obj => obj.adminPasswordResetRequests }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
270
|
+
__esDecorate(this, null, _adminResetPassword_decorators, { kind: "method", name: "adminResetPassword", static: false, private: false, access: { has: obj => "adminResetPassword" in obj, get: obj => obj.adminResetPassword }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
220
271
|
__esDecorate(this, null, _adminConversations_decorators, { kind: "method", name: "adminConversations", static: false, private: false, access: { has: obj => "adminConversations" in obj, get: obj => obj.adminConversations }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
221
272
|
__esDecorate(this, null, _adminConversation_decorators, { kind: "method", name: "adminConversation", static: false, private: false, access: { has: obj => "adminConversation" in obj, get: obj => obj.adminConversation }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
222
273
|
__esDecorate(this, null, _adminDeleteConversation_decorators, { kind: "method", name: "adminDeleteConversation", static: false, private: false, access: { has: obj => "adminDeleteConversation" in obj, get: obj => obj.adminDeleteConversation }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
@@ -235,6 +286,9 @@ let QaSurface = (() => {
|
|
|
235
286
|
__esDecorate(this, null, _answerQuestion_decorators, { kind: "method", name: "answerQuestion", static: false, private: false, access: { has: obj => "answerQuestion" in obj, get: obj => obj.answerQuestion }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
236
287
|
__esDecorate(this, null, _cancelQuestion_decorators, { kind: "method", name: "cancelQuestion", static: false, private: false, access: { has: obj => "cancelQuestion" in obj, get: obj => obj.cancelQuestion }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
237
288
|
__esDecorate(this, null, _readSourceFile_decorators, { kind: "method", name: "readSourceFile", static: false, private: false, access: { has: obj => "readSourceFile" in obj, get: obj => obj.readSourceFile }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
289
|
+
__esDecorate(this, null, _listWorkspaceFiles_decorators, { kind: "method", name: "listWorkspaceFiles", static: false, private: false, access: { has: obj => "listWorkspaceFiles" in obj, get: obj => obj.listWorkspaceFiles }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
290
|
+
__esDecorate(this, null, _readWorkspaceFile_decorators, { kind: "method", name: "readWorkspaceFile", static: false, private: false, access: { has: obj => "readWorkspaceFile" in obj, get: obj => obj.readWorkspaceFile }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
291
|
+
__esDecorate(this, null, _previewWorkspaceDocument_decorators, { kind: "method", name: "previewWorkspaceDocument", static: false, private: false, access: { has: obj => "previewWorkspaceDocument" in obj, get: obj => obj.previewWorkspaceDocument }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
238
292
|
__esDecorate(this, null, _skillsList_decorators, { kind: "method", name: "skillsList", static: false, private: false, access: { has: obj => "skillsList" in obj, get: obj => obj.skillsList }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
239
293
|
__esDecorate(this, null, _skillsGet_decorators, { kind: "method", name: "skillsGet", static: false, private: false, access: { has: obj => "skillsGet" in obj, get: obj => obj.skillsGet }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
240
294
|
__esDecorate(this, null, _skillsCreate_decorators, { kind: "method", name: "skillsCreate", static: false, private: false, access: { has: obj => "skillsCreate" in obj, get: obj => obj.skillsCreate }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
@@ -252,6 +306,7 @@ let QaSurface = (() => {
|
|
|
252
306
|
logger;
|
|
253
307
|
admission;
|
|
254
308
|
approvals;
|
|
309
|
+
fileDeleteGate;
|
|
255
310
|
userQuestions;
|
|
256
311
|
provenance;
|
|
257
312
|
notes;
|
|
@@ -282,6 +337,14 @@ let QaSurface = (() => {
|
|
|
282
337
|
webServer;
|
|
283
338
|
disposeRoute;
|
|
284
339
|
routeKey;
|
|
340
|
+
/**
|
|
341
|
+
* The HTTP API an external application asks questions through. Constructed
|
|
342
|
+
* always — it is cheap and stateless until a request arrives — and exposed
|
|
343
|
+
* on the network only while the deployment turns it on.
|
|
344
|
+
*/
|
|
345
|
+
integration;
|
|
346
|
+
disposeIntegrationRoutes;
|
|
347
|
+
integrationRouteKey;
|
|
285
348
|
/**
|
|
286
349
|
* The quality store opens its file on first use, so a deployment that never
|
|
287
350
|
* opens the admin console never grows one.
|
|
@@ -332,6 +395,10 @@ let QaSurface = (() => {
|
|
|
332
395
|
// per-browser row, and only an administrator removes the chat itself.
|
|
333
396
|
sessionFiles: createSessionEraser(),
|
|
334
397
|
dropSources: (sessionId) => this.provenance.dropSession(sessionId),
|
|
398
|
+
// The console writes skills through the same service the owner's editor
|
|
399
|
+
// uses, so an administrator's save is path-checked, validated and
|
|
400
|
+
// published to DSH by exactly the one code path that already does it.
|
|
401
|
+
skills: () => this.personalSkills.service,
|
|
335
402
|
logger: this.logger,
|
|
336
403
|
});
|
|
337
404
|
this.skillRemotes = createQaPersonalSkillRemotes({
|
|
@@ -355,17 +422,41 @@ let QaSurface = (() => {
|
|
|
355
422
|
?.ensureSessionAccess(token, sessionId, facts);
|
|
356
423
|
},
|
|
357
424
|
userWorkspace: (userId, registeredWorkspacePath) => existingQaUserWorkspace(registeredWorkspacePath, userId),
|
|
425
|
+
// Read only by the integration API, whose caller proved an account
|
|
426
|
+
// with a service token instead of a browser one. The ownership
|
|
427
|
+
// record stays the authority either way.
|
|
428
|
+
ownerIdOf: (sessionId) => this.accountRemotes.resolve(this.getConfig())?.ownerIdOf(sessionId),
|
|
358
429
|
},
|
|
359
430
|
// Legacy account-free sessions retain the dynamic catalog behavior;
|
|
360
431
|
// role-managed sessions authorize its known entries through the frozen
|
|
361
432
|
// capability policy instead.
|
|
362
|
-
(agent) => this.tools?.activeToolNames(agent) ?? [], (
|
|
433
|
+
(agent) => this.tools?.activeToolNames(agent) ?? [], (owner, sessionId, agent) => this.access.policyForSessionOwner(owner, sessionId, agent), () => this.tools?.catalogToolNames() ?? []);
|
|
363
434
|
this.provenance = new QaProvenanceHost(ctx, () => this.getConfig(),
|
|
364
435
|
// Sharded per chat and bounded by the resolved retention policy: the
|
|
365
436
|
// turn path must never rewrite history it did not touch.
|
|
366
437
|
new FileQaProvenanceSnapshotStore(defaultQaProvenanceDirectoryPath(), () => this.getConfig().sources.retention, defaultLegacyProvenanceFilePath()), (error) => this.logger.error("sources.persistence-failed", {
|
|
367
438
|
message: error instanceof Error ? error.message : String(error),
|
|
368
439
|
}));
|
|
440
|
+
this.integration = new QaIntegrationService({
|
|
441
|
+
getConfig: () => this.getConfig(),
|
|
442
|
+
accounts: () => this.accountRemotes.resolve(this.getConfig()),
|
|
443
|
+
runner: createQaIntegrationRunner({
|
|
444
|
+
ctx,
|
|
445
|
+
getConfig: () => this.getConfig(),
|
|
446
|
+
accounts: () => this.accountRemotes.resolve(this.getConfig()),
|
|
447
|
+
admission: this.admission,
|
|
448
|
+
access: this.access,
|
|
449
|
+
sessionLog,
|
|
450
|
+
provenance: this.provenance,
|
|
451
|
+
// Resolved per call, like the files panel does it: the document plugin
|
|
452
|
+
// may install after this one, and a document attachment that arrives
|
|
453
|
+
// before it did is refused with the caller's own fallback signal.
|
|
454
|
+
documents: () => ctx.get("documents"),
|
|
455
|
+
logger: this.logger,
|
|
456
|
+
}),
|
|
457
|
+
logger: this.logger,
|
|
458
|
+
version: qaSurfaceVersion(),
|
|
459
|
+
});
|
|
369
460
|
// The one place a composed gate's `ask` becomes a decision for an attested
|
|
370
461
|
// chat: refused outright while approvals are blocked, parked for the
|
|
371
462
|
// operator's answer while they are interactive. The question seam shares
|
|
@@ -373,8 +464,15 @@ let QaSurface = (() => {
|
|
|
373
464
|
const ownership = new QaSessionOwnership((sessionId) => this.admission.knowsSession(sessionId));
|
|
374
465
|
this.approvals = new QaApprovalGate(ctx, () => this.getConfig().interaction.approvals === "interactive", ownership, this.logger);
|
|
375
466
|
this.userQuestions = new QaQuestionGate(ctx, () => this.getConfig().interaction.questions === "interactive", ownership, this.logger);
|
|
467
|
+
// The destructive tool of the QA catalog composes the same approval flow
|
|
468
|
+
// around itself: registered without `prepend`, it sits inside the approval
|
|
469
|
+
// gate and answers `ask` for every file_delete call of an attested chat,
|
|
470
|
+
// so the interactive card parks it for the operator (or the blocked
|
|
471
|
+
// configuration refuses it — nothing is deleted without a person).
|
|
472
|
+
this.fileDeleteGate = new QaFileDeleteGate(ctx, ownership);
|
|
376
473
|
this.approvals.install();
|
|
377
474
|
this.userQuestions.install();
|
|
475
|
+
this.fileDeleteGate.install();
|
|
378
476
|
// The identity note and the provenance rule ride the conversation as
|
|
379
477
|
// durable context messages, delegated experts included: the QA preset's
|
|
380
478
|
// complete persona closes the system prompt to plugins, the conversation
|
|
@@ -394,6 +492,7 @@ let QaSurface = (() => {
|
|
|
394
492
|
ctx.effect(() => async () => this.logger.close(), "dsh-qa-surface.logger");
|
|
395
493
|
ctx.effect(() => () => this.admission.dispose(), "dsh-qa-surface.lockdown-policies");
|
|
396
494
|
ctx.effect(() => () => this.approvals.dispose(), "dsh-qa-surface.approvals");
|
|
495
|
+
ctx.effect(() => () => this.fileDeleteGate.dispose(), "dsh-qa-surface.file-delete-gate");
|
|
397
496
|
ctx.effect(() => () => this.userQuestions.dispose(), "dsh-qa-surface.user-questions");
|
|
398
497
|
ctx.effect(() => () => this.provenance.dispose(), "dsh-qa-surface.provenance");
|
|
399
498
|
ctx.effect(() => () => this.notes.dispose(), "dsh-qa-surface.prompt-notes");
|
|
@@ -411,12 +510,17 @@ let QaSurface = (() => {
|
|
|
411
510
|
});
|
|
412
511
|
ctx.effect(() => () => this.tools.dispose(), "dsh-qa-surface.qa-tools");
|
|
413
512
|
// The root index gains one head script: non-loopback hostnames continue
|
|
414
|
-
// into /qa, the loopback operator keeps the full harness UI.
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
513
|
+
// into /qa, the loopback operator keeps the full harness UI. Not in the
|
|
514
|
+
// kiosk composition: there the index itself is served under /qa, so the
|
|
515
|
+
// script would meet its own target on every load and reload the page in
|
|
516
|
+
// a loop, and the server policy already routes the site root into /qa.
|
|
517
|
+
if (!qaKioskDeployment()) {
|
|
518
|
+
ctx.on("webserver/index-inject", (table) => {
|
|
519
|
+
const row = entryRedirectRow(this.getConfig());
|
|
520
|
+
if (row !== undefined)
|
|
521
|
+
table.push(row);
|
|
522
|
+
});
|
|
523
|
+
}
|
|
420
524
|
ctx.inject(["settings"], (settingsCtx) => {
|
|
421
525
|
settingsCtx.settings.installSection(ctx, QA_SURFACE_SETTINGS_NAMESPACE, ConfigSchema, entry, {
|
|
422
526
|
setSource: (source) => {
|
|
@@ -425,6 +529,7 @@ let QaSurface = (() => {
|
|
|
425
529
|
onChange: () => {
|
|
426
530
|
const config = this.getConfig();
|
|
427
531
|
this.refreshRoute();
|
|
532
|
+
this.refreshIntegrationRoutes();
|
|
428
533
|
this.warnDocumentsMoved();
|
|
429
534
|
this.warnLegacySlashDefaults();
|
|
430
535
|
this.logger.info("config.updated", {
|
|
@@ -441,10 +546,14 @@ let QaSurface = (() => {
|
|
|
441
546
|
ctx.inject(["webServer"], (webContext) => {
|
|
442
547
|
this.webServer = webContext.webServer;
|
|
443
548
|
this.refreshRoute();
|
|
549
|
+
this.refreshIntegrationRoutes();
|
|
444
550
|
webContext.effect(() => () => {
|
|
445
551
|
this.disposeRoute?.();
|
|
446
552
|
this.disposeRoute = undefined;
|
|
447
553
|
this.routeKey = undefined;
|
|
554
|
+
this.disposeIntegrationRoutes?.();
|
|
555
|
+
this.disposeIntegrationRoutes = undefined;
|
|
556
|
+
this.integrationRouteKey = undefined;
|
|
448
557
|
this.webServer = undefined;
|
|
449
558
|
}, "dsh-qa-surface.navigation-route");
|
|
450
559
|
});
|
|
@@ -570,6 +679,18 @@ let QaSurface = (() => {
|
|
|
570
679
|
return this.accountRemotes.login(email, password);
|
|
571
680
|
}
|
|
572
681
|
/** Identity probe; safe to call with an empty or expired token. */
|
|
682
|
+
accountsChangePassword(token, currentPassword, nextPassword) {
|
|
683
|
+
return this.accountRemotes.changePassword(token, currentPassword, nextPassword);
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* The sign-in screen's "забыли пароль?" path. It answers the same way for
|
|
687
|
+
* every address: whether an account exists is not something this endpoint
|
|
688
|
+
* tells a caller.
|
|
689
|
+
*/
|
|
690
|
+
accountsRequestPasswordReset(email) {
|
|
691
|
+
this.accountRemotes.requestPasswordReset(email);
|
|
692
|
+
return { accepted: true };
|
|
693
|
+
}
|
|
573
694
|
accountsWhoami(token) {
|
|
574
695
|
return this.accountRemotes.whoami(token);
|
|
575
696
|
}
|
|
@@ -610,6 +731,31 @@ let QaSurface = (() => {
|
|
|
610
731
|
accountsUpdateStarters(token, input) {
|
|
611
732
|
return this.accountRemotes.updateStarters(token, input);
|
|
612
733
|
}
|
|
734
|
+
/**
|
|
735
|
+
* The caller's own integration tokens. The list is the account's own: the
|
|
736
|
+
* token names it, and a secret is never part of a summary, so reading this
|
|
737
|
+
* cannot repeat a credential that was already handed over.
|
|
738
|
+
*/
|
|
739
|
+
accountsListServiceTokens(token) {
|
|
740
|
+
return this.accountRemotes.listServiceTokens(token);
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* Mint one integration token for the caller. The answer carries the
|
|
744
|
+
* plaintext exactly once — nothing stores it, so nothing can repeat it — and
|
|
745
|
+
* the account is always the authenticated one: there is no owner field on
|
|
746
|
+
* the wire.
|
|
747
|
+
*/
|
|
748
|
+
accountsCreateServiceToken(token, input) {
|
|
749
|
+
return this.accountRemotes.createServiceToken(token, input);
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Revoke one of the caller's own integration tokens. This is the immediate
|
|
753
|
+
* kill switch the profile page offers: the next request that presents the
|
|
754
|
+
* credential is refused, without waiting for its expiry.
|
|
755
|
+
*/
|
|
756
|
+
accountsRevokeServiceToken(token, tokenId) {
|
|
757
|
+
return this.accountRemotes.revokeServiceToken(token, tokenId);
|
|
758
|
+
}
|
|
613
759
|
/**
|
|
614
760
|
* Serve the effective QA configuration to the browser. The DSH gateway pins
|
|
615
761
|
* settings RPCs to loopback, so a browser served over the LAN always sees
|
|
@@ -745,6 +891,38 @@ let QaSurface = (() => {
|
|
|
745
891
|
// Administrative console. Every method names its permission inside the
|
|
746
892
|
// service; the wire carries a token and never an identity.
|
|
747
893
|
// ---------------------------------------------------------------------------
|
|
894
|
+
/**
|
|
895
|
+
* The skill catalog of one scope: the deployment's shared skills, or the
|
|
896
|
+
* personal skills of the account the scope names. Reading another account's
|
|
897
|
+
* skills is an administrative act, so it needs `skills.manage`.
|
|
898
|
+
*/
|
|
899
|
+
adminSkills(token, scope) {
|
|
900
|
+
return this.accountRemotes.runAsync(() => this.admin.skills(token, scope));
|
|
901
|
+
}
|
|
902
|
+
/** One skill file with the body, revision and administrator mark. */
|
|
903
|
+
adminSkill(token, scope, name) {
|
|
904
|
+
return this.accountRemotes.runAsync(() => this.admin.skill(token, scope, name));
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* Create (`name` null) or replace one skill in place. The write is recorded
|
|
908
|
+
* as this administrator's, and the owner sees that it was.
|
|
909
|
+
*/
|
|
910
|
+
adminSkillSave(token, scope, name, input) {
|
|
911
|
+
return this.accountRemotes.runAsync(() => this.admin.saveSkill(token, scope, name, input));
|
|
912
|
+
}
|
|
913
|
+
/** Remove one skill into the trash beside its own skills root. */
|
|
914
|
+
adminSkillDelete(token, scope, name, expectedRevision) {
|
|
915
|
+
return this.accountRemotes.runAsync(() => this.admin.removeSkill(token, scope, name, expectedRevision));
|
|
916
|
+
}
|
|
917
|
+
/** The file a save would write, plus every diagnostic for the draft. */
|
|
918
|
+
adminSkillValidate(token, scope, name, input) {
|
|
919
|
+
return this.accountRemotes.runAsync(() => this.admin.validateSkill(token, scope, name, input));
|
|
920
|
+
}
|
|
921
|
+
/** The tool catalog the picker offers for one scope. */
|
|
922
|
+
async adminSkillTools(token, scope) {
|
|
923
|
+
const tools = await this.accountRemotes.runAsync(() => this.admin.skillTools(token, scope));
|
|
924
|
+
return { tools };
|
|
925
|
+
}
|
|
748
926
|
/** Counters, attention lines and the newest quality signals. */
|
|
749
927
|
adminOverview(token) {
|
|
750
928
|
return this.accountRemotes.runAsync(() => this.admin.overview(token));
|
|
@@ -759,6 +937,12 @@ let QaSurface = (() => {
|
|
|
759
937
|
adminUpdateUser(token, userId, update) {
|
|
760
938
|
return this.accountRemotes.runAsync(() => this.admin.updateUser(token, userId, update));
|
|
761
939
|
}
|
|
940
|
+
adminPasswordResetRequests(token) {
|
|
941
|
+
return this.accountRemotes.runAsync(() => this.admin.passwordResetRequests(token));
|
|
942
|
+
}
|
|
943
|
+
adminResetPassword(token, userId, password) {
|
|
944
|
+
return this.accountRemotes.runAsync(() => this.admin.resetUserPassword(token, userId, password));
|
|
945
|
+
}
|
|
762
946
|
adminConversations(token, query, cursor, limit) {
|
|
763
947
|
return this.accountRemotes.runAsync(() => this.admin.conversations(token, query, cursor ?? undefined, limit ?? undefined));
|
|
764
948
|
}
|
|
@@ -912,6 +1096,105 @@ let QaSurface = (() => {
|
|
|
912
1096
|
throw sourcePreviewRefusal(error instanceof QaSourcePreviewError ? error.reason : "unavailable");
|
|
913
1097
|
}
|
|
914
1098
|
}
|
|
1099
|
+
/**
|
|
1100
|
+
* List one directory of the chat's own workspace for the files panel.
|
|
1101
|
+
*
|
|
1102
|
+
* Browsing is deliberately narrower than the source preview: it stays inside
|
|
1103
|
+
* the chat's own directory tree, so a visitor can look at what their
|
|
1104
|
+
* conversation produced and at nothing else of the deployment.
|
|
1105
|
+
* `readWorkspaceFile` opens one entry of such a listing.
|
|
1106
|
+
*/
|
|
1107
|
+
async listWorkspaceFiles(token, sessionId, path) {
|
|
1108
|
+
await this.admission.secureSession(token, sessionId);
|
|
1109
|
+
const { config, cwd } = await this.browseContext(sessionId);
|
|
1110
|
+
try {
|
|
1111
|
+
return await listWorkspaceDirectory({
|
|
1112
|
+
dirPath: path ?? "",
|
|
1113
|
+
cwd,
|
|
1114
|
+
maxEntries: config.sources.filePreview.maxListingEntries,
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
catch (error) {
|
|
1118
|
+
throw this.browseRefusal("workspace.list-refused", sessionId, error);
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
/**
|
|
1122
|
+
* Read one file of the chat's workspace: text when it decodes as UTF-8, bytes
|
|
1123
|
+
* when it does not, so a document the agent produced can be downloaded while
|
|
1124
|
+
* a note previews inline. The readable roots are the ones the model itself
|
|
1125
|
+
* may read; unlike the source preview this does not require the file to be
|
|
1126
|
+
* recorded evidence, because the panel is browsing a tree rather than
|
|
1127
|
+
* reopening a cited source.
|
|
1128
|
+
*/
|
|
1129
|
+
async readWorkspaceFile(token, sessionId, path) {
|
|
1130
|
+
await this.admission.secureSession(token, sessionId);
|
|
1131
|
+
const { config, cwd } = await this.browseContext(sessionId);
|
|
1132
|
+
const attachmentRoot = this.admission.attachmentRoot();
|
|
1133
|
+
try {
|
|
1134
|
+
return await readWorkspaceFile({
|
|
1135
|
+
filePath: path ?? "",
|
|
1136
|
+
cwd,
|
|
1137
|
+
sharedReadOnlyRoots: config.lockdown.sharedReadOnlyRoots,
|
|
1138
|
+
...(attachmentRoot === undefined ? {} : { attachmentRoot }),
|
|
1139
|
+
maxBytes: config.sources.filePreview.maxBytes,
|
|
1140
|
+
maxMarkdownRenderBytes: config.sources.filePreview.maxMarkdownRenderBytes,
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
catch (error) {
|
|
1144
|
+
throw this.browseRefusal("workspace.read-refused", sessionId, error);
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Render one Word document of the chat's workspace as a PDF for the panel.
|
|
1149
|
+
*
|
|
1150
|
+
* The conversion is the document pipeline's own, reached through the service
|
|
1151
|
+
* `@yadsh/dsh-documents` publishes for its Host siblings — the panel gets the
|
|
1152
|
+
* same providers, limits and refusals the `document_*` tools see, and a
|
|
1153
|
+
* deployment without that plugin refuses instead of showing a guess. The
|
|
1154
|
+
* produced PDF is read back here and travels as base64, so the audience never
|
|
1155
|
+
* reaches an unfenced byte route.
|
|
1156
|
+
*/
|
|
1157
|
+
async previewWorkspaceDocument(token, sessionId, path) {
|
|
1158
|
+
await this.admission.secureSession(token, sessionId);
|
|
1159
|
+
const { config, cwd } = await this.browseContext(sessionId);
|
|
1160
|
+
const attachmentRoot = this.admission.attachmentRoot();
|
|
1161
|
+
try {
|
|
1162
|
+
return await previewConvertibleDocument({
|
|
1163
|
+
filePath: path ?? "",
|
|
1164
|
+
cwd,
|
|
1165
|
+
sharedReadOnlyRoots: config.lockdown.sharedReadOnlyRoots,
|
|
1166
|
+
...(attachmentRoot === undefined ? {} : { attachmentRoot }),
|
|
1167
|
+
documents: () => this.ctx.get("documents"),
|
|
1168
|
+
sessionId,
|
|
1169
|
+
maxBytes: config.sources.filePreview.maxBytes,
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
catch (error) {
|
|
1173
|
+
throw this.browseRefusal("workspace.preview-refused", sessionId, error);
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Shared admission facts of both browse methods: the preview switch is what
|
|
1178
|
+
* opens the panel's file reading at all, and the chat's cwd is the tree that
|
|
1179
|
+
* browsing is confined to.
|
|
1180
|
+
*/
|
|
1181
|
+
async browseContext(sessionId) {
|
|
1182
|
+
const config = this.getConfig();
|
|
1183
|
+
if (!config.sources.filePreview.enabled) {
|
|
1184
|
+
throw sourcePreviewRefusal("unavailable");
|
|
1185
|
+
}
|
|
1186
|
+
const agent = this.ctx.agents.get((await import("@deepseek-ai/dsh-session/types")).SessionId(sessionId));
|
|
1187
|
+
const cwd = agent?.session.header.cwd;
|
|
1188
|
+
if (cwd === undefined)
|
|
1189
|
+
throw sourcePreviewRefusal("unavailable");
|
|
1190
|
+
return { config, cwd };
|
|
1191
|
+
}
|
|
1192
|
+
/** One browse refusal, logged with its coarse reason and rethrown for the wire. */
|
|
1193
|
+
browseRefusal(event, sessionId, error) {
|
|
1194
|
+
const reason = error instanceof QaSourcePreviewError ? error.reason : "unavailable";
|
|
1195
|
+
this.logger.debug(event, { sessionId, reason });
|
|
1196
|
+
return sourcePreviewRefusal(reason);
|
|
1197
|
+
}
|
|
915
1198
|
/** Every personal skill of the token's account, sorted by name. */
|
|
916
1199
|
skillsList(token) {
|
|
917
1200
|
return this.skillRemotes.list(token);
|
|
@@ -975,11 +1258,57 @@ let QaSurface = (() => {
|
|
|
975
1258
|
slashExecute(token, sessionId, line, attachments) {
|
|
976
1259
|
return this.slashRemotes.execute(token, sessionId, line, attachments);
|
|
977
1260
|
}
|
|
978
|
-
|
|
1261
|
+
/**
|
|
1262
|
+
* Register (or drop) the integration API's routes for the current config.
|
|
1263
|
+
*
|
|
1264
|
+
* The key is the whole registration decision — whether the API is on and
|
|
1265
|
+
* where it lives — so a config change that does not move the endpoints
|
|
1266
|
+
* leaves the live routes alone, and turning the API off disposes them
|
|
1267
|
+
* immediately rather than at the next restart.
|
|
1268
|
+
*/
|
|
1269
|
+
refreshIntegrationRoutes() {
|
|
979
1270
|
const config = this.getConfig();
|
|
980
|
-
const key = config.enabled
|
|
981
|
-
? `${config.
|
|
1271
|
+
const key = config.integration.enabled && config.accounts.enabled
|
|
1272
|
+
? `${config.integration.basePath}:${String(config.integration.maxRequestBytes)}:${String(config.integration.maxAttachmentBytes)}`
|
|
982
1273
|
: undefined;
|
|
1274
|
+
if (key === this.integrationRouteKey)
|
|
1275
|
+
return;
|
|
1276
|
+
this.disposeIntegrationRoutes?.();
|
|
1277
|
+
this.disposeIntegrationRoutes = undefined;
|
|
1278
|
+
this.integrationRouteKey = undefined;
|
|
1279
|
+
if (key === undefined || this.webServer === undefined)
|
|
1280
|
+
return;
|
|
1281
|
+
try {
|
|
1282
|
+
this.disposeIntegrationRoutes = registerQaIntegrationRoutes(this.webServer, { config, service: this.integration, logger: this.logger });
|
|
1283
|
+
this.integrationRouteKey = key;
|
|
1284
|
+
this.logger.info("integration.routes-registered", {
|
|
1285
|
+
basePath: config.integration.basePath,
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
catch (error) {
|
|
1289
|
+
// A collision on (kind, path) means another plugin owns the namespace.
|
|
1290
|
+
// The page and the accounts keep working; only the API stays off, and
|
|
1291
|
+
// the operator sees why.
|
|
1292
|
+
this.logger.error("integration.routes-failed", {
|
|
1293
|
+
basePath: config.integration.basePath,
|
|
1294
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1295
|
+
});
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
refreshRoute() {
|
|
1299
|
+
const config = this.getConfig();
|
|
1300
|
+
// Kiosk: the harness route policy owns the QA paths and serves the
|
|
1301
|
+
// application there directly. This plugin's navigation redirect route
|
|
1302
|
+
// must not register — a named route shadows the fallback seat, so it
|
|
1303
|
+
// would bounce every /qa navigation to /?marker while the policy bounces
|
|
1304
|
+
// / back to /qa: a redirect loop. The kiosk key keeps the transition
|
|
1305
|
+
// machinery honest (dispose on entering kiosk, no re-registration, one
|
|
1306
|
+
// log line per transition).
|
|
1307
|
+
const key = qaKioskDeployment()
|
|
1308
|
+
? "kiosk"
|
|
1309
|
+
: config.enabled
|
|
1310
|
+
? `${config.route.path}:${config.route.matchChildren}`
|
|
1311
|
+
: undefined;
|
|
983
1312
|
if (key === this.routeKey)
|
|
984
1313
|
return;
|
|
985
1314
|
this.disposeRoute?.();
|
|
@@ -987,6 +1316,13 @@ let QaSurface = (() => {
|
|
|
987
1316
|
this.routeKey = undefined;
|
|
988
1317
|
if (key === undefined || this.webServer === undefined)
|
|
989
1318
|
return;
|
|
1319
|
+
if (key === "kiosk") {
|
|
1320
|
+
this.logger.info("route.kiosk", {
|
|
1321
|
+
message: "DSH_UI_MODE=qa: the navigation redirect route is not registered; the harness route policy serves the QA surface directly",
|
|
1322
|
+
});
|
|
1323
|
+
this.routeKey = key;
|
|
1324
|
+
return;
|
|
1325
|
+
}
|
|
990
1326
|
this.disposeRoute = registerQaNavigationRoute(this.webServer, config, {
|
|
991
1327
|
launchToken: this.launchToken,
|
|
992
1328
|
});
|