native macOS codings agent orchestrator
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #91 from onevcat/onevpaw/issue-66-cli-focus-output-contract

docs(cli): define JSON contract for prowl focus

authored by

Wei Wang and committed by
GitHub
79fae3f6 1b97b9fd

+189
+189
doc-onevcat/contracts/cli/focus.md
··· 1 + # CLI Contract: `prowl focus` 2 + 3 + Status: draft truth source for `#66`. 4 + 5 + This file defines the **JSON output contract** for: 6 + 7 + - `prowl focus ... --json` 8 + 9 + ## Contract goals 10 + 11 + - JSON success output must resolve the caller's selector into the **actual focused pane context**. 12 + - `focus` must return enough information for a script to immediately chain into `send`, `key`, or `read` without another `list` call. 13 + - Ambiguous or missing targets must fail with explicit machine-readable errors. 14 + 15 + ## Supported selectors 16 + 17 + - `--worktree <id|name|path>` 18 + - `--tab <id>` 19 + - `--pane <id>` 20 + - no selector, meaning “focus current target” 21 + 22 + ## Success payload 23 + 24 + ```json 25 + { 26 + "ok": true, 27 + "command": "focus", 28 + "schema_version": "prowl.cli.focus.v1", 29 + "data": { 30 + "requested": { 31 + "selector": "worktree", 32 + "value": "Prowl" 33 + }, 34 + "resolved_via": "worktree", 35 + "brought_to_front": true, 36 + "target": { 37 + "worktree": { 38 + "id": "Prowl:/Users/onevcat/Projects/Prowl", 39 + "name": "Prowl", 40 + "path": "/Users/onevcat/Projects/Prowl", 41 + "root_path": "/Users/onevcat/Projects/Prowl", 42 + "kind": "git" 43 + }, 44 + "tab": { 45 + "id": "2FC00CF0-3974-4E1B-BEF8-7A08A8E3B7C0", 46 + "title": "Prowl 1", 47 + "selected": true 48 + }, 49 + "pane": { 50 + "id": "6E1A2A10-D99F-4E3F-920C-D93AA3C05764", 51 + "title": "zsh", 52 + "cwd": "/Users/onevcat/Projects/Prowl", 53 + "focused": true 54 + } 55 + } 56 + } 57 + } 58 + ``` 59 + 60 + ## Required top-level fields 61 + 62 + - `ok`: boolean, must be `true` on success. 63 + - `command`: string, must be `"focus"`. 64 + - `schema_version`: string, currently `"prowl.cli.focus.v1"`. 65 + - `data`: object. 66 + 67 + ## `data` fields 68 + 69 + ### `requested` 70 + 71 + - `selector`: `"worktree"` | `"tab"` | `"pane"` | `"current"` 72 + - `value`: string or `null` 73 + - `null` only when `selector == "current"`. 74 + 75 + ### `resolved_via` 76 + 77 + - `"worktree"` | `"tab"` | `"pane"` 78 + - Represents the precision of the final resolution step. 79 + - Examples: 80 + - `focus --worktree ...` usually returns `"worktree"` 81 + - `focus --tab ...` returns `"tab"` 82 + - `focus --pane ...` returns `"pane"` 83 + - `focus` with no selector returns whichever concrete target was already active 84 + 85 + ### `brought_to_front` 86 + 87 + - boolean 88 + - Must be `true` on success. 89 + 90 + ### `target` 91 + 92 + The final focused context after the command completed. 93 + 94 + #### `target.worktree` 95 + 96 + - `id`: string 97 + - `name`: string 98 + - `path`: string, absolute path 99 + - `root_path`: string, absolute path 100 + - `kind`: `"git"` | `"plain"` 101 + 102 + #### `target.tab` 103 + 104 + - `id`: string, UUID text form 105 + - `title`: string 106 + - `selected`: boolean, must be `true` on success 107 + 108 + #### `target.pane` 109 + 110 + - `id`: string, UUID text form 111 + - `title`: string 112 + - `cwd`: string or `null` 113 + - `focused`: boolean, must be `true` on success 114 + 115 + ## Output invariants 116 + 117 + - A successful `focus` call always returns the final pane that became active, even when the caller selected only a worktree or tab. 118 + - `target.tab.selected` and `target.pane.focused` must both be `true` on success. 119 + - When the selector is less precise than pane, the runtime may choose the already-focused pane within the resolved tab/worktree. 120 + 121 + ## Error payload 122 + 123 + ```json 124 + { 125 + "ok": false, 126 + "command": "focus", 127 + "schema_version": "prowl.cli.focus.v1", 128 + "error": { 129 + "code": "TARGET_NOT_UNIQUE", 130 + "message": "Worktree selector 'Prowl' matched more than one target", 131 + "details": { 132 + "selector": "worktree", 133 + "value": "Prowl" 134 + } 135 + } 136 + } 137 + ``` 138 + 139 + ## Error codes for v1 140 + 141 + - `APP_NOT_RUNNING` 142 + - `INVALID_ARGUMENT` 143 + - `TARGET_NOT_FOUND` 144 + - `TARGET_NOT_UNIQUE` 145 + - `FOCUS_FAILED` 146 + 147 + ## Notes 148 + 149 + - The contract intentionally returns the fully resolved pane context so callers can avoid an immediate follow-up discovery pass. 150 + - `focus --worktree` and `focus --tab` do not need to invent new IDs; they must report the IDs of the tab and pane that actually became active. 151 + - A future richer selection model can extend `details`, but the v1 top-level shape should stay stable. 152 + 153 + ## Example: `--pane` 154 + 155 + ```json 156 + { 157 + "ok": true, 158 + "command": "focus", 159 + "schema_version": "prowl.cli.focus.v1", 160 + "data": { 161 + "requested": { 162 + "selector": "pane", 163 + "value": "6E1A2A10-D99F-4E3F-920C-D93AA3C05764" 164 + }, 165 + "resolved_via": "pane", 166 + "brought_to_front": true, 167 + "target": { 168 + "worktree": { 169 + "id": "Prowl:/Users/onevcat/Projects/Prowl", 170 + "name": "Prowl", 171 + "path": "/Users/onevcat/Projects/Prowl", 172 + "root_path": "/Users/onevcat/Projects/Prowl", 173 + "kind": "git" 174 + }, 175 + "tab": { 176 + "id": "2FC00CF0-3974-4E1B-BEF8-7A08A8E3B7C0", 177 + "title": "Prowl 1", 178 + "selected": true 179 + }, 180 + "pane": { 181 + "id": "6E1A2A10-D99F-4E3F-920C-D93AA3C05764", 182 + "title": "build", 183 + "cwd": "/Users/onevcat/Projects/Prowl", 184 + "focused": true 185 + } 186 + } 187 + } 188 + } 189 + ```