native macOS codings agent orchestrator
6
fork

Configure Feed

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

Merge pull request #94 from onevcat/onevpaw/issue-69-cli-read-output-contract

docs(cli): define JSON contract for prowl read

authored by

Wei Wang and committed by
GitHub
f8cb3b5c 203c5ed4

+181
+181
doc-onevcat/contracts/cli/read.md
··· 1 + # CLI Contract: `prowl read` 2 + 3 + Status: draft truth source for `#69`. 4 + 5 + This file defines the **JSON output contract** for: 6 + 7 + - `prowl read --json` 8 + - `prowl read --last <n> --json` 9 + 10 + ## Contract goals 11 + 12 + - JSON output must carry the actual captured text, not just metadata. 13 + - The payload must say whether the text came from the visible screen, scrollback, or a best-effort mix of both. 14 + - `--last N` should have a stable machine-readable shape even if the first implementation is best-effort. 15 + 16 + ## Supported targeting 17 + 18 + - `--worktree <id|name|path>` 19 + - `--tab <id>` 20 + - `--pane <id>` 21 + - no selector, meaning current focused pane 22 + 23 + ## Success payload 24 + 25 + ```json 26 + { 27 + "ok": true, 28 + "command": "read", 29 + "schema_version": "prowl.cli.read.v1", 30 + "data": { 31 + "target": { 32 + "worktree": { 33 + "id": "Prowl:/Users/onevcat/Projects/Prowl", 34 + "name": "Prowl", 35 + "path": "/Users/onevcat/Projects/Prowl", 36 + "root_path": "/Users/onevcat/Projects/Prowl", 37 + "kind": "git" 38 + }, 39 + "tab": { 40 + "id": "2FC00CF0-3974-4E1B-BEF8-7A08A8E3B7C0", 41 + "title": "Prowl 1", 42 + "selected": true 43 + }, 44 + "pane": { 45 + "id": "6E1A2A10-D99F-4E3F-920C-D93AA3C05764", 46 + "title": "build", 47 + "cwd": "/Users/onevcat/Projects/Prowl", 48 + "focused": true 49 + } 50 + }, 51 + "mode": "last", 52 + "last": 100, 53 + "source": "scrollback", 54 + "truncated": false, 55 + "line_count": 87, 56 + "text": "Compile Swift module ProwlCore\n..." 57 + } 58 + } 59 + ``` 60 + 61 + ## Required top-level fields 62 + 63 + - `ok`: boolean, must be `true` on success. 64 + - `command`: string, must be `"read"`. 65 + - `schema_version`: string, currently `"prowl.cli.read.v1"`. 66 + - `data`: object. 67 + 68 + ## `data.target` shape 69 + 70 + ### `worktree` 71 + 72 + - `id`: string 73 + - `name`: string 74 + - `path`: string, absolute path 75 + - `root_path`: string, absolute path 76 + - `kind`: `"git"` | `"plain"` 77 + 78 + ### `tab` 79 + 80 + - `id`: string, UUID text form 81 + - `title`: string 82 + - `selected`: boolean 83 + 84 + ### `pane` 85 + 86 + - `id`: string, UUID text form 87 + - `title`: string 88 + - `cwd`: string or `null` 89 + - `focused`: boolean 90 + 91 + ## `data` capture fields 92 + 93 + - `mode`: `"snapshot"` | `"last"` 94 + - `"snapshot"` for plain `prowl read` 95 + - `"last"` for `prowl read --last N` 96 + - `last`: integer or `null` 97 + - required as an integer when `mode == "last"` 98 + - must be `null` when `mode == "snapshot"` 99 + - `source`: `"screen"` | `"scrollback"` | `"mixed"` 100 + - `"screen"`: visible screen snapshot only 101 + - `"scrollback"`: satisfied from scrollback/history 102 + - `"mixed"`: combined view when the runtime had to stitch sources together 103 + - `truncated`: boolean 104 + - `true` when the runtime could not return the full requested text volume 105 + - `line_count`: integer 106 + - number of newline-delimited lines present in `text` 107 + - `text`: string 108 + - UTF-8 text payload 109 + - may be empty if the target pane currently has no readable text 110 + 111 + ## Output invariants 112 + 113 + - `text` is always present on success, even when empty. 114 + - `line_count` must describe the returned text, not the requested amount. 115 + - `mode == "last"` does not guarantee exact history completeness; that uncertainty is represented by `source` and `truncated`, not by changing the response shape. 116 + 117 + ## Error payload 118 + 119 + ```json 120 + { 121 + "ok": false, 122 + "command": "read", 123 + "schema_version": "prowl.cli.read.v1", 124 + "error": { 125 + "code": "TARGET_NOT_FOUND", 126 + "message": "No pane matched '6E1A2A10-D99F-4E3F-920C-D93AA3C05764'" 127 + } 128 + } 129 + ``` 130 + 131 + ## Error codes for v1 132 + 133 + - `APP_NOT_RUNNING` 134 + - `INVALID_ARGUMENT` 135 + - `TARGET_NOT_FOUND` 136 + - `TARGET_NOT_UNIQUE` 137 + - `READ_FAILED` 138 + 139 + ## Notes 140 + 141 + - The parent issue explicitly requires `--last N` to cover recent history beyond the visible screen when possible, so `source` is a first-class field in the contract. 142 + - The contract does not include ANSI styling or structured screen cells in v1; JSON is text-first. 143 + - Future richer output can add optional fields, but `text` must remain the primary machine-facing content. 144 + 145 + ## Example: visible snapshot 146 + 147 + ```json 148 + { 149 + "ok": true, 150 + "command": "read", 151 + "schema_version": "prowl.cli.read.v1", 152 + "data": { 153 + "target": { 154 + "worktree": { 155 + "id": "Prowl:/Users/onevcat/Projects/Prowl", 156 + "name": "Prowl", 157 + "path": "/Users/onevcat/Projects/Prowl", 158 + "root_path": "/Users/onevcat/Projects/Prowl", 159 + "kind": "git" 160 + }, 161 + "tab": { 162 + "id": "2FC00CF0-3974-4E1B-BEF8-7A08A8E3B7C0", 163 + "title": "Prowl 1", 164 + "selected": true 165 + }, 166 + "pane": { 167 + "id": "6E1A2A10-D99F-4E3F-920C-D93AA3C05764", 168 + "title": "zsh", 169 + "cwd": "/Users/onevcat/Projects/Prowl", 170 + "focused": true 171 + } 172 + }, 173 + "mode": "snapshot", 174 + "last": null, 175 + "source": "screen", 176 + "truncated": false, 177 + "line_count": 12, 178 + "text": "onevcat@mini Prowl % swift test\n..." 179 + } 180 + } 181 + ```