feat: expose browser receiver pairing API

This commit is contained in:
2026-07-10 03:42:07 +08:00
parent e2d07145d6
commit 2b3c6d0557
14 changed files with 60 additions and 9 deletions
+10
View File
@@ -43,6 +43,8 @@ describe('VerstakPluginAPI contract', () => {
expect(typeof api.sync.configure).toBe('function');
expect(typeof api.sync.resetKey).toBe('function');
expect(typeof api.sync.now).toBe('function');
expect(typeof api.browserReceiver.pairing).toBe('function');
expect(typeof api.browserReceiver.rotateToken).toBe('function');
});
test('manifest schema accepts files permissions used by platform-test', () => {
@@ -68,6 +70,14 @@ describe('VerstakPluginAPI contract', () => {
expect(permissionEnum).toEqual(expect.arrayContaining(['secrets.read', 'secrets.write']));
});
test('browser receiver token management is declared as a dangerous platform contract', () => {
const permissions = ((permissionsSchema as any).permissions || []) as Array<{ name: string; dangerous: boolean }>;
const permissionEnum = ((manifestSchema as any).properties.permissions.items.enum || []) as string[];
expect(permissions).toContainEqual(expect.objectContaining({ name: 'browser.receiver.manage', dangerous: true }));
expect(permissionEnum).toContain('browser.receiver.manage');
});
test('file.changed schema documents watcher refresh payload', () => {
const fileChanged = (vaultEventsSchema as any).events.find((event: any) => event.name === 'file.changed');
+10
View File
@@ -87,6 +87,11 @@ export interface SyncNowResult {
applyErrors?: string[];
}
export interface BrowserReceiverPairing {
receiverUrl: string;
receiverToken: string;
}
export interface VerstakPluginAPI {
readonly pluginId: string;
@@ -171,6 +176,11 @@ export interface VerstakPluginAPI {
now(): Promise<SyncNowResult>;
};
browserReceiver: {
pairing(): Promise<BrowserReceiverPairing>;
rotateToken(): Promise<BrowserReceiverPairing>;
};
dispose?: () => void;
}
+10
View File
@@ -395,6 +395,16 @@ export function createMockPluginAPI(pluginId = 'test.plugin', options: MockPlugi
resetKey: vi.fn(async () => {}),
now: vi.fn(async () => ({ pushed: 0, pulled: 0, serverSequence: 0 })),
},
browserReceiver: {
pairing: vi.fn(async () => ({
receiverUrl: 'http://127.0.0.1:47731/api/browser-inbox/v1/captures',
receiverToken: 'mock-browser-receiver-token',
})),
rotateToken: vi.fn(async () => ({
receiverUrl: 'http://127.0.0.1:47731/api/browser-inbox/v1/captures',
receiverToken: 'mock-browser-receiver-token-rotated',
})),
},
dispose: vi.fn(),
};
}
+2 -1
View File
@@ -82,7 +82,8 @@ export type Permission =
| 'process.spawn'
| 'secrets.read'
| 'secrets.write'
| 'sync.participate';
| 'sync.participate'
| 'browser.receiver.manage';
export interface PermissionEntry {
name: Permission;