merge: integrate remote and local main histories

# Conflicts:
#	.project-docs/20-architecture/module-map.md
#	.project-docs/30-worklog/current-state.md
#	.project-docs/50-evidence/evidence-index.md
#	src/pages/MyPlugins/index.tsx
#	tests/unit/pi-agent-server-process-real.test.ts
#	tests/unit/pi-managed-worker-opener.test.ts
#	tests/unit/plugin-marketplace-pages.test.tsx
This commit is contained in:
inman committed 2026-09-03 10:44:04 +08:00
commit d25ed08aae
122 files changed
+10866 -436

No files matched your search

@@ -75,6 +75,36 @@ describe('My Plugins', () => {
],
};
it('separates official and device-installed packages without a visible install picker', () => {
const setEnabled = vi.fn();
const uninstall = vi.fn();
render(<MemoryRouter><MyPluginsView
library={{ ...library, items: [library.items[0]] }} installations={{}} state="ready"
pending={{}} onRefresh={vi.fn()} onInstall={vi.fn()} onUpdate={vi.fn()}
onInstallBeta={vi.fn()} onUninstall={vi.fn()} onRemove={vi.fn()} onReacquire={vi.fn()}
deviceIndex={{ schemaVersion: 1, generation: 2, packages: [{
schemaVersion: 1, packageId: 'pi-web-search', displayName: 'Pi Web Search',
resolvedVersion: '1.2.3',
source: { kind: 'npm', requested: 'npm:pi-web-search', resolved: 'npm:pi-web-search@1.2.3' },
kind: 'mixed', skillEntries: [{ id: 'pi-web-search', entryPath: 'skills/search/SKILL.md' }],
extensionEntries: ['extensions/search.ts'], enabled: true, confirmedExecutableCode: true,
installedAt: '2026-09-02T00:00:00.000Z',
}] }} deviceState="ready" devicePending={{}}
onDeviceRefresh={vi.fn()} onDeviceSetEnabled={setEnabled} onDeviceUninstall={uninstall}
/></MemoryRouter>);
expect(screen.getByRole('heading', { name: '官方插件' })).toBeVisible();
expect(screen.getByRole('heading', { name: '本机安装' })).toBeVisible();
expect(screen.getByText('Pi Web Search')).toBeVisible();
expect(screen.getByText(/完整桌面权限/)).toBeVisible();
expect(screen.queryByRole('textbox', { name: /包|路径|source/i })).not.toBeInTheDocument();
expect(screen.getByText(/在对话中/)).toBeVisible();
fireEvent.click(screen.getByRole('button', { name: '停用 Pi Web Search' }));
fireEvent.click(screen.getByRole('button', { name: '移除本机包 Pi Web Search' }));
expect(setEnabled).toHaveBeenCalledWith('pi-web-search', false);
expect(uninstall).toHaveBeenCalledWith('pi-web-search');
});
it('shows update/remove/reacquire and project/partner actions without chaining them', () => {
const onUpdate = vi.fn();
const onRemove = vi.fn();
@@ -143,6 +173,29 @@ describe('My Plugins', () => {
expect(screen.getByRole('link', { name: '浏览插件' })).toHaveAttribute('href', '/project-config?resource=plugins&pluginTab=discover');
});
it('shows acquired code-owned bundled Plugins as supplied without device download actions', () => {
const bundled = {
...library.items[0],
pluginId: 'makelore.game-resource',
title: '游戏资源生成',
stableVersion: '1.0.0',
betaVersion: null,
};
render(<MemoryRouter><MyPluginsView
library={{ ...library, items: [bundled] }} installations={{}} state="ready"
pending={{}} onRefresh={vi.fn()} onInstall={vi.fn()} onUpdate={vi.fn()}
onInstallBeta={vi.fn()} onUninstall={vi.fn()} onRemove={vi.fn()} onReacquire={vi.fn()}
/></MemoryRouter>);
expect(screen.getByText('随 MakeLore 提供')).toBeVisible();
expect(screen.queryByText('尚未下载到设备')).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: '下载游戏资源生成' })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: '更新游戏资源生成' })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: '删除设备上的游戏资源生成' })).not.toBeInTheDocument();
expect(screen.getByRole('button', { name: '移除游戏资源生成' })).toBeVisible();
expect(screen.getByRole('link', { name: '启用到项目' })).toBeVisible();
});
it('updates an installed Beta package only through the explicit Beta action', () => {
const onUpdate = vi.fn();
const onInstallBeta = vi.fn();