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
2026-09-03 10:44:04 +08:00
122 changed files with 10866 additions and 436 deletions

View File

@@ -993,4 +993,58 @@ describe('CodingConversationTimeline', () => {
expect(document.querySelector('[data-node-id="tool-changed-file-feature"]')).toBeNull();
expect(screen.queryByText(/回滚|revert/i)).not.toBeInTheDocument();
});
it('renders receipt-unavailable as a generic hosted-plugin billing state', async () => {
const { codingConversationStore } = await import('@/stores/coding-conversations');
const { CodingConversationTimeline } = await import(
'@/pages/Chat/CodingConversationTimeline'
);
const base = createProductSnapshot('conversation-web-search-billing', 1);
const snapshot = {
...base,
nodes: [{
kind: 'tool' as const,
id: 'tool-web-search-billing',
toolCallId: 'call-web-search-billing',
toolName: 'game_resource_generate',
title: '生成游戏资源',
inputText: '{"kind":"sprite"}',
status: 'error' as const,
output: [],
details: {
schema: 'makelore-capability.v1' as const,
plugin_id: 'makelore.game-resource',
plugin_version: '1.0.0',
capability_id: 'game-resource.generate',
operation: 'generate',
request_id: 'pi:run-a:resource-a',
success: false,
status: 503,
code: 'plugin_receipt_unavailable',
error: 'Billing status could not be synchronized',
retryable: false,
billing: { mode: 'platform_metered' as const, status: 'receipt_unavailable' as const },
payload_schema: 'game-resource.v1',
data: null,
},
}],
};
codingConversationStore.getState().applySnapshotEvent({
type: 'snapshot',
conversationId: 'conversation-web-search-billing',
workerGeneration: 1,
seq: snapshot.cursor.seq,
snapshot,
});
render(<CodingConversationTimeline conversationId="conversation-web-search-billing" />);
const process = screen.getByTestId('coding-process-group');
fireEvent.click(process.querySelector('summary')!);
const tool = document.querySelector('[data-node-id="tool-web-search-billing"]')!;
fireEvent.click(tool.querySelector('summary')!);
const details = within(tool as HTMLElement).getByTestId('tool-details');
expect(within(details).getByText('收费状态未同步,请勿重复发起')).toBeVisible();
expect(within(details).queryByText(/来源|搜索结果|Makelore\.com/u)).not.toBeInTheDocument();
});
});