Major changes: - Migrate browser-extension to use web-ui package (85% code reduction) - Add JailJS content script with ES6+ transform support - Expose DOM constructors (Event, KeyboardEvent, etc.) to JailJS - Support top-level await by wrapping code in async IIFE - Add returnFile() support in JailJS execution - Refactor KeyStore into pluggable storage-adapter pattern - Make ChatPanel configurable with sandboxUrlProvider and additionalTools - Update jailjs to 0.1.1 Files deleted (33 duplicate files): - All browser-extension components, dialogs, state, tools, utils - Now using web-ui versions via @mariozechner/pi-web-ui Files added: - packages/browser-extension/src/content.ts (JailJS content script) - packages/web-ui/src/state/storage-adapter.ts - packages/web-ui/src/state/key-store.ts Browser extension now has only 5 source files (down from 38).
68 lines
1.8 KiB
TypeScript
68 lines
1.8 KiB
TypeScript
import { getProviders } from "@mariozechner/pi-ai";
|
|
import { LocalStorageAdapter, type StorageAdapter } from "./storage-adapter.js";
|
|
|
|
/**
|
|
* API key storage interface
|
|
*/
|
|
export interface KeyStore {
|
|
getKey(provider: string): Promise<string | null>;
|
|
setKey(provider: string, key: string): Promise<void>;
|
|
removeKey(provider: string): Promise<void>;
|
|
getAllKeys(): Promise<Record<string, boolean>>;
|
|
}
|
|
|
|
/**
|
|
* API key storage implementation using a pluggable storage adapter
|
|
*/
|
|
export class LocalStorageKeyStore implements KeyStore {
|
|
private readonly prefix = "apiKey_";
|
|
|
|
constructor(private readonly storage: StorageAdapter) {}
|
|
|
|
async getKey(provider: string): Promise<string | null> {
|
|
const key = `${this.prefix}${provider}`;
|
|
return await this.storage.get(key);
|
|
}
|
|
|
|
async setKey(provider: string, key: string): Promise<void> {
|
|
const storageKey = `${this.prefix}${provider}`;
|
|
await this.storage.set(storageKey, key);
|
|
}
|
|
|
|
async removeKey(provider: string): Promise<void> {
|
|
const key = `${this.prefix}${provider}`;
|
|
await this.storage.remove(key);
|
|
}
|
|
|
|
async getAllKeys(): Promise<Record<string, boolean>> {
|
|
const providers = getProviders();
|
|
const allStorage = await this.storage.getAll();
|
|
const result: Record<string, boolean> = {};
|
|
|
|
for (const provider of providers) {
|
|
const key = `${this.prefix}${provider}`;
|
|
result[provider] = !!allStorage[key];
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
// Default instance using localStorage
|
|
let _keyStore: KeyStore = new LocalStorageKeyStore(new LocalStorageAdapter());
|
|
|
|
/**
|
|
* Get the current KeyStore instance
|
|
*/
|
|
export function getKeyStore(): KeyStore {
|
|
return _keyStore;
|
|
}
|
|
|
|
/**
|
|
* Set a custom KeyStore implementation
|
|
* Call this once at application startup before any components are initialized
|
|
*/
|
|
export function setKeyStore(store: KeyStore): void {
|
|
_keyStore = store;
|
|
}
|