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 from it! :)
at main 66 lines 2.1 kB view raw
1import { execSync } from 'node:child_process'; 2import type { TangledApiClient } from '../lib/api-client.js'; 3import { KeychainAccessError } from '../lib/session.js'; 4 5/** 6 * Validate that the client is authenticated and has an active session 7 * @throws Error if not authenticated or no session found 8 * @returns The current session with did and handle 9 */ 10export async function requireAuth(client: TangledApiClient): Promise<{ 11 did: string; 12 handle: string; 13}> { 14 if (!client.isAuthenticated()) { 15 throw new Error('Must be authenticated. Run "tangled auth login" first.'); 16 } 17 18 const session = client.getSession(); 19 if (!session) { 20 throw new Error('No active session found'); 21 } 22 23 return session; 24} 25 26function tryUnlockKeychain(): boolean { 27 if (process.platform !== 'darwin') return false; 28 try { 29 execSync('security unlock-keychain', { stdio: 'inherit' }); 30 return true; 31 } catch { 32 return false; 33 } 34} 35 36/** 37 * Resume session and ensure the client is authenticated. 38 * On macOS, if the keychain is locked, attempts to unlock it interactively 39 * via `security unlock-keychain` before falling back to an error message. 40 * Exits the process with a clear error message if authentication fails. 41 */ 42export async function ensureAuthenticated(client: TangledApiClient): Promise<void> { 43 try { 44 const authenticated = await client.resumeSession(); 45 if (!authenticated) { 46 console.error('✗ Not authenticated. Run "tangled auth login" first.'); 47 process.exit(1); 48 } 49 } catch (error) { 50 if (error instanceof KeychainAccessError) { 51 const unlocked = tryUnlockKeychain(); 52 if (unlocked) { 53 try { 54 const retried = await client.resumeSession(); 55 if (retried) return; 56 } catch { 57 // fall through to error message 58 } 59 } 60 console.error('✗ Cannot access keychain. Please unlock your Mac keychain and try again.'); 61 console.error(' You can unlock it manually with: security unlock-keychain'); 62 process.exit(1); 63 } 64 throw error; 65 } 66}