From beeb6472a2d8e5393037b8544d27abe8d1aedd11 Mon Sep 17 00:00:00 2001 From: Lan_zhijiang Date: Mon, 17 Aug 2026 14:47:59 +0800 Subject: [PATCH 1/9] feat(extension): add Twitter setup wizard - add extension-owned multi-step setup popup - restore peer registration and settings lifecycle - support per-peer extension control and registry overrides --- .../extension/extensionCard/extensionCard.md | 7 +- .../extensionCard/extensionCard.spec.ts | 113 +++++ .../extension/extensionCard/extensionCard.ts | 6 +- .../extension/extensionCard/extensionCard.vue | 45 +- apps/client-web/src/core.ts | 75 ++- .../src/extension-peer-control.spec.ts | 106 +++++ apps/client-web/src/extension-peer-control.ts | 64 +++ apps/client-web/src/locales/messages/en.json | 12 + .../src/locales/messages/zh-CN.json | 12 + apps/client-web/src/main.ts | 15 +- apps/client-web/src/twitter-setup-api.spec.ts | 130 ++++++ .../src/twitter-setup-wizard.spec.ts | 91 ++++ .../src/views/extensions/extensions.scss | 11 + .../src/views/extensions/extensions.spec.ts | 122 +++++ .../src/views/extensions/extensions.vue | 114 ++++- .../src/views/settings/settings.scss | 7 +- .../src/views/settings/settings.spec.ts | 140 ++++++ .../src/views/settings/settings.vue | 99 +++- .../twitterSetupWizard/twitterSetupWizard.md | 10 + .../twitterSetupWizard.scss | 124 +++++ .../twitterSetupWizard/twitterSetupWizard.ts | 10 + .../twitterSetupWizard/twitterSetupWizard.vue | 428 ++++++++++++++++++ extensions/twitter/src/index.ts | 5 + extensions/twitter/src/setup-api.ts | 207 +++++++++ packages/core/package.json | 2 +- packages/core/src/base/db-api.ts | 6 +- packages/core/src/config/schema.ts | 34 +- packages/core/src/config/store.test.ts | 82 ++++ packages/core/src/config/store.ts | 39 +- packages/core/src/extension/host.ts | 14 +- packages/core/src/extension/index.ts | 8 + packages/core/src/extension/model.ts | 7 + .../core/src/extension/postgrest-state.ts | 36 +- .../src/extension/registry-origin.test.ts | 71 +++ .../core/src/extension/registry-origin.ts | 66 +++ packages/core/src/extension/registry.ts | 27 +- packages/core/src/index.ts | 4 + packages/core/src/peer/index.ts | 1 + packages/core/src/peer/runtime.test.ts | 104 +++++ packages/core/src/peer/runtime.ts | 107 +++++ scripts/check-local-runtime-contract.mjs | 2 + 41 files changed, 2474 insertions(+), 89 deletions(-) create mode 100644 apps/client-web/src/components/extension/extensionCard/extensionCard.spec.ts create mode 100644 apps/client-web/src/extension-peer-control.spec.ts create mode 100644 apps/client-web/src/extension-peer-control.ts create mode 100644 apps/client-web/src/twitter-setup-api.spec.ts create mode 100644 apps/client-web/src/twitter-setup-wizard.spec.ts create mode 100644 apps/client-web/src/views/extensions/extensions.spec.ts create mode 100644 apps/client-web/src/views/settings/settings.spec.ts create mode 100644 extensions/twitter/src/components/twitterSetupWizard/twitterSetupWizard.md create mode 100644 extensions/twitter/src/components/twitterSetupWizard/twitterSetupWizard.scss create mode 100644 extensions/twitter/src/components/twitterSetupWizard/twitterSetupWizard.ts create mode 100644 extensions/twitter/src/components/twitterSetupWizard/twitterSetupWizard.vue create mode 100644 extensions/twitter/src/setup-api.ts create mode 100644 packages/core/src/config/store.test.ts create mode 100644 packages/core/src/extension/registry-origin.test.ts create mode 100644 packages/core/src/extension/registry-origin.ts create mode 100644 packages/core/src/peer/runtime.test.ts create mode 100644 packages/core/src/peer/runtime.ts diff --git a/apps/client-web/src/components/extension/extensionCard/extensionCard.md b/apps/client-web/src/components/extension/extensionCard/extensionCard.md index 2911d00..ec13f24 100644 --- a/apps/client-web/src/components/extension/extensionCard/extensionCard.md +++ b/apps/client-web/src/components/extension/extensionCard/extensionCard.md @@ -5,11 +5,12 @@ A component that displays extension information and provides controls for toggli ## Props - `extension` (InstalledExtension, required): the canonical installed row -- `enabled` (boolean, required): whether the current Web Peer UUID is in `enabled[]` +- `enabled` (boolean, required): whether the selected Client's Peer UUID is in `enabled[]` +- `controlsCurrentWebRuntime` (boolean, required): whether the switch owns this browser's runtime +- `setEnabled` (function, required): application-level selected-Client control operation ## Emits -- `changed`: Emitted after current-Peer enablement changes and the list should be refreshed - `updated`: Emitted with the canonical row after configuration or version changes - `uninstalled`: Emitted after the canonical row is removed @@ -17,6 +18,8 @@ A component that displays extension information and provides controls for toggli - Display canonical Extension Name, exact version, and optional nickname - Toggle enable/disable status with a switch +- Mount an Extension-owned setup contribution from this browser's running Web Distribution +- Keep setup availability independent of which Client is selected for enablement control - Edit extension configuration via JSON editor in a dialog - Change the exact shared version only while every Peer is disabled - Auto-formats configuration as JSON for easier editing diff --git a/apps/client-web/src/components/extension/extensionCard/extensionCard.spec.ts b/apps/client-web/src/components/extension/extensionCard/extensionCard.spec.ts new file mode 100644 index 0000000..e8a604c --- /dev/null +++ b/apps/client-web/src/components/extension/extensionCard/extensionCard.spec.ts @@ -0,0 +1,113 @@ +import { defineComponent } from 'vue' +import { flushPromises, mount } from '@vue/test-utils' +import { beforeEach, describe, expect, it, vi } from 'vitest' +import ExtensionCard from './extensionCard.vue' + +const SetupComponent = defineComponent({ + template: '

Twitter setup

', +}) +const host = { + getSetupContribution: vi.fn((): { component: typeof SetupComponent } | null => ({ + component: SetupComponent, + })), + changeVersion: vi.fn(), + updateConfig: vi.fn(), + uninstall: vi.fn(), +} + +vi.mock('@/core', () => ({ getExtensionHost: () => host })) +vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key: string) => key }) })) + +const extension = { + name: 'inkcre/twitter', + version: '0.2.0', + enabled: ['00000000-0000-4000-8000-000000000001'], + nickname: 'Twitter', + config: {}, + config_schema: null, +} + +const stubs = { + InkButton: defineComponent({ + props: ['text'], + emits: ['click'], + template: '', + }), + InkSwitch: defineComponent({ + props: ['modelValue'], + emits: ['update:modelValue'], + template: '