@productlobster/plob 0.1.2 → 0.1.4

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.
package/README.md CHANGED
@@ -35,13 +35,14 @@ plob --help
35
35
  | `plob run-replay <runId> [--from-stage <name>]` | Replay a run, optionally from a given stage. |
36
36
  | `plob prototype-list [--cursor <cursor>]` | List prototypes in the workspace. |
37
37
  | `plob prototype-pack --prototype-id <id> [--out <dir>]` | Fetch a prototype ZIP reference (extracts when `--out` is set). |
38
- | `plob document-list [--type <type>] [--run <runId>] [--latest] [--since <iso>] [--limit <n>] [--cursor <cursor>]` | List workspace documents. |
38
+ | `plob document-list [--type <type>] [--run <runId>] [--latest] [--since <iso>] [--limit <n>] [--cursor <cursor>]` | List workspace documents. `--latest` applies only with `--type`. |
39
39
  | `plob document-get --document-id <id>` | Read a document. |
40
40
  | `plob document-put --document-id <id> --version-token <token> --content <markdown> [--idempotency-key <key>]` | Update a document. |
41
41
  | `plob context-pack [--sections <list>] [--limit <n>] [--cursor <cursor>]` | Read accumulated workspace context. |
42
42
  | `plob observe --kind <kind> --content <text> [--idempotency-key <key>]` | Record a single observation. |
43
43
  | `plob ingest --bundle <path-or-dash> [--content-type <type>] [--source-name <name>] [--idempotency-key <key>]` | Ingest a bundle of notes. |
44
44
  | `plob --workspace <workspaceId> upload --file <path>` | Upload a document file to a workspace. |
45
+ | `plob --version` | Print the installed CLI version. |
45
46
 
46
47
  `plob workspaces` lists the workspace your stored credential can access. The initial credential is workspace-bound, so it returns that single workspace.
47
48
 
@@ -76,12 +77,31 @@ Use an explicit idempotency key for a scripted retry:
76
77
  plob observe --kind signal --content "Three users asked for CSV export" --idempotency-key "$JOB_ID"
77
78
  ```
78
79
 
79
- Fetch and extract a prototype pack:
80
+ Fetch and extract a prototype pack into a new directory:
80
81
 
81
82
  ```bash
82
83
  plob prototype-pack --prototype-id proto_123 --out ./proto
83
84
  ```
84
85
 
86
+ The output directory must not already exist, and its parent must exist. Choose a
87
+ new name for each extraction; existing files, empty directories, and symlink
88
+ output roots are rejected without being changed. The CLI does not merge or
89
+ overwrite an earlier extraction. Parent path aliases are resolved to their
90
+ canonical location, which is returned as `extraction.outDir`. Create missing
91
+ parent directories yourself before running the command.
92
+
93
+ Extraction creates a fresh tree, uses exclusive file creation, and removes that
94
+ new tree if extraction fails. Unsafe archive paths and colliding filenames are
95
+ rejected, including case or Unicode aliases recognized by the host filesystem.
96
+ Directory-entry paths are validated, but empty directories are not extracted;
97
+ parent directories are created as needed for files. Inconsistent ZIP directory
98
+ counts, payload ranges, and decoded sizes are rejected. On POSIX the new
99
+ directories and files use permissions 0700 and 0600; Windows inherits the
100
+ caller's filesystem permissions. Use a trusted, stable parent directory on a
101
+ local filesystem: this does not defend against another process replacing parent
102
+ directories during extraction, and exclusive creation may not be reliable on
103
+ every network filesystem.
104
+
85
105
  `plob upload` attaches one file to the selected workspace. Use the workspace `id` from `plob workspaces`, not the display name. The connection must include the `write:upload` scope. Supported extensions: `.pdf`, `.docx`, `.txt`, `.md`, `.markdown`, `.png`, `.jpg`, `.jpeg`, and `.webp`; files must be non-empty and at most 10 MB.
86
106
 
87
107
  ```bash
@@ -102,6 +122,8 @@ https://app.productlobster.ai/settings/connections
102
122
 
103
123
  Create an API key in the hosted app, then paste the one-time `ak_` key into the CLI prompt. The key is stored only in the OS keychain through `@napi-rs/keyring`; it is never written to a plaintext config file and is never printed by the CLI.
104
124
 
125
+ Where there is no OS keychain (headless Linux, CI runners, containers, cloud agent sandboxes), skip `login` and set `PRODUCTLOBSTER_API_KEY` instead; see [Credentials](#credentials).
126
+
105
127
  Automation-safe login reads the key from stdin and does not open a browser:
106
128
 
107
129
  ```bash
@@ -132,13 +154,15 @@ In `--json` mode, stdout contains exactly one JSON document for both success and
132
154
 
133
155
  ## Debugging
134
156
 
135
- Use `--debug` to print request IDs to stderr when the server returns one:
157
+ Use `--debug` to print request IDs to stderr when the server returns one, the credential source (`keychain` or `PRODUCTLOBSTER_API_KEY`, never the key), and the HTTP status and response body or local error behind a failure:
136
158
 
137
159
  ```bash
138
160
  plob --debug --json workspaces
139
161
  ```
140
162
 
141
- The CLI ships no client-side telemetry. Server-side request IDs are the support join key.
163
+ Anything shaped like an API key is redacted to `ak_[redacted]` in those diagnostics. The CLI ships no client-side telemetry. Server-side request IDs are the support join key.
164
+
165
+ `plob --version` prints the bare version; with `--json` (or piped stdout) it writes `{"data":{"version":"<version>"},"schemaVersion":1}`.
142
166
 
143
167
  ## Exit Codes
144
168
 
@@ -156,21 +180,33 @@ The CLI ships no client-side telemetry. Server-side request IDs are the support
156
180
  | 16 | Rate limited |
157
181
  | 17 | CLI version revoked; upgrade before retrying |
158
182
  | 18 | Backend temporarily unavailable; retry shortly |
183
+ | 19 | Included outcomes used; the account is read-only for agents |
159
184
  | 70 | Network or transport failure |
160
185
 
161
186
  When the server reports a version is no longer supported, the CLI exits 17 and prints the npm upgrade command from the structured error details. In `--json` mode, the same detail is emitted in the single JSON error document.
162
187
 
188
+ An HTTP-level refusal (rate limit, Terms re-acceptance, a rejected key) carries the server's own error document, so the CLI reports that code and message. A response that is not a ProductLobster error document reports its HTTP status in `details.httpStatus`, plus its `requestId` when the body is JSON that carries one: 401 maps to `unauthorized`, 429 to `rate_limited` (exit `16`), and any 5xx (including Cloudflare's own origin-error pages) to `service_unavailable` (exit `18`). A network-edge challenge or block page reports `details.reason: "edge_challenge"`. `plob upload` and the `prototype-pack --out` download apply the same mapping. If the response body cannot be read (the connection closed mid-body), the status alone decides the code. With `--debug`, the CLI also writes the HTTP status and the start of the response body, or the local error, to stderr, with anything shaped like an API key redacted. A `requestId` is kept only when it is id-shaped (letters, digits, `.`, `_`, `:`, `-`; at most 128 characters) and not shaped like an API key.
189
+
163
190
  ## Credentials
164
191
 
165
- The API key is loaded from the OS keychain through `@napi-rs/keyring`. `plob login` writes the pasted or stdin-provided `ak_` key to the keychain entry, and `plob logout` deletes it. A missing credential returns exit code `10` with a structured unauthorized error.
192
+ Every command except `login` and `logout` takes the API key from, in order:
193
+
194
+ 1. the OS keychain entry `plob login` saved, through `@napi-rs/keyring` (macOS Keychain, Windows Credential Manager, or the Linux Secret Service). A stored value that is not a valid `ak_` key is refused (exit `10`; run `plob login` again);
195
+ 2. the `PRODUCTLOBSTER_API_KEY` environment variable, only when the keychain holds no key or there is no keychain backend (CI, containers, headless Linux). A value that is not an `ak_` key is refused (exit `10`) rather than ignored.
196
+
197
+ The keychain wins so that a variable exported for another tool or workspace never silently replaces the key you logged in with. `--debug` names which source a command used.
198
+
199
+ `plob login` writes the pasted or stdin-provided `ak_` key to the keychain entry, and `plob logout` deletes it; neither reads or changes the environment variable, and `logout` notes on stderr when the variable is still set, since plob falls back to it once no keychain key is stored. A missing credential returns exit code `10` with a structured unauthorized error. When the keychain itself is unavailable (no Secret Service on a headless Linux host, for example), the error carries `details.reason: "keychain_unavailable"` and names the environment variable. The environment variable is visible to the process and anything it starts; prefer the keychain on a workstation.
166
200
 
167
201
  Default keychain entry:
168
202
 
169
203
  | Field | Value |
170
204
  | --- | --- |
171
- | Service | `productlobster.pl-cli` |
205
+ | Service | `productlobster.plob-cli` |
172
206
  | Account | `default` |
173
207
 
208
+ Versions 0.1.3 and earlier stored the key under the service `productlobster.pl-cli`. The CLI still reads that entry when the new one is empty, so an upgrade keeps working without a new login; reading never writes the keychain. `plob login` saves to the new entry and removes the old one, and `plob logout` removes both. Because a 0.1.4 `login` removes the legacy entry, going back to 0.1.3 afterwards needs a fresh `plob login`.
209
+
174
210
  ## Endpoint
175
211
 
176
212
  The default endpoint is:
@@ -182,10 +218,12 @@ https://app.productlobster.ai/api/mcp
182
218
  For local development, set:
183
219
 
184
220
  ```bash
185
- PL_MCP_URL=http://localhost:3000/api/mcp
221
+ PLOB_MCP_URL=http://localhost:3000/api/mcp
186
222
  ```
187
223
 
188
- `plob upload` uses the same origin as `PL_MCP_URL`.
224
+ The override must be an `https` URL on `productlobster.ai` (or a subdomain) or a `localhost` URL; any other host is refused (exit `2`) before the API key is sent. `plob upload` and `plob prototype-pack --out` use the same origin.
225
+
226
+ Versions 0.1.3 and earlier read `PL_MCP_URL`. It still works when `PLOB_MCP_URL` is unset, and plob writes one deprecation note to stderr when it uses it.
189
227
 
190
228
  ## Dependency Posture
191
229