@crazx/dsh-experimental-liveshare 0.0.0-stage → 0.2.2-rc.3.zw.1
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.i18n.yaml +52 -0
- package/README.md +182 -2
- package/README.zh.md +183 -0
- package/cordis.patch.yml +13 -0
- package/icon.svg +12 -0
- package/lib/client.js +3 -0
- package/lib/client.js.map +1 -0
- package/lib/index.js +8293 -0
- package/lib/owner-gateway/cli.js +370 -0
- package/lib/retry-backoff-ccJYtzOj.js +121 -0
- package/lib/typert.host.d.ts +3 -0
- package/lib/typert.host.js +845 -0
- package/lib/typert.remote-client.d.ts +61 -0
- package/lib/typert.remote-client.d.ts.map +1 -0
- package/lib/typert.remote-client.js +606 -0
- package/lib/types/client/ManageSharesDialog.d.ts +21 -0
- package/lib/types/client/ManageSharesDialog.d.ts.map +1 -0
- package/lib/types/client/ManageSharesDialog.js.map +1 -0
- package/lib/types/client/ShareAction.d.ts +19 -0
- package/lib/types/client/ShareAction.d.ts.map +1 -0
- package/lib/types/client/ShareAction.js.map +1 -0
- package/lib/types/client/ShareCapabilitiesPicker.d.ts +114 -0
- package/lib/types/client/ShareCapabilitiesPicker.d.ts.map +1 -0
- package/lib/types/client/ShareCapabilitiesPicker.js.map +1 -0
- package/lib/types/client/ShareCreateForm.d.ts +108 -0
- package/lib/types/client/ShareCreateForm.d.ts.map +1 -0
- package/lib/types/client/ShareCreateForm.js.map +1 -0
- package/lib/types/client/ShareDialog.d.ts +28 -0
- package/lib/types/client/ShareDialog.d.ts.map +1 -0
- package/lib/types/client/ShareDialog.js.map +1 -0
- package/lib/types/client/ShareEditPanel.d.ts +100 -0
- package/lib/types/client/ShareEditPanel.d.ts.map +1 -0
- package/lib/types/client/ShareEditPanel.js.map +1 -0
- package/lib/types/client/SharePermissionFields.d.ts +48 -0
- package/lib/types/client/SharePermissionFields.d.ts.map +1 -0
- package/lib/types/client/SharePermissionFields.js.map +1 -0
- package/lib/types/client/endpoint-classification.d.ts +214 -0
- package/lib/types/client/endpoint-classification.d.ts.map +1 -0
- package/lib/types/client/endpoint-classification.js.map +1 -0
- package/lib/types/client/index.d.ts +33 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client/index.js.map +1 -0
- package/lib/types/client/locales.d.ts +280 -0
- package/lib/types/client/locales.d.ts.map +1 -0
- package/lib/types/client/locales.js.map +1 -0
- package/lib/types/client/owner-display.d.ts +41 -0
- package/lib/types/client/owner-display.d.ts.map +1 -0
- package/lib/types/client/owner-display.js.map +1 -0
- package/lib/types/client/owner-identity-login.d.ts +72 -0
- package/lib/types/client/owner-identity-login.d.ts.map +1 -0
- package/lib/types/client/owner-identity-login.js.map +1 -0
- package/lib/types/client/owner-identity.d.ts +81 -0
- package/lib/types/client/owner-identity.d.ts.map +1 -0
- package/lib/types/client/owner-identity.js.map +1 -0
- package/lib/types/client/owner-login.d.ts +146 -0
- package/lib/types/client/owner-login.d.ts.map +1 -0
- package/lib/types/client/owner-login.js.map +1 -0
- package/lib/types/client/owner-routes.d.ts +20 -0
- package/lib/types/client/owner-routes.d.ts.map +1 -0
- package/lib/types/client/owner-routes.js.map +1 -0
- package/lib/types/client/owner-shares.d.ts +89 -0
- package/lib/types/client/owner-shares.d.ts.map +1 -0
- package/lib/types/client/owner-shares.js.map +1 -0
- package/lib/types/client/share-navigation.d.ts +25 -0
- package/lib/types/client/share-navigation.d.ts.map +1 -0
- package/lib/types/client/share-navigation.js.map +1 -0
- package/lib/types/client/share-options.d.ts +19 -0
- package/lib/types/client/share-options.d.ts.map +1 -0
- package/lib/types/client/share-options.js.map +1 -0
- package/lib/types/client/share-relay-address.d.ts +117 -0
- package/lib/types/client/share-relay-address.d.ts.map +1 -0
- package/lib/types/client/share-relay-address.js.map +1 -0
- package/lib/types/client/share-types.d.ts +83 -0
- package/lib/types/client/share-types.d.ts.map +1 -0
- package/lib/types/client/share-types.js.map +1 -0
- package/lib/types/client/user-origin.d.ts +46 -0
- package/lib/types/client/user-origin.d.ts.map +1 -0
- package/lib/types/client/user-origin.js.map +1 -0
- package/lib/types/client/viewer-brand.d.ts +48 -0
- package/lib/types/client/viewer-brand.d.ts.map +1 -0
- package/lib/types/client/viewer-brand.js.map +1 -0
- package/lib/types/client/viewer-capabilities.d.ts +74 -0
- package/lib/types/client/viewer-capabilities.d.ts.map +1 -0
- package/lib/types/client/viewer-capabilities.js.map +1 -0
- package/lib/types/client/viewer-context.d.ts +45 -0
- package/lib/types/client/viewer-context.d.ts.map +1 -0
- package/lib/types/client/viewer-context.js.map +1 -0
- package/lib/types/client/viewer-model.d.ts +77 -0
- package/lib/types/client/viewer-model.d.ts.map +1 -0
- package/lib/types/client/viewer-model.js.map +1 -0
- package/lib/types/client/viewer-permission.d.ts +44 -0
- package/lib/types/client/viewer-permission.d.ts.map +1 -0
- package/lib/types/client/viewer-permission.js.map +1 -0
- package/lib/types/client/viewer-plugin-warning.d.ts +35 -0
- package/lib/types/client/viewer-plugin-warning.d.ts.map +1 -0
- package/lib/types/client/viewer-plugin-warning.js.map +1 -0
- package/lib/types/client/viewer-seat.d.ts +55 -0
- package/lib/types/client/viewer-seat.d.ts.map +1 -0
- package/lib/types/client/viewer-seat.js.map +1 -0
- package/lib/types/client/viewer-session-plugin.d.ts +47 -0
- package/lib/types/client/viewer-session-plugin.d.ts.map +1 -0
- package/lib/types/client/viewer-session-plugin.js.map +1 -0
- package/lib/types/client/viewer-session-row.d.ts +21 -0
- package/lib/types/client/viewer-session-row.d.ts.map +1 -0
- package/lib/types/client/viewer-session-row.js.map +1 -0
- package/lib/types/client/viewer-session.d.ts +20 -0
- package/lib/types/client/viewer-session.d.ts.map +1 -0
- package/lib/types/client/viewer-session.js.map +1 -0
- package/lib/types/client/viewer-share-path.d.ts +32 -0
- package/lib/types/client/viewer-share-path.d.ts.map +1 -0
- package/lib/types/client/viewer-share-path.js.map +1 -0
- package/lib/types/client/viewer-status-banner.d.ts +33 -0
- package/lib/types/client/viewer-status-banner.d.ts.map +1 -0
- package/lib/types/client/viewer-status-banner.js.map +1 -0
- package/lib/types/client/viewer-status.d.ts +69 -0
- package/lib/types/client/viewer-status.d.ts.map +1 -0
- package/lib/types/client/viewer-status.js.map +1 -0
- package/lib/types/endpoint-classification.d.ts +246 -0
- package/lib/types/endpoint-classification.d.ts.map +1 -0
- package/lib/types/endpoint-classification.js.map +1 -0
- package/lib/types/fork-lineage.d.ts +47 -0
- package/lib/types/fork-lineage.d.ts.map +1 -0
- package/lib/types/fork-lineage.js.map +1 -0
- package/lib/types/host/base64-url.d.ts +17 -0
- package/lib/types/host/base64-url.d.ts.map +1 -0
- package/lib/types/host/base64-url.js.map +1 -0
- package/lib/types/host/bundle-titles.d.ts +50 -0
- package/lib/types/host/bundle-titles.d.ts.map +1 -0
- package/lib/types/host/bundle-titles.js.map +1 -0
- package/lib/types/host/fork-ceiling.d.ts +41 -0
- package/lib/types/host/fork-ceiling.d.ts.map +1 -0
- package/lib/types/host/fork-ceiling.js.map +1 -0
- package/lib/types/host/fork-enforcement.d.ts +271 -0
- package/lib/types/host/fork-enforcement.d.ts.map +1 -0
- package/lib/types/host/fork-enforcement.js.map +1 -0
- package/lib/types/host/fork-policy.d.ts +150 -0
- package/lib/types/host/fork-policy.d.ts.map +1 -0
- package/lib/types/host/fork-policy.js.map +1 -0
- package/lib/types/host/fork-registry.d.ts +231 -0
- package/lib/types/host/fork-registry.d.ts.map +1 -0
- package/lib/types/host/fork-registry.js.map +1 -0
- package/lib/types/host/fork-tool-guard.d.ts +148 -0
- package/lib/types/host/fork-tool-guard.d.ts.map +1 -0
- package/lib/types/host/fork-tool-guard.js.map +1 -0
- package/lib/types/host/owner-authorization.d.ts +128 -0
- package/lib/types/host/owner-authorization.d.ts.map +1 -0
- package/lib/types/host/owner-authorization.js.map +1 -0
- package/lib/types/host/owner-credential-file.d.ts +64 -0
- package/lib/types/host/owner-credential-file.d.ts.map +1 -0
- package/lib/types/host/owner-credential-file.js.map +1 -0
- package/lib/types/host/owner-http-routes.d.ts +49 -0
- package/lib/types/host/owner-http-routes.d.ts.map +1 -0
- package/lib/types/host/owner-http-routes.js.map +1 -0
- package/lib/types/host/owner-persistence.d.ts +102 -0
- package/lib/types/host/owner-persistence.d.ts.map +1 -0
- package/lib/types/host/owner-persistence.js.map +1 -0
- package/lib/types/host/owner-share-operations.d.ts +76 -0
- package/lib/types/host/owner-share-operations.d.ts.map +1 -0
- package/lib/types/host/owner-share-operations.js.map +1 -0
- package/lib/types/host/owner-types.d.ts +73 -0
- package/lib/types/host/owner-types.d.ts.map +1 -0
- package/lib/types/host/owner-types.js.map +1 -0
- package/lib/types/host/relay-authority.d.ts +133 -0
- package/lib/types/host/relay-authority.d.ts.map +1 -0
- package/lib/types/host/relay-authority.js.map +1 -0
- package/lib/types/host/relay-fetch.d.ts +51 -0
- package/lib/types/host/relay-fetch.d.ts.map +1 -0
- package/lib/types/host/relay-fetch.js.map +1 -0
- package/lib/types/host/relay-h2-idle.d.ts +23 -0
- package/lib/types/host/relay-h2-idle.d.ts.map +1 -0
- package/lib/types/host/relay-h2-idle.js.map +1 -0
- package/lib/types/host/relay-url.d.ts +16 -0
- package/lib/types/host/relay-url.d.ts.map +1 -0
- package/lib/types/host/relay-url.js.map +1 -0
- package/lib/types/host/share-host.d.ts +61 -0
- package/lib/types/host/share-host.d.ts.map +1 -0
- package/lib/types/host/share-host.js.map +1 -0
- package/lib/types/host/share-operations.d.ts +93 -0
- package/lib/types/host/share-operations.d.ts.map +1 -0
- package/lib/types/host/share-operations.js.map +1 -0
- package/lib/types/host/share-remote.d.ts +102 -0
- package/lib/types/host/share-remote.d.ts.map +1 -0
- package/lib/types/host/share-remote.js.map +1 -0
- package/lib/types/host/shareable-catalog.d.ts +76 -0
- package/lib/types/host/shareable-catalog.d.ts.map +1 -0
- package/lib/types/host/shareable-catalog.js.map +1 -0
- package/lib/types/host/shared-tools.d.ts +116 -0
- package/lib/types/host/shared-tools.d.ts.map +1 -0
- package/lib/types/host/shared-tools.js.map +1 -0
- package/lib/types/host/source-access.d.ts +175 -0
- package/lib/types/host/source-access.d.ts.map +1 -0
- package/lib/types/host/source-access.js.map +1 -0
- package/lib/types/host/source-sessions.d.ts +19 -0
- package/lib/types/host/source-sessions.d.ts.map +1 -0
- package/lib/types/host/source-sessions.js.map +1 -0
- package/lib/types/host/tunnel-supervision.d.ts +221 -0
- package/lib/types/host/tunnel-supervision.d.ts.map +1 -0
- package/lib/types/host/tunnel-supervision.js.map +1 -0
- package/lib/types/host/tunnel-worker.d.ts +80 -0
- package/lib/types/host/tunnel-worker.d.ts.map +1 -0
- package/lib/types/host/tunnel-worker.js.map +1 -0
- package/lib/types/host/viewer-access-policy.d.ts +101 -0
- package/lib/types/host/viewer-access-policy.d.ts.map +1 -0
- package/lib/types/host/viewer-access-policy.js.map +1 -0
- package/lib/types/host/viewer-assets.d.ts +23 -0
- package/lib/types/host/viewer-assets.d.ts.map +1 -0
- package/lib/types/host/viewer-assets.js.map +1 -0
- package/lib/types/host/viewer-capability-selection.d.ts +37 -0
- package/lib/types/host/viewer-capability-selection.d.ts.map +1 -0
- package/lib/types/host/viewer-capability-selection.js.map +1 -0
- package/lib/types/host/viewer-capability-types.d.ts +8 -0
- package/lib/types/host/viewer-capability-types.d.ts.map +1 -0
- package/lib/types/host/viewer-capability-types.js.map +1 -0
- package/lib/types/host/viewer-dispatch.d.ts +88 -0
- package/lib/types/host/viewer-dispatch.d.ts.map +1 -0
- package/lib/types/host/viewer-dispatch.js.map +1 -0
- package/lib/types/host/viewer-fork.d.ts +84 -0
- package/lib/types/host/viewer-fork.d.ts.map +1 -0
- package/lib/types/host/viewer-fork.js.map +1 -0
- package/lib/types/host/viewer-lifecycle.d.ts +226 -0
- package/lib/types/host/viewer-lifecycle.d.ts.map +1 -0
- package/lib/types/host/viewer-lifecycle.js.map +1 -0
- package/lib/types/host/viewer-principal.d.ts +59 -0
- package/lib/types/host/viewer-principal.d.ts.map +1 -0
- package/lib/types/host/viewer-principal.js.map +1 -0
- package/lib/types/host/viewer-read.d.ts +201 -0
- package/lib/types/host/viewer-read.d.ts.map +1 -0
- package/lib/types/host/viewer-read.js.map +1 -0
- package/lib/types/host/wire-json.d.ts +24 -0
- package/lib/types/host/wire-json.d.ts.map +1 -0
- package/lib/types/host/wire-json.js.map +1 -0
- package/lib/types/index.d.ts +14 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/owner-gateway/cli.d.ts +3 -0
- package/lib/types/owner-gateway/cli.d.ts.map +1 -0
- package/lib/types/owner-gateway/cli.js.map +1 -0
- package/lib/types/owner-gateway/pending-rpc.d.ts +47 -0
- package/lib/types/owner-gateway/pending-rpc.d.ts.map +1 -0
- package/lib/types/owner-gateway/pending-rpc.js.map +1 -0
- package/lib/types/owner-gateway/registration-url.d.ts +20 -0
- package/lib/types/owner-gateway/registration-url.d.ts.map +1 -0
- package/lib/types/owner-gateway/registration-url.js.map +1 -0
- package/lib/types/owner-gateway/relay-refusal.d.ts +28 -0
- package/lib/types/owner-gateway/relay-refusal.d.ts.map +1 -0
- package/lib/types/owner-gateway/relay-refusal.js.map +1 -0
- package/lib/types/owner-gateway/retry-backoff.d.ts +37 -0
- package/lib/types/owner-gateway/retry-backoff.d.ts.map +1 -0
- package/lib/types/owner-gateway/retry-backoff.js.map +1 -0
- package/lib/types/owner-gateway/worker.d.ts +7 -0
- package/lib/types/owner-gateway/worker.d.ts.map +1 -0
- package/lib/types/owner-gateway/worker.js.map +1 -0
- package/lib/types/owner-identity.d.ts +23 -0
- package/lib/types/owner-identity.d.ts.map +1 -0
- package/lib/types/owner-identity.js.map +1 -0
- package/lib/types/read-budgets.d.ts +45 -0
- package/lib/types/read-budgets.d.ts.map +1 -0
- package/lib/types/read-budgets.js.map +1 -0
- package/lib/types/share-api-types.d.ts +339 -0
- package/lib/types/share-api-types.d.ts.map +1 -0
- package/lib/types/share-api-types.js.map +1 -0
- package/lib/types/viewer-channel.d.ts +107 -0
- package/lib/types/viewer-channel.d.ts.map +1 -0
- package/lib/types/viewer-channel.js.map +1 -0
- package/locale/de.json +6 -0
- package/locale/en.json +6 -0
- package/locale/es.json +6 -0
- package/locale/fr.json +6 -0
- package/locale/ja.json +6 -0
- package/locale/pt.json +6 -0
- package/locale/ru.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +170 -3
- package/src/client/ManageSharesDialog.tsx +137 -0
- package/src/client/README.i18n.yaml +7 -0
- package/src/client/README.md +11 -0
- package/src/client/README.zh.md +11 -0
- package/src/client/ShareAction.module.css +21 -0
- package/src/client/ShareAction.tsx +94 -0
- package/src/client/ShareCapabilitiesPicker.tsx +337 -0
- package/src/client/ShareCreateForm.tsx +243 -0
- package/src/client/ShareDialog.module.css +401 -0
- package/src/client/ShareDialog.tsx +381 -0
- package/src/client/ShareEditPanel.tsx +492 -0
- package/src/client/SharePermissionFields.tsx +111 -0
- package/src/client/endpoint-classification.ts +40 -0
- package/src/client/index.ts +120 -0
- package/src/client/locales.ts +1930 -0
- package/src/client/owner-display.ts +78 -0
- package/src/client/owner-identity-login.ts +220 -0
- package/src/client/owner-identity.ts +169 -0
- package/src/client/owner-login.ts +400 -0
- package/src/client/owner-routes.ts +20 -0
- package/src/client/owner-shares.ts +124 -0
- package/src/client/share-navigation.ts +44 -0
- package/src/client/share-options.ts +25 -0
- package/src/client/share-relay-address.ts +365 -0
- package/src/client/share-types.ts +178 -0
- package/src/client/user-origin.module.css +13 -0
- package/src/client/user-origin.tsx +93 -0
- package/src/client/viewer-brand.module.css +61 -0
- package/src/client/viewer-brand.tsx +118 -0
- package/src/client/viewer-capabilities.ts +150 -0
- package/src/client/viewer-context.ts +167 -0
- package/src/client/viewer-model.tsx +215 -0
- package/src/client/viewer-permission.tsx +89 -0
- package/src/client/viewer-plugin-warning.ts +174 -0
- package/src/client/viewer-seat.module.css +28 -0
- package/src/client/viewer-seat.tsx +76 -0
- package/src/client/viewer-session-plugin.ts +343 -0
- package/src/client/viewer-session-row.tsx +47 -0
- package/src/client/viewer-session.ts +67 -0
- package/src/client/viewer-share-path.module.css +7 -0
- package/src/client/viewer-share-path.tsx +102 -0
- package/src/client/viewer-status-banner.module.css +8 -0
- package/src/client/viewer-status-banner.ts +159 -0
- package/src/client/viewer-status.ts +107 -0
- package/src/css-modules.d.ts +6 -0
- package/src/endpoint-classification.ts +309 -0
- package/src/fork-lineage.ts +61 -0
- package/src/host/base64-url.ts +21 -0
- package/src/host/bundle-titles.ts +110 -0
- package/src/host/fork-ceiling.ts +73 -0
- package/src/host/fork-enforcement.ts +983 -0
- package/src/host/fork-policy.ts +230 -0
- package/src/host/fork-registry.ts +524 -0
- package/src/host/fork-tool-guard.ts +268 -0
- package/src/host/owner-authorization.ts +191 -0
- package/src/host/owner-credential-file.ts +148 -0
- package/src/host/owner-http-routes.ts +279 -0
- package/src/host/owner-persistence.ts +348 -0
- package/src/host/owner-share-operations.ts +871 -0
- package/src/host/owner-types.ts +75 -0
- package/src/host/relay-authority.ts +389 -0
- package/src/host/relay-fetch.ts +102 -0
- package/src/host/relay-h2-idle.ts +86 -0
- package/src/host/relay-url.ts +34 -0
- package/src/host/share-host.ts +657 -0
- package/src/host/share-operations.ts +128 -0
- package/src/host/share-remote.ts +162 -0
- package/src/host/shareable-catalog.ts +173 -0
- package/src/host/shared-tools.ts +236 -0
- package/src/host/source-access.ts +686 -0
- package/src/host/source-sessions.ts +27 -0
- package/src/host/tunnel-supervision.ts +959 -0
- package/src/host/tunnel-worker.ts +378 -0
- package/src/host/viewer-access-policy.ts +533 -0
- package/src/host/viewer-assets.ts +59 -0
- package/src/host/viewer-capability-selection.ts +93 -0
- package/src/host/viewer-capability-types.ts +8 -0
- package/src/host/viewer-dispatch.ts +809 -0
- package/src/host/viewer-fork.ts +590 -0
- package/src/host/viewer-lifecycle.ts +576 -0
- package/src/host/viewer-principal.ts +84 -0
- package/src/host/viewer-read.ts +231 -0
- package/src/host/wire-json.ts +35 -0
- package/src/index.ts +16 -0
- package/src/owner-gateway/cli.ts +6 -0
- package/src/owner-gateway/pending-rpc.ts +78 -0
- package/src/owner-gateway/registration-url.ts +62 -0
- package/src/owner-gateway/relay-refusal.ts +45 -0
- package/src/owner-gateway/retry-backoff.ts +46 -0
- package/src/owner-gateway/worker.ts +327 -0
- package/src/owner-identity.ts +30 -0
- package/src/read-budgets.ts +49 -0
- package/src/share-api-types.ts +356 -0
- package/src/viewer-channel.ts +172 -0
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
|
|
2
|
+
# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
|
|
3
|
+
# After editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/experimental/liveshare/README.md
|
|
5
|
+
/:
|
|
6
|
+
en: 01889c844628a948
|
|
7
|
+
zh: 94366d9239f1c383
|
|
8
|
+
/deepseek-ai-dsh-experimental-liveshare:
|
|
9
|
+
en: d922aebfcdd341f4
|
|
10
|
+
zh: 92b631fd849b6d03
|
|
11
|
+
/deepseek-ai-dsh-experimental-liveshare/summary:
|
|
12
|
+
en: 5079cf4c5eb1d15a
|
|
13
|
+
zh: 96b21dd402dfae5c
|
|
14
|
+
/deepseek-ai-dsh-experimental-liveshare/table-of-contents:
|
|
15
|
+
en: d152484eb41ac6b4
|
|
16
|
+
zh: 405b30feaf48c087
|
|
17
|
+
/deepseek-ai-dsh-experimental-liveshare/use-this-package:
|
|
18
|
+
en: bbff250eba0f1b89
|
|
19
|
+
zh: 0a618f05cc88ee2b
|
|
20
|
+
/deepseek-ai-dsh-experimental-liveshare/use-this-package/profile-and-build-requirements:
|
|
21
|
+
en: 86aa723d77827dca
|
|
22
|
+
zh: 3cb8774c8c7b1b8c
|
|
23
|
+
/deepseek-ai-dsh-experimental-liveshare/use-this-package/default-visibility-and-enabling:
|
|
24
|
+
en: 34cb99a56d9c5c9f
|
|
25
|
+
zh: 9e06fb1a28fd06c3
|
|
26
|
+
/deepseek-ai-dsh-experimental-liveshare/use-this-package/owner-configuration:
|
|
27
|
+
en: 42b24e06e416eb1d
|
|
28
|
+
zh: 45f7e2003eb3ae2f
|
|
29
|
+
/deepseek-ai-dsh-experimental-liveshare/use-this-package/sign-in-and-manage-shares:
|
|
30
|
+
en: e1bad148f61e1e12
|
|
31
|
+
zh: 0197ba5379c21cb2
|
|
32
|
+
/deepseek-ai-dsh-experimental-liveshare/use-this-package/session-tiers:
|
|
33
|
+
en: 2052fd7c4e9c3f98
|
|
34
|
+
zh: 5ef2ac5ad9ec7990
|
|
35
|
+
/deepseek-ai-dsh-experimental-liveshare/understand-the-implementation:
|
|
36
|
+
en: 74c336962ca47ab5
|
|
37
|
+
zh: ae3628a038bd4791
|
|
38
|
+
/deepseek-ai-dsh-experimental-liveshare/further-exploration:
|
|
39
|
+
en: 0570170704bbe5b6
|
|
40
|
+
zh: 832f86024b26e5b3
|
|
41
|
+
/deepseek-ai-dsh-experimental-liveshare/model-experience:
|
|
42
|
+
en: 3b248c02220df02d
|
|
43
|
+
zh: 9d752fb049a04e83
|
|
44
|
+
/deepseek-ai-dsh-experimental-liveshare/model-experience/kv-cache-effect:
|
|
45
|
+
en: 22a9da7d4b23a015
|
|
46
|
+
zh: 5700901ba5f655c8
|
|
47
|
+
/deepseek-ai-dsh-experimental-liveshare/known-limitations-and-deferred-work:
|
|
48
|
+
en: d51c0895166207f0
|
|
49
|
+
zh: 82cd69842c8f74d6
|
|
50
|
+
/deepseek-ai-dsh-experimental-liveshare/known-limitations-and-deferred-work/dev-note:
|
|
51
|
+
en: e67f633dc6fe7773
|
|
52
|
+
zh: 8ec3e73528ddb1a6
|
package/README.md
CHANGED
|
@@ -1,3 +1,183 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
description: "Share DSH Sessions through a separate Liveshare server, with verified owner sign-in, viewer controls, and bounded execution."
|
|
3
|
+
kind: "package-bundle"
|
|
4
|
+
---
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
# @deepseek-ai/dsh-experimental-liveshare
|
|
7
|
+
|
|
8
|
+
English | [中文](README.zh.md)
|
|
9
|
+
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
Share a Session with colleagues through the normal DSH browser interface. The owner chooses viewing or bounded writing, and independently allows forking; the owner host enforces those choices. Attachment upload follows sharing itself: a Session the viewer can see accepts files. This opt-in bundle adds owner sign-in, sharing controls, the outgoing gateway, and the viewer surfaces of the owner's own Web page. The default Web profile excludes it. The separately deployed Liveshare server authenticates viewers and transports their requests; its OAuth, database, routing, and deployment implementation are not part of this package.
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Use this package](#use-this-package)
|
|
17
|
+
- [Understand the implementation](#understand-the-implementation)
|
|
18
|
+
- [Further Exploration](#further-exploration)
|
|
19
|
+
- [Model Experience](#model-experience)
|
|
20
|
+
- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
|
|
21
|
+
- [Dev Note](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## Use this package
|
|
27
|
+
|
|
28
|
+
### Profile and build requirements
|
|
29
|
+
|
|
30
|
+
The manifest declares an installable `dsh.bundle` layer and a browser face. The bundle stays hidden until a profile enables it, as described in [Default visibility and enabling](#default-visibility-and-enabling); supported applications still start through `dsh --profile`.
|
|
31
|
+
|
|
32
|
+
Owner, viewer, and the Liveshare server must use matching protocol versions. The build includes the Owner's gateway process; the viewer page has no separate build. Package version, exports, and publication contents are declared in [package.json](package.json).
|
|
33
|
+
|
|
34
|
+
<a id="default-visibility-and-enabling"></a>
|
|
35
|
+
|
|
36
|
+
### Default visibility and enabling
|
|
37
|
+
|
|
38
|
+
A dsh installation ships this package as a runtime dependency, but no shipped profile selects its bundle, so none of its plugins run and the plugin manager lists it in neither **Built-in plugin settings** nor **Experimental plugins**, including the **More** page. The bundle ID stays addressable, so a page that opens a bundle by ID still reaches this bundle's details.
|
|
39
|
+
|
|
40
|
+
Enable it by inserting its one entry into the active profile's patch file, `$DSH_HOME/profiles/<profile>/cordis.patch.yml`. That file is one YAML sequence of Loader patches; this is the entry the bundle's own [patch](cordis.patch.yml) inserts, and `!!js` expressions are allowed there:
|
|
41
|
+
|
|
42
|
+
```yaml
|
|
43
|
+
- insert:
|
|
44
|
+
- id: liveshare-share-host
|
|
45
|
+
name: '@deepseek-ai/dsh-experimental-liveshare'
|
|
46
|
+
config:
|
|
47
|
+
ownerIdentityProvider: <provider-id>
|
|
48
|
+
ownerIdentityTenant: <tenant-id>
|
|
49
|
+
ownerIdentitySubject: <subject-id>
|
|
50
|
+
allowedSubjectIds: []
|
|
51
|
+
ownerStateFile: /path/to/owner-shares.json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Replace every `<...>` placeholder with the deployment's own value: the identity provider, tenant, and subject are the ones its Liveshare server deployment was configured with, and the example holdings are placeholders rather than real identities. The environment layer works too: set `LIVESHARE_*` in `$DSH_HOME/.env` and keep the bundle's own `!!js process.env.…` expressions. The Liveshare server address is not part of this configuration: the owner enters it in the Share dialog on first use, as Owner configuration below describes.
|
|
55
|
+
|
|
56
|
+
The profile can select the bundle instead of patching it: add `"@deepseek-ai/dsh-experimental-liveshare"` to `dsh.profile.bundles` in `$DSH_HOME/profiles/<profile>/package.json`, which is the write the card's switch performs once the card is listed.
|
|
57
|
+
|
|
58
|
+
Either route takes effect only on a recomposition. With the profile's HMR row enabled, the change applies when the profile is re-read; without it, the next `dsh` start applies it. Once at least one row the bundle declares runs, its card appears under **Experimental plugins** and on the **More** page. Removing the entries, disabling them, or removing the bundle from `dsh.profile.bundles` stops those rows and the card leaves both lists again.
|
|
59
|
+
|
|
60
|
+
### Owner configuration
|
|
61
|
+
|
|
62
|
+
| Variable | Default | Meaning |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| `LIVESHARE_OWNER_PROVIDER_ID` / `LIVESHARE_OWNER_TENANT_ID` / `LIVESHARE_OWNER_SUBJECT_ID` | unset | Owner identity used for legacy subject matching; it does not replace a server-issued credential |
|
|
65
|
+
| `LIVESHARE_OWNER_DISPLAY_NAME` | unset | Display label for the configured identity |
|
|
66
|
+
| `LIVESHARE_ALLOWED_SUBJECTS` | empty | Deployment-wide subject allowlist in addition to the share's access rules |
|
|
67
|
+
| `LIVESHARE_OWNER_STATE_FILE` | `$DSH_HOME/liveshare/owner-shares.json` | Stored share metadata, the saved Liveshare server address, instance identity, and management tokens |
|
|
68
|
+
| `LIVESHARE_OWNER_CREDENTIAL_FILE` | `owner-credential.json` beside the state file | Stored credential bound to the Liveshare server that issued it |
|
|
69
|
+
|
|
70
|
+
The Liveshare server address is set on first use: enter it in the Share dialog's address field and save it. The saved address persists in the owner state file, and later shares publish to it; a publication already waiting for registration keeps its starting server address in its registration, stored record, and returned link, and existing shares retain their recorded Liveshare server address. Clearing the saved address through the share-management Remote leaves this host without one — creating a share then reports that an address has to be saved — rather than falling back to a deployment value. The name a reader sees beside a share comes from the display name on the Relay-verified credential, and local configuration cannot override it; a credential that carries only a subject shows that subject's label. Provider application secrets belong to the Liveshare server, not this configuration.
|
|
71
|
+
|
|
72
|
+
### Sign in and manage shares
|
|
73
|
+
|
|
74
|
+
The Share dialog starts a short-lived authorization transaction on the Owner. A popup returns a single-use code only to the expected window, origin, and transaction. The Owner redeems it with its private verifier and saves the credential bound to that Liveshare server; the normal browser login flow never stores that credential in browser storage or a URL. Expired, cancelled, replayed, or mismatched transactions fail closed. Changing the Liveshare server during code redemption, including a change away and back, refuses login before credential storage. After storage commits, probes and share claims retain that operation’s Liveshare server and credential identity. Publishing without verified identity is refused, including when the Liveshare server does not support identity binding.
|
|
75
|
+
|
|
76
|
+
Share management is the `liveshareShares` Typert Remote: the share list, creation, stopping, tier and fork changes, endpoint selection, the Liveshare server state, the owner identity, the audit trail the Liveshare server holds, and both Liveshare server checks are methods on the mounted namespace. `liveshareShares.addSessions` adds more source Sessions to an existing share, under that share's ACL, tier, lifetime, fork switch, and exposed endpoints; every source must belong to the same Workspace, and an addition the Host cannot place there is refused. The Share dialog does not offer it yet, so callers use the Remote directly. The sign-in round trip and credential storage are the only same-origin HTTP routes the owner page still calls.
|
|
77
|
+
|
|
78
|
+
The owner admits viewers by organization link; the deployment's `LIVESHARE_ALLOWED_SUBJECTS` gates every share and narrows an organization-link share to the subjects it lists. Stored `selected` or `approval` shares keep their original ACL and access summary, and the dialog no longer creates them; `liveshareShares.create` keeps `accessMode` and `allowedSubjectIds` for those records and direct Remote callers. Manage Shares lists stored links, tiers, availability, and the Liveshare server's audit responses, and it can change a share's tier, turn its fork switch on or off, and stop a share. Failed operations remain visible as errors; the UI re-reads the Owner's response rather than treating a click as success. The Share dialog edits an existing share too: its tier, fork switch, and plugin endpoints are picked there and submitted by one save that sits outside the scrolling fields and re-reads the Owner's record; unsaved picks are stated, and closing first warns that they would be discarded.
|
|
79
|
+
|
|
80
|
+
### Session tiers
|
|
81
|
+
|
|
82
|
+
<a id="session-tiers"></a>
|
|
83
|
+
|
|
84
|
+
| Tier | Viewer actions | Execution limit |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `view` | Prompt the source Session and stop its running turn | Read-only sandbox mounted on the Session, applied to every turn a share viewer starts: that turn may use the read and search surface (`read`, `read_image`, `glob`, `grep`, `present`), the tools with no local file effect (`todo_write`, `skill`, `web_search`, `web_fetch`), and the PTC transport `run_code`; every path a call declares is checked against the granted workspace |
|
|
87
|
+
| `write` | Also modify files inside that workspace | Writable sandbox with limits: the view surface plus bounded `edit` and `write` inside the granted workspace, for every viewer-started turn of the Session |
|
|
88
|
+
|
|
89
|
+
Both tiers drive the shared Session; what separates them is writing. The sandbox is mounted on the Session for as long as any share over it is active, but it confines only the turns a share viewer starts: a turn the owner starts keeps the Session's own tools, including `bash` and its unrestricted filesystem tools, and an owner's steering input inside a viewer's turn stays confined with it. The decision is kept in Host memory per turn and never written to the Session log; stopping every share or letting them all expire releases the layer and restores the Session's own tools. Forking is not a tier: the share carries its own switch, independent of the tier, and a viewer it admits forks a completed source prefix into a child that runs under the read-only ceiling, or under the bounded-write ceiling when the share is at the `write` tier.
|
|
90
|
+
|
|
91
|
+
A share that carries several source Sessions keeps the first one as its Relay registration and page target. The added Sessions are bound by the `share-viewer` policy, so the reader's Session list offers them; the page opens the first source again after a reload. Stopping the share ends every source and revokes the forks they authorized.
|
|
92
|
+
|
|
93
|
+
**Shared PTC programs are not sandboxed to the share.** `run_code` is admitted at both tiers because a viewer may need programmatic tool use, but the program runs under the owner's standing file policy rather than a share tier: it can read and write files outside the shared workspace, and the tier does not narrow that. The viewer's nested `tools.*` calls still pass the same guard and path checks as any other call, so `bash` stays refused and file tools stay inside the grant. Share only with people you trust until a PTC sandbox can be bounded to a share.
|
|
94
|
+
|
|
95
|
+
Attachment uploads are neither a tier nor part of the fork switch: they follow visibility. An admitted viewer may attach uploaded files to the shared Session and to the forks it created through this share, whichever tier the share carries and whether or not it allows forking. The owner has no separate attachment switch.
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
Shareable viewer methods come from installed plugins' live Remote methods, enumerated from the Host's Typert registry in [`shareable-catalog.ts`](src/host/shareable-catalog.ts). DSH core service namespaces are excluded ([`EXCLUDED_SHARE_NAMESPACES`](src/host/shareable-catalog.ts) lists them), and so are components of a core profile bundle as the plugin manager reports them; other user-installed and DSH experimental plugins remain. The owner may open every installed plugin at once, or set each plugin to none, all its methods, or a subset. There is no read/write distinction: a method is callable only where the live catalog and that share's own policy name it, on the resources the reader can see.
|
|
99
|
+
|
|
100
|
+
The Owner Gateway decides each call on the Session and Workspace it names and refuses a call whose target is missing or invalid. The viewer's Session list and workspace membership are trimmed to the source and the children that viewer owns. The page reads each Session's own answer from the reader's access snapshot, so a selection change never carries the previous Session's permission across. Unknown or unreadable modes fail closed. The Owner rechecks admission for source and child calls; revocation cancels the affected calls and streams, and a share whose admission narrows stops the shared Session's running turn. The page distinguishes authentication, access, expiry, stopped shares, offline owners, and transport failures, and retries only the failures classified as repeatable.
|
|
101
|
+
|
|
102
|
+
-----
|
|
103
|
+
|
|
104
|
+
<a id="understand-the-implementation"></a>
|
|
105
|
+
## Understand the implementation
|
|
106
|
+
|
|
107
|
+
<details>
|
|
108
|
+
<summary>Implementation internals — click to expand</summary>
|
|
109
|
+
|
|
110
|
+
The viewer page is the Owner's own Web shell. The Liveshare server fetches the Owner's rendered index document through an `asset` read and places the carrier script from [viewer-carrier.ts](../liveshare-protocol/src/viewer-carrier.ts) first in it. Shell assets, client plugin bundles, and the three exact top-level files the index references against the document base — `manifest.webmanifest`, `favicon.svg`, and `favicon-dark.svg` — arrive through the same read, from the Owner's frontend reader and client module registry, so the page runs every Owner plugin at the Owner's version. Source maps are refused on every asset path, and that check is the authoritative one: an `asset` read forwarded through the Liveshare server arrives here unread, so the Liveshare server's own same-named rule covers its page-resource route only. The served document also drops its manifest link, which a browser would otherwise fetch without credentials. The carrier converts Connection calls and Gateway streams into `POST {base}/__share/rpc` requests, and forwards the read-only page-origin owner routes the Liveshare server cannot answer — `/open-in-app/apps` and `/api/present.host` — through that channel instead of leaving them to the Liveshare server's tail. The Liveshare server supplies the authenticated actor outside the opaque body. The Owner's read handler dispatches each reader's calls and streams into its own Connection and Gateway as one Peer per share and reader, whose `share-viewer` principal carries the share and the server-asserted identity. The Gateway decides that Peer's calls, and the Session notifications it forwards to it, through [`dsh-api-remote-access`](../../api/remote-access/README.md) from the `share-viewer` policy this package registers: a served reader holds read roles on the shared Session, its own forks, and the Workspaces holding them, fork and write roles whose conditions apply the share's tier and its own fork switch, and nothing else; attachment upload rides the read roles. The read handler keeps the share-lifecycle refusals, Liveshare server authority refresh, cold Session preparation, and fork orchestration, reads the policy's write rules before it prepares or dispatches a prompt or stop, and disposes a reader's Peer when its grant ends, the share stops or expires, or a re-check refuses it. Preparing a share's source Session also starts when a reader asks for its page or opens a stream, so a host that restarted before that Session's agent was live still gains the actions it drives with; a share whose Session cannot be confined states that instead of the read-only fact. This package's browser face mounts the viewer surfaces when the carrier's `__DSH_LIVESHARE_VIEWER__` global is present and the Share action otherwise. The served index assigns the reader's own access snapshot to the global that every index sets to the owner baseline, and the page then follows the reader's `remoteAccess/follow` snapshot; CSS hiding is not authorization.
|
|
111
|
+
|
|
112
|
+
Fork requests bind the actor, share, source, operation identity, and completed prefix. A durable reservation and the recorded child let a retry of a recorded operation replay the same child; the owner's `SessionForkRequest` mints the child id, so a request interrupted after the child was created but before it was recorded forks again. Registry mutations are asynchronous and resolve only after locked read-modify-write and atomic publication; callers must await reservation, recording, and revocation. Cold activation uses the Host’s ordinary Agent lookup, with serial `agent/created` enforcement before queued input can run, not a Remote `session/prepare` endpoint. The child scope retains one fail-closed guard; reconnection replaces its enforcement installation, and releasing an old installation cannot remove its successor.
|
|
113
|
+
|
|
114
|
+
A reader's prompt reaches the Session as a `user-rpc` message whose `source.principal` names that reader, and the pre-step re-checks every entering message's viewer against the Relay's admission before it reaches the model. Execution is confined per turn: while any share over the Session is active, a turn whose admitted input names a share viewer runs the Host's confined replacements for the read and search surface (`read`, `read_image`, `glob`, `grep`, `present`), keeps the deployment's own definitions of the tools with no local file effect (`todo_write`, `skill`, `web_search`, `web_fetch`), admits the PTC transport `run_code` from the selected executor, and, when some share may write, its bounded `edit` and `write`. Every other tool is refused to that turn, and every path a permitted call declares is resolved and checked against the granted root. An owner-started turn keeps the Session's native tools until the last share stops or expires. The turn decision is Host memory only, recomputed for each turn and never appended to the Session log. Each operation re-reads the shares' current Relay grants and checks the resolved target against the granted root. A reader's stop is dispatched through the Gateway like a prompt: the `share-viewer` policy admits it while the share's tier is established and the Session is confined, and the owner's own Session controller stops whatever turn the Session is running, including one the owner started. Reads and writes preserve the normal write-observation policy. See the [LiveShare subsystem](../../../docs/subsystems/liveshare.md) for the execution rules.
|
|
115
|
+
|
|
116
|
+
| Owner | Source |
|
|
117
|
+
|---|---|
|
|
118
|
+
| Login, credential storage, and gateway lifetime | [share-host.ts](src/host/share-host.ts) |
|
|
119
|
+
| Share-management operations and their `liveshareShares` Remote | [share-operations.ts](src/host/share-operations.ts), [share-remote.ts](src/host/share-remote.ts) |
|
|
120
|
+
| Fork records and runtime enforcement | [fork-registry.ts](src/host/fork-registry.ts), [fork-enforcement.ts](src/host/fork-enforcement.ts), [shared-tools.ts](src/host/shared-tools.ts) |
|
|
121
|
+
| Page carrier, viewer surfaces, and served-page reads | [viewer-carrier.ts](../liveshare-protocol/src/viewer-carrier.ts), [client/index.ts](src/client/index.ts), [viewer-session-plugin.ts](src/client/viewer-session-plugin.ts), [viewer-assets.ts](src/host/viewer-assets.ts) |
|
|
122
|
+
| Shared identity and frame definitions | [protocol package](../liveshare-protocol/README.md) |
|
|
123
|
+
| Registration and socket-scoped request correlation | [registration-url.ts](src/owner-gateway/registration-url.ts), [pending-rpc.ts](src/owner-gateway/pending-rpc.ts) |
|
|
124
|
+
|
|
125
|
+
Registration declares the wire version and optional capabilities. A declared mismatch receives HTTP 426; there is no version translation. IPC requests use unique tokens bound to their original socket and worker generation; responses and cancellation match token, share id, and Liveshare server id. Unsupported requests receive a scoped refusal when they can be correlated.
|
|
126
|
+
|
|
127
|
+
The optional `share-access-state` frame and authenticated request-list response supply complete, versioned Liveshare server authority. The Host retains the Owner's selected mode separately and uses the narrower mode for execution. All complete request-list reads, including management reads, apply the same version and generation checks; missing authority invalidates admission. A request that first discovers revocation receives `403 viewer-not-authorized`, while other revoked work is cancelled. The `share-viewer` policy and `agent/pre-step` bind the receiving Session to the share's source or that actor's recorded child. Queued external input refreshes authority even after restart; a deleted share cannot authorize recovered Inbox input. See the [shared protocol reference](../liveshare-protocol/README.md) for snapshot fields.
|
|
128
|
+
|
|
129
|
+
Viewer streams belong to their opening actor. Notifications and control projections expose only the source and that actor’s children; interactive approvals and questions remain on the Host. `forkLineage` is a LiveShare-owned UI projection, not a grant. The per-Session grants of the reader's access snapshot decide whether the page offers prompt and stop, independently of display lineage.
|
|
130
|
+
|
|
131
|
+
The external Liveshare server's service, stores, OAuth provider, and deployment remain separately owned. Owner-only tests live here; tests that start both complete products remain with the upper Liveshare server integration.
|
|
132
|
+
|
|
133
|
+
</details>
|
|
134
|
+
|
|
135
|
+
-----
|
|
136
|
+
|
|
137
|
+
<a id="further-exploration"></a>
|
|
138
|
+
## Further Exploration
|
|
139
|
+
|
|
140
|
+
- [LiveShare subsystem](../../../docs/subsystems/liveshare.md)
|
|
141
|
+
- [Owner decision record](../../../.agents/notes/implemented/feature/2026-09-13-liveshare-protocol-and-owner-surfaces.md)
|
|
142
|
+
- [Web bundle](../../bundle/web-app/README.md)
|
|
143
|
+
|
|
144
|
+
-----
|
|
145
|
+
|
|
146
|
+
<a id="model-experience"></a>
|
|
147
|
+
## Model Experience
|
|
148
|
+
|
|
149
|
+
Indirectly, through the host driving viewer prompts into the shared Session, so a model request follows the viewer input that host forwards as that Session's ordinary user input.
|
|
150
|
+
|
|
151
|
+
#### KV Cache effect
|
|
152
|
+
|
|
153
|
+
Viewer prompts enter the shared Session as ordinary user input, so they extend the same cached prompt prefix the owner's own input extends; the bundle adds no request field, tool, or system-prompt text of its own.
|
|
154
|
+
|
|
155
|
+
## Known Limitations and Deferred Work
|
|
156
|
+
|
|
157
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
158
|
+
|
|
159
|
+
- Owner, viewer, and the Liveshare server require matching versions; cross-version compatibility is not established.
|
|
160
|
+
- The owner cannot refuse attachment uploads for an admitted viewer: a viewer that may read a Session may also attach files to it, independent of the tier and of the fork switch. This is an accepted risk.
|
|
161
|
+
- Viewer file operations are confined by a path check against the granted root, so a local process that swaps a directory inside the grant for a symlink between the check and the open can redirect them; directory-handle anchoring is deferred to a separate change. Viewer tools are limited to the confined read and search surface (`read`, `read_image`, `glob`, `grep`, `present`), the tools with no local file effect (`todo_write`, `skill`, `web_search`, `web_fetch`), the PTC transport `run_code`, and, at the write tier, bounded `edit` and `write`; `bash`, `pwsh`, `cua`, `plugin_manager`, the `schedule_*` tools, and no other name is granted. A `run_code` program is not bounded by the share: [Session tiers](#session-tiers) states what its program may reach.
|
|
162
|
+
- The viewer has no separate workspace-file editing interface and no DSH core management authority; an installed plugin the owner opens can still change what that plugin owns.
|
|
163
|
+
- `liveshareShares.addSessions` has no Share-dialog entry, and a viewer page reload returns to the share's first source; added sources are reached from the reader's Session list.
|
|
164
|
+
- All source Sessions of a share must belong to one Workspace; an addition from another Workspace, or one no Workspace lists, is refused.
|
|
165
|
+
- Endpoint capabilities enumerate installed plugins' Remote methods from the live Typert registry in [`shareable-catalog.ts`](src/host/shareable-catalog.ts); DSH core service namespaces are excluded. There is no sandbox around a method call and no read/write classification: granting a method trusts that installed plugin's code, which runs in the Host process. A selected method is callable by every authenticated share viewer on the resources the policy binds, across the `global`, `session`, and `workspace` resource kinds.
|
|
166
|
+
- The owner selects installed-plugin methods in the share panel through a global switch and per-plugin rows. The global switch is `none` (open nothing), `custom` (follow the per-plugin list), or `all` (open every method the live catalog offers). Each plugin is then off, all its methods, or a subset; a partial selection stores an explicit method list, so methods the catalog adds later stay closed until the owner saves again. Plugin rows use the package's localized title when one exists and otherwise fall back to the package segment or namespace; search and bounded scrolling keep a large catalog usable. The selection is share-wide: every admitted viewer may call a selected method on the resources the policy binds, and per-viewer method levels are not established. Method authorization is independent of the session tier; the core share roles still decide Session and Workspace calls. A selection naming a method the catalog no longer offers exposes nothing but stays stored until the owner saves again.
|
|
167
|
+
- A Workspace that stops holding a Session the reader can see leaves the reader's Workspace feed only at that Workspace's or the Workspace order's next change ([remote access limitation](../../api/remote-access/README.md#known-limitations-and-deferred-work)).
|
|
168
|
+
- Registry file locking prevents concurrent file writes from dropping durable entries, but each registry reads its own in-memory snapshot. Owner share-state updates and gateway ownership are not coordinated across Hosts; use one active Owner Host per home. This is not a multi-host authorization service.
|
|
169
|
+
- No runtime invariant companion is published: authorization is checked in the operations themselves, and this package has no separate invariant observer.
|
|
170
|
+
- A worker restart re-registers retained shares but does not replay viewer streams; viewers recover through their transport. Registration refusals 401, 403, 410, and 426 stop that share’s reconnect loop until something registers it again: republishing or changing its tier does, and so does storing a credential for that Liveshare server, which registers the shares that address left offline. A restore presents the credential this host holds for the share’s Liveshare server whatever this host’s own expiry read says, because the Liveshare server renews the login behind it and only the Liveshare server decides whether that credential still authorizes; a new share is still refused on that same local read.
|
|
171
|
+
- The access mode grants `view` admission, while effective fork/write authority comes from the share mode. Per-viewer execution levels and immediate cross-instance stop/cancellation completion are not established; cancellation cannot undo committed writes. A write-to-readonly snapshot denies later writes but does not promise immediate cancellation of a running child turn.
|
|
172
|
+
- Final assembled snapshot verification remains required before the feature is ready for release.
|
|
173
|
+
- On the viewer page, client reads that bypass the Connection carrier (deliverable reads, open-in-app, PDF assets, HMR events) reach the Liveshare server rather than the Owner; the index document's root-absolute manifest and icon links do not resolve under a Liveshare server prefix.
|
|
174
|
+
|
|
175
|
+
<a id="dev-note"></a>
|
|
176
|
+
### Dev Note
|
|
177
|
+
|
|
178
|
+
<details>
|
|
179
|
+
<summary>Working context for maintainers — click to expand</summary>
|
|
180
|
+
|
|
181
|
+
None.
|
|
182
|
+
|
|
183
|
+
</details>
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "通过独立的 Liveshare 服务端分享 DSH 会话,提供已验证的所有者登录、查看者控制和受限执行。"
|
|
3
|
+
kind: "package-bundle"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @deepseek-ai/dsh-experimental-liveshare
|
|
7
|
+
|
|
8
|
+
[English](README.md) | 中文
|
|
9
|
+
|
|
10
|
+
## 概述
|
|
11
|
+
|
|
12
|
+
通过常规 DSH 浏览器界面向同事分享会话。所有者选择查看或受限写入,并单独决定是否允许分叉会话;所有者主机执行这些选择。附件上传属于分享本身:查看者可见的会话都可以接收文件。这个可选组合包增加所有者登录、分享控件、出站网关,以及所有者自身 Web 页面中的查看页界面。默认 Web profile 不包含它。单独部署的 Liveshare 服务端验证查看者并传输请求;其 OAuth、数据库、路由和部署实现不属于本包。
|
|
13
|
+
|
|
14
|
+
## 目录
|
|
15
|
+
|
|
16
|
+
- [使用本包](#use-this-package)
|
|
17
|
+
- [理解实现](#understand-the-implementation)
|
|
18
|
+
- [延伸阅读](#further-exploration)
|
|
19
|
+
- [模型体验](#model-experience)
|
|
20
|
+
- [已知限制与后续工作](#known-limitations-and-deferred-work)
|
|
21
|
+
- [开发备注](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## 使用本包
|
|
27
|
+
|
|
28
|
+
### Profile 与构建要求
|
|
29
|
+
|
|
30
|
+
manifest(元数据清单)声明可安装的 `dsh.bundle` 层和浏览器端入口。该组合包在被 profile 启用前保持隐藏,见[默认可见性与启用](#default-visibility-and-enabling);受支持的应用仍通过 `dsh --profile` 启动。
|
|
31
|
+
|
|
32
|
+
Owner、查看页和 Liveshare 服务端必须使用匹配的协议版本。构建包含 Owner 网关进程;查看页没有单独的构建。包版本、导出和发布内容由 [package.json](package.json) 声明。
|
|
33
|
+
|
|
34
|
+
<a id="default-visibility-and-enabling"></a>
|
|
35
|
+
|
|
36
|
+
### 默认可见性与启用
|
|
37
|
+
|
|
38
|
+
dsh 安装会把本包作为运行时依赖一起安装,但没有任何随发行版交付的 profile 选中它的组合包,因此它的插件一条都不会运行,插件管理器既不会在**内置插件配置**里列出它,也不会在**实验性插件**(含**更多**页)里列出。组合包 ID 仍可按 ID 打开,因此按 ID 打开组合包的页面仍能到达它的详情。
|
|
39
|
+
|
|
40
|
+
要启用它,把它的一条条目插入当前 profile 的 patch 文件 `$DSH_HOME/profiles/<profile>/cordis.patch.yml`。该文件是一个 YAML 序列的 Loader patch;这一条就是组合包自己的 [patch](cordis.patch.yml) 插入的条目,其中允许使用 `!!js` 表达式:
|
|
41
|
+
|
|
42
|
+
```yaml
|
|
43
|
+
- insert:
|
|
44
|
+
- id: liveshare-share-host
|
|
45
|
+
name: '@deepseek-ai/dsh-experimental-liveshare'
|
|
46
|
+
config:
|
|
47
|
+
ownerIdentityProvider: <provider-id>
|
|
48
|
+
ownerIdentityTenant: <tenant-id>
|
|
49
|
+
ownerIdentitySubject: <subject-id>
|
|
50
|
+
allowedSubjectIds: []
|
|
51
|
+
ownerStateFile: /path/to/owner-shares.json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
把每个 `<...>` 占位符换成部署自己的值:身份 provider、tenant 与 subject 是该部署的 Liveshare 服务端配置使用的值,示例中的都是占位符而非真实身份。环境层同样可用:在 `$DSH_HOME/.env` 里设置 `LIVESHARE_*`,并保留组合包自己的 `!!js process.env.…` 表达式。Liveshare 服务端地址不属于这里的配置:首次使用时由所有者在分享弹窗里填写,见下文的所有者配置。
|
|
55
|
+
|
|
56
|
+
profile 也可以改为选中组合包:在 `$DSH_HOME/profiles/<profile>/package.json` 的 `dsh.profile.bundles` 里加入 `"@deepseek-ai/dsh-experimental-liveshare"`;卡片可见后,卡片上的开关执行的就是这次写入。
|
|
57
|
+
|
|
58
|
+
两条路线都只在重新组合时生效。profile 的 HMR 行开启时,改动在 profile 被重新读取后应用;没有 HMR 时,等下一次 `dsh` 启动才应用。只要组合包声明的行有一条在运行,它的卡片就会出现在**实验性插件**下,也出现在**更多**页。删除这些条目、把它们置为 disabled,或把组合包从 `dsh.profile.bundles` 移除,都会停止这些行,卡片也随之从两个列表消失。
|
|
59
|
+
|
|
60
|
+
### 所有者配置
|
|
61
|
+
|
|
62
|
+
| 变量 | 默认值 | 含义 |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| `LIVESHARE_OWNER_PROVIDER_ID` / `LIVESHARE_OWNER_TENANT_ID` / `LIVESHARE_OWNER_SUBJECT_ID` | 未设置 | 用于旧主体匹配的所有者身份;不替代 Liveshare 服务端签发的凭据 |
|
|
65
|
+
| `LIVESHARE_OWNER_DISPLAY_NAME` | 未设置 | 配置身份的显示标签 |
|
|
66
|
+
| `LIVESHARE_ALLOWED_SUBJECTS` | 空 | 分享访问规则之外的部署级主体允许列表 |
|
|
67
|
+
| `LIVESHARE_OWNER_STATE_FILE` | `$DSH_HOME/liveshare/owner-shares.json` | 保存分享元数据、已保存的 Liveshare 服务端地址、实例身份和管理 token |
|
|
68
|
+
| `LIVESHARE_OWNER_CREDENTIAL_FILE` | 状态文件旁的 `owner-credential.json` | 保存绑定至签发它的 Liveshare 服务端的凭据 |
|
|
69
|
+
|
|
70
|
+
Liveshare 服务端地址在首次使用时设置:在分享弹窗的地址输入框里填写并保存。保存的地址持久化在 owner state 文件中,之后创建的分享都发布到该地址;已经等待注册的发布在注册信息、持久记录和返回链接中保留起始服务端地址,已有分享保留记录中的 Liveshare 服务端地址。经分享管理 Remote 清除保存的地址后,这个宿主就没有地址可用——此时创建分享会明确要求先保存地址,而不是回退到某个部署默认值。读者看到的分享者名称来自 Relay 验证凭据上的显示名,本地配置不能覆盖它;凭据只带主体时显示主体标签。提供方应用密钥属于 Liveshare 服务端,不属于这里的配置。
|
|
71
|
+
|
|
72
|
+
### 登录与管理分享
|
|
73
|
+
|
|
74
|
+
分享对话框在 Owner 上创建短期授权事务。弹窗只向预期窗口、来源和事务返回一次性代码。Owner 使用私有校验值兑换代码并保存绑定该 Liveshare 服务端的凭据;正常浏览器登录流程不会把该凭据存入浏览器存储或 URL。过期、取消、重放或不匹配的事务均拒绝。代码兑换期间更改 Liveshare 服务端,包括切换后再切回,会在保存凭据前拒绝登录。存储提交后,探测和分享认领保留该操作的 Liveshare 服务端与凭据身份。未验证身份时禁止发布,Liveshare 服务端不支持身份绑定时也一样。
|
|
75
|
+
|
|
76
|
+
分享管理本身走 `liveshareShares` Typert Remote:分享列表、创建、停止、档位与分叉开关变更、端点选择、Liveshare 服务端状态、所有者身份、Liveshare 服务端保存的审计以及两项服务端检查都是挂载命名空间上的方法。登录往返与凭据保存是所有者页面仍然调用的仅有的同源 HTTP 路由。`liveshareShares.addSessions` 可以向已有分享增加更多源会话,这些源会话沿用该分享的 ACL、档位、有效期、fork 开关与暴露的插件端点;所有源会话必须属于同一个工作区,Host 会拒绝无法放进该工作区的源。分享对话框暂不提供该入口,调用方直接使用 Remote。
|
|
77
|
+
|
|
78
|
+
所有者通过组织链接接纳查看者;部署的 `LIVESHARE_ALLOWED_SUBJECTS` 作用于每份分享,把组织链接分享的准入收窄到它列出的主体。已存储的 `selected` 或 `approval` 分享保留原有 ACL 与访问摘要,弹窗不再创建这类分享;`liveshareShares.create` 的 `accessMode` 与 `allowedSubjectIds` 只保留给这些记录与直接 Remote 调用方。管理分享页面列出保存的链接、档位、可用状态及 Liveshare 服务端的审计响应,并可修改分享档位、开关「允许分叉会话」以及停止分享。失败操作显示错误;界面重新读取 Owner 响应,不把点击本身当作成功。分享弹窗也能修改已有分享:档位、分叉开关与插件端点在弹窗里选择,由滚动区之外的一次保存一并提交,并在保存后回读 Owner 的记录;未保存的选择会明确标出,关闭前先提示它们会被丢弃。
|
|
79
|
+
|
|
80
|
+
### 会话档位
|
|
81
|
+
|
|
82
|
+
<a id="session-tiers"></a>
|
|
83
|
+
|
|
84
|
+
| 档位 | 查看者操作 | 执行限制 |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `view` | 向源会话发送提示词,并停止其正在运行的轮次 | 挂在会话上的只读沙箱,只约束分享查看者发起的轮次:该轮次只能使用读取与检索面(`read`、`read_image`、`glob`、`grep`、`present`)、无本地文件副作用的工具(`todo_write`、`skill`、`web_search`、`web_fetch`),以及 PTC 传输工具 `run_code`;每次调用声明的每个路径都按获授工作区检查 |
|
|
87
|
+
| `write` | 还可修改该工作区内的文件 | 有上限的可写沙箱:读取与检索面加上有界 `edit` 与 `write`,同样作用于查看者发起的轮次 |
|
|
88
|
+
|
|
89
|
+
两档都会驱动共享会话,区别在于能否写入。沙箱挂在会话上,只要该会话还有分享活跃就会安装,但它只约束分享查看者发起的轮次:所有者自己发起的轮次保留会话原生工具,包括 `bash` 与不受限的文件工具;所有者在查看者轮次中追加的输入仍留在该受限轮次内。该判定只存在于 Host 内存、按轮次重算,不写入会话日志;所有分享停止或全部过期后执行层被释放,会话恢复自己的工具。分叉会话不是一个档位:分享自带独立开关,与档位无关;被允许的查看者可从已完成的源前缀分叉出会话,分叉会话运行在只读上限下;分享处于 `write` 档时改为受约束的写上限。
|
|
90
|
+
|
|
91
|
+
携带多个源会话的分享仍以第一个源会话作为 Relay 注册与页面目标。新增的源会话由 `share-viewer` 策略绑定,读者的会话列表因此会提供它们;页面刷新后仍打开第一个源会话。停止该分享会结束全部源会话,并撤销它们授权过的 fork。
|
|
92
|
+
|
|
93
|
+
**共享出去的 PTC 程序并不受分享沙箱约束。** 两档都准入 `run_code`,因为查看者可能需要用程序调用工具;但程序运行在所有者自己的常驻文件策略下,而不是分享档位下:它可以读写共享工作区之外的文件,档位不会收窄它。查看者发起的嵌套 `tools.*` 调用仍走与其它调用相同的守卫与路径检查,因此 `bash` 仍被拒绝、文件工具仍限制在获授范围内。在 PTC 可以被收窄到分享范围之前,只分享给可信任的人。
|
|
94
|
+
|
|
95
|
+
附件上传既不是档位,也不属于分叉开关:它跟随可见性。无论分享处于哪个档位、是否允许分叉,已准入的查看者都可以向共享会话以及自己通过本分享分叉出的会话上传附件。所有者没有单独的附件开关。
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
可分享给 viewer 的方法是已安装插件注册的 Remote 方法,由 Host 的 Typert registry 在 [`shareable-catalog.ts`](src/host/shareable-catalog.ts) 动态枚举。DSH 核心服务命名空间被排除([`EXCLUDED_SHARE_NAMESPACES`](src/host/shareable-catalog.ts) 列出这些命名空间),插件管理器报告为核心 profile bundle 组件的插件也被排除;其他用户安装的插件和 DSH 实验性插件保留。所有者可以一次性开放全部已安装插件,也可以按插件设为不可用、全部方法或部分方法。这里没有读写之分:只有当前目录与该 share 的策略同时点名某个方法、且资源对读者可见时,该方法才可被调用。
|
|
99
|
+
|
|
100
|
+
Owner Gateway 按调用指明的 Session 与工作区判定每次调用,并拒绝目标缺失或无效的调用。查看页的会话列表和工作区成员裁剪为源会话及该查看者自己的分叉会话。页面从读者的访问快照读取每个会话自己的答案,因此切换选择不会把前一会话的权限带过去。未知或无法读取的模式默认拒绝。Owner 为源会话与分叉会话调用重新检查准入;撤权会取消受影响的调用和流,分享准入收窄时还会停止共享会话正在运行的轮次。页面区分认证、访问、过期、停止分享、所有者离线和传输失败,仅重试明确分类为可重试的失败。
|
|
101
|
+
|
|
102
|
+
-----
|
|
103
|
+
|
|
104
|
+
<a id="understand-the-implementation"></a>
|
|
105
|
+
## 理解实现
|
|
106
|
+
|
|
107
|
+
<details>
|
|
108
|
+
<summary>实现内部机制 — 点击展开</summary>
|
|
109
|
+
|
|
110
|
+
查看页就是 Owner 自己的 Web shell。Liveshare 服务端通过 `asset` 读取取得 Owner 渲染好的 index 文档,并把 [viewer-carrier.ts](../liveshare-protocol/src/viewer-carrier.ts) 生成的载体脚本放在文档最前面。Shell 资源、客户端插件 bundle,以及 index 相对文档基准引用的三个确切顶层文件(`manifest.webmanifest`、`favicon.svg`、`favicon-dark.svg`)都经同一读取取得,来自 Owner 的前端读取服务和客户端模块注册表,因此页面以 Owner 的版本运行 Owner 的全部插件。任何 asset 路径上的 source map 都被拒绝,且该判定是权威的:经 Liveshare 服务端转发的 `asset` 读取会原样到达这里,因此 Liveshare 服务端侧的同名规则只覆盖它自己的页面资源路由;被服务的文档还会去掉自己的 manifest 链接,否则浏览器会不带凭据地抓取它。载体把 Connection 调用和 Gateway 流转换为 `POST {base}/__share/rpc` 请求,并把 Liveshare 服务端无法作答的只读页面源 Owner 路由(`/open-in-app/apps` 与 `/api/present.host`)也经该通道转发,而不是留给 Liveshare 服务端尾部。Liveshare 服务端在不透明请求体之外提供已认证主体。Owner 读取处理器把每位读者的调用和流以「每个分享、每位读者一个 Peer」分派进自己的 Connection 与 Gateway,该 Peer 的 `share-viewer` principal 携带分享与服务端断言的身份。Gateway 依据本包注册的 `share-viewer` 策略,经 [`dsh-api-remote-access`](../../api/remote-access/README.zh.md) 判定该 Peer 的调用以及转发给它的会话通知:受服务的读者持有共享会话、其自己的 fork 及包含它们的工作区上的读取角色,持有条件按分享档位与其自身 fork 开关判定的 fork 与写入角色,此外别无授权;附件上传随读取角色生效。读取处理器保留分享生命周期拒绝、Liveshare 服务端授权刷新、冷会话准备和 fork 编排,在准备或分派提示词与停止之前读取策略的写入规则,并在授权结束、分享停止或过期、或复检拒绝时释放读者的 Peer。读者索取页面或打开流时也会开始准备该分享的源会话,因此宿主重启时该会话的 agent 尚未存活也能补上驱动所需的层;无法被 confine 的分享会如实说明该状态,而不再声明只读。存在载体写入的 `__DSH_LIVESHARE_VIEWER__` 全局变量时,本包的浏览器端挂载查看页界面,否则挂载分享操作。读者收到的 index 把读者自己的访问快照赋给每个 index 设为所有者基线的同一全局变量,页面随后跟随读者的 `remoteAccess/follow` 快照;CSS 隐藏不构成授权。
|
|
111
|
+
|
|
112
|
+
Fork 请求绑定主体、分享、源会话、操作身份和已完成前缀。持久化预留记录与已记录的分叉会话使重试已记录的操作时重放同一分叉会话;owner 的 `SessionForkRequest` 自己生成分叉会话 id,因此在分叉会话已创建、但尚未记录时中断的请求会再次 fork。注册表变更为异步操作,仅在加锁的读取、修改与原子发布后完成;调用方必须等待预留、记录与撤销。冷态激活使用 Host 常规 Agent lookup,由串行 `agent/created` 在排队输入运行前安装限制,不使用 Remote `session/prepare` 端点。分叉会话作用域保留单个默认拒绝的 guard;重连替换其限制安装,释放旧安装不会移除继任。
|
|
113
|
+
|
|
114
|
+
读者的提示词以 `user-rpc` 消息进入会话,其 `source.principal` 指明该读者;pre-step 在每条进入消息到达模型前,按 Relay 的准入重新检查其查看者。执行按轮次受限:只要有分享处于活跃状态,已准入输入中带有 share-viewer principal 的轮次就运行 Host 挂载的读取与检索面(`read`、`read_image`、`glob`、`grep`、`present`)受限替代、保留无本地文件副作用工具(`todo_write`、`skill`、`web_search`、`web_fetch`)的原生定义、放行选定执行器提供的 PTC 传输工具 `run_code`,以及(当某个分享允许写入时)有界 `edit` 与 `write`。其余所有工具对该轮次一律拒绝,且每次允许的调用声明的每个路径都会解析并按获授根目录检查。所有者自己发起的轮次保留会话原生工具,直到最后一个分享停止或过期。该轮次判定只存在于 Host 内存,按轮次重算,不写入会话日志。每次操作都会重新读取分享当前的 Relay 授权,并按获授根目录检查解析后的目标。读者的停止与提示词一样经 Gateway 分派:`share-viewer` 策略在分享档位确立且会话受沙箱限制时放行,随后由所有者自己的会话控制器停止该会话当前运行的轮次,包括所有者发起的轮次。读写保留正常写入观察策略。执行规则见 [LiveShare 子系统](../../../docs/subsystems/liveshare.zh.md)。
|
|
115
|
+
|
|
116
|
+
| 职责 | 源码 |
|
|
117
|
+
|---|---|
|
|
118
|
+
| 登录、凭据存储及网关生命周期 | [share-host.ts](src/host/share-host.ts) |
|
|
119
|
+
| 分享管理操作及其 `liveshareShares` Remote | [share-operations.ts](src/host/share-operations.ts), [share-remote.ts](src/host/share-remote.ts) |
|
|
120
|
+
| Fork 记录与运行时限制 | [fork-registry.ts](src/host/fork-registry.ts)、[fork-enforcement.ts](src/host/fork-enforcement.ts)、[shared-tools.ts](src/host/shared-tools.ts) |
|
|
121
|
+
| 页面载体、查看页界面和页面资源读取 | [viewer-carrier.ts](../liveshare-protocol/src/viewer-carrier.ts)、[client/index.ts](src/client/index.ts)、[viewer-session-plugin.ts](src/client/viewer-session-plugin.ts)、[viewer-assets.ts](src/host/viewer-assets.ts) |
|
|
122
|
+
| 共享身份和帧定义 | [协议包](../liveshare-protocol/README.zh.md) |
|
|
123
|
+
| 注册与 socket 范围请求关联 | [registration-url.ts](src/owner-gateway/registration-url.ts)、[pending-rpc.ts](src/owner-gateway/pending-rpc.ts) |
|
|
124
|
+
|
|
125
|
+
注册声明线路版本与可选能力。声明的版本不匹配时返回 HTTP 426;不做版本转换。IPC 请求使用绑定原始 socket 和 worker generation 的唯一 token;响应与取消匹配 token、分享 ID 和 Liveshare 服务端 ID。可关联的不支持请求会收到作用域内拒绝。
|
|
126
|
+
|
|
127
|
+
可选 `share-access-state` 帧及鉴权请求列表响应提供完整、带版本的 Liveshare 服务端授权。Host 独立保留 Owner 选择的模式,执行时使用两者中较窄的模式。所有完整请求列表读取,包括管理读取,都应用同一版本与 generation 校验;缺失授权使准入失效。首次发现撤权的请求收到 `403 viewer-not-authorized`,其它已撤权工作被取消。`share-viewer` 策略及 `agent/pre-step` 将接收 Session 绑定到分享源会话或该主体记录的分叉会话。排队外部输入在重启后仍刷新授权;已删除分享不能授权恢复的 Inbox 输入。快照字段见 [共享协议参考](../liveshare-protocol/README.zh.md)。
|
|
128
|
+
|
|
129
|
+
查看流属于打开它的主体。通知与控制投影只暴露源会话及该主体的分叉会话;交互审批与提问留在 Host。`forkLineage` 是 LiveShare 自有 UI 投影,不是授权。读者访问快照中的逐会话 grant 独立于展示谱系,决定页面是否提供提示词与停止。
|
|
130
|
+
|
|
131
|
+
外部 Liveshare 服务端的服务、存储、OAuth 提供方和部署保持独立归属。仅涉及 Owner 的测试位于本包;启动两端完整产品的测试留在上层 Liveshare 服务端集成中。
|
|
132
|
+
|
|
133
|
+
</details>
|
|
134
|
+
|
|
135
|
+
-----
|
|
136
|
+
|
|
137
|
+
<a id="further-exploration"></a>
|
|
138
|
+
## 延伸阅读
|
|
139
|
+
|
|
140
|
+
- [LiveShare 子系统](../../../docs/subsystems/liveshare.zh.md)
|
|
141
|
+
- [Owner 决策记录](../../../.agents/notes/implemented/feature/2026-09-13-liveshare-protocol-and-owner-surfaces.zh.md)
|
|
142
|
+
- [Web 组合包](../../bundle/web-app/README.zh.md)
|
|
143
|
+
|
|
144
|
+
-----
|
|
145
|
+
|
|
146
|
+
<a id="model-experience"></a>
|
|
147
|
+
## 模型体验
|
|
148
|
+
|
|
149
|
+
间接触达:host 把 viewer 的 prompt 驱动进共享会话,模型请求因而承载该 host 以会话普通用户输入转发的 viewer 内容。
|
|
150
|
+
|
|
151
|
+
#### KV Cache 影响
|
|
152
|
+
|
|
153
|
+
viewer 的 prompt 以普通用户输入进入共享会话,因此扩展的是与所有者自身输入相同的缓存 prompt 前缀;本组合包不增加任何请求字段、工具或系统提示文本。
|
|
154
|
+
|
|
155
|
+
## 已知限制与后续工作
|
|
156
|
+
|
|
157
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
158
|
+
|
|
159
|
+
- Owner、查看页和 Liveshare 服务端需要匹配版本;尚未建立跨版本兼容保证。
|
|
160
|
+
- 所有者无法拒绝已准入查看者的附件上传:能读取某条会话的查看者也可以向它附加文件,与档位和分叉开关无关。这是已接受的风险。
|
|
161
|
+
- 查看者的文件操作按获授根目录做路径检查,若本地进程在检查与打开之间把获授范围内的目录换成符号链接,读写可能被改指别处;目录句柄锚定留待单独变更引入。查看者工具仅限受限的读取与检索面(`read`、`read_image`、`glob`、`grep`、`present`)、无本地文件副作用的工具(`todo_write`、`skill`、`web_search`、`web_fetch`)、PTC 传输工具 `run_code`,以及 write 档下的有界 `edit` 与 `write`;不授予 `bash`、`pwsh`、`cua`、`plugin_manager`、`schedule_*` 及其他任何未列出的工具。`run_code` 程序不受分享范围约束,[会话档位](#session-tiers) 一节说明其程序可以触及什么。
|
|
162
|
+
- 查看页没有独立工作区文件编辑界面,也没有 DSH 核心管理权限;所有者开放的已安装插件方法仍可改变该插件自己拥有的状态。
|
|
163
|
+
- `liveshareShares.addSessions` 没有分享对话框入口,查看页刷新后会回到分享的第一个源会话;新增源会话需从读者的会话列表进入。
|
|
164
|
+
- 一条分享的所有源会话必须属于同一个工作区;来自其他工作区、或不属于任何工作区的源会被拒绝。
|
|
165
|
+
- 端点能力从 Typert registry 枚举已安装插件的 Remote 方法(见 [`shareable-catalog.ts`](src/host/shareable-catalog.ts)),DSH 核心服务命名空间被排除。方法调用不经过沙箱,也没有读写分类:开放一个方法即信任该已安装插件的代码,它在 Host 进程中执行。被选中的方法会在 policy 绑定的资源上被任意已认证分享读者调用,覆盖 `global`、`session`、`workspace` 三种资源种类。
|
|
166
|
+
- owner 在分享面板里通过全局开关和按插件行选择已安装插件的方法。全局开关为“不可用”(全部关闭)、“自定义”(按插件列表)或“全部允许”(开放当前目录全部方法)。每个插件再设为不可用、全部方法或部分方法;部分选择保存显式方法列表,因此目录之后新增的方法不会自动开放,直到 owner 再次保存。插件行优先显示包内本地化名称,取不到时回退到包名末段或 namespace;搜索与限高滚动让大目录仍可操作。选择是分享级的:每位已准入查看者都可以在 policy 绑定的资源上调用被选中的方法,尚未建立逐查看者方法级别。方法授权独立于会话档位,Session 与 Workspace 调用仍由核心分享角色决定。目录不再提供的方法即使留在记录里也不暴露。
|
|
167
|
+
- 工作区不再包含读者可见的会话后,要到该工作区或工作区顺序下次变化时才离开读者的工作区订阅([remote access 限制](../../api/remote-access/README.zh.md#known-limitations-and-deferred-work))。
|
|
168
|
+
- 注册表文件锁防止并发文件写入丢失持久条目,但每个注册表读取自身内存快照。多个 Host 之间不协调 Owner 分享状态更新与网关归属;每个 home 只使用一个活动 Owner Host。这不是多宿主授权服务。
|
|
169
|
+
- 不发布运行时 invariant 配套模块:授权在操作本身检查,本包没有单独的 invariant 观察器。
|
|
170
|
+
- Worker 重启会重新注册保留分享,但不重放查看流;查看者通过传输层恢复。注册被 401、403、410 或 426 拒绝时,该分享的重连就此停止,直到有别的操作把它重新注册:重新发布或改档位都会重新注册,为该 Liveshare 服务端存入凭据也会,它会把该地址下未在线的分享重新注册。恢复分享时出示的是本机为该分享所属 Liveshare 服务端保存的凭据,与本机自己对凭据过期的判断无关,因为 Liveshare 服务端会在背后为登录续期,凭据是否仍然授权只由 Liveshare 服务端决定;新建分享时仍按本机这一判断拒绝。
|
|
171
|
+
- 访问档位授予 `view` 准入,有效 fork/write 权限来自分享模式。尚未建立逐查看者执行级别或立即跨实例停止/取消完成保证;取消不能撤回已提交写入。写入降为只读的快照会拒绝后续写入,但不承诺立即取消正在运行的分叉会话轮次。
|
|
172
|
+
- 功能达到发布条件前,仍须完成最终装配快照验证。
|
|
173
|
+
- 在查看页上,绕过 Connection 载体的客户端读取(交付物读取、open-in-app、PDF 资源、HMR 事件)到达的是 Liveshare 服务端而不是 Owner;index 文档中以根路径开头的 manifest 和图标链接在 Liveshare 服务端前缀下无法解析。
|
|
174
|
+
|
|
175
|
+
<a id="dev-note"></a>
|
|
176
|
+
### 开发备注
|
|
177
|
+
|
|
178
|
+
<details>
|
|
179
|
+
<summary>维护者工作上下文 — 点击展开</summary>
|
|
180
|
+
|
|
181
|
+
无。
|
|
182
|
+
|
|
183
|
+
</details>
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Opt-in Liveshare owner bundle: mount the same-origin share APIs and their
|
|
2
|
+
# browser Session-header action. Shipped profiles do not include this layer.
|
|
3
|
+
- insert:
|
|
4
|
+
- id: liveshare-share-host
|
|
5
|
+
name: '@deepseek-ai/dsh-experimental-liveshare'
|
|
6
|
+
config:
|
|
7
|
+
ownerIdentityProvider: !!js process.env.LIVESHARE_OWNER_PROVIDER_ID
|
|
8
|
+
ownerIdentityTenant: !!js process.env.LIVESHARE_OWNER_TENANT_ID
|
|
9
|
+
ownerIdentitySubject: !!js process.env.LIVESHARE_OWNER_SUBJECT_ID
|
|
10
|
+
ownerIdentityDisplayName: !!js process.env.LIVESHARE_OWNER_DISPLAY_NAME
|
|
11
|
+
allowedSubjectIds: !!js (process.env.LIVESHARE_ALLOWED_SUBJECTS ?? '').split(',').map((value) => value.trim()).filter((value) => value !== '')
|
|
12
|
+
ownerStateFile: !!js process.env.LIVESHARE_OWNER_STATE_FILE
|
|
13
|
+
ownerCredentialFile: !!js process.env.LIVESHARE_OWNER_CREDENTIAL_FILE
|
package/icon.svg
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect x="5.5" y="8.5" width="25" height="17" rx="2.6" fill="url(#a)" fill-opacity="0.85" />
|
|
3
|
+
<path d="M9.5 22.5V12.5H17.5V22.5H9.5Z" fill="#FFFFFF" fill-opacity="0.9" />
|
|
4
|
+
<path d="M21 15.2L25.5 12.6V23.4L21 20.8V15.2Z" fill="#45D9E7" />
|
|
5
|
+
<circle cx="28.5" cy="9.5" r="3.2" fill="#45D9E7" />
|
|
6
|
+
<defs>
|
|
7
|
+
<linearGradient id="a" x1="18" y1="8.5" x2="18" y2="25.5" gradientUnits="userSpaceOnUse">
|
|
8
|
+
<stop stop-color="#7CB7FF" />
|
|
9
|
+
<stop offset="1" stop-color="#145AF3" />
|
|
10
|
+
</linearGradient>
|
|
11
|
+
</defs>
|
|
12
|
+
</svg>
|