From cf394f56fece0b4d1abe59a1bc27dde0fa26e4c4 Mon Sep 17 00:00:00 2001 From: shanyuhai123 <864299347@qq.com> Date: Wed, 21 Oct 2026 08:25:43 +0800 Subject: [PATCH] =?UTF-8?q?feat(buddy):=20=E5=AE=8C=E5=96=84=E7=BD=91?= =?UTF-8?q?=E7=BB=9C=E6=9D=83=E9=99=90=E4=B8=8E=E7=A9=BA=E9=97=B4=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E6=8E=88=E6=9D=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__tests__/network-permissions.e2e.mjs | 158 +++++++++++ .../__tests__/localChatIpcLifecycle.spec.ts | 28 +- .../electron/main/app/DesktopRuntimeHost.ts | 7 + .../electron/main/browser/BrowserHost.ts | 21 +- .../browser/BrowserNetworkAuthorization.ts | 74 +++++ .../main/browser/BrowserPageSession.ts | 4 + .../main/browser/BrowserSecurityPolicy.ts | 44 ++- .../BrowserNetworkAuthorization.spec.ts | 174 ++++++++++++ .../browser/__tests__/browserHostFixture.ts | 1 + .../registerBrowserDesktopIpc.spec.ts | 2 +- .../__tests__/registerBrowserHostRpc.spec.ts | 9 +- .../main/browser/registerBrowserDesktopIpc.ts | 3 +- .../main/browser/registerBrowserHostRpc.ts | 48 ++-- .../electron/main/config/LexoraConfigStore.ts | 19 +- .../__tests__/networkPermissions.spec.ts | 67 +++++ apps/buddy/electron/main/local-chat/spaces.ts | 4 +- .../electron/main/network/HostWebNetwork.ts | 18 +- .../electron/main/network/WebRenderHost.ts | 10 +- .../network/__tests__/HostWebNetwork.spec.ts | 9 +- .../__tests__/networkAuthorization.spec.ts | 110 ++++++++ .../__tests__/requestThroughHost.spec.ts | 82 ++++++ .../main/network/registerWebHostRpc.ts | 16 +- .../main/network/requestThroughHost.ts | 7 +- .../electron/main/spaceDirectorySelections.ts | 10 + .../electron/shared/desktopApiSchemas.ts | 4 +- .../windows/__tests__/fileConsumers.spec.ts | 2 +- apps/buddy/service/src/BuddyService.ts | 2 + .../buddyService.integration.spec.ts | 13 +- .../__tests__/mutationConcurrencyFixture.ts | 1 + .../src/agent/extensions/BuddyCapability.ts | 2 + .../__tests__/toolPolicyExtension.spec.ts | 59 ---- .../createBuddySessionExtensions.ts | 22 ++ .../BuddySessionBlueprintService.spec.ts | 11 +- .../service/src/approvals/ApprovalService.ts | 42 ++- .../src/approvals/approvalAuthorization.ts | 4 + .../src/approvals/registerApprovalRpc.ts | 2 +- .../src/approvals/toolClassification.ts | 1 + .../service/src/browser/BrowserHostClient.ts | 27 +- .../__tests__/BrowserHostClient.spec.ts | 2 +- .../service/src/browser/browserExtension.ts | 26 +- .../src/browser/browserToolContract.ts | 2 +- .../src/createBuddyCapabilityFactory.ts | 3 +- .../service/src/events/RunEventProjector.ts | 2 +- .../networkAuthorizationContext.spec.ts | 122 ++++++++ .../network/networkAuthorizationContext.ts | 127 +++++++++ .../permissions/NetworkPermissionsClient.ts | 25 ++ .../src/permissions/PermissionEngine.ts | 8 +- .../permissions/ToolAuthorizationService.ts | 103 +++++-- .../ToolAuthorizationService.spec.ts | 167 ++++++++++- .../__tests__/shellFileDeletion.spec.ts | 14 +- .../src/permissions/permissionContract.ts | 3 + .../__tests__/shellNetworkFeedback.spec.ts | 17 ++ .../service/src/sandbox/shellCapability.ts | 2 +- .../service/src/spaces/SpaceFileService.ts | 24 +- apps/buddy/service/src/spaces/SpaceService.ts | 29 +- .../spaces/__tests__/SpaceFileService.spec.ts | 53 +++- .../src/spaces/__tests__/SpaceService.spec.ts | 57 +++- .../service/src/web/WebCapabilityService.ts | 7 + apps/buddy/service/src/web/WebHostClient.ts | 25 +- .../__tests__/WebCapabilityService.spec.ts | 18 ++ apps/buddy/service/src/web/webExtension.ts | 19 +- .../shared/browser/browserPreferences.ts | 7 + .../shared/network/networkAuthorization.ts | 32 +++ .../__tests__/featureDiscovery.spec.ts | 11 + .../shared/onboarding/featureDiscovery.ts | 2 + .../__tests__/networkPermissions.spec.ts | 100 +++++++ .../permissions/approvalReviewPayload.ts | 42 ++- .../shared/permissions/networkPermissions.ts | 142 ++++++++++ .../permissions/networkPermissionsRpc.ts | 11 + .../shared/permissions/safeNetworkRegex.ts | 194 +++++++++++++ apps/buddy/shared/spaces/spaceApi.ts | 20 +- .../src/app/bootstrap/DesktopAppProvider.vue | 6 +- .../src/app/workbench/FileOperationService.ts | 4 +- .../__tests__/FileOperationService.spec.ts | 23 +- .../buddy/src/i18n/locales/en-US/approvals.ts | 24 +- .../buddy/src/i18n/locales/en-US/discovery.ts | 6 + apps/buddy/src/i18n/locales/en-US/settings.ts | 48 +++- apps/buddy/src/i18n/locales/en-US/tasks.ts | 3 + .../buddy/src/i18n/locales/zh-CN/approvals.ts | 44 +-- .../buddy/src/i18n/locales/zh-CN/discovery.ts | 6 + apps/buddy/src/i18n/locales/zh-CN/settings.ts | 48 +++- apps/buddy/src/i18n/locales/zh-CN/tasks.ts | 3 + .../onboarding/model/featureGuideSteps.ts | 6 + .../browser/DesktopBrowserSettings.vue | 2 + .../DesktopNetworkPermissionPreview.vue | 57 ++++ .../DesktopNetworkPermissionSelect.vue | 25 ++ .../browser/DesktopNetworkPermissions.vue | 210 ++++++++++++++ .../browser/DesktopNetworkRuleDialog.vue | 139 +++++++++ .../DesktopNetworkPermissions.spec.ts | 263 ++++++++++++++++++ .../model/transcript/chatToolFileTarget.ts | 25 +- .../model/transcript/chatToolPresentation.ts | 8 +- .../__tests__/useTaskContextPanel.spec.ts | 28 ++ .../context-panel/useTaskContextPanel.ts | 17 +- .../context-panel/useTaskResourcePanel.ts | 2 +- .../modules/tasks/state/task-index/typing.ts | 2 + .../context-panel/DesktopFileSpacePicker.vue | 20 +- .../DesktopTaskResourcePanel.vue | 18 +- ...DesktopSpaceAdditionalDirectoriesField.vue | 53 ++++ .../widgets/task-index/DesktopSpaceDialog.vue | 13 +- .../__tests__/useSpaceEditor.spec.ts | 34 +++ .../widgets/task-index/useSpaceEditor.ts | 46 ++- .../widgets/workspace/DesktopApprovalCard.vue | 76 ++++- 102 files changed, 3496 insertions(+), 296 deletions(-) create mode 100644 .playwright/scripts/__tests__/network-permissions.e2e.mjs create mode 100644 apps/buddy/electron/main/browser/BrowserNetworkAuthorization.ts create mode 100644 apps/buddy/electron/main/browser/__tests__/BrowserNetworkAuthorization.spec.ts create mode 100644 apps/buddy/electron/main/config/__tests__/networkPermissions.spec.ts create mode 100644 apps/buddy/electron/main/network/__tests__/networkAuthorization.spec.ts create mode 100644 apps/buddy/electron/main/network/__tests__/requestThroughHost.spec.ts create mode 100644 apps/buddy/service/src/network/__tests__/networkAuthorizationContext.spec.ts create mode 100644 apps/buddy/service/src/network/networkAuthorizationContext.ts create mode 100644 apps/buddy/service/src/permissions/NetworkPermissionsClient.ts create mode 100644 apps/buddy/shared/network/networkAuthorization.ts create mode 100644 apps/buddy/shared/permissions/__tests__/networkPermissions.spec.ts create mode 100644 apps/buddy/shared/permissions/networkPermissions.ts create mode 100644 apps/buddy/shared/permissions/networkPermissionsRpc.ts create mode 100644 apps/buddy/shared/permissions/safeNetworkRegex.ts create mode 100644 apps/buddy/src/modules/settings/widgets/browser/DesktopNetworkPermissionPreview.vue create mode 100644 apps/buddy/src/modules/settings/widgets/browser/DesktopNetworkPermissionSelect.vue create mode 100644 apps/buddy/src/modules/settings/widgets/browser/DesktopNetworkPermissions.vue create mode 100644 apps/buddy/src/modules/settings/widgets/browser/DesktopNetworkRuleDialog.vue create mode 100644 apps/buddy/src/modules/settings/widgets/browser/__tests__/DesktopNetworkPermissions.spec.ts create mode 100644 apps/buddy/src/modules/tasks/widgets/task-index/DesktopSpaceAdditionalDirectoriesField.vue diff --git a/.playwright/scripts/__tests__/network-permissions.e2e.mjs b/.playwright/scripts/__tests__/network-permissions.e2e.mjs new file mode 100644 index 000000000..786dc5467 --- /dev/null +++ b/.playwright/scripts/__tests__/network-permissions.e2e.mjs @@ -0,0 +1,158 @@ +import { Buffer } from 'node:buffer' +import { once } from 'node:events' +import { createServer } from 'node:http' +import path from 'node:path' +import { DatabaseSync } from 'node:sqlite' +import { expect, test, useSyntheticCredentialStorage } from '../fixtures/electron.mjs' + +test('real network requests enforce saved access, file download, redirects and manual takeover', async ({ buddy }, testInfo) => { + const requests = [] + const hits = [] + const server = createServer(async (request, response) => { + if (request.method === 'GET') { + const pathname = new URL(request.url, 'http://permission.example.test').pathname + hits.push(pathname) + if (pathname === '/redirect') { + response.writeHead(302, { location: 'http://redirect.example.test/landing' }).end() + return + } + if (pathname === '/landing') { + response.writeHead(200, { 'content-type': 'text/html' }).end('
+ {{ t(draft ? 'desktop.browser.testDraftDescription' : 'desktop.browser.testHostDescription') }} +
++ {{ t('desktop.browser.invalidHost') }} +
++ {{ normalized }} · {{ matched ? t('desktop.browser.matchedRule', { pattern: matched.pattern }) : t('desktop.browser.matchedDefaults') }} +
++ {{ t('desktop.browser.networkPermissionsDescription') }} +
++ {{ t('desktop.browser.rulePriority') }} +
++ {{ t('desktop.browser.transferBoundary') }} +
++ {{ t('desktop.browser.permissionScope') }} +
++ {{ t('desktop.browser.permissionSaveFailed') }} +
++ {{ t('desktop.browser.ruleLimit') }} +
++ {{ persistentNotice }} +
{{ review.host }} · {{ review.port }}
+ {{ review.command }}
+