From c75eee0b43a71fd282409378a450a87fdfc62781 Mon Sep 17 00:00:00 2001 From: katspaugh Date: Sun, 26 Oct 2025 08:59:35 +0100 Subject: [PATCH 1/9] Docs: rm old files --- MIGRATION_PLAN.md | 720 ------------------------------------- PROJECT_PLAN.md | 898 ---------------------------------------------- 2 files changed, 1618 deletions(-) delete mode 100644 MIGRATION_PLAN.md delete mode 100644 PROJECT_PLAN.md diff --git a/MIGRATION_PLAN.md b/MIGRATION_PLAN.md deleted file mode 100644 index 09609e8..0000000 --- a/MIGRATION_PLAN.md +++ /dev/null @@ -1,720 +0,0 @@ -# Migration Plan: Imperative Console → Reactive Ink Architecture - -## Current State Summary -- **561 console occurrences** (primarily console.log) -- Mixed UI patterns: @clack/prompts for interactive input + raw console.log for output -- Heavy usage in: account commands (34-26 instances), config commands (27-21), tx/wallet commands (19-10) -- Good separation: services layer already isolated from commands -- Manual formatting for tables, lists, and structured data - ---- - -## Phase 1: Foundation & Infrastructure (Week 1) - -### 1.1 Add Ink Dependencies -```bash -npm install ink react -npm install --save-dev @types/react -``` - -### 1.2 Create Core Architecture -**New directory structure:** -``` -src/ -├── ui/ -│ ├── components/ # Reusable Ink components -│ │ ├── Layout.tsx # Container, Box, Text wrappers -│ │ ├── Table.tsx # Generic table component -│ │ ├── List.tsx # List with markers -│ │ ├── KeyValue.tsx # Key-value pairs display -│ │ ├── Header.tsx # Styled headers/titles -│ │ ├── StatusBadge.tsx # Status indicators -│ │ └── Spinner.tsx # Loading states -│ ├── screens/ # Full-screen views -│ │ ├── WelcomeScreen.tsx -│ │ ├── AccountListScreen.tsx -│ │ ├── AccountInfoScreen.tsx -│ │ └── ... -│ ├── hooks/ # Custom React hooks -│ │ ├── useConfig.ts # Config state management -│ │ ├── useSafe.ts # Safe state management -│ │ └── useWallet.ts # Wallet state management -│ ├── theme.ts # Color palette and styles -│ └── render.tsx # Ink render wrapper utility -``` - -### 1.3 Create Render Utility -**Purpose:** Bridge between command functions and Ink rendering -```typescript -// src/ui/render.tsx -import { render } from 'ink' -import React from 'react' - -export function renderScreen( - Component: React.ComponentType, - props: T -): Promise { - return new Promise((resolve) => { - const { unmount, waitUntilExit } = render() - waitUntilExit().then(() => { - unmount() - resolve() - }) - }) -} -``` - ---- - -## Phase 2: Component Library (Week 2) - -### 2.1 Build Core Components - -**Priority components based on usage patterns:** - -1. **Table Component** (replaces 100+ console.log instances) - - Aligned columns - - Headers with styling - - Row highlighting - - Used in: account info, config show, tx list - -2. **List Component** (replaces 80+ console.log instances) - - Bullet markers (●/○) - - Active/inactive states - - Nested indentation - - Used in: account list, wallet list - -3. **KeyValue Component** (replaces 150+ console.log instances) - - Label/value pairs - - Consistent spacing - - Color theming - - Used in: all info/summary displays - -4. **Header Component** (replaces 50+ console.log instances) - - Title with icons - - Dividers - - Used in: all command outputs - -5. **StatusBadge Component** (replaces 30+ console.log instances) - - Success/error/warning/info - - Icons + colors - - Used in: confirmations, error messages - -### 2.2 Create Theme System -**src/ui/theme.ts:** -```typescript -export const theme = { - colors: { - primary: '#00D9FF', // cyan - success: '#00FF88', // green - error: '#FF5555', // red - warning: '#FFAA00', // yellow - info: '#5599FF', // blue - dim: '#666666', // gray - }, - spacing: { - small: 1, - medium: 2, - large: 3, - }, -} -``` - ---- - -## Phase 3: Logic/Presentation Separation (Week 3) ✅ - -### 3.1 Extract Business Logic from Commands - -**Pattern: Command → Controller → View** - -**COMPLETED EXAMPLE: Wallet List Migration** - -**Before (imperative - 41 lines):** -```typescript -// commands/wallet/list.ts (OLD) -import * as p from '@clack/prompts' -import pc from 'picocolors' -import { getWalletStorage } from '../../storage/wallet-store.js' -import { shortenAddress } from '../../utils/ethereum.js' - -export async function listWallets() { - p.intro(pc.bgCyan(pc.black(' Wallets '))) - - const walletStorage = getWalletStorage() - const wallets = walletStorage.getAllWallets() - const activeWallet = walletStorage.getActiveWallet() - - if (wallets.length === 0) { - console.log('') - console.log(pc.dim('No wallets found')) - console.log('') - p.outro('Use "safe wallet import" to import a wallet') - return - } - - console.log('') - for (const wallet of wallets) { - const isActive = activeWallet?.id === wallet.id - const marker = isActive ? pc.green('●') : pc.dim('○') - const label = isActive ? pc.bold(pc.green(wallet.name)) : wallet.name - - console.log(`${marker} ${label}`) - console.log(` ${pc.dim('Address:')} ${wallet.address}`) - console.log(` ${pc.dim('Short:')} ${shortenAddress(wallet.address)}`) - if (wallet.lastUsed) { - console.log(` ${pc.dim('Last used:')} ${new Date(wallet.lastUsed).toLocaleString()}`) - } - console.log('') - } - - if (activeWallet) { - console.log(pc.dim(`Active wallet: ${activeWallet.name}`)) - } - - p.outro(pc.green(`Total: ${wallets.length} wallet(s)`)) -} -``` - -**After (reactive - 3 lines):** -```typescript -// commands/wallet/list.ts (NEW - Controller) -import { renderScreen } from '../../ui/render.js' -import { WalletListScreen } from '../../ui/screens/index.js' - -export async function listWallets() { - await renderScreen(WalletListScreen, {}) -} - -// ui/hooks/useWallet.ts (State Hook) -export function useWallets() { - const [wallets, setWallets] = useState([]) - const [activeWallet, setActiveWallet] = useState(null) - const [loading, setLoading] = useState(true) - - useEffect(() => { - const walletStorage = getWalletStorage() - setWallets(walletStorage.getAllWallets()) - setActiveWallet(walletStorage.getActiveWallet()) - setLoading(false) - }, []) - - return { wallets, activeWallet, loading } -} - -// ui/screens/WalletListScreen.tsx (View) -export function WalletListScreen({ onExit }) { - const { wallets, activeWallet, loading } = useWallets() - - if (loading) return - if (wallets.length === 0) return - - return ( - -
- ( - - )} - /> -