experiments in a post-browser web
at main 230 lines 6.4 kB view raw view rendered
1# Cmd Extension 2 3Command palette for quick command access via keyboard shortcut. 4 5## Overview 6 7The cmd extension provides a command palette interface accessible via a global keyboard shortcut (default: `Alt+Space`). Commands can be typed, selected from a dropdown, and executed. Commands from other extensions can be registered with the cmd system. 8 9## Features 10 11- Global keyboard shortcut for quick access 12- Type-ahead filtering with adaptive matching 13- Command chaining with typed data flow (MIME types) 14- Preview pane for viewing command output 15- Output selection mode for array results 16 17## Command Chaining 18 19Commands can be composed into pipelines where the output of one command becomes the input of the next. This enables powerful data transformation workflows. 20 21### Example Flow 22 231. Run `lists` command → produces JSON array output 242. Select an item from the output list (arrow keys + Enter) 253. Run `csv` command → converts JSON to CSV format 264. Run `save` command → prompts to save the file 27 28### How It Works 29 30Commands declare what MIME types they accept and produce: 31 32```javascript 33export default { 34 name: 'csv', 35 description: 'Convert JSON to CSV format', 36 accepts: ['application/json'], // Input types this command handles 37 produces: ['text/csv'], // Output type this command generates 38 39 execute: async (ctx) => { 40 // ctx.input - data from previous command 41 // ctx.inputMimeType - MIME type of input 42 // ctx.inputTitle - human-readable title 43 44 return { 45 success: true, 46 output: { 47 data: csvString, 48 mimeType: 'text/csv', 49 title: 'CSV Output' 50 } 51 }; 52 } 53}; 54``` 55 56### Command Types 57 58**Producer Commands** - Start chains, produce output 59- `accepts: []` (empty or omitted) 60- `produces: ['application/json']` 61- Example: `lists` 62 63**Transformer Commands** - Accept input, produce output 64- `accepts: ['application/json']` 65- `produces: ['text/csv']` 66- Example: `csv` 67 68**Consumer Commands** - Accept input, end chains 69- `accepts: ['*/*']` (or specific types) 70- `produces: []` (empty or omitted) 71- Example: `save` 72 73### MIME Type Matching 74 75The chaining system supports wildcards: 76- `*/*` - matches any MIME type 77- `text/*` - matches any text type (text/plain, text/csv, etc.) 78- `application/json` - exact match 79 80### Output Selection Mode 81 82When a command produces an array of items, the panel enters "output selection mode": 83- Items are displayed in the results dropdown 84- Navigate with arrow keys (up/down) 85- Select with Enter or Right Arrow 86- The selected item becomes input for the next command 87- ESC exits selection mode 88 89### Chain Mode UI 90 91When in chain mode: 92- A chain indicator shows the current MIME type and title 93- Only commands that accept the current MIME type are shown 94- A preview pane displays the current data 95- ESC exits chain mode first, then closes panel 96 97## Available Commands 98 99### lists 100 101Produces sample list data for chaining demonstration. 102 103``` 104lists - produce sample list data 105``` 106 107Output: `application/json` array 108 109### csv 110 111Converts JSON data to CSV format. 112 113``` 114csv - convert JSON input to CSV 115``` 116 117Accepts: `application/json` 118Produces: `text/csv` 119 120### save 121 122Saves data to a file using the native save dialog. 123 124``` 125save - save with auto-generated filename 126save myfile.csv - save with specified filename 127``` 128 129Accepts: `*/*` (any MIME type) 130Produces: nothing (end of chain) 131 132## Execution Context 133 134Commands receive an execution context object: 135 136```javascript 137{ 138 typed: 'csv', // Full typed string 139 name: 'csv', // Command name 140 params: [], // Array of parameters 141 search: null, // Text after command name 142 143 // Chain mode only: 144 input: {...}, // Input data from previous command 145 inputMimeType: 'application/json', 146 inputTitle: 'Sample list', 147 inputSource: 'lists' // Source command name 148} 149``` 150 151## Keyboard Shortcuts 152 153| Key | Action | 154|-----|--------| 155| Arrow Down | Show results / navigate down | 156| Arrow Up | Navigate up in results | 157| Enter | Execute selected command / select output item | 158| Tab | Autocomplete command name | 159| ESC | Exit chain mode → close panel | 160| Right Arrow | Select output item (in selection mode) | 161 162## Settings 163 164Configure via Settings UI: 165 166- **Shortcut Key**: Global shortcut to open cmd panel (default: `Alt+Space`) 167- **Width**: Panel window width (default: 600) 168- **Height**: Panel window height (default: 400) 169 170## Registering Commands 171 172Extensions can register commands by publishing to the `cmd:register` topic: 173 174```javascript 175api.publish('cmd:register', { 176 name: 'my-command', 177 description: 'Does something', 178 source: 'my-extension', 179 accepts: ['application/json'], 180 produces: ['text/plain'] 181}, api.scopes.GLOBAL); 182``` 183 184Or using the commands API: 185 186```javascript 187api.commands.register({ 188 name: 'my-command', 189 description: 'Does something', 190 execute: async (ctx) => { ... } 191}); 192``` 193 194## Architecture 195 196### Files 197 198| File | Purpose | 199|------|---------| 200| `background.js` | Command registry, shortcut handling, save file coordination | 201| `panel.js` | Panel UI, chain mode logic, output selection, preview rendering | 202| `panel.html` | Panel layout and styles | 203| `commands.js` | Command proxy/dispatch to background | 204| `config.js` | Extension configuration and defaults | 205| `download.html` | Save dialog window (non-modal for native dialog) | 206| `commands/lists.js` | Lists command implementation | 207| `commands/csv.js` | CSV converter command | 208| `commands/save.js` | File save command | 209 210### Provider Pattern 211 212The cmd extension uses the Provider pattern: 213- Owns the command registry 214- Subscribes to `cmd:register`, `cmd:unregister` for command management 215- Subscribes to `cmd:query` for late-arriving consumers 216- Publishes `cmd:ready` when fully initialized 217 218### Save Dialog Flow 219 220The save command uses a separate window approach to avoid modal blur issues: 221 2221. `save` command publishes `cmd:save-file` to background 2232. Background stores data in `pendingDownloads` Map 2243. Background opens `download.html` window with download ID 2254. Download window subscribes to `cmd:download-data:{id}` 2265. Download window publishes `cmd:download-ready` 2276. Background sends data to download window 2287. Download window calls `api.files.save()` for native dialog 229 230This approach works because the download window is not modal and doesn't have a blur handler that would close it when the native dialog takes focus.