Something went wrong. Try again.
WIP: A simple cli for daily tangled use cases and AI integration. This is for my personal use right now, but happy if others get mileage fro
Something went wrong. Try again.
2.9 kB · 96 lines
TypeScript
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697import type { AtpSessionData } from '@atproto/api';import { AsyncEntry } from '@napi-rs/keyring';
const SERVICE_NAME = 'tangled-cli';
export interface SessionMetadata { handle: string; did: string; pds: string; lastUsed: string; // ISO timestamp}
/** * Store session data in OS keychain * @param sessionData - Session data from AtpAgent */export async function saveSession(sessionData: AtpSessionData): Promise<void> { try { const accountId = sessionData.did || sessionData.handle; if (!accountId) { throw new Error('Session data must include DID or handle'); }
const serialized = JSON.stringify(sessionData); const entry = new AsyncEntry(SERVICE_NAME, accountId); await entry.setPassword(serialized); } catch (error) { throw new Error( `Failed to save session to keychain: ${error instanceof Error ? error.message : 'Unknown error'}` ); }}
/** * Retrieve session data from OS keychain * @param accountId - User's DID or handle */export async function loadSession(accountId: string): Promise<AtpSessionData | null> { try { const entry = new AsyncEntry(SERVICE_NAME, accountId); const serialized = await entry.getPassword(); if (!serialized) { return null; } return JSON.parse(serialized) as AtpSessionData; } catch (error) { throw new Error( `Failed to load session from keychain: ${error instanceof Error ? error.message : 'Unknown error'}` ); }}
/** * Delete session from OS keychain * @param accountId - User's DID or handle */export async function deleteSession(accountId: string): Promise<boolean> { try { const entry = new AsyncEntry(SERVICE_NAME, accountId); return await entry.deleteCredential(); } catch (error) { throw new Error( `Failed to delete session from keychain: ${error instanceof Error ? error.message : 'Unknown error'}` ); }}
/** * Store metadata about current session for CLI to track active user * Uses a special "current" account in keychain */export async function saveCurrentSessionMetadata(metadata: SessionMetadata): Promise<void> { const serialized = JSON.stringify(metadata); const entry = new AsyncEntry(SERVICE_NAME, 'current-session-metadata'); await entry.setPassword(serialized);}
/** * Get metadata about current active session */export async function getCurrentSessionMetadata(): Promise<SessionMetadata | null> { const entry = new AsyncEntry(SERVICE_NAME, 'current-session-metadata'); const serialized = await entry.getPassword(); if (!serialized) { return null; } return JSON.parse(serialized) as SessionMetadata;}
/** * Clear current session metadata */export async function clearCurrentSessionMetadata(): Promise<void> { const entry = new AsyncEntry(SERVICE_NAME, 'current-session-metadata'); await entry.deleteCredential();}