mirror of
https://github.com/stablyai/orca.git
synced 2026-11-13 17:37:40 +00:00
* refactor(plugins): group panel and worker modules by owner * chore(tests): prune retired plugin supervision timeout allowance * refactor(plugins): consolidate duplicate owner imports
268 lines
13 KiB
JavaScript
268 lines
13 KiB
JavaScript
import { isUnitTestSupportSource } from './pr-code-change-scope.mjs'
|
|
|
|
const isProductSource = (file) => !/\.test\.tsx?$/.test(file) && !isUnitTestSupportSource(file)
|
|
|
|
/** Plugin system sources; every product file here (outside `__mocks__`) routes to a plugin spec. */
|
|
export const PLUGIN_SYSTEM_SOURCE =
|
|
/^src\/(?:renderer\/src\/(?:components\/plugins\/|store\/plugin-)|main\/plugins\/|shared\/plugins\/)/
|
|
|
|
const UI = 'src\\/renderer\\/src\\/components\\/plugins\\/'
|
|
const STORE = 'src\\/renderer\\/src\\/store\\/plugin-'
|
|
|
|
/** A route for product sources under `pattern` plus the e2e helpers its specs import. */
|
|
function pluginRoute(id, specs, pattern, helpers) {
|
|
return {
|
|
id,
|
|
specs: specs.map((name) => `tests/e2e/${name}.spec.ts`),
|
|
matches: (file) =>
|
|
(helpers !== undefined &&
|
|
new RegExp(`^tests\\/e2e\\/helpers\\/(?:${helpers})\\.ts$`).test(file)) ||
|
|
(isProductSource(file) && new RegExp(`^(?:${pattern})`).test(file))
|
|
}
|
|
}
|
|
|
|
const SPECIFIC_PLUGIN_ROUTES = [
|
|
// #36218 broke review/list/dialog flows with no plugin spec selected.
|
|
pluginRoute(
|
|
'plugins.update-review',
|
|
['plugin-update-review', 'plugin-update-review-toast'],
|
|
[
|
|
`${UI}(?:review\\/|list\\/|dialogs\\/Plugin(?:UpdateAll|Remove)Dialog)`,
|
|
`${UI}state\\/use-plugin-(?:review-queue|update-dialog|page-model)`,
|
|
`${UI}presentation\\/plugin-(?:publisher-trust|consent-copy|access-profile|capability-presentation)`,
|
|
`${STORE}(?:update-review-toast|auto-updates)`,
|
|
'src\\/main\\/plugins\\/catalog\\/plugin-(?:auto-updater|update-approval|update-review-notices|release-first-seen-store)',
|
|
'src\\/shared\\/plugins\\/(?:approval\\/|catalog\\/plugin-update-policy|contributions\\/plugin-contribution-summary)'
|
|
].join('|'),
|
|
'plugin-git-fixture|plugin-update-catalog-fixture'
|
|
),
|
|
pluginRoute(
|
|
'plugins.catalog-and-page',
|
|
['plugin-install-link'],
|
|
[
|
|
`${UI}(?:catalog\\/|list\\/|page\\/|PluginContributionIcon|dialogs\\/Plugin(?:Install|CatalogLink|MarketplaceSource)Dialog)`,
|
|
`${UI}state\\/use-plugin-(?:catalog|install-link|install-action|marketplace-lifecycle|page-navigation|page-model|hover-prefetch|in-use|art-palettes|contribution-source)`,
|
|
`${UI}(?:state\\/plugin-preview-cache|presentation\\/plugin-(?:status-presentation|install-source|release-date|contributions|error-presentation))`,
|
|
`${STORE}content-list-store`,
|
|
'src\\/main\\/plugins\\/(?:installation\\/|catalog\\/plugin-(?:marketplace-|catalog-|one-click-enable|community-marketplace-seed|kill-list-))',
|
|
'src\\/main\\/plugins\\/plugin-(?:list-projection|client-list|image-)',
|
|
'src\\/shared\\/plugins\\/(?:catalog\\/|installation\\/|images\\/|plugin-list-entry|contributions\\/plugin-contribution-(?:summary|points))'
|
|
].join('|'),
|
|
'plugin-git-fixture|plugin-gleam-catalog-fixture'
|
|
),
|
|
pluginRoute(
|
|
'plugins.file-type-suggestion',
|
|
['plugin-file-type-suggestion'],
|
|
[
|
|
'src\\/renderer\\/src\\/components\\/editor\\/PluginFileTypeSuggestion\\.tsx$',
|
|
`${UI}state\\/use-plugin-settings-writes`,
|
|
'src\\/main\\/plugins\\/catalog\\/plugin-file-type-suggestion',
|
|
'src\\/shared\\/plugins\\/contributions\\/plugin-(?:file-type|file-match|custom-editor-core-file-types)'
|
|
].join('|'),
|
|
'plugin-git-fixture|plugin-smoke'
|
|
),
|
|
pluginRoute(
|
|
'plugins.try-it',
|
|
['plugin-try-it'],
|
|
[
|
|
`${UI}state\\/(?:plugin-try-action|plugin-action-toast|use-plugin-install-action)`,
|
|
`${STORE}preview-request`
|
|
].join('|'),
|
|
'plugin-git-fixture|plugin-gleam-catalog-fixture|plugin-smoke|plugin-frame-guest'
|
|
),
|
|
pluginRoute(
|
|
'plugins.themes',
|
|
['plugin-theme-smoke'],
|
|
[
|
|
`${UI}(?:state\\/plugin-theme-apply|page\\/PluginTheme)`,
|
|
`${STORE}(?:themes|icon-themes|monaco-theme)`,
|
|
'src\\/main\\/plugins\\/contributions\\/plugin-(?:theme-registries|icon-theme-registry|content-pack-registry|artifact-pack-registry)',
|
|
'src\\/shared\\/plugins\\/(?:artifacts\\/plugin-(?:theme|icon-theme|terminal-theme)-artifact|contributions\\/plugin-content-pack-contributions)'
|
|
].join('|'),
|
|
'plugin-smoke'
|
|
),
|
|
pluginRoute(
|
|
'plugins.syntax-and-language-packs',
|
|
['plugin-syntax-smoke'],
|
|
[
|
|
`${UI}page\\/PluginContributionAction(?:Syntax|Language)`,
|
|
`${STORE}(?:syntax-packs|syntax-failures|language-packs)`,
|
|
'src\\/main\\/plugins\\/contributions\\/plugin-(?:syntax|language-pack)-registry',
|
|
'src\\/shared\\/plugins\\/(?:languages\\/|plugin-language-pack-i18n-resources|artifacts\\/plugin-(?:syntax|language-pack)-artifact)'
|
|
].join('|'),
|
|
'plugin-smoke'
|
|
),
|
|
pluginRoute(
|
|
'plugins.custom-editors-and-new-files',
|
|
['plugin-custom-editor', 'plugin-new-file'],
|
|
[
|
|
`${UI}page\\/PluginContributionActionNewFile`,
|
|
`${STORE}(?:custom-editors|new-files)`,
|
|
'src\\/main\\/plugins\\/plugin-new-file-template',
|
|
'src\\/shared\\/plugins\\/(?:contributions\\/plugin-(?:custom-editor-contribution|new-file-contribution)|frames\\/plugin-custom-editor-bridge)'
|
|
].join('|'),
|
|
'plugin-smoke|plugin-frame-guest'
|
|
),
|
|
pluginRoute(
|
|
'plugins.panels-and-workers',
|
|
['plugin-demo', 'plugin-panel-containment'],
|
|
[
|
|
`${UI}(?:page\\/PluginContributionAction(?:Panel|Command|Events)|state\\/use-plugin-logs)`,
|
|
`${STORE}panels`,
|
|
'src\\/main\\/plugins\\/(?:panels\\/|workers\\/|plugin-(?:command-|event-delivery|agent-status-event|storage-store|secrets-store|log-buffer))',
|
|
'src\\/shared\\/plugins\\/(?:frames\\/|workers\\/|events\\/|capabilities\\/|contributions\\/plugin-(?:command-|event-|panel-|execution-profile))',
|
|
'examples\\/plugins\\/(?:hello-orca|test-fixtures\\/hostile-panel)\\/'
|
|
].join('|'),
|
|
'plugin-panel-navigation-observer|plugin-frame-guest'
|
|
),
|
|
// Desktop frames are isolated <webview> guests; a regression here breaks every frame on desktop.
|
|
pluginRoute(
|
|
'plugins.isolated-frames',
|
|
['plugin-isolated-frame', 'plugin-panel-containment'],
|
|
[
|
|
'src\\/main\\/plugins\\/panels\\/(?:frame-serving\\/|guest-isolation\\/|desktop-actions\\/)?plugin-frame-',
|
|
'src\\/shared\\/plugins\\/frames\\/plugin-(?:frame-guest|panel-shell)',
|
|
'src\\/preload\\/plugin-frame-guest',
|
|
'src\\/main\\/window\\/(?:main-window-webview-security|attach-main-window-services|host-frame-permission-policy)',
|
|
'src\\/main\\/ipc\\/(?:plugins|plugin-frame-entry-ipc)\\.ts$',
|
|
'src\\/main\\/startup\\/main-process-plugins',
|
|
'config\\/build-plugins\\/main-build-entry-points',
|
|
'src\\/main\\/browser\\/guest-lifecycle\\/input\\/browser-guest-shortcut-(?:forwarding|dispatch)',
|
|
'src\\/renderer\\/src\\/components\\/(?:plugins\\/frames\\/|right-sidebar\\/plugin-panels\\/PluginPanel\\.tsx$)',
|
|
'src\\/renderer\\/src\\/components\\/editor\\/(?:PluginCustomEditorFrame\\.tsx$|plugin-custom-editor-host)'
|
|
].join('|'),
|
|
'plugin-frame-guest|plugin-smoke'
|
|
),
|
|
pluginRoute(
|
|
'plugins.declarative-panels',
|
|
['plugin-declarative-panel'],
|
|
[
|
|
`${UI}(?:declarative\\/|plugin-icon-glyphs\\.ts$)`,
|
|
'src\\/shared\\/plugins\\/(?:declarative\\/|frames\\/plugin-declarative-)',
|
|
'src\\/renderer\\/src\\/components\\/right-sidebar\\/plugin-panels\\/declarative\\/(?:PluginDeclarativePanel|use-plugin-declarative-|plugin-declarative-)',
|
|
'resources\\/plugins\\/declarative\\/'
|
|
].join('|'),
|
|
'plugin-frame-guest|plugin-smoke'
|
|
),
|
|
// The component catalog: Orca draws each component, so the gallery exercises every one.
|
|
pluginRoute(
|
|
'plugins.components-catalog',
|
|
['plugin-components-gallery'],
|
|
[
|
|
`${UI}declarative\\/`,
|
|
'src\\/shared\\/plugins\\/declarative\\/plugin-declarative-(?:catalog|[a-z]+-props|prop-schemas|tree)',
|
|
'resources\\/plugins\\/declarative\\/orca-components',
|
|
'src\\/main\\/plugins\\/panels\\/panel-lifetime\\/plugin-panel-image',
|
|
'examples\\/plugins\\/components-gallery\\/'
|
|
].join('|'),
|
|
'plugin-frame-guest|plugin-smoke'
|
|
),
|
|
// Build-less TS/TSX: the frame protocol transpiles source modules and resolves their imports.
|
|
pluginRoute(
|
|
'plugins.buildless-tsx',
|
|
['plugin-buildless-tsx'],
|
|
[
|
|
'src\\/main\\/plugins\\/panels\\/(?:frame-serving\\/)?plugin-frame-(?:module-|source-serving|protocol\\.ts$)',
|
|
'src\\/main\\/plugins\\/plugin-content-hash',
|
|
'src\\/shared\\/plugins\\/frames\\/plugin-frame-source-modules',
|
|
'src\\/cli\\/plugin-authoring\\/plugin-(?:type-files|components-template)',
|
|
'examples\\/plugins\\/hello-tsx\\/'
|
|
].join('|'),
|
|
'plugin-frame-guest|plugin-smoke'
|
|
),
|
|
// Dev hot reload of components panels: memory atoms carried over, last good tree kept on errors.
|
|
pluginRoute(
|
|
'plugins.components-hot-reload',
|
|
['plugin-components-hot-reload'],
|
|
[
|
|
'src\\/shared\\/plugins\\/declarative\\/(?:plugin-declarative-message|runtime\\/declarative-(?:atoms|memory-retention|error-location|panel-context|renderer))',
|
|
'src\\/shared\\/plugins\\/frames\\/plugin-(?:declarative-host-document|frame-bridge)',
|
|
'src\\/renderer\\/src\\/components\\/right-sidebar\\/plugin-panels\\/(?:PluginPanel\\.tsx$|declarative\\/(?:PluginDeclarativePanel|use-plugin-declarative-(?:state|tree)|plugin-declarative-retained-memory))',
|
|
'src\\/main\\/plugins\\/(?:plugin-dev-|panels\\/guest-isolation\\/plugin-frame-guest-sessions)',
|
|
'resources\\/plugins\\/declarative\\/'
|
|
].join('|'),
|
|
'plugin-frame-guest|plugin-smoke'
|
|
),
|
|
// Agents and workspace changes in panels: agents.list, terminal ids on agent events.
|
|
pluginRoute(
|
|
'plugins.panel-agents',
|
|
['plugin-panel-agents'],
|
|
[
|
|
'src\\/main\\/plugins\\/(?:plugin-runtime-binding|plugin-agent-status-event|workers\\/host-api\\/plugin-workspace-projection)',
|
|
'src\\/shared\\/plugins\\/events\\/plugin-events'
|
|
].join('|'),
|
|
'plugin-frame-guest|plugin-smoke|agent-hook-endpoint'
|
|
),
|
|
// A panel and its own worker: requests, posts, storage, settings and pushes.
|
|
pluginRoute(
|
|
'plugins.worker-panel',
|
|
['plugin-worker-panel'],
|
|
[
|
|
'src\\/main\\/plugins\\/panels\\/plugin-panel-bridge',
|
|
'src\\/main\\/plugins\\/(?:plugin-declared-settings|workers\\/(?:plugin-worker-orca-api|host-api\\/plugin-host-panel-method-bindings|parent-process\\/plugin-worker-requests))',
|
|
'src\\/main\\/ipc\\/plugin-(?:panel-push|settings)-ipc',
|
|
'src\\/shared\\/plugins\\/(?:workers\\/plugin-panel-bridge-protocol|frames\\/plugin-panel-shell-facades|contributions\\/plugin-settings-)',
|
|
'src\\/shared\\/plugins\\/declarative\\/runtime\\/declarative-(?:data-sdk|storage-sync)',
|
|
'src\\/renderer\\/src\\/components\\/plugins\\/(?:page\\/PluginSettingsSection|state\\/use-plugin-declared-settings)',
|
|
'examples\\/plugins\\/hello-worker-panel\\/'
|
|
].join('|'),
|
|
'plugin-frame-guest|plugin-smoke'
|
|
),
|
|
// `orca plugin open` / `shot`: renderer reveal, draw wait and main's capture of the panel rect.
|
|
pluginRoute(
|
|
'plugins.view-shot',
|
|
['plugin-shot', 'plugin-shot-editor'],
|
|
[
|
|
`${UI}view\\/(?!PluginShotReplay|plugin-view-replay)`,
|
|
`${STORE}view-capture`,
|
|
'src\\/(?:main\\/plugins\\/view\\/(?!plugin-view-replay)|shared\\/plugins\\/view\\/)',
|
|
'src\\/main\\/runtime\\/rpc\\/methods\\/plugin-view',
|
|
// Every `plugin shot` checks for a chrome region and resolves the default shots folder.
|
|
'src\\/cli\\/(?:handlers\\/plugin-(?:view|shot-chrome|shot-default-dir)|specs\\/plugin-view)',
|
|
'src\\/renderer\\/src\\/hooks\\/(?:ipc-events\\/plugin-view-ipc-bridge|use-document-dark-theme)',
|
|
'src\\/renderer\\/src\\/components\\/right-sidebar\\/(?:plugin-panels\\/health\\/(?:plugin-panel-draw-status|use-plugin-panel-draw-report)|right-sidebar-panel-content)'
|
|
].join('|'),
|
|
'plugin-frame-guest|plugin-smoke|compiled-orca-cli'
|
|
),
|
|
// `shot --scenario`: the check child draws the tree, then the renderer replays it.
|
|
pluginRoute(
|
|
'plugins.view-shot-scenario',
|
|
['plugin-shot'],
|
|
[
|
|
`${UI}view\\/(?:PluginShotReplay|plugin-view-replay)`,
|
|
`${STORE}shot-replay`,
|
|
'src\\/main\\/plugins\\/view\\/plugin-view-replay',
|
|
'src\\/main\\/plugins\\/testing\\/plugin-test-(?:hooks|register)',
|
|
'src\\/cli\\/(?:handlers|specs)\\/plugin-shot-scenario',
|
|
'src\\/cli\\/plugin-authoring\\/plugin-(?:panel-check|test-runner|test-node)'
|
|
].join('|')
|
|
),
|
|
pluginRoute(
|
|
'plugins.view-shot-editor',
|
|
['plugin-shot-editor'],
|
|
'src\\/cli\\/handlers\\/plugin-shot-editor'
|
|
),
|
|
pluginRoute(
|
|
'plugins.startup-and-manifest',
|
|
['plugin-demo'],
|
|
[
|
|
'src\\/main\\/plugins\\/plugin-(?:service|discovery|enablement|activation-policy|bundled-bootstrap|refresh-settlement|manifest-|content-|declarative-content-integrity|dev-)',
|
|
'src\\/shared\\/plugins\\/(?:manifest\\/|approval\\/plugin-consent-|plugin-system-settings)'
|
|
].join('|')
|
|
)
|
|
]
|
|
|
|
export const PR_PLUGIN_E2E_SOURCE_ROUTES = [
|
|
...SPECIFIC_PLUGIN_ROUTES,
|
|
{
|
|
// New or unlisted plugin sources still run the broadest single plugin journey.
|
|
id: 'plugins.unrouted-source',
|
|
specs: ['tests/e2e/plugin-demo.spec.ts'],
|
|
matches: (file) =>
|
|
isProductSource(file) &&
|
|
PLUGIN_SYSTEM_SOURCE.test(file) &&
|
|
!file.includes('/__mocks__/') &&
|
|
!SPECIFIC_PLUGIN_ROUTES.some((route) => route.matches(file))
|
|
}
|
|
]
|