@plori/cli 0.3.3 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +100 -16
  2. package/package.json +6 -6
package/README.md CHANGED
@@ -135,9 +135,11 @@ plori attach mate # open the live session (interactive)
135
135
  plori create mate # get-or-create an agent named "mate"
136
136
  plori run mate "clone repo X and run the tests"
137
137
  plori run mate "long job" --no-wait # returns a run id immediately
138
- plori result mate <run-id> --wait # poll it later
138
+ plori result mate <run-id> --wait # wait for it later
139
139
  plori run mate "build it" --follow # stream the turn live (tools on stderr)
140
140
  echo "summarize this" | plori run mate - # message from stdin
141
+ plori watch --agent mate # one JSON line per run ending
142
+ plori inbox # what ended, and what waits on you
141
143
  plori schedule mate "daily report" --in 86400
142
144
  plori inputs mate # runs paused on a human question
143
145
  plori answer <run-id> <tool-call-id> --approve
@@ -155,26 +157,108 @@ Agents are addressed by name or UUID. Every command accepts `--json`; when
155
157
  stdout is not a TTY the output is JSON automatically, so scripts and agents
156
158
  can parse without flags. `plori attach` is the one exception: it is a live
157
159
  stream rather than a single result, so it always writes plain text, and a
158
- redirected stream turns it into a read-only tail. Errors go to stderr; exit
159
- codes: 0 success, 1 API failure, 2 usage error.
160
+ redirected stream turns it into a read-only tail. `plori watch` is the other:
161
+ its output is a stream of JSON lines in every mode. Errors go to stderr, and
162
+ the exit codes are listed under [Agent-driven use](#agent-driven-use).
160
163
 
161
- ## For agent authors
164
+ ## Agent-driven use
162
165
 
163
166
  The reply text of `plori run` is the only thing written to stdout (tool
164
- narration streams to stderr), so a calling agent can pipe it directly. A run
165
- that pauses on a human approval reports `status: "awaiting_input"`; surface
166
- it and answer with `plori answer`. An approval that gates an outward-facing
167
- write carries a `consent_tool` (visible in `plori inputs --json`); answering it
168
- with `--always-allow` also grants a standing consent so the agent stops asking
169
- for that tool. That is the human's call to make, not the calling agent's; on a
170
- row without a `consent_tool` the flag grants nothing. Prefer one long-lived
171
- agent (`create` returns the existing agent for a reused name) over creating
172
- new ones.
167
+ narration streams to stderr), so a calling agent can pipe it directly. Prefer
168
+ one long-lived agent (`create` returns the existing agent for a reused name)
169
+ over creating new ones.
170
+
171
+ ### Start a run and keep working
172
+
173
+ A local agent (a Claude Code or Codex shell, an orchestrator) does not have to
174
+ wait out a run. Start it, go on to something else, and let the CLI report the
175
+ ending:
176
+
177
+ ```sh
178
+ plori run mate "long job" --no-wait # returns the run id at once
179
+ plori watch --agent mate # one JSON line per ending; run it in the background
180
+ plori inbox # what ended since you last acknowledged
181
+ ```
182
+
183
+ `plori watch` holds a connection to the run-event feed and prints one JSON
184
+ object per line, unchanged, until you stop it with Ctrl-C or SIGTERM (exit 0).
185
+ A dropped connection is reopened with a delay that starts at one second and
186
+ doubles to thirty, and the reconnect asks for everything after the last line it
187
+ printed, so a restart neither loses a line nor repeats one.
188
+
189
+ ```json
190
+ {"event":"run.completed","status":"completed","run_id":"…","agent_id":"…","agent_name":"mate","session_id":"…","seq":41,"at":"2026-09-11T10:00:00Z","url":"https://plori.ai/agent/…?session=…"}
191
+ {"event":"run.awaiting_input","status":"awaiting_input","run_id":"…","pending_inputs":[{"tool_call_id":"…","kind":"approval","prompt":"…"}]}
192
+ {"event":"run.error","status":"error","run_id":"…","error":"…"}
193
+ ```
194
+
195
+ `event` is one of `run.completed`, `run.error`, `run.cancelled` and
196
+ `run.awaiting_input`, plus `run.event` under `--events all`, which carries every
197
+ event of every selected run in a `data` field. The flags:
198
+
199
+ - `--agent <name|id>`, repeatable. Without it, every agent on the account,
200
+ including agents created after the watch started.
201
+ - `--since <rfc3339>`: before the live lines, replay what ended after that
202
+ time. A replayed line carries `"replay": true`.
203
+ - `--events terminal,input` (the default) or `--events all`.
204
+
205
+ ### Catch up in one shot
206
+
207
+ `plori inbox` is the same information without a long-lived process: the runs
208
+ that ended since your last acknowledgement, plus everything waiting on a human.
209
+ `plori inbox --ack <run-id>` moves the watermark to that run's ending, so the
210
+ next inbox starts after it. The watermark is local and per account, stored next
211
+ to your credentials in `~/.config/plori/inbox.json`.
212
+
213
+ ### Answer what is waiting
214
+
215
+ A run that pauses on a human approval reports `status: "awaiting_input"` and
216
+ carries the rows to answer in its `pending_inputs`; `plori inputs <agent>` lists
217
+ them per agent. An approval that gates an outward-facing write carries a
218
+ `consent_tool` (visible in `plori inputs --json`); answering it with
219
+ `--always-allow` also grants a standing consent so the agent stops asking for
220
+ that tool. That is the human's call to make, not the calling agent's; on a row
221
+ without a `consent_tool` the flag grants nothing.
222
+
223
+ ### Machine-readable streams
224
+
225
+ `plori run --jsonl` replaces the rendered stream with one JSON object per line
226
+ (`message_delta`, `tool_call`, `tool_result`, `step`, `awaiting_input`, `done`,
227
+ `error`), and ends with the run result on one more line, tagged
228
+ `"type":"result"`.
229
+
230
+ `--json` (automatic when stdout is not a terminal) uses the field names the MCP
231
+ tools return: `run_id`, `status`, `session_id`, `url`, `pending_inputs`.
232
+
233
+ ### Exit codes
234
+
235
+ | code | meaning |
236
+ | ---- | ------- |
237
+ | 0 | the command succeeded; a run that was waited for completed |
238
+ | 1 | API or runtime failure |
239
+ | 2 | usage error |
240
+ | 3 | missing, rejected, or expired credentials |
241
+ | 4 | the control plane could not be reached |
242
+ | 10 | the run is waiting on a human answer |
243
+ | 20 | the run ended in error |
244
+ | 30 | the run was cancelled |
245
+ | 40 | the wait ran out with the run still going |
246
+
247
+ `plori run`, `plori result --wait` (bounded by `--wait-seconds`) and
248
+ `plori watch` all report these codes. Waiting goes through the session socket,
249
+ so exit 4 means the CLI could not watch the run, not that the run failed: the
250
+ run keeps going on the server either way.
251
+ Exit 3 and exit 4 also print one JSON object on stdout,
252
+ `{"error":"…","code":"auth"}` or `{"error":"…","code":"connect"}`, so a caller
253
+ reading the stream sees why it stopped.
254
+
255
+ ### What not to use
173
256
 
174
257
  `plori attach` is for a human at a terminal: it takes over the keyboard and
175
258
  expects someone to answer approvals. A calling agent should stay on
176
- `run`/`result`/`inputs`/`answer`, which are one-shot and parse as JSON. If you
177
- only want to watch a session, `plori attach --read-only` is the scriptable
178
- form, and redirecting either stdin or stdout already selects it.
259
+ `run`/`result`/`watch`/`inbox`/`inputs`/`answer`, which either parse as JSON or
260
+ stream JSON lines. If you only want to follow one session's output,
261
+ `plori attach --read-only` is the scriptable form, and redirecting either stdin
262
+ or stdout already selects it.
179
263
 
180
264
  Wire-level acceptance cases live in the godog UAT suite at [`uat/`](../uat/) (`make uat`).
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@plori/cli",
3
3
  "description": "plori (plori.ai): a cloud AI agent with its own persistent environment - durable disk, real CLI tools, and memory. The official plori CLI.",
4
- "version": "0.3.3",
4
+ "version": "0.4.1",
5
5
  "license": "MIT",
6
6
  "homepage": "https://plori.ai",
7
7
  "repository": {
@@ -26,10 +26,10 @@
26
26
  "node": ">=18"
27
27
  },
28
28
  "optionalDependencies": {
29
- "@plori/cli-darwin-arm64": "0.3.3",
30
- "@plori/cli-darwin-x64": "0.3.3",
31
- "@plori/cli-linux-x64": "0.3.3",
32
- "@plori/cli-linux-arm64": "0.3.3",
33
- "@plori/cli-win32-x64": "0.3.3"
29
+ "@plori/cli-darwin-arm64": "0.4.1",
30
+ "@plori/cli-darwin-x64": "0.4.1",
31
+ "@plori/cli-linux-x64": "0.4.1",
32
+ "@plori/cli-linux-arm64": "0.4.1",
33
+ "@plori/cli-win32-x64": "0.4.1"
34
34
  }
35
35
  }