@yadsh/dsh-qa-surface 0.5.0 → 0.6.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 +194 -9
- package/compatibility.json +10 -1
- package/cordis.patch.yml +9 -0
- package/lib/account-remotes.js +10 -0
- package/lib/account-remotes.js.map +1 -1
- package/lib/accounts/errors.js.map +1 -1
- package/lib/accounts/file.js.map +1 -1
- package/lib/accounts/store.js +22 -0
- package/lib/accounts/store.js.map +1 -1
- package/lib/client/QaAccountsController.js +29 -0
- package/lib/client/QaAccountsController.js.map +1 -1
- package/lib/client/QaSessionController.js +168 -48
- package/lib/client/QaSessionController.js.map +1 -1
- package/lib/client/QaSurface.js +125 -56
- package/lib/client/QaSurface.js.map +1 -1
- package/lib/client/QaSurfaceGuard.js +96 -0
- package/lib/client/QaSurfaceGuard.js.map +1 -0
- package/lib/client/QaTranscriptAdapter.js +11 -5
- package/lib/client/QaTranscriptAdapter.js.map +1 -1
- package/lib/client/components/QaChangelog.js +31 -0
- package/lib/client/components/QaChangelog.js.map +1 -1
- package/lib/client/components/QaComposer.js +1 -1
- package/lib/client/components/QaComposer.js.map +1 -1
- package/lib/client/components/QaHeader.js +2 -8
- package/lib/client/components/QaHeader.js.map +1 -1
- package/lib/client/components/QaMessage.js +20 -7
- package/lib/client/components/QaMessage.js.map +1 -1
- package/lib/client/components/QaModal.js +24 -6
- package/lib/client/components/QaModal.js.map +1 -1
- package/lib/client/components/QaSidebar.js +2 -6
- package/lib/client/components/QaSidebar.js.map +1 -1
- package/lib/client/components/QaSourcesPanel.js +6 -5
- package/lib/client/components/QaSourcesPanel.js.map +1 -1
- package/lib/client/components/QaWidthHandle.js +21 -1
- package/lib/client/components/QaWidthHandle.js.map +1 -1
- package/lib/client/components/surface-utils.js +2 -0
- package/lib/client/components/surface-utils.js.map +1 -1
- package/lib/client/index.js +72 -24
- package/lib/client/index.js.map +1 -1
- package/lib/client/panels/PanelHost.js +209 -0
- package/lib/client/panels/PanelHost.js.map +1 -0
- package/lib/client/panels/PanelLauncher.js +39 -0
- package/lib/client/panels/PanelLauncher.js.map +1 -0
- package/lib/client/panels/contract.js +2 -0
- package/lib/client/panels/contract.js.map +1 -0
- package/lib/client/panels/index.js +2 -0
- package/lib/client/panels/index.js.map +1 -0
- package/lib/client/panels/registry.js +171 -0
- package/lib/client/panels/registry.js.map +1 -0
- package/lib/client/project-session-state.js +3 -0
- package/lib/client/project-session-state.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/accounts.js +3 -1
- package/lib/client/settings/sections/accounts.js.map +1 -1
- package/lib/client/settings/sections/documents.js +88 -0
- package/lib/client/settings/sections/documents.js.map +1 -0
- package/lib/client/settings/sections/interface.js +2 -0
- package/lib/client/settings/sections/interface.js.map +1 -1
- package/lib/client/settings/sections.js +1 -0
- package/lib/client/settings/sections.js.map +1 -1
- package/lib/client/settings-extensions/contract.js +2 -0
- package/lib/client/settings-extensions/contract.js.map +1 -0
- package/lib/client/settings-extensions/index.js +2 -0
- package/lib/client/settings-extensions/index.js.map +1 -0
- package/lib/client/settings-extensions/registry.js +63 -0
- package/lib/client/settings-extensions/registry.js.map +1 -0
- package/lib/client/settlement.js +51 -5
- package/lib/client/settlement.js.map +1 -1
- package/lib/client/source-preview.js +24 -0
- package/lib/client/source-preview.js.map +1 -0
- package/lib/client/styles.js +157 -32
- package/lib/client/styles.js.map +1 -1
- package/lib/client/subagent-codenames.js +109 -0
- package/lib/client/subagent-codenames.js.map +1 -0
- package/lib/client/types.js +1 -0
- package/lib/client/types.js.map +1 -1
- package/lib/client/user-settings/GeneralSettingsPage.js +13 -0
- package/lib/client/user-settings/GeneralSettingsPage.js.map +1 -0
- package/lib/client/user-settings/ProfileSettingsPage.js +59 -0
- package/lib/client/user-settings/ProfileSettingsPage.js.map +1 -0
- package/lib/client/user-settings/SkillCatalog.js +23 -0
- package/lib/client/user-settings/SkillCatalog.js.map +1 -0
- package/lib/client/user-settings/SkillEditor.js +89 -0
- package/lib/client/user-settings/SkillEditor.js.map +1 -0
- package/lib/client/user-settings/SkillToolPicker.js +58 -0
- package/lib/client/user-settings/SkillToolPicker.js.map +1 -0
- package/lib/client/user-settings/SkillsSettingsPage.js +171 -0
- package/lib/client/user-settings/SkillsSettingsPage.js.map +1 -0
- package/lib/client/user-settings/StartersSettingsPage.js +78 -0
- package/lib/client/user-settings/StartersSettingsPage.js.map +1 -0
- package/lib/client/user-settings/UserSettingsDialog.js +50 -0
- package/lib/client/user-settings/UserSettingsDialog.js.map +1 -0
- package/lib/client/user-settings/copy.js +84 -0
- package/lib/client/user-settings/copy.js.map +1 -0
- package/lib/client/user-settings/draft.js +127 -0
- package/lib/client/user-settings/draft.js.map +1 -0
- package/lib/client/user-settings/fields.js +24 -0
- package/lib/client/user-settings/fields.js.map +1 -0
- package/lib/client.js +5467 -1379
- package/lib/client.js.map +1 -1
- package/lib/config-resolvers/accounts.js +30 -0
- package/lib/config-resolvers/accounts.js.map +1 -1
- package/lib/config-resolvers/defaults.js +23 -0
- package/lib/config-resolvers/defaults.js.map +1 -1
- package/lib/config-resolvers/tools.js +37 -0
- package/lib/config-resolvers/tools.js.map +1 -0
- package/lib/config-resolvers/ui.js +2 -0
- package/lib/config-resolvers/ui.js.map +1 -1
- package/lib/config.js +288 -0
- package/lib/config.js.map +1 -1
- package/lib/documents/artifacts/ids.js +43 -0
- package/lib/documents/artifacts/ids.js.map +1 -0
- package/lib/documents/artifacts/manifest.js +66 -0
- package/lib/documents/artifacts/manifest.js.map +1 -0
- package/lib/documents/artifacts/store.js +169 -0
- package/lib/documents/artifacts/store.js.map +1 -0
- package/lib/documents/capabilities.js +93 -0
- package/lib/documents/capabilities.js.map +1 -0
- package/lib/documents/config.js +302 -0
- package/lib/documents/config.js.map +1 -0
- package/lib/documents/defaults.js +78 -0
- package/lib/documents/defaults.js.map +1 -0
- package/lib/documents/errors.js +101 -0
- package/lib/documents/errors.js.map +1 -0
- package/lib/documents/index.js +80 -0
- package/lib/documents/index.js.map +1 -0
- package/lib/documents/inspect/facts.js +161 -0
- package/lib/documents/inspect/facts.js.map +1 -0
- package/lib/documents/inspect/zip.js +108 -0
- package/lib/documents/inspect/zip.js.map +1 -0
- package/lib/documents/markdown/directives.js +135 -0
- package/lib/documents/markdown/directives.js.map +1 -0
- package/lib/documents/markdown/frontmatter.js +35 -0
- package/lib/documents/markdown/frontmatter.js.map +1 -0
- package/lib/documents/markdown/normalize.js +113 -0
- package/lib/documents/markdown/normalize.js.map +1 -0
- package/lib/documents/orchestrator/assets.js +243 -0
- package/lib/documents/orchestrator/assets.js.map +1 -0
- package/lib/documents/orchestrator/convert-document.js +186 -0
- package/lib/documents/orchestrator/convert-document.js.map +1 -0
- package/lib/documents/orchestrator/create-document.js +292 -0
- package/lib/documents/orchestrator/create-document.js.map +1 -0
- package/lib/documents/orchestrator/extract-document.js +162 -0
- package/lib/documents/orchestrator/extract-document.js.map +1 -0
- package/lib/documents/orchestrator/inspect-document.js +89 -0
- package/lib/documents/orchestrator/inspect-document.js.map +1 -0
- package/lib/documents/orchestrator/runtime-deps.js +59 -0
- package/lib/documents/orchestrator/runtime-deps.js.map +1 -0
- package/lib/documents/orchestrator/scope.js +132 -0
- package/lib/documents/orchestrator/scope.js.map +1 -0
- package/lib/documents/providers/docling.js +247 -0
- package/lib/documents/providers/docling.js.map +1 -0
- package/lib/documents/providers/libreoffice.js +130 -0
- package/lib/documents/providers/libreoffice.js.map +1 -0
- package/lib/documents/providers/markitdown.js +89 -0
- package/lib/documents/providers/markitdown.js.map +1 -0
- package/lib/documents/providers/pandoc.js +161 -0
- package/lib/documents/providers/pandoc.js.map +1 -0
- package/lib/documents/providers/process.js +164 -0
- package/lib/documents/providers/process.js.map +1 -0
- package/lib/documents/providers/registry.js +152 -0
- package/lib/documents/providers/registry.js.map +1 -0
- package/lib/documents/providers/shared.js +75 -0
- package/lib/documents/providers/shared.js.map +1 -0
- package/lib/documents/runtime.js +114 -0
- package/lib/documents/runtime.js.map +1 -0
- package/lib/documents/security/file-types.js +188 -0
- package/lib/documents/security/file-types.js.map +1 -0
- package/lib/documents/security/limits.js +78 -0
- package/lib/documents/security/limits.js.map +1 -0
- package/lib/documents/security/mime.js +43 -0
- package/lib/documents/security/mime.js.map +1 -0
- package/lib/documents/security/paths.js +133 -0
- package/lib/documents/security/paths.js.map +1 -0
- package/lib/documents/templates/registry.js +147 -0
- package/lib/documents/templates/registry.js.map +1 -0
- package/lib/documents/templates/resolver.js +59 -0
- package/lib/documents/templates/resolver.js.map +1 -0
- package/lib/documents/tools/convert.js +125 -0
- package/lib/documents/tools/convert.js.map +1 -0
- package/lib/documents/tools/create.js +187 -0
- package/lib/documents/tools/create.js.map +1 -0
- package/lib/documents/tools/index.js +41 -0
- package/lib/documents/tools/index.js.map +1 -0
- package/lib/documents/tools/inspect.js +135 -0
- package/lib/documents/tools/inspect.js.map +1 -0
- package/lib/documents/tools/shared.js +88 -0
- package/lib/documents/tools/shared.js.map +1 -0
- package/lib/documents/tools/to-markdown.js +125 -0
- package/lib/documents/tools/to-markdown.js.map +1 -0
- package/lib/documents/types.js +12 -0
- package/lib/documents/types.js.map +1 -0
- package/lib/index.js +225 -20
- package/lib/index.js.map +1 -1
- package/lib/integration-principals.js +22 -0
- package/lib/integration-principals.js.map +1 -0
- package/lib/lockdown-policy.js +15 -3
- package/lib/lockdown-policy.js.map +1 -1
- package/lib/personal-skills/errors.js +9 -0
- package/lib/personal-skills/errors.js.map +1 -0
- package/lib/personal-skills/host.js +80 -0
- package/lib/personal-skills/host.js.map +1 -0
- package/lib/personal-skills/index.js +10 -0
- package/lib/personal-skills/index.js.map +1 -0
- package/lib/personal-skills/paths.js +127 -0
- package/lib/personal-skills/paths.js.map +1 -0
- package/lib/personal-skills/provider.js +109 -0
- package/lib/personal-skills/provider.js.map +1 -0
- package/lib/personal-skills/remotes.js +40 -0
- package/lib/personal-skills/remotes.js.map +1 -0
- package/lib/personal-skills/service.js +686 -0
- package/lib/personal-skills/service.js.map +1 -0
- package/lib/personal-skills/skill-file.js +278 -0
- package/lib/personal-skills/skill-file.js.map +1 -0
- package/lib/personal-skills/skill-format.js +202 -0
- package/lib/personal-skills/skill-format.js.map +1 -0
- package/lib/personal-skills/watcher.js +96 -0
- package/lib/personal-skills/watcher.js.map +1 -0
- package/lib/profile.js +6 -4
- package/lib/profile.js.map +1 -1
- package/lib/prompt-notes.js +19 -0
- package/lib/prompt-notes.js.map +1 -1
- package/lib/provenance/file-preview.js +68 -21
- package/lib/provenance/file-preview.js.map +1 -1
- package/lib/provenance/host-store.js +44 -11
- package/lib/provenance/host-store.js.map +1 -1
- package/lib/provenance/index.js +1 -0
- package/lib/provenance/index.js.map +1 -1
- package/lib/provenance/normalize.js +3 -1
- package/lib/provenance/normalize.js.map +1 -1
- package/lib/provenance/snapshot-store.js +154 -0
- package/lib/provenance/snapshot-store.js.map +1 -0
- package/lib/qa-tools/activation-detector.js +53 -0
- package/lib/qa-tools/activation-detector.js.map +1 -0
- package/lib/qa-tools/activation-manager.js +111 -0
- package/lib/qa-tools/activation-manager.js.map +1 -0
- package/lib/qa-tools/catalog.js +108 -0
- package/lib/qa-tools/catalog.js.map +1 -0
- package/lib/qa-tools/durable-marker.js +115 -0
- package/lib/qa-tools/durable-marker.js.map +1 -0
- package/lib/qa-tools/index.js +83 -0
- package/lib/qa-tools/index.js.map +1 -0
- package/lib/qa-tools/lifecycle.js +64 -0
- package/lib/qa-tools/lifecycle.js.map +1 -0
- package/lib/qa-tools/types.js +2 -0
- package/lib/qa-tools/types.js.map +1 -0
- package/lib/resolve-config.js +5 -0
- package/lib/resolve-config.js.map +1 -1
- package/lib/secure-session.js +35 -3
- package/lib/secure-session.js.map +1 -1
- package/lib/starters.js +117 -0
- package/lib/starters.js.map +1 -0
- package/lib/typert.host.js +767 -22
- package/lib/typert.remote-client.d.ts +17 -1
- package/lib/typert.remote-client.js +609 -17
- package/lib/types/account-remotes.d.ts +3 -1
- package/lib/types/accounts/errors.d.ts +1 -1
- package/lib/types/accounts/file.d.ts +10 -0
- package/lib/types/accounts/store.d.ts +7 -1
- package/lib/types/client/QaAccountsController.d.ts +7 -1
- package/lib/types/client/QaSessionController.d.ts +12 -0
- package/lib/types/client/QaSurface.d.ts +14 -4
- package/lib/types/client/QaSurfaceGuard.d.ts +27 -0
- package/lib/types/client/QaTranscriptAdapter.d.ts +7 -0
- package/lib/types/client/components/QaComposer.d.ts +3 -1
- package/lib/types/client/components/QaHeader.d.ts +3 -1
- package/lib/types/client/components/QaModal.d.ts +5 -4
- package/lib/types/client/components/QaSidebar.d.ts +8 -11
- package/lib/types/client/components/QaWidthHandle.d.ts +13 -0
- package/lib/types/client/index.d.ts +1 -0
- package/lib/types/client/panels/PanelHost.d.ts +18 -0
- package/lib/types/client/panels/PanelLauncher.d.ts +5 -0
- package/lib/types/client/panels/contract.d.ts +83 -0
- package/lib/types/client/panels/index.d.ts +3 -0
- package/lib/types/client/panels/registry.d.ts +40 -0
- package/lib/types/client/project-session-state.d.ts +5 -0
- package/lib/types/client/settings/sections/documents.d.ts +13 -0
- package/lib/types/client/settings/sections.d.ts +1 -0
- package/lib/types/client/settings-extensions/contract.d.ts +32 -0
- package/lib/types/client/settings-extensions/index.d.ts +3 -0
- package/lib/types/client/settings-extensions/registry.d.ts +15 -0
- package/lib/types/client/settlement.d.ts +41 -5
- package/lib/types/client/source-preview.d.ts +8 -0
- package/lib/types/client/styles.d.ts +2 -0
- package/lib/types/client/subagent-codenames.d.ts +18 -0
- package/lib/types/client/types.d.ts +35 -3
- package/lib/types/client/user-settings/GeneralSettingsPage.d.ts +14 -0
- package/lib/types/client/user-settings/ProfileSettingsPage.d.ts +18 -0
- package/lib/types/client/user-settings/SkillCatalog.d.ts +16 -0
- package/lib/types/client/user-settings/SkillEditor.d.ts +42 -0
- package/lib/types/client/user-settings/SkillToolPicker.d.ts +17 -0
- package/lib/types/client/user-settings/SkillsSettingsPage.d.ts +15 -0
- package/lib/types/client/user-settings/StartersSettingsPage.d.ts +14 -0
- package/lib/types/client/user-settings/UserSettingsDialog.d.ts +43 -0
- package/lib/types/client/user-settings/copy.d.ts +25 -0
- package/lib/types/client/user-settings/draft.d.ts +51 -0
- package/lib/types/client/user-settings/fields.d.ts +43 -0
- package/lib/types/config-resolvers/tools.d.ts +6 -0
- package/lib/types/documents/artifacts/ids.d.ts +14 -0
- package/lib/types/documents/artifacts/manifest.d.ts +32 -0
- package/lib/types/documents/artifacts/store.d.ts +67 -0
- package/lib/types/documents/capabilities.d.ts +32 -0
- package/lib/types/documents/config.d.ts +27 -0
- package/lib/types/documents/defaults.d.ts +161 -0
- package/lib/types/documents/errors.d.ts +42 -0
- package/lib/types/documents/index.d.ts +63 -0
- package/lib/types/documents/inspect/facts.d.ts +43 -0
- package/lib/types/documents/inspect/zip.d.ts +28 -0
- package/lib/types/documents/markdown/directives.d.ts +39 -0
- package/lib/types/documents/markdown/frontmatter.d.ts +15 -0
- package/lib/types/documents/markdown/normalize.d.ts +30 -0
- package/lib/types/documents/orchestrator/assets.d.ts +55 -0
- package/lib/types/documents/orchestrator/convert-document.d.ts +25 -0
- package/lib/types/documents/orchestrator/create-document.d.ts +18 -0
- package/lib/types/documents/orchestrator/extract-document.d.ts +24 -0
- package/lib/types/documents/orchestrator/inspect-document.d.ts +12 -0
- package/lib/types/documents/orchestrator/runtime-deps.d.ts +43 -0
- package/lib/types/documents/orchestrator/scope.d.ts +52 -0
- package/lib/types/documents/providers/docling.d.ts +54 -0
- package/lib/types/documents/providers/libreoffice.d.ts +40 -0
- package/lib/types/documents/providers/markitdown.d.ts +28 -0
- package/lib/types/documents/providers/pandoc.d.ts +42 -0
- package/lib/types/documents/providers/process.d.ts +54 -0
- package/lib/types/documents/providers/registry.d.ts +68 -0
- package/lib/types/documents/providers/shared.d.ts +27 -0
- package/lib/types/documents/runtime.d.ts +59 -0
- package/lib/types/documents/security/file-types.d.ts +39 -0
- package/lib/types/documents/security/limits.d.ts +24 -0
- package/lib/types/documents/security/mime.d.ts +13 -0
- package/lib/types/documents/security/paths.d.ts +38 -0
- package/lib/types/documents/templates/registry.d.ts +50 -0
- package/lib/types/documents/templates/resolver.d.ts +30 -0
- package/lib/types/documents/tools/convert.d.ts +9 -0
- package/lib/types/documents/tools/create.d.ts +14 -0
- package/lib/types/documents/tools/index.d.ts +33 -0
- package/lib/types/documents/tools/inspect.d.ts +9 -0
- package/lib/types/documents/tools/shared.d.ts +77 -0
- package/lib/types/documents/tools/to-markdown.d.ts +12 -0
- package/lib/types/documents/types.d.ts +294 -0
- package/lib/types/index.d.ts +75 -3
- package/lib/types/integration-principals.d.ts +9 -0
- package/lib/types/lockdown-policy.d.ts +12 -2
- package/lib/types/personal-skills/errors.d.ts +11 -0
- package/lib/types/personal-skills/host.d.ts +42 -0
- package/lib/types/personal-skills/index.d.ts +10 -0
- package/lib/types/personal-skills/paths.d.ts +39 -0
- package/lib/types/personal-skills/provider.d.ts +33 -0
- package/lib/types/personal-skills/remotes.d.ts +35 -0
- package/lib/types/personal-skills/service.d.ts +131 -0
- package/lib/types/personal-skills/skill-file.d.ts +64 -0
- package/lib/types/personal-skills/skill-format.d.ts +100 -0
- package/lib/types/personal-skills/watcher.d.ts +39 -0
- package/lib/types/profile.d.ts +13 -0
- package/lib/types/prompt-notes.d.ts +9 -0
- package/lib/types/provenance/file-preview.d.ts +47 -4
- package/lib/types/provenance/host-store.d.ts +7 -1
- package/lib/types/provenance/index.d.ts +1 -0
- package/lib/types/provenance/snapshot-store.d.ts +23 -0
- package/lib/types/qa-tools/activation-detector.d.ts +29 -0
- package/lib/types/qa-tools/activation-manager.d.ts +47 -0
- package/lib/types/qa-tools/catalog.d.ts +40 -0
- package/lib/types/qa-tools/durable-marker.d.ts +16 -0
- package/lib/types/qa-tools/index.d.ts +40 -0
- package/lib/types/qa-tools/lifecycle.d.ts +44 -0
- package/lib/types/qa-tools/types.d.ts +45 -0
- package/lib/types/secure-session.d.ts +24 -2
- package/lib/types/starters.d.ts +45 -0
- package/lib/types/types.d.ts +202 -3
- package/package.json +24 -11
- package/scripts/repair-session-events.mjs +260 -0
- package/lib/client/components/QaProfile.js +0 -64
- package/lib/client/components/QaProfile.js.map +0 -1
- package/lib/types/client/components/QaProfile.d.ts +0 -25
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem boundary of the personal-skills feature.
|
|
3
|
+
*
|
|
4
|
+
* Every path is derived, never accepted: the browser names a skill, the Host
|
|
5
|
+
* combines the authenticated account's own workspace directory with the
|
|
6
|
+
* configured relative root, and each step re-checks that the canonical result
|
|
7
|
+
* still sits below that account's root. Symlinked directories are refused
|
|
8
|
+
* rather than followed, so a link planted inside the personal root cannot
|
|
9
|
+
* move reads or writes to another account's storage.
|
|
10
|
+
*
|
|
11
|
+
* `.dsh/skills-trash` is the removal destination: the last segment of the
|
|
12
|
+
* configured relative root with a `-trash` suffix, so a deployment that moved
|
|
13
|
+
* its skill directory keeps the trash beside it.
|
|
14
|
+
*/
|
|
15
|
+
export declare const QA_SKILL_TRASH_SUFFIX = "-trash";
|
|
16
|
+
export interface QaSkillRoots {
|
|
17
|
+
/** The canonical account root every derived path must stay inside. */
|
|
18
|
+
readonly personalRoot: string;
|
|
19
|
+
/** The canonical directory holding one subdirectory per skill. */
|
|
20
|
+
readonly skills: string;
|
|
21
|
+
/** The canonical directory a removed skill directory is moved into. */
|
|
22
|
+
readonly trash: string;
|
|
23
|
+
}
|
|
24
|
+
/** Derive and verify every directory the feature touches for one account. */
|
|
25
|
+
export declare function resolveSkillRoots(personalRoot: string, relativeRoot: string): QaSkillRoots;
|
|
26
|
+
/** The directory of one skill, validated against the account's skills root. */
|
|
27
|
+
export declare function skillDirectory(roots: QaSkillRoots, name: string): string;
|
|
28
|
+
export declare function skillFilePath(roots: QaSkillRoots, name: string): string;
|
|
29
|
+
/** Whether the directory exists at all, without following a symlink. */
|
|
30
|
+
export declare function directoryExists(input: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Materialize the skills root inside one account's personal root. Creation is
|
|
33
|
+
* followed by a re-canonicalization, so a directory that appeared as a link
|
|
34
|
+
* between the check and the `mkdir` is still refused.
|
|
35
|
+
*/
|
|
36
|
+
export declare function ensureSkillRoots(roots: QaSkillRoots): void;
|
|
37
|
+
/** The skill subdirectories present for one account, sorted by name. */
|
|
38
|
+
export declare function listSkillDirectories(roots: QaSkillRoots): readonly string[];
|
|
39
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { SkillProvider, SkillProviderControl } from "@deepseek-ai/dsh-skill";
|
|
2
|
+
import type { QaPersonalSkills } from "./service.js";
|
|
3
|
+
/**
|
|
4
|
+
* Discovery provider for one QA account's own skills.
|
|
5
|
+
*
|
|
6
|
+
* It exists because the shipped filesystem provider resolves the project root
|
|
7
|
+
* through the nearest `.git`, which for a personal QA directory inside a larger
|
|
8
|
+
* checkout would climb above the account and mix users together. This provider
|
|
9
|
+
* reads exactly one place — `<cwd>/.dsh/skills` where the cwd is a provisioned
|
|
10
|
+
* `.qa-users/<uuid>` directory — and replaces the filesystem layer inside the
|
|
11
|
+
* QA scope rather than adding a second one beside it.
|
|
12
|
+
*/
|
|
13
|
+
export declare const QA_USER_SKILLS_PROVIDER = "qa-user-skills";
|
|
14
|
+
/** Prompt-visible provenance label for a skill stored in an account directory. */
|
|
15
|
+
export declare const QA_USER_SKILLS_SOURCE = "qa-user";
|
|
16
|
+
/**
|
|
17
|
+
* Rank below the project layer (100) and the bundled layer (600): inside the
|
|
18
|
+
* QA scope a personal skill wins a same-named duplicate from any other layer.
|
|
19
|
+
*/
|
|
20
|
+
export declare const QA_USER_SKILLS_RANK = 50;
|
|
21
|
+
/**
|
|
22
|
+
* Build the provider for one registration. The factory runs synchronously
|
|
23
|
+
* during `registerProvider` and all filesystem work stays inside
|
|
24
|
+
* `list`/`get`, which the registry calls per read.
|
|
25
|
+
*
|
|
26
|
+
* Note what the registry caches and what it does not: a loaded definition is
|
|
27
|
+
* never cached, so an edited body is visible to the next `get` immediately,
|
|
28
|
+
* while the candidate list behind a catalog summary is cached until something
|
|
29
|
+
* invalidates it. A save goes through the service, which invalidates; a file
|
|
30
|
+
* edited by hand is what the watcher exists for.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createQaUserSkillProvider(control: SkillProviderControl, skills: QaPersonalSkills): SkillProvider;
|
|
33
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { PluginLogger } from "@yadsh/dsh-plugin-log";
|
|
2
|
+
import type { QaAccountRemotes } from "../account-remotes.js";
|
|
3
|
+
import type { QaSkillDocument, QaSkillDraftInput, QaSkillRemoval, QaSkillSummary, QaSkillToolDescriptor, QaSkillValidation, ResolvedQaSurfaceConfig } from "../types.js";
|
|
4
|
+
import type { QaPersonalSkills } from "./service.js";
|
|
5
|
+
/**
|
|
6
|
+
* Host-side bodies of the personal-skill remotes. The `@Remote`-decorated
|
|
7
|
+
* signatures stay on the `QaSurface` service class (typert code generation
|
|
8
|
+
* reads the class shape); this context owns everything behind them: turning
|
|
9
|
+
* the wire's account token into the storage context, and mapping a refusal
|
|
10
|
+
* onto the shared `(reason: <code>)` marker the browser renders copy for.
|
|
11
|
+
*
|
|
12
|
+
* The browser never names a filesystem location. It names a skill; the account
|
|
13
|
+
* id behind the token decides where that name resolves.
|
|
14
|
+
*/
|
|
15
|
+
export interface QaPersonalSkillRemotes {
|
|
16
|
+
list(token: string): {
|
|
17
|
+
readonly skills: readonly QaSkillSummary[];
|
|
18
|
+
};
|
|
19
|
+
get(token: string, name: string): QaSkillDocument;
|
|
20
|
+
create(token: string, input: QaSkillDraftInput): QaSkillDocument;
|
|
21
|
+
update(token: string, name: string, input: QaSkillDraftInput): QaSkillDocument;
|
|
22
|
+
remove(token: string, name: string, expectedRevision: string | null): QaSkillRemoval;
|
|
23
|
+
validate(token: string, name: string | null, input: QaSkillDraftInput): QaSkillValidation;
|
|
24
|
+
tools(token: string): {
|
|
25
|
+
readonly tools: readonly QaSkillToolDescriptor[];
|
|
26
|
+
};
|
|
27
|
+
validate(token: string, name: string | null, input: QaSkillDraftInput): QaSkillValidation;
|
|
28
|
+
}
|
|
29
|
+
export declare function createQaPersonalSkillRemotes(options: {
|
|
30
|
+
getConfig: () => ResolvedQaSurfaceConfig;
|
|
31
|
+
logger: PluginLogger;
|
|
32
|
+
skills: QaPersonalSkills;
|
|
33
|
+
accounts: QaAccountRemotes;
|
|
34
|
+
}): QaPersonalSkillRemotes;
|
|
35
|
+
//# sourceMappingURL=remotes.d.ts.map
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { Context } from "@deepseek-ai/cordis";
|
|
2
|
+
import type { PluginLogger } from "@yadsh/dsh-plugin-log";
|
|
3
|
+
import type { QaSkillDiagnostic, QaSkillDocument, QaSkillDraftInput, QaSkillRemoval, QaSkillSummary, QaSkillToolDescriptor, QaSkillValidation, ResolvedQaSurfaceConfig } from "../types.js";
|
|
4
|
+
import { type QaSkillFileContents } from "./skill-file.js";
|
|
5
|
+
/** Per-account identity of the skill storage boundary. */
|
|
6
|
+
export interface QaPersonalSkillContext {
|
|
7
|
+
/** The authenticated account id whose personal root holds these skills. */
|
|
8
|
+
readonly userId: string;
|
|
9
|
+
}
|
|
10
|
+
/** One stored skill: its parsed contents plus the facts a DTO needs. */
|
|
11
|
+
export interface QaStoredSkill {
|
|
12
|
+
/** Whether the skill directory itself exists. */
|
|
13
|
+
readonly exists: boolean;
|
|
14
|
+
/** Directory name; the skill's identity for every write. */
|
|
15
|
+
readonly directoryName: string;
|
|
16
|
+
readonly directory: string;
|
|
17
|
+
readonly filePath: string;
|
|
18
|
+
readonly raw: string;
|
|
19
|
+
readonly revision: string;
|
|
20
|
+
readonly updatedAt: string | null;
|
|
21
|
+
/** Absent when the file is missing or its frontmatter does not parse. */
|
|
22
|
+
readonly contents: QaSkillFileContents | undefined;
|
|
23
|
+
readonly diagnostics: readonly QaSkillDiagnostic[];
|
|
24
|
+
readonly resourceCount: number;
|
|
25
|
+
}
|
|
26
|
+
export interface QaPersonalSkillsOptions {
|
|
27
|
+
readonly getConfig: () => ResolvedQaSurfaceConfig;
|
|
28
|
+
readonly logger: PluginLogger;
|
|
29
|
+
/** The registered workspace path this deployment pins QA accounts under. */
|
|
30
|
+
readonly workspacePath: () => string | undefined;
|
|
31
|
+
/** Tells the DSH skill registry that a personal catalog may have changed. */
|
|
32
|
+
readonly invalidate: () => void;
|
|
33
|
+
/** Called once per storage root the discovery provider meets. */
|
|
34
|
+
readonly onRootDiscovered?: (root: string) => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Personal Skills over one account's own directory.
|
|
38
|
+
*
|
|
39
|
+
* The service is the only writer: it derives every path from the account id,
|
|
40
|
+
* validates a draft before touching the disk, writes `SKILL.md` through a
|
|
41
|
+
* temporary file and a rename, and keeps a removed skill recoverable in the
|
|
42
|
+
* trash beside its skills root. Reading is deliberately permissive — a skill
|
|
43
|
+
* whose file the parser rejects still returns a document carrying the
|
|
44
|
+
* diagnostic that says why, so the editor can repair it.
|
|
45
|
+
*/
|
|
46
|
+
export declare class QaPersonalSkills {
|
|
47
|
+
private readonly ctx;
|
|
48
|
+
private readonly options;
|
|
49
|
+
constructor(ctx: Context, options: QaPersonalSkillsOptions);
|
|
50
|
+
/** Whether the feature is available on this deployment at all. */
|
|
51
|
+
get enabled(): boolean;
|
|
52
|
+
/** Resolve one account's storage roots, or refuse the operation. */
|
|
53
|
+
private rootsFor;
|
|
54
|
+
/**
|
|
55
|
+
* Resolve the storage roots a session cwd names. This is the discovery
|
|
56
|
+
* provider's entry point and takes no account token: the cwd itself is the
|
|
57
|
+
* boundary, validated as a provisioned `<workspace>/.qa-users/<uuid>`
|
|
58
|
+
* directory, so no arbitrary directory can name another account's storage.
|
|
59
|
+
*/
|
|
60
|
+
private rootsForCwd;
|
|
61
|
+
/** Every skill of one account, sorted by directory name. */
|
|
62
|
+
list(context: QaPersonalSkillContext): readonly QaSkillSummary[];
|
|
63
|
+
/** One skill with everything the editor needs. */
|
|
64
|
+
get(context: QaPersonalSkillContext, name: string): QaSkillDocument;
|
|
65
|
+
/**
|
|
66
|
+
* Check one unsaved draft without touching storage: the serializer is the
|
|
67
|
+
* one a Save uses and the preserved frontmatter is the stored file's, so the
|
|
68
|
+
* preview the editor shows is byte-for-byte the file that save would write,
|
|
69
|
+
* and the diagnostics carry the operator's own limit (which the browser
|
|
70
|
+
* cannot know). `name` is the stored skill being edited, or null to create.
|
|
71
|
+
*/
|
|
72
|
+
validate(context: QaPersonalSkillContext, name: string | null, input: QaSkillDraftInput): QaSkillValidation;
|
|
73
|
+
/** Whether one account stores a skill under this name. */
|
|
74
|
+
has(context: QaPersonalSkillContext, name: string): boolean;
|
|
75
|
+
/** Create one skill directory and its `SKILL.md`. */
|
|
76
|
+
create(context: QaPersonalSkillContext, input: QaSkillDraftInput): QaSkillDocument;
|
|
77
|
+
/**
|
|
78
|
+
* Replace one skill's file, preserving the frontmatter fields this editor
|
|
79
|
+
* does not own and moving the whole directory when the name changed.
|
|
80
|
+
*/
|
|
81
|
+
update(context: QaPersonalSkillContext, name: string, input: QaSkillDraftInput): QaSkillDocument;
|
|
82
|
+
/** Move one skill directory into the trash beside its skills root. */
|
|
83
|
+
remove(context: QaPersonalSkillContext, name: string, expectedRevision: string | null): QaSkillRemoval;
|
|
84
|
+
/**
|
|
85
|
+
* The tool catalog the picker offers. Availability is the QA session's own
|
|
86
|
+
* scope — the deployment's reviewed allow-list — never a suggestion of what
|
|
87
|
+
* a skill may grant: a declared tool the scope excludes stays listed and
|
|
88
|
+
* stays unavailable.
|
|
89
|
+
*/
|
|
90
|
+
tools(context: QaPersonalSkillContext): readonly QaSkillToolDescriptor[];
|
|
91
|
+
/**
|
|
92
|
+
* The skills one session cwd exposes to DSH. A file the parser rejects, or
|
|
93
|
+
* one whose name disagrees with its directory, is reported in the editor and
|
|
94
|
+
* never handed to the model as a half-valid skill.
|
|
95
|
+
*/
|
|
96
|
+
discover(cwd: string): readonly QaStoredSkill[];
|
|
97
|
+
/** Re-read one skill of a session cwd, re-checking the same boundary. */
|
|
98
|
+
read(cwd: string, directoryName: string): QaStoredSkill | undefined;
|
|
99
|
+
private observe;
|
|
100
|
+
private isDiscoverable;
|
|
101
|
+
private availableTools;
|
|
102
|
+
private declaredTools;
|
|
103
|
+
/** The foreign frontmatter a save must keep, read from the stored file. */
|
|
104
|
+
private storedFrontmatter;
|
|
105
|
+
/** Read one skill directory, tolerating every failure the editor must see. */
|
|
106
|
+
private load;
|
|
107
|
+
private resources;
|
|
108
|
+
/**
|
|
109
|
+
* Normalize one editor draft into the file to write. `strict` is the
|
|
110
|
+
* difference between a save and a check: a save refuses a draft the Host
|
|
111
|
+
* will not store, while a check hands the same problems back as diagnostics,
|
|
112
|
+
* because that is what the editor asked for.
|
|
113
|
+
*/
|
|
114
|
+
private prepareWrite;
|
|
115
|
+
/** Move a renamed skill's whole directory, resources included. */
|
|
116
|
+
private renameSkillDirectory;
|
|
117
|
+
/** Write one file through a temporary sibling and a rename. */
|
|
118
|
+
private writeSkillFile;
|
|
119
|
+
private trashTarget;
|
|
120
|
+
private assertRevision;
|
|
121
|
+
private summarize;
|
|
122
|
+
private document;
|
|
123
|
+
private storageError;
|
|
124
|
+
/**
|
|
125
|
+
* Publish one write: audit it, then refresh the DSH catalog. The two are
|
|
126
|
+
* separate stages on purpose — a stored skill whose catalog refresh failed
|
|
127
|
+
* is still stored, and the deployment needs to see which half broke.
|
|
128
|
+
*/
|
|
129
|
+
private refreshCatalog;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { QaSkillDiagnostic, QaSkillDiagnosticCode, QaSkillJsonValue } from "../types.js";
|
|
2
|
+
/** The parsed shape of one skill file, without its generated diagnostics. */
|
|
3
|
+
export interface QaSkillFileContents {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly description: string;
|
|
6
|
+
readonly whenToUse: string | null;
|
|
7
|
+
readonly modelInvocable: boolean;
|
|
8
|
+
readonly userInvocable: boolean;
|
|
9
|
+
readonly allowedTools: readonly string[];
|
|
10
|
+
/** Declared tool names dropped as unusable; reported, never silently kept. */
|
|
11
|
+
readonly rejectedTools: readonly string[];
|
|
12
|
+
/** Every frontmatter key the editor does not own, in document order. */
|
|
13
|
+
readonly extraFrontmatter: Readonly<Record<string, QaSkillJsonValue>>;
|
|
14
|
+
readonly body: string;
|
|
15
|
+
/** Non-blocking anomalies found while reading the file. */
|
|
16
|
+
readonly warnings: readonly QaSkillDiagnostic[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A parse either yields contents or the single reason the file cannot become
|
|
20
|
+
* a skill. The blocking codes carry the upstream reason: `frontmatter-missing`
|
|
21
|
+
* covers both an absent block and a file that is nothing but a body.
|
|
22
|
+
*/
|
|
23
|
+
export type QaSkillFileParse = {
|
|
24
|
+
readonly ok: true;
|
|
25
|
+
readonly value: QaSkillFileContents;
|
|
26
|
+
} | {
|
|
27
|
+
readonly ok: false;
|
|
28
|
+
readonly code: QaSkillDiagnosticCode;
|
|
29
|
+
readonly detail: string | null;
|
|
30
|
+
};
|
|
31
|
+
export interface QaSkillFileDraft {
|
|
32
|
+
readonly name: string;
|
|
33
|
+
readonly description: string;
|
|
34
|
+
readonly whenToUse: string | null;
|
|
35
|
+
readonly modelInvocable: boolean;
|
|
36
|
+
readonly userInvocable: boolean;
|
|
37
|
+
readonly allowedTools: readonly string[];
|
|
38
|
+
readonly extraFrontmatter: Readonly<Record<string, QaSkillJsonValue>>;
|
|
39
|
+
readonly body: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Coerce one YAML node to a JSON value, or undefined when JSON cannot carry
|
|
43
|
+
* it: preserved frontmatter crosses a JSON bridge, so what crosses it has to
|
|
44
|
+
* be exactly what a Save writes back.
|
|
45
|
+
*/
|
|
46
|
+
export declare function toJsonValue(value: unknown): QaSkillJsonValue | undefined;
|
|
47
|
+
/** Parse one `SKILL.md` into its canonical shape plus read-time warnings. */
|
|
48
|
+
export declare function parseSkillFile(raw: string): QaSkillFileParse;
|
|
49
|
+
/**
|
|
50
|
+
* Write one `SKILL.md` from a draft. Known fields are emitted first in the
|
|
51
|
+
* canonical order every reader of this plugin sees; preserved foreign fields
|
|
52
|
+
* follow in the order they were read, so a skill authored elsewhere keeps its
|
|
53
|
+
* extra frontmatter across a Save in the editor.
|
|
54
|
+
*/
|
|
55
|
+
export declare function serializeSkillFile(draft: QaSkillFileDraft): string;
|
|
56
|
+
/**
|
|
57
|
+
* The markdown body of a skill file, whether or not its frontmatter parses.
|
|
58
|
+
* A file the editor cannot open still has to show its instructions, so a
|
|
59
|
+
* malformed block yields the text below it and a file without a block yields
|
|
60
|
+
* itself.
|
|
61
|
+
*/
|
|
62
|
+
export declare function skillFileBody(raw: string): string;
|
|
63
|
+
export * from "./skill-format.js";
|
|
64
|
+
//# sourceMappingURL=skill-file.d.ts.map
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { QaSkillDiagnostic, QaSkillDiagnosticCode } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The rules of the `SKILL.md` format that need no YAML: the name grammar, the
|
|
4
|
+
* declared-tool list, the draft limits, and where a personal root may sit.
|
|
5
|
+
*
|
|
6
|
+
* This module is deliberately free of Node builtins *and* of the YAML
|
|
7
|
+
* dependency, because the browser editor imports it: a YAML library ships a
|
|
8
|
+
* Node build beside its browser one, and the DSH module loader has no engine
|
|
9
|
+
* for the `require("process")` that build contains. The parser and serializer
|
|
10
|
+
* that do need YAML live in `skill-file.js`, which only the Host loads — the
|
|
11
|
+
* editor asks the Host for the file a draft would write and for the
|
|
12
|
+
* authoritative diagnostics, and shows its own answer immediately for the
|
|
13
|
+
* rules below.
|
|
14
|
+
*/
|
|
15
|
+
/** Name length cap; the upstream grammar itself is unbounded. */
|
|
16
|
+
export declare const QA_SKILL_NAME_MAX = 64;
|
|
17
|
+
export declare const QA_SKILL_DESCRIPTION_MAX = 1024;
|
|
18
|
+
export declare const QA_SKILL_WHEN_TO_USE_MAX = 2048;
|
|
19
|
+
/** One skill file's own ceiling, before any resource directory is considered. */
|
|
20
|
+
export declare const QA_SKILL_FILE_MAX_BYTES: number;
|
|
21
|
+
export declare const QA_SKILL_MAX_BYTES_MIN = 4096;
|
|
22
|
+
export declare const QA_SKILL_MAX_BYTES_MAX: number;
|
|
23
|
+
export declare const QA_SKILL_MAX_TOOLS = 256;
|
|
24
|
+
/**
|
|
25
|
+
* Whether the feature is on for a deployment that could host it. The resolver
|
|
26
|
+
* still turns it off wherever accounts or per-account directories are absent:
|
|
27
|
+
* this is the operator's intent, not a capability.
|
|
28
|
+
*/
|
|
29
|
+
export declare const QA_SKILL_ENABLED_BY_DEFAULT = true;
|
|
30
|
+
/** Where personal skills live below one account's own workspace directory. */
|
|
31
|
+
export declare const QA_SKILL_DEFAULT_RELATIVE_ROOT = ".dsh/skills";
|
|
32
|
+
export declare const QA_SKILL_RELATIVE_ROOT_MAX = 512;
|
|
33
|
+
/** DSH's skill-name grammar: the registry refuses anything else outright. */
|
|
34
|
+
export declare const QA_SKILL_NAME_PATTERN: RegExp;
|
|
35
|
+
/** Frontmatter keys the editor owns. */
|
|
36
|
+
export declare const KNOWN_SKILL_FIELDS: Set<string>;
|
|
37
|
+
/**
|
|
38
|
+
* Agent Skills fields the editor preserves without offering a control for
|
|
39
|
+
* them. Anything outside both sets is still preserved; it only earns a
|
|
40
|
+
* warning that the deployment's editor does not know the field.
|
|
41
|
+
*/
|
|
42
|
+
export declare const PRESERVED_SKILL_FIELDS: Set<string>;
|
|
43
|
+
/**
|
|
44
|
+
* Whether a configured `relativeRoot` may be resolved below a personal root.
|
|
45
|
+
* Only a relative, ordinary path qualifies: the value decides where the
|
|
46
|
+
* filesystem boundary of the feature sits, so an absolute path or one
|
|
47
|
+
* climbing out would move the boundary rather than relocate inside it.
|
|
48
|
+
*/
|
|
49
|
+
export declare function skillRelativeRootProblem(value: string): string | null;
|
|
50
|
+
/** The directory segments of an already-validated relative root. */
|
|
51
|
+
export declare function skillRelativeRootSegments(value: string): readonly string[];
|
|
52
|
+
/** The reason a candidate name cannot be used, or null when it can. */
|
|
53
|
+
export declare function skillNameProblem(value: string): "name-required" | "name-invalid" | null;
|
|
54
|
+
export interface QaToolListNormalization {
|
|
55
|
+
readonly tools: readonly string[];
|
|
56
|
+
/** Entries that are not usable tool names; reported, never silently kept. */
|
|
57
|
+
readonly rejected: readonly string[];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Read a declared tool list. The canonical form is one space-separated
|
|
61
|
+
* scalar, but an array (and comma separators) are accepted for compatibility
|
|
62
|
+
* with skills authored elsewhere, and every form normalizes to the canonical
|
|
63
|
+
* deduplicated order.
|
|
64
|
+
*/
|
|
65
|
+
export declare function normalizeAllowedTools(value: unknown): QaToolListNormalization | undefined;
|
|
66
|
+
export declare function skillWarning(code: QaSkillDiagnosticCode, field: string | null, detail: string | null): QaSkillDiagnostic;
|
|
67
|
+
/** Byte length of the text a Save would write, in UTF-8. */
|
|
68
|
+
export declare function skillFileBytes(text: string): number;
|
|
69
|
+
export interface QaSkillValidationInput {
|
|
70
|
+
readonly name: string;
|
|
71
|
+
readonly description: string;
|
|
72
|
+
readonly whenToUse: string | null;
|
|
73
|
+
readonly modelInvocable: boolean;
|
|
74
|
+
readonly userInvocable: boolean;
|
|
75
|
+
readonly allowedTools: readonly string[];
|
|
76
|
+
/**
|
|
77
|
+
* Byte length of the serialized file. Omitted by a caller that cannot
|
|
78
|
+
* serialize — the browser editor — so the size rule stays on the Host,
|
|
79
|
+
* which knows both the operator's ceiling and the file it would write.
|
|
80
|
+
*/
|
|
81
|
+
readonly sizeBytes?: number | undefined;
|
|
82
|
+
/** Operator-configured ceiling; the built-in default applies when omitted. */
|
|
83
|
+
readonly maxBytes?: number | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* Names the current QA scope can actually use. Omitted when the catalog is
|
|
86
|
+
* unknown: a missing catalog must not turn every tool into a warning.
|
|
87
|
+
*/
|
|
88
|
+
readonly availableTools?: readonly string[] | undefined;
|
|
89
|
+
/** Tool names submitted through the picker that are not usable names. */
|
|
90
|
+
readonly rejectedTools?: readonly string[] | undefined;
|
|
91
|
+
/** Frontmatter keys carried over from the file, for the unknown-field notice. */
|
|
92
|
+
readonly extraFieldNames?: readonly string[] | undefined;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Validate an editor draft. Every rule here is enforced again on the Host at
|
|
96
|
+
* write time; running it in the browser only makes the editor immediate, it is
|
|
97
|
+
* not the authority.
|
|
98
|
+
*/
|
|
99
|
+
export declare function validateSkillDraft(input: QaSkillValidationInput): readonly QaSkillDiagnostic[];
|
|
100
|
+
//# sourceMappingURL=skill-format.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Follows personal skill directories so a file edited by hand — outside the
|
|
3
|
+
* editor — still reaches the DSH catalog without a restart.
|
|
4
|
+
*
|
|
5
|
+
* Registration is lazy and bounded: a root is watched the first time the
|
|
6
|
+
* discovery provider meets it, at most {@link QA_SKILL_WATCH_LIMIT} roots stay
|
|
7
|
+
* open (least recently used first), and every watcher is closed on dispose. A
|
|
8
|
+
* root that cannot be watched degrades to "no live refresh for that account":
|
|
9
|
+
* a save through the editor invalidates the registry directly and never
|
|
10
|
+
* depends on this path.
|
|
11
|
+
*/
|
|
12
|
+
export declare const QA_SKILL_WATCH_LIMIT = 16;
|
|
13
|
+
export interface QaSkillWatcherOptions {
|
|
14
|
+
readonly onChange: () => void;
|
|
15
|
+
readonly onError: (message: string) => void;
|
|
16
|
+
readonly limit?: number;
|
|
17
|
+
readonly debounceMs?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare class QaSkillWatcher {
|
|
20
|
+
private readonly options;
|
|
21
|
+
private readonly watchers;
|
|
22
|
+
private readonly limit;
|
|
23
|
+
private readonly debounceMs;
|
|
24
|
+
private timer;
|
|
25
|
+
constructor(options: QaSkillWatcherOptions);
|
|
26
|
+
/** How many roots are currently watched (tests and diagnostics). */
|
|
27
|
+
get size(): number;
|
|
28
|
+
/** Start following one skills root; idempotent per path. */
|
|
29
|
+
follow(root: string): void;
|
|
30
|
+
/** Stop following one root. */
|
|
31
|
+
close(root: string): void;
|
|
32
|
+
dispose(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Coalesce a burst of filesystem events into one catalog refresh. The timer
|
|
35
|
+
* never holds the process open: a watcher must not keep the Host alive.
|
|
36
|
+
*/
|
|
37
|
+
private schedule;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=watcher.d.ts.map
|
package/lib/types/profile.d.ts
CHANGED
|
@@ -24,6 +24,19 @@ export declare const QA_PROFILE_INSTRUCTIONS_MAX_MIN = 200;
|
|
|
24
24
|
export declare const QA_PROFILE_INSTRUCTIONS_MAX_MAX = 20000;
|
|
25
25
|
/** The profile of an account that never filled one in. */
|
|
26
26
|
export declare function emptyProfile(): QaAccountProfile;
|
|
27
|
+
/**
|
|
28
|
+
* One single-line field: control characters out, whitespace runs collapsed to
|
|
29
|
+
* a space, trimmed to at most `maxLength` characters. Shared with the starter
|
|
30
|
+
* editor, whose button label obeys the same rules.
|
|
31
|
+
*/
|
|
32
|
+
export declare function cleanLine(value: unknown, maxLength: number): string;
|
|
33
|
+
/**
|
|
34
|
+
* One multi-line field: line feeds survive (three or more collapse to a blank
|
|
35
|
+
* line), every other control character is dropped, and the result is trimmed
|
|
36
|
+
* to at most `maxLength` characters. Shared with the starter editor, whose
|
|
37
|
+
* sent prompt obeys the same rules.
|
|
38
|
+
*/
|
|
39
|
+
export declare function cleanBlock(value: unknown, maxLength: number): string;
|
|
27
40
|
/**
|
|
28
41
|
* Read one stored (or wire-delivered) profile into its public shape. Unknown
|
|
29
42
|
* or hand-edited input degrades to the readable subset instead of throwing:
|
|
@@ -12,6 +12,8 @@ export declare const QA_NOTES_PLUGIN = "qa-surface";
|
|
|
12
12
|
export declare const QA_IDENTITY_NOTE = "dsh-qa-surface:user-identity";
|
|
13
13
|
/** Note name carrying the deployment's rule about source provenance. */
|
|
14
14
|
export declare const QA_SOURCES_NOTE = "dsh-qa-surface:structured-sources";
|
|
15
|
+
/** Note name asking the model to name its delegations. */
|
|
16
|
+
export declare const QA_DELEGATION_NOTE = "dsh-qa-surface:delegation-naming";
|
|
15
17
|
export interface QaIdentityRenderInput {
|
|
16
18
|
/** The owner's account address; the one fact accounts always provide. */
|
|
17
19
|
readonly email: string;
|
|
@@ -89,6 +91,13 @@ export declare class QaPromptNotes {
|
|
|
89
91
|
private identityNotes;
|
|
90
92
|
/** What the deployment expects around the sources the surface collects. */
|
|
91
93
|
private sourcesNotes;
|
|
94
|
+
/**
|
|
95
|
+
* How the model should label its delegations: the host keeps the
|
|
96
|
+
* delegation's `description` as the child's durable creation label, and the
|
|
97
|
+
* surface shows it as the subagent's display name. A named delegation is
|
|
98
|
+
* the difference between a panel of hashes and a panel of tasks.
|
|
99
|
+
*/
|
|
100
|
+
private delegationNotes;
|
|
92
101
|
private carriedKey;
|
|
93
102
|
/**
|
|
94
103
|
* The text one note already carries in this agent's conversation. Process
|
|
@@ -1,10 +1,53 @@
|
|
|
1
1
|
import type { QaSourceFilePreview } from "../types.js";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Coarse, wire-safe preview refusal codes. They ride the shared
|
|
4
|
+
* `(reason: <code>)` marker, so the panel can tell "this file is not in a
|
|
5
|
+
* directory the QA read policy opens" from "this file is gone" instead of
|
|
6
|
+
* telling every audience that a present file moved away.
|
|
7
|
+
*/
|
|
8
|
+
export type QaSourcePreviewReason = "outside-roots" | "not-evidence" | "unavailable";
|
|
9
|
+
/** Host refusal whose wire message carries the coarse reason marker. */
|
|
10
|
+
export declare class QaSourcePreviewError extends Error {
|
|
11
|
+
readonly reason: QaSourcePreviewReason;
|
|
12
|
+
constructor(reason: QaSourcePreviewReason);
|
|
13
|
+
}
|
|
14
|
+
export interface QaSourceFilePreviewRequest {
|
|
4
15
|
readonly sourcePath: string;
|
|
16
|
+
/**
|
|
17
|
+
* The attested chat's cwd. It is the root every relative source path in the
|
|
18
|
+
* evidence bundle was canonicalized against, and the anchor this read
|
|
19
|
+
* resolves a relative request against.
|
|
20
|
+
*/
|
|
21
|
+
readonly cwd: string;
|
|
22
|
+
/**
|
|
23
|
+
* Whether one canonical path is evidence of the attested chat. The preview
|
|
24
|
+
* never browses: it opens exactly the files the bundle already recorded.
|
|
25
|
+
*/
|
|
26
|
+
readonly isEvidence: (canonicalPath: string) => boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Shared read directories of the deployment. The per-user execution guard
|
|
29
|
+
* already lets the model read these, so a source recorded from one of them
|
|
30
|
+
* must stay previewable.
|
|
31
|
+
*/
|
|
32
|
+
readonly sharedReadOnlyRoots?: readonly string[];
|
|
33
|
+
/**
|
|
34
|
+
* The mounted attachment store. It sits outside every workspace on purpose,
|
|
35
|
+
* and the upload prompt points the model at the exact file an upload
|
|
36
|
+
* produced, so that one file is readable here too.
|
|
37
|
+
*/
|
|
38
|
+
readonly attachmentRoot?: string;
|
|
5
39
|
readonly maxBytes: number;
|
|
6
40
|
readonly maxMarkdownRenderBytes: number;
|
|
7
41
|
}
|
|
8
|
-
/**
|
|
9
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Read one evidence file from the roots the QA read policy opens.
|
|
44
|
+
*
|
|
45
|
+
* The bundle canonicalized each recorded path against the chat cwd, while the
|
|
46
|
+
* browser may hold either spelling of the same file: it projects sources with
|
|
47
|
+
* the *configured* session cwd, which is null whenever the chat is pinned by
|
|
48
|
+
* workspaceId or by an account directory. So the request is canonicalized the
|
|
49
|
+
* same way before it is matched, or a file inside the chat's own workspace is
|
|
50
|
+
* refused as foreign evidence.
|
|
51
|
+
*/
|
|
52
|
+
export declare function readSourceFilePreview({ sourcePath, cwd, isEvidence, sharedReadOnlyRoots, attachmentRoot, maxBytes, maxMarkdownRenderBytes, }: QaSourceFilePreviewRequest): Promise<QaSourceFilePreview>;
|
|
10
53
|
//# sourceMappingURL=file-preview.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Context } from "@deepseek-ai/cordis";
|
|
2
|
+
import { type QaProvenanceSnapshotStore } from "./snapshot-store.js";
|
|
2
3
|
import type { QaTurnSources } from "./types.js";
|
|
3
4
|
import type { ResolvedQaSurfaceConfig } from "../types.js";
|
|
4
5
|
export declare const QA_REPORT_SOURCES_TOOL = "qa_report_sources";
|
|
@@ -23,12 +24,15 @@ declare module "@deepseek-ai/cordis" {
|
|
|
23
24
|
export declare class QaProvenanceHost {
|
|
24
25
|
private readonly ctx;
|
|
25
26
|
private readonly config;
|
|
27
|
+
private readonly store;
|
|
28
|
+
private readonly onPersistenceError;
|
|
26
29
|
private readonly collectors;
|
|
27
30
|
private readonly snapshots;
|
|
31
|
+
private readonly seededSessions;
|
|
28
32
|
private readonly calls;
|
|
29
33
|
private readonly lineage;
|
|
30
34
|
private readonly disposers;
|
|
31
|
-
constructor(ctx: Context, config: () => ResolvedQaSurfaceConfig);
|
|
35
|
+
constructor(ctx: Context, config: () => ResolvedQaSurfaceConfig, store?: QaProvenanceSnapshotStore, onPersistenceError?: (error: unknown) => void);
|
|
32
36
|
dispose(): void;
|
|
33
37
|
/**
|
|
34
38
|
* Drop every per-session record of one chat. Long-lived servers outlive
|
|
@@ -49,6 +53,8 @@ export declare class QaProvenanceHost {
|
|
|
49
53
|
private collector;
|
|
50
54
|
private sessionCalls;
|
|
51
55
|
private sessionSnapshots;
|
|
56
|
+
private hydrateStored;
|
|
57
|
+
private persistSnapshot;
|
|
52
58
|
}
|
|
53
59
|
export {};
|
|
54
60
|
//# sourceMappingURL=host-store.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { QaTurnSources } from "./types.js";
|
|
2
|
+
export interface QaProvenanceSnapshotStore {
|
|
3
|
+
list(sessionId: string): readonly QaTurnSources[];
|
|
4
|
+
put(bundle: QaTurnSources): void;
|
|
5
|
+
}
|
|
6
|
+
/** Process-local store used by tests and explicit ephemeral deployments. */
|
|
7
|
+
export declare class MemoryQaProvenanceSnapshotStore implements QaProvenanceSnapshotStore {
|
|
8
|
+
private readonly sessions;
|
|
9
|
+
list(sessionId: string): readonly QaTurnSources[];
|
|
10
|
+
put(bundle: QaTurnSources): void;
|
|
11
|
+
}
|
|
12
|
+
/** Default durable provenance path, deliberately outside Harness journals. */
|
|
13
|
+
export declare function defaultQaProvenanceFilePath(): string;
|
|
14
|
+
/** Atomically persists per-turn QA source snapshots in plugin-owned storage. */
|
|
15
|
+
export declare class FileQaProvenanceSnapshotStore implements QaProvenanceSnapshotStore {
|
|
16
|
+
private readonly filePath;
|
|
17
|
+
constructor(filePath?: string);
|
|
18
|
+
list(sessionId: string): readonly QaTurnSources[];
|
|
19
|
+
put(bundle: QaTurnSources): void;
|
|
20
|
+
private load;
|
|
21
|
+
private persist;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=snapshot-store.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Agent } from "@deepseek-ai/dsh-agent";
|
|
2
|
+
import type { Context } from "@deepseek-ai/cordis";
|
|
3
|
+
import type { PluginLogger } from "@yadsh/dsh-plugin-log";
|
|
4
|
+
import type { QaToolActivationManager } from "./activation-manager.js";
|
|
5
|
+
export interface QaToolActivationDetectorOptions {
|
|
6
|
+
readonly manager: QaToolActivationManager;
|
|
7
|
+
readonly logger: PluginLogger;
|
|
8
|
+
/** The exact skill name that unlocks the QA tools. */
|
|
9
|
+
readonly activationSkill: string;
|
|
10
|
+
/** Whether this agent's composition participates in QA tool activation. */
|
|
11
|
+
readonly isManagedAgent: (agent: Agent) => boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Turns a successful QA skill load into an activation request.
|
|
15
|
+
*
|
|
16
|
+
* The trigger is the authoritative `tools/result` of the built-in `skill` tool,
|
|
17
|
+
* not the model's attempt and not the rendered conversation text: a refused,
|
|
18
|
+
* unknown, or cancelled skill load reaches this listener as an error result and
|
|
19
|
+
* activates nothing.
|
|
20
|
+
*/
|
|
21
|
+
export declare class QaToolActivationDetector {
|
|
22
|
+
private readonly ctx;
|
|
23
|
+
private readonly options;
|
|
24
|
+
private readonly dispose;
|
|
25
|
+
constructor(ctx: Context, options: QaToolActivationDetectorOptions);
|
|
26
|
+
private observe;
|
|
27
|
+
disposeListeners(): void;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=activation-detector.d.ts.map
|