metergraph-cli 0.1.0 → 0.2.0-preview.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.
- package/README.md +500 -33
- package/assets/skill/SKILL.md +17 -1
- package/assets/skill/manifest.json +3 -3
- package/package.json +2 -2
- package/src/args.js +323 -17
- package/src/auth-binding.js +202 -0
- package/src/auth-browser.js +74 -0
- package/src/auth-callback.js +177 -0
- package/src/auth-login.js +410 -0
- package/src/auth-oauth.js +462 -0
- package/src/auth-session.js +174 -0
- package/src/auth-store.js +397 -0
- package/src/cli.js +78 -2
- package/src/constants.js +99 -4
- package/src/deployment-credential.js +207 -0
- package/src/deployment-route.js +449 -0
- package/src/doctor.js +10 -0
- package/src/http.js +1 -1
- package/src/output.js +454 -2
- package/src/read-contract.js +609 -0
- package/src/read-output.js +216 -0
- package/src/read.js +325 -0
- package/src/setup-deployment.js +178 -0
- package/src/setup-env-acl.js +99 -0
- package/src/setup-env-git.js +103 -0
- package/src/setup-env-parse.js +169 -0
- package/src/setup-env.js +685 -0
- package/src/setup-state.js +141 -0
- package/src/setup.js +326 -0
- package/src/skill-bundle.js +1 -1
- package/src/trace-contract.js +129 -0
- package/src/trace-open.js +36 -0
- package/src/transport.js +171 -0
- package/src/verify-output.js +36 -0
- package/src/verify.js +120 -0
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# metergraph-cli
|
|
2
2
|
|
|
3
|
-
The Metergraph command line tool.
|
|
3
|
+
The Metergraph command line tool. Version `0.2.0-preview.1` is published on the
|
|
4
|
+
`next` npm tag. The `latest` tag remains on `0.1.0`.
|
|
4
5
|
|
|
5
|
-
Install the preview channel with npm or run it directly:
|
|
6
|
+
Install the released preview channel with npm or run it directly:
|
|
6
7
|
|
|
7
8
|
```sh
|
|
8
9
|
npx --yes metergraph-cli@next --help
|
|
@@ -10,18 +11,45 @@ npx --yes metergraph-cli@next doctor --json
|
|
|
10
11
|
npm install -g metergraph-cli@next
|
|
11
12
|
```
|
|
12
13
|
|
|
13
|
-
The installed command is `metergraph`. Pin `metergraph-cli@0.
|
|
14
|
-
this exact preview
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
The installed command is `metergraph`. Pin `metergraph-cli@0.2.0-preview.1`
|
|
15
|
+
when you need this exact preview rather than whichever version `next` names later.
|
|
16
|
+
|
|
17
|
+
**Availability:**
|
|
18
|
+
|
|
19
|
+
- `metergraph-cli@0.1.0` contains only `doctor` and `skill install` /
|
|
20
|
+
`skill update`. It has no sign in commands.
|
|
21
|
+
- `metergraph-cli@0.2.0-preview.0` adds `login`, `logout`, `setup`, `verify`,
|
|
22
|
+
`status`, `context`, `capabilities`, `usage`, `routes` and `traces`.
|
|
23
|
+
- `metergraph-cli@0.2.0-preview.1` makes `setup` write the SDK service root as
|
|
24
|
+
`METERGRAPH_INGEST_URL` and repairs the full ingest endpoint that
|
|
25
|
+
`0.2.0-preview.0` wrote, after checking the saved key. It also keeps validated,
|
|
26
|
+
workspace-bound trace links in Metadata reads.
|
|
27
|
+
- Sign in needs a Metergraph service that offers Metadata-only CLI grants and grant
|
|
28
|
+
revocation. A service without them is reported as unsupported, and the CLI never
|
|
29
|
+
falls back to broader access.
|
|
30
|
+
- The read commands need a project signed in with `login`. `setup` also needs the
|
|
31
|
+
deployment's ingest bootstrap API and browser approval by a workspace member.
|
|
32
|
+
`verify` checks one exact trace identity in an explicit invocation window using
|
|
33
|
+
Metadata access. It never sends application data.
|
|
34
|
+
|
|
35
|
+
The preview includes:
|
|
17
36
|
|
|
18
37
|
- `doctor` checks whether a Metergraph service is reachable, healthy and supported.
|
|
19
38
|
- `skill install` and `skill update` copy the Metergraph agent skill bundled with the
|
|
20
39
|
CLI into one coding agent's project skill directory.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
40
|
+
- `login` and `logout` sign a project in to one workspace through your
|
|
41
|
+
browser with a delegated, Metadata-only grant, and sign it out again.
|
|
42
|
+
- The read commands use that grant to read bounded workspace Metadata:
|
|
43
|
+
connection status, workspace context, capabilities, daily usage, routes and one page
|
|
44
|
+
of trace metadata.
|
|
45
|
+
- `setup` guides browser sign in and workspace choice, asks for
|
|
46
|
+
ingest-only approval, writes a private project env file, confirms delivery, and
|
|
47
|
+
installs the selected client skill.
|
|
48
|
+
- `verify` polls for one exact processed trace in a bounded window.
|
|
49
|
+
It does not infer application provenance from a Metadata match.
|
|
50
|
+
|
|
51
|
+
It does not read retained content, replay traces, call model providers or send
|
|
52
|
+
application data. Setup does not prove that the application sent a trace.
|
|
25
53
|
|
|
26
54
|
## Requirements
|
|
27
55
|
|
|
@@ -41,10 +69,38 @@ metergraph doctor [--url ORIGIN] [--timeout-ms N] [--json]
|
|
|
41
69
|
metergraph help skill [--json]
|
|
42
70
|
metergraph skill install --client CLIENT --runtime RUNTIME [--project DIR] [--json]
|
|
43
71
|
metergraph skill update --client CLIENT --runtime RUNTIME [--project DIR] [--json]
|
|
72
|
+
metergraph help login [--json]
|
|
73
|
+
metergraph login --runtime local [--url ORIGIN] [--workspace UUID] [--project DIR] [--config-dir DIR] [--timeout-ms N] [--signup] [--no-browser] [--reconnect] [--json]
|
|
74
|
+
metergraph logout [--project DIR] [--config-dir DIR] [--json]
|
|
75
|
+
metergraph setup --runtime local (--client codex|claude|cursor | --skip-skill) [--deployment managed|customer-local|byoc|oss] [--url ORIGIN] [--workspace UUID] [--confirm-prerequisites] [--agent-token-file FILE] [--project DIR] [--config-dir DIR] [--env-file .env] [--timeout-ms N] [--signup] [--reconnect] [--no-browser] [--repair] [--json]
|
|
76
|
+
metergraph status [--project DIR] [--config-dir DIR] [--timeout-ms N] [--json]
|
|
77
|
+
metergraph context [--project DIR] [--config-dir DIR] [--timeout-ms N] [--json]
|
|
78
|
+
metergraph capabilities [--project DIR] [--config-dir DIR] [--timeout-ms N] [--json]
|
|
79
|
+
metergraph usage [--days N] [--limit N] [--project DIR] [--config-dir DIR] [--timeout-ms N] [--json]
|
|
80
|
+
metergraph routes [--limit N] [--project DIR] [--config-dir DIR] [--timeout-ms N] [--json]
|
|
81
|
+
metergraph traces [--days N] [--limit N] [--route NAME] [--status success|error] [--cursor CURSOR] [--project DIR] [--config-dir DIR] [--timeout-ms N] [--json]
|
|
82
|
+
metergraph verify (--trace-id ID | --request-id ID) --since TIME --until TIME [--source application|synthetic|demo|import|unspecified] [--days N] [--timeout-ms N] [--poll-ms N] [--max-attempts N] [--open] [--no-browser] [--project DIR] [--config-dir DIR] [--json]
|
|
44
83
|
```
|
|
45
84
|
|
|
46
85
|
`--help`, `--version` and the `skill` commands work offline and make no network
|
|
47
|
-
requests.
|
|
86
|
+
requests. `login`, `logout`, `setup`, `verify` and the read commands are not in the published `0.1.0`
|
|
87
|
+
package.
|
|
88
|
+
|
|
89
|
+
### Exact trace verification
|
|
90
|
+
|
|
91
|
+
After an application invocation, pass its exact trace ID or request ID and the
|
|
92
|
+
invocation start and end timestamps to `verify`. The optional `--source` label is a
|
|
93
|
+
caller assertion. A matching Metadata row proves a processed trace is visible in the
|
|
94
|
+
bound workspace, but does not independently prove that it came from your application.
|
|
95
|
+
The result therefore keeps `application_traffic_verified: false` until a separate
|
|
96
|
+
application instrumentation check supplies that evidence. A missing, ambiguous, stale
|
|
97
|
+
or wrong-workspace result fails closed. The command neither creates an ingest key nor
|
|
98
|
+
sends a test event.
|
|
99
|
+
|
|
100
|
+
`--open` launches only a server-provided link carrying the exact trace and the
|
|
101
|
+
verified workspace ID. The dashboard must check that ID against its signed-in
|
|
102
|
+
workspace before displaying traces. Older links without a workspace remain a
|
|
103
|
+
manual handoff; a conflicting workspace or unsafe link is refused.
|
|
48
104
|
|
|
49
105
|
### doctor
|
|
50
106
|
|
|
@@ -148,9 +204,320 @@ does not match. It never downloads the skill or runs a remote script. A new skil
|
|
|
148
204
|
revision ships only in a new CLI release; `skill update` then upgrades projects that
|
|
149
205
|
hold an unchanged earlier revision.
|
|
150
206
|
|
|
207
|
+
### login and logout
|
|
208
|
+
|
|
209
|
+
`login` binds a project directory to one Metergraph workspace. Your browser does the
|
|
210
|
+
sign in, sign up, invitation and workspace consent on the service's own pages and
|
|
211
|
+
keeps its own session. The CLI receives only a delegated OAuth grant limited to the
|
|
212
|
+
Metadata scope, `agent:metadata`, checks it with the service and saves it privately.
|
|
213
|
+
|
|
214
|
+
```sh
|
|
215
|
+
metergraph login --runtime local --url https://metergraph.example.com
|
|
216
|
+
metergraph logout
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
| Option | Default | Notes |
|
|
220
|
+
| --- | --- | --- |
|
|
221
|
+
| `--runtime RUNTIME` | required | `local`: the browser runs on this machine. `cloud` and `cloud-no-shell` get a handoff to the [connection guide](https://www.metergraph.dev/docs/guides/agent-access/) with exit code 6. |
|
|
222
|
+
| `--url ORIGIN` | `https://app.metergraph.dev` | Bare origin only, see [Safe origins](#safe-origins). |
|
|
223
|
+
| `--workspace UUID` | none | The workspace you expect. Sign in fails unless the browser grants exactly this one. Without it, the workspace you choose in the browser is used after the service confirms it. |
|
|
224
|
+
| `--project DIR` | current directory | Existing project directory to bind. |
|
|
225
|
+
| `--config-dir DIR` | see below | Private per-user directory for the saved grant. |
|
|
226
|
+
| `--timeout-ms N` | `300000` | How long to wait for the browser, 1000 to 900000. |
|
|
227
|
+
| `--signup` | off | Start at the hosted sign up page, which returns to the same authorization request. Managed service only; other profiles exit 6. |
|
|
228
|
+
| `--no-browser` | off | Print the authorization URL on stderr for you to open on this machine, then wait. Not with `--json`. |
|
|
229
|
+
| `--reconnect` | off | Allow replacing a binding to a different origin or workspace. |
|
|
230
|
+
| `--json` | off | Print exactly one JSON line on stdout and nothing on stderr. |
|
|
231
|
+
|
|
232
|
+
What `login` does, in order:
|
|
233
|
+
|
|
234
|
+
1. Refuses cloud runtimes, SSH sessions, cloud development environments and CI (by the
|
|
235
|
+
presence of variables such as `SSH_CONNECTION`, `CODESPACES` or `CI`; values are
|
|
236
|
+
never read into output) before any request, listener or file write.
|
|
237
|
+
2. Reads the project binding. A project bound to another origin or workspace is refused
|
|
238
|
+
with exit code 8 unless you pass `--reconnect`. A project that is already signed in
|
|
239
|
+
and still verified is left as it is, with no browser and no new client.
|
|
240
|
+
3. Runs the same checks as `doctor`, then reads the service's OAuth metadata from the
|
|
241
|
+
same origin. Every endpoint must be a fixed path on that origin, and the service must
|
|
242
|
+
offer `agent:metadata`, PKCE with `S256`, public clients and revocation.
|
|
243
|
+
4. Registers a public client named `Metergraph CLI` for one loopback redirect,
|
|
244
|
+
`http://127.0.0.1:PORT/callback` on an ephemeral port, creates a random state and
|
|
245
|
+
PKCE verifier, and arms the callback listener and its timeout before the browser
|
|
246
|
+
opens.
|
|
247
|
+
5. Opens the authorization URL with the operating system's launcher (no shell). The
|
|
248
|
+
listener accepts one `GET` with the exact host, path and state. Other requests get a
|
|
249
|
+
fixed page and do not end the wait.
|
|
250
|
+
6. Exchanges the code and accepts only a Bearer grant for exactly `agent:metadata` whose
|
|
251
|
+
claims name this issuer, resource, client and one workspace. The claims are a sanity
|
|
252
|
+
check; the CLI does not verify token signatures.
|
|
253
|
+
7. Asks the service, with the new token, for `/v1/agent/workspace` and
|
|
254
|
+
`/v1/agent/capabilities`. The workspace ID, its provenance and the token must agree,
|
|
255
|
+
the deployment profile must match step 3, the access scopes must be exactly
|
|
256
|
+
`agent:metadata`, and content, evidence and replay capabilities must be unavailable.
|
|
257
|
+
Nothing else is read.
|
|
258
|
+
8. Saves the grant in the config directory and writes `.metergraph/project.json`.
|
|
259
|
+
|
|
260
|
+
Once the token response has been validated and holds a usable refresh token, a grant
|
|
261
|
+
the CLI decides not to keep (a workspace other than the one expected or bound, failed
|
|
262
|
+
verification, cancellation) is sent to the revocation endpoint before the command
|
|
263
|
+
exits. If the grant cannot be saved or the binding cannot be written, the saved grant
|
|
264
|
+
is removed, revocation is requested the same way, and the command exits 9. This is best
|
|
265
|
+
effort: the service may not answer or may not confirm, and the CLI does not retry. A
|
|
266
|
+
token response that fails validation is dropped without a revocation request, because
|
|
267
|
+
the CLI cannot safely use anything in it; a server-side grant may remain active until it
|
|
268
|
+
expires or is revoked from the service.
|
|
269
|
+
|
|
270
|
+
The config directory is `--config-dir`, else `METERGRAPH_CONFIG_DIR` (an absolute
|
|
271
|
+
path), else `~/.config/metergraph` on Linux and macOS or `AppData\Roaming\Metergraph` in
|
|
272
|
+
your Windows profile. It holds `credentials/SLOT.json`:
|
|
273
|
+
|
|
274
|
+
- On Linux and macOS the directories must be `0700` and the file `0600`, all owned by
|
|
275
|
+
you. Existing paths with other permissions, other owners or symbolic links are
|
|
276
|
+
refused and never changed.
|
|
277
|
+
- On Windows the grant is encrypted with DPAPI for the current user before it is
|
|
278
|
+
written. File permissions alone are not relied on there.
|
|
279
|
+
|
|
280
|
+
`.metergraph/project.json` holds the origin, workspace ID, deployment profile and the
|
|
281
|
+
name of the credential slot. It holds no token, user name or absolute path, so it is
|
|
282
|
+
safe to commit. Other files in `.metergraph`, such as the skill receipt, are kept.
|
|
283
|
+
|
|
284
|
+
Access tokens near expiry are refreshed once, under a lock, and the new refresh token
|
|
285
|
+
is saved before it is used. If a refresh request may have reached the service but its
|
|
286
|
+
result was not saved (a timeout after sending, a dropped connection, a server error or
|
|
287
|
+
an unusable answer), the old refresh token is never sent again: the next use asks you
|
|
288
|
+
to run `login` again. A revoked grant or lost workspace access fails closed with exit
|
|
289
|
+
code 12.
|
|
290
|
+
|
|
291
|
+
`logout` asks the service to revoke the project's grant through its revocation
|
|
292
|
+
endpoint, then removes the saved grant and `.metergraph/project.json`. Other credential
|
|
293
|
+
slots and project files are kept. A `200` from the service means it accepted the
|
|
294
|
+
revocation request. If it does not answer `200`, local sign out still happens and the
|
|
295
|
+
command exits 13 with `revocation: "unconfirmed"`. A project that is not signed in
|
|
296
|
+
exits 0 without any request.
|
|
297
|
+
|
|
298
|
+
### setup
|
|
299
|
+
|
|
300
|
+
Run setup once from a project directory, choosing the coding client that will use
|
|
301
|
+
the skill:
|
|
302
|
+
|
|
303
|
+
```sh
|
|
304
|
+
metergraph setup --runtime local --client codex --project /path/to/project
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
For a customer-local bundle, point setup at its installed origin and exact
|
|
308
|
+
workspace:
|
|
309
|
+
|
|
310
|
+
```sh
|
|
311
|
+
metergraph setup --runtime local --deployment customer-local --url http://localhost:8080 --workspace 11111111-1111-4111-8111-111111111111 --confirm-prerequisites --client codex
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
`--confirm-prerequisites` records the operator's attestation that the released
|
|
315
|
+
signed bundle, registry invitation, local admin, and separate Metadata access
|
|
316
|
+
prerequisites are ready. It is not proof of bundle publication or registry
|
|
317
|
+
access. Setup checks the live deployment profile before login. BYOC uses
|
|
318
|
+
`--deployment byoc` and an explicit HTTPS private origin; its provisioning,
|
|
319
|
+
network, and identity prerequisites remain the operator's work. An optional
|
|
320
|
+
`--agent-token-file` can verify a separate Metadata credential for either
|
|
321
|
+
route. OSS uses separate `MG_TOKENS` ingestion and `MG_AGENT_TOKENS` read
|
|
322
|
+
credentials; `--deployment oss` verifies its Metadata route with a private
|
|
323
|
+
agent token file and hands ingest configuration to the operator. It does not
|
|
324
|
+
try hosted login or ingest bootstrap against OSS. Remote runtimes are handed
|
|
325
|
+
off to a local machine, with no implicit tunnel or credential forwarding.
|
|
326
|
+
|
|
327
|
+
If the project has no usable Metadata sign in, `setup` opens the deployment's
|
|
328
|
+
browser sign in and workspace choice. `--signup` starts at hosted sign up;
|
|
329
|
+
`--workspace UUID` requires that exact workspace. An existing binding to a
|
|
330
|
+
different origin or workspace requires explicit `--reconnect`. The selected
|
|
331
|
+
deployment must advertise `metergraph.cli-setup/v1` on its own origin. Setup
|
|
332
|
+
refuses reconnecting an existing ingest family to another workspace; its
|
|
333
|
+
original workspace must be restored before that family can be reused. Setup
|
|
334
|
+
checks the env file and Git state, then opens the deployment's consent page. An
|
|
335
|
+
owner or member of the verified workspace approves an ingest-only key. The CLI
|
|
336
|
+
redeems the single-use receipt, writes `METERGRAPH_APP_TOKEN` and
|
|
337
|
+
`METERGRAPH_INGEST_URL` into `.env`, checks the new key with the service, and
|
|
338
|
+
acknowledges delivery. It then installs the bundled skill for `codex`, `claude`
|
|
339
|
+
or `cursor`. Use `--skip-skill` only if you intentionally want to install it
|
|
340
|
+
later. Neither sign in nor setup requests Debug or Replay access. The browser
|
|
341
|
+
page shows the workspace and the consequence of approval. A signed-in browser
|
|
342
|
+
on another workspace must switch in Metergraph and rerun; the CLI does not
|
|
343
|
+
switch it automatically.
|
|
344
|
+
|
|
345
|
+
`METERGRAPH_INGEST_URL` is the deployment's service root. The Python SDK
|
|
346
|
+
appends `/v1/ingest` itself. A setup rerun with a verified
|
|
347
|
+
key repairs the endpoint value written by the first preview without minting a
|
|
348
|
+
new key.
|
|
349
|
+
|
|
350
|
+
The env file must be a project-relative `.env`, `.env.<name>` or `<name>.env`
|
|
351
|
+
(`--env-file` selects another). The writer refuses tracked files, links,
|
|
352
|
+
ambiguous dotenv syntax and unsafe paths. It adds a project `.gitignore` rule
|
|
353
|
+
when needed and makes the env file private; Windows uses a user-only ACL.
|
|
354
|
+
The env token is never printed, read from argv or stdin, or copied to the
|
|
355
|
+
project's setup state file. An already working key is checked and reused without
|
|
356
|
+
another browser approval.
|
|
357
|
+
|
|
358
|
+
`.metergraph/setup.json` holds a family UUID, its current key ID and fixed state,
|
|
359
|
+
but no credential. It is written before approval. If the redemption response is
|
|
360
|
+
lost, a rerun asks for a new browser approval for that same family. The server
|
|
361
|
+
resolves the request to creation if no key was issued or replacement of that
|
|
362
|
+
family's pending key if one exists; the old receipt is not retried. If an
|
|
363
|
+
acknowledged key no longer verifies or its env file was lost, use `--repair`
|
|
364
|
+
to explicitly approve replacement of that exact key.
|
|
365
|
+
An unsafe or changed state file is refused. If the earlier approval never
|
|
366
|
+
reached redemption, rerun the command; the `create` intent is still safe.
|
|
367
|
+
|
|
368
|
+
The JSON result includes a secret-free `receipt` with the origin, workspace ID,
|
|
369
|
+
deployment profile, selected client, and completed and pending steps. A skill
|
|
370
|
+
conflict leaves the delivered key in place and reports `credential_ready_skill_pending`;
|
|
371
|
+
resolve the skill file conflict and rerun setup without another approval.
|
|
372
|
+
Success means the key was delivered and the project is ready to instrument.
|
|
373
|
+
It does **not** mean application traffic has arrived. Run your application and
|
|
374
|
+
verify one exact trace afterward. The hosted service advertises the setup
|
|
375
|
+
contract, but each non-hosted deployment must be checked at its own origin.
|
|
376
|
+
Local protocol tests do not prove browser approval or real application traffic.
|
|
377
|
+
|
|
378
|
+
### Read commands
|
|
379
|
+
|
|
380
|
+
The read commands use the grant `login` saved for this project. They never open a
|
|
381
|
+
browser, never sign in on their own and never request another scope. Each one:
|
|
382
|
+
|
|
383
|
+
- reads `.metergraph/project.json` and the saved grant, and refreshes the grant at most
|
|
384
|
+
once, under the same lock and rules as `login` (an interrupted refresh is never
|
|
385
|
+
retried with a possibly used token);
|
|
386
|
+
- asks the service for `/v1/agent/workspace` and `/v1/agent/capabilities` and checks,
|
|
387
|
+
as `login` does, that the workspace, deployment profile and `agent:metadata` scope
|
|
388
|
+
still match the binding and that content, evidence and replay are unavailable;
|
|
389
|
+
- sends only `GET` requests to fixed paths on the bound origin, follows no redirects and
|
|
390
|
+
reads at most 1 MiB of a response;
|
|
391
|
+
- runs every request, including a refresh and any wait for another command that is
|
|
392
|
+
refreshing the same grant, within one total `--timeout-ms` deadline (1000 to 60000,
|
|
393
|
+
default 15000), which is never reset per request or page. A deadline exits 4
|
|
394
|
+
(`timeout`) and Ctrl+C exits 17, also while waiting for that lock; a lock held by
|
|
395
|
+
another process is never removed or taken over;
|
|
396
|
+
- prints only fields it validated. Unknown response fields are ignored and never named.
|
|
397
|
+
A metadata row that holds a field such as `prompt`, `messages`, `tool_calls` or
|
|
398
|
+
`access_token` is refused as a whole (exit 11). Names that contain control or
|
|
399
|
+
formatting characters are shown as `null`. Service warning and error text is not
|
|
400
|
+
printed. If any printed value, such as a workspace name, route name, cursor or
|
|
401
|
+
provenance source, contains a token the CLI holds for this project, nothing is
|
|
402
|
+
printed and the command exits 11 with `credential_in_metadata_response`.
|
|
403
|
+
|
|
404
|
+
Read commands do not change workspace configuration or telemetry, send no ingest data
|
|
405
|
+
and call no model provider. They are not side-effect free on the service: a command may
|
|
406
|
+
refresh its own saved grant, and the service may update its audit records and last used
|
|
407
|
+
times for the grant.
|
|
408
|
+
|
|
409
|
+
| Command | Request | What it prints |
|
|
410
|
+
| --- | --- | --- |
|
|
411
|
+
| `status` | `GET /healthz` and `GET /v1/deployment` (no credentials, checked as `doctor` does), then the two checks above | `configured`, `reachable`, `healthy`, `authenticated`, the bound (`intended`) and verified (`actual`) workspace, the bound deployment profile and `deployment_profile_verified`, scopes and capability flags. A `/v1/deployment` profile that differs from the binding exits 11 with `profile_mismatch` before the grant is used. `application_traffic_verified` is always `false`: a signed in project, existing data or a configured SDK does not prove that your application sends traffic. |
|
|
412
|
+
| `context` | the two checks above | Workspace ID, slug, name and creation time, Metadata retention days, whether the workspace captures content (never included here) and the access scope. |
|
|
413
|
+
| `capabilities` | the two checks above | Each known agent capability with `available`, `privacy_class`, `required_scope` and flags, and the service's bounds. Privacy class descriptions are not printed. |
|
|
414
|
+
| `usage` | `GET /v1/agent/usage?days=N&limit=N` | Daily rows per route: calls, errors, cost, tokens and latency (latency may be `null`), the window, evidence completeness, warning codes and totals of the returned rows. |
|
|
415
|
+
| `routes` | `GET /v1/agent/routes` | Route name, calls, replay eligible calls, evaluation contract version and hash, and whether a description or contract exists. |
|
|
416
|
+
| `traces` | `GET /v1/agent/traces?days=N&limit=N[&route=&status=&cursor=]` | One page of trace metadata: IDs, name, status, times, span count, tokens, cost (may be `null`), routes, providers and models, plus `next_cursor`. |
|
|
417
|
+
|
|
418
|
+
Bounds and honesty rules:
|
|
419
|
+
|
|
420
|
+
- `--days` is 1 to 90 (default 7) and `--limit` 1 to 200 (default 50, or 20 for
|
|
421
|
+
`traces`). Values outside these ranges exit 2. A value above the service's own
|
|
422
|
+
advertised `max_days` or `max_rows` exits 6 with `exceeds_service_bounds`; it is never
|
|
423
|
+
reduced silently.
|
|
424
|
+
- `usage` and `traces` report `truncated` and `complete`. Totals are sums of the
|
|
425
|
+
returned rows only; when `complete` is `false` they are not workspace totals. An
|
|
426
|
+
empty window is a successful result with `empty: true`.
|
|
427
|
+
- `GET /v1/agent/routes` takes no limit or window. The CLI validates every returned row,
|
|
428
|
+
keeps the first `--limit`, and reports `server_rows`, `truncated` and
|
|
429
|
+
`truncation: "local"`. Route descriptions, constraints and evaluation contract bodies
|
|
430
|
+
are never printed; `omitted_fields` lists them.
|
|
431
|
+
- `traces` fetches exactly one page. When more exist it returns `next_cursor`; pass it
|
|
432
|
+
back with `--cursor` to read the next page. The cursor is opaque and at most 512
|
|
433
|
+
printable characters. A page whose `limit` differs from the request, or rows that do
|
|
434
|
+
not match `--status` or `--route`, exit 11. Free-text filter values are not printed
|
|
435
|
+
back.
|
|
436
|
+
- The `traces` listing prints no trace links; each row has `link: null` and the
|
|
437
|
+
page reports `link_status: "server_link_unavailable"`. Exact-trace
|
|
438
|
+
`verify --open` uses a server link only when it includes the verified
|
|
439
|
+
workspace binding.
|
|
440
|
+
- `--environment`, `--workload`, `--since`, `--until`, `--sql`, `--query`, `--content`,
|
|
441
|
+
`--include-content`, `--debug` and `--replay` are recognized and refused with exit 6
|
|
442
|
+
before any request. The agent access contract has no environment selector or
|
|
443
|
+
absolute time range, and these commands never read content or replay. `--workload`
|
|
444
|
+
is refused by this CLI version because the returned trace rows do not show which
|
|
445
|
+
workload they belong to, so a filtered page could not be verified.
|
|
446
|
+
- A capability the service does not offer to this grant exits 14 without a read. A
|
|
447
|
+
refused read exits 15 (`insufficient_scope` or `forbidden`), rate limiting exits 16
|
|
448
|
+
with `retry_after_seconds` when the service sends a whole number of seconds, and a
|
|
449
|
+
token refused during the read exits 12. Nothing is retried. Ctrl+C exits 17.
|
|
450
|
+
|
|
451
|
+
A successful `usage`, shortened:
|
|
452
|
+
|
|
453
|
+
```json
|
|
454
|
+
{
|
|
455
|
+
"schema_version": 1,
|
|
456
|
+
"command": "usage",
|
|
457
|
+
"ok": true,
|
|
458
|
+
"outcome": "ok",
|
|
459
|
+
"exit_code": 0,
|
|
460
|
+
"data": {
|
|
461
|
+
"origin": "https://metergraph.example.com",
|
|
462
|
+
"workspace": { "id": "0b5c7c1e-1a2b-4c3d-8e4f-5a6b7c8d9e01" },
|
|
463
|
+
"deployment_profile": "managed",
|
|
464
|
+
"authenticated": true,
|
|
465
|
+
"scopes": ["agent:metadata"],
|
|
466
|
+
"result": {
|
|
467
|
+
"provenance": {
|
|
468
|
+
"deployment_profile": "managed",
|
|
469
|
+
"workspace_id": "0b5c7c1e-1a2b-4c3d-8e4f-5a6b7c8d9e01",
|
|
470
|
+
"generated_at": "2026-01-08T12:00:00Z",
|
|
471
|
+
"source": "example-source"
|
|
472
|
+
},
|
|
473
|
+
"window": { "days": 7, "since": "2026-01-01T12:00:00Z", "until": "2026-01-08T12:00:00Z" },
|
|
474
|
+
"evidence": { "sources": ["telemetry"], "rows": 1, "complete": true },
|
|
475
|
+
"warnings": [],
|
|
476
|
+
"content_included": false,
|
|
477
|
+
"truncated": false,
|
|
478
|
+
"complete": true,
|
|
479
|
+
"empty": false,
|
|
480
|
+
"rows": 1,
|
|
481
|
+
"items": [
|
|
482
|
+
{
|
|
483
|
+
"date": "2026-01-02",
|
|
484
|
+
"route": "checkout-summary",
|
|
485
|
+
"calls": 40,
|
|
486
|
+
"error_calls": 2,
|
|
487
|
+
"cost_usd": 0.0125,
|
|
488
|
+
"input_tokens": 12000,
|
|
489
|
+
"output_tokens": 3400,
|
|
490
|
+
"avg_latency_ms": 820,
|
|
491
|
+
"p95_latency_ms": null
|
|
492
|
+
}
|
|
493
|
+
],
|
|
494
|
+
"totals": {
|
|
495
|
+
"scope": "returned_rows",
|
|
496
|
+
"complete": true,
|
|
497
|
+
"calls": 40,
|
|
498
|
+
"error_calls": 2,
|
|
499
|
+
"cost_usd": 0.0125,
|
|
500
|
+
"input_tokens": 12000,
|
|
501
|
+
"output_tokens": 3400
|
|
502
|
+
}
|
|
503
|
+
},
|
|
504
|
+
"retry_after_seconds": null,
|
|
505
|
+
"notices": [],
|
|
506
|
+
"next_action": null
|
|
507
|
+
},
|
|
508
|
+
"error": null
|
|
509
|
+
}
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
On failure `result` is `null`, `authenticated` says whether the grant was verified
|
|
513
|
+
before the failure, and `notices` lists fixed tokens such as `rows_truncated`,
|
|
514
|
+
`evidence_incomplete`, `routes_truncated_locally`, `unsafe_text_omitted` or
|
|
515
|
+
`trace_links_unavailable`.
|
|
516
|
+
|
|
151
517
|
## Exit codes
|
|
152
518
|
|
|
153
|
-
Exit codes are stable. Changing one is a breaking change.
|
|
519
|
+
Exit codes are stable. Changing one is a breaking change. Codes 10 to 17 were
|
|
520
|
+
added in `0.2.0-preview.0` and are unavailable in `0.1.0`.
|
|
154
521
|
|
|
155
522
|
| Code | Outcome | Meaning |
|
|
156
523
|
| --- | --- | --- |
|
|
@@ -160,10 +527,18 @@ Exit codes are stable. Changing one is a breaking change.
|
|
|
160
527
|
| 3 | `authentication_required` | Service is reachable, healthy and supported, and requires authentication. No workspace is connected. |
|
|
161
528
|
| 4 | `connection_failed` | The origin could not be reached, the connection failed, or the probe timed out. |
|
|
162
529
|
| 5 | `unhealthy` | The service answered but reported that it is not healthy, or answered with a server error. |
|
|
163
|
-
| 6 | `unsupported` | The service answered with a response, deployment profile or status this CLI does not support, or the skill client or runtime cannot use project skill files. Nothing was written. |
|
|
530
|
+
| 6 | `unsupported` | The service answered with a response, deployment profile or status this CLI does not support, or the skill client or runtime cannot use project skill files, or sign in cannot run in this environment. Nothing was written. |
|
|
164
531
|
| 7 | `redirect_rejected` | The service answered with a redirect. Redirects are never followed. |
|
|
165
|
-
| 8 | `conflict` | The skill target is not owned by this CLI, was modified, is unsafe, is locked or needs an explicit update. Nothing was changed. |
|
|
166
|
-
| 9 | `filesystem_error` | Project files could not be read or written. Partial changes were rolled back unless the message says otherwise. |
|
|
532
|
+
| 8 | `conflict` | The skill target is not owned by this CLI, was modified, is unsafe, is locked or needs an explicit update, or the project is bound to a different origin or workspace. Nothing was changed. |
|
|
533
|
+
| 9 | `filesystem_error` | Project or credential files could not be read or written. Partial changes were rolled back unless the message says otherwise. |
|
|
534
|
+
| 10 | `authorization_failed` | Browser authorization did not finish: it was denied, cancelled, timed out or returned an invalid callback. Nothing was saved. |
|
|
535
|
+
| 11 | `verification_failed` | The service issued a grant that does not match the requested origin, workspace, client, resource or Metadata scope. Nothing was saved. |
|
|
536
|
+
| 12 | `login_required` | No usable sign in for this project: none was saved, it expired, was revoked, lost access or could not be refreshed safely. Run login again. |
|
|
537
|
+
| 13 | `revocation_unconfirmed` | Local credentials were removed, but the service did not confirm that the grant was revoked. |
|
|
538
|
+
| 14 | `capability_unavailable` | The service does not make this read available to the project's Metadata grant. No data was read. |
|
|
539
|
+
| 15 | `permission_denied` | The service refused this read for the signed in grant, for example for a missing scope or permission. |
|
|
540
|
+
| 16 | `rate_limited` | The service asked the CLI to slow down. Nothing was retried. Try again later. |
|
|
541
|
+
| 17 | `cancelled` | A read command was interrupted before it finished. Read commands never change workspace configuration or telemetry. |
|
|
167
542
|
|
|
168
543
|
## JSON output
|
|
169
544
|
|
|
@@ -226,8 +601,8 @@ A successful `skill install`:
|
|
|
226
601
|
"status": "installed",
|
|
227
602
|
"source": {
|
|
228
603
|
"name": "metergraph",
|
|
229
|
-
"revision": "sha256-
|
|
230
|
-
"sha256": "
|
|
604
|
+
"revision": "sha256-57b920677adf",
|
|
605
|
+
"sha256": "57b920677adf62759c7221629327192a2d16b7e6034f7948ffd96cee402d4891"
|
|
231
606
|
},
|
|
232
607
|
"discovery": "pending",
|
|
233
608
|
"authenticated": false,
|
|
@@ -247,7 +622,57 @@ A successful `skill install`:
|
|
|
247
622
|
`receipt_invalid`, `locked`, `invalid_project`, `client_not_supported`,
|
|
248
623
|
`write_failed` or `bundled_skill_invalid`.
|
|
249
624
|
|
|
625
|
+
A successful `login`:
|
|
626
|
+
|
|
627
|
+
```json
|
|
628
|
+
{
|
|
629
|
+
"schema_version": 1,
|
|
630
|
+
"command": "login",
|
|
631
|
+
"ok": true,
|
|
632
|
+
"outcome": "ok",
|
|
633
|
+
"exit_code": 0,
|
|
634
|
+
"data": {
|
|
635
|
+
"origin": "https://metergraph.example.com",
|
|
636
|
+
"runtime": "local",
|
|
637
|
+
"deployment_profile": "managed",
|
|
638
|
+
"workspace": { "id": "0b5c7c1e-1a2b-4c3d-8e4f-5a6b7c8d9e01" },
|
|
639
|
+
"scopes": ["agent:metadata"],
|
|
640
|
+
"authenticated": true,
|
|
641
|
+
"configured": true,
|
|
642
|
+
"status": "signed_in",
|
|
643
|
+
"binding": ".metergraph/project.json",
|
|
644
|
+
"credential_protection": "owner_only_file",
|
|
645
|
+
"previous_grant_revocation": null,
|
|
646
|
+
"next_action": {
|
|
647
|
+
"kind": "connected",
|
|
648
|
+
"message": "This project is signed in with Metadata access. Run \"metergraph logout\" to sign out."
|
|
649
|
+
}
|
|
650
|
+
},
|
|
651
|
+
"error": null
|
|
652
|
+
}
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
- `status` is `signed_in`, `reused` (already signed in and verified, nothing changed)
|
|
656
|
+
or `reconnected` (a new grant replaced the previous one; `previous_grant_revocation`
|
|
657
|
+
is then `accepted`, `unconfirmed` or `not_attempted`).
|
|
658
|
+
- `credential_protection` is `owner_only_file` or `dpapi`.
|
|
659
|
+
- On failure `authenticated` and `configured` are `false`, `scopes` is empty, and
|
|
660
|
+
`next_action` is `null` or a handoff such as `connection_guide`, `reconnect`,
|
|
661
|
+
`run_in_terminal` or `no_browser`.
|
|
662
|
+
- The schema version `1` is the version of this CLI's own JSON output. It is unrelated
|
|
663
|
+
to the service's agent access contract version, `metergraph.agent-access/v1`.
|
|
664
|
+
- `login` and `logout` never print tokens, the authorization code, the PKCE verifier,
|
|
665
|
+
user names, email addresses, workspace names, absolute paths or server text. The
|
|
666
|
+
read commands never print tokens, email addresses, absolute paths or server error
|
|
667
|
+
text either; `context` prints the workspace slug and name, and the read commands
|
|
668
|
+
print validated route, trace, provider and model names, as described above.
|
|
669
|
+
|
|
670
|
+
`logout` prints `local_credentials` (`removed` or `none`), `binding` (`removed`,
|
|
671
|
+
`kept` or `none`) and `revocation` (`accepted`, `unconfirmed` or `not_attempted`).
|
|
672
|
+
|
|
250
673
|
Without `--json`, results are printed as text on stdout and usage errors go to stderr.
|
|
674
|
+
`login` prints progress lines, and with `--no-browser` the authorization URL, on
|
|
675
|
+
stderr.
|
|
251
676
|
|
|
252
677
|
## Safe origins
|
|
253
678
|
|
|
@@ -259,7 +684,7 @@ Without `--json`, results are printed as text on stdout and usage errors go to s
|
|
|
259
684
|
Usernames, passwords, paths, queries and fragments are rejected before any request is
|
|
260
685
|
made. Invalid values and unknown arguments are not printed back, because a mistyped
|
|
261
686
|
argument can contain a credential. An accepted origin is printed in the output and sent
|
|
262
|
-
to the network, so do not put secrets in a hostname. See [
|
|
687
|
+
to the network, so do not put secrets in a hostname. See [Security](#security).
|
|
263
688
|
|
|
264
689
|
## Deployment profiles
|
|
265
690
|
|
|
@@ -287,6 +712,36 @@ CLI never assumes such a server is hosted.
|
|
|
287
712
|
- It does not claim a client has loaded the skill. `discovery` stays `pending`.
|
|
288
713
|
- It never prints file contents, absolute paths or raw error text.
|
|
289
714
|
|
|
715
|
+
## What login does not do
|
|
716
|
+
|
|
717
|
+
- It never asks for Debug (`agent:read`) or Replay (`agent:replay`) access, and never
|
|
718
|
+
falls back to them when the service does not offer `agent:metadata`.
|
|
719
|
+
- It never copies browser cookies or the browser's sign in.
|
|
720
|
+
- It does not create an application ingest key, and no manual API key is required. The
|
|
721
|
+
service records the grant as an OAuth connection on its own side; that connection
|
|
722
|
+
can only use `agent:metadata`, is separate from any API or ingest key you manage, and
|
|
723
|
+
is what `logout` asks the service to revoke.
|
|
724
|
+
- It reads no telemetry, retained content or traces, and makes no model provider calls.
|
|
725
|
+
- It sends the grant only to the origin it came from, follows no redirects and reads
|
|
726
|
+
bounded responses within fixed time limits.
|
|
727
|
+
- It accepts no credential on the command line, in the environment or on stdin.
|
|
728
|
+
|
|
729
|
+
## What the read commands do not do
|
|
730
|
+
|
|
731
|
+
- They never sign in, open a browser, create a grant or change the project binding.
|
|
732
|
+
The only file they may write is the saved grant, when a refresh rotates it.
|
|
733
|
+
- They never request `agent:read` or `agent:replay`, never read retained content,
|
|
734
|
+
evidence or replays, and never call a model provider.
|
|
735
|
+
- They make only `GET` requests to the read endpoints (a grant refresh, when needed, is
|
|
736
|
+
the only `POST`). They send no ingest data and change no evaluations, provider
|
|
737
|
+
settings, workspace configuration or telemetry. The service may still record the
|
|
738
|
+
access, for example audit entries and the grant's last used time.
|
|
739
|
+
- They never print a token the CLI holds, even inside an otherwise valid name.
|
|
740
|
+
- They never follow a cursor or page on their own, and never widen a request: an
|
|
741
|
+
unsupported option, an out of range value or a capability the grant lacks fails
|
|
742
|
+
instead.
|
|
743
|
+
- They accept no credential on the command line, in the environment or on stdin.
|
|
744
|
+
|
|
290
745
|
## Development
|
|
291
746
|
|
|
292
747
|
```sh
|
|
@@ -295,13 +750,20 @@ npm run test:package # npm pack into a temporary directory, clean install,
|
|
|
295
750
|
node bin/metergraph.js --help
|
|
296
751
|
node bin/metergraph.js doctor --url http://127.0.0.1:8080 --json
|
|
297
752
|
node bin/metergraph.js skill install --client claude --runtime local --project /path/to/project --json
|
|
753
|
+
node bin/metergraph.js login --runtime local --url http://127.0.0.1:8080 --project /path/to/project
|
|
298
754
|
```
|
|
299
755
|
|
|
756
|
+
The sign in and read command tests run against a synthetic loopback service and a
|
|
757
|
+
test-only browser stand-in loaded with `--import`. They prove the protocol, file
|
|
758
|
+
handling and output rules, not the real service, a real browser, real workspace
|
|
759
|
+
consent or real workspace data. The Windows DPAPI round trip
|
|
760
|
+
runs only on the Windows CI runner.
|
|
761
|
+
|
|
300
762
|
To try a packed artifact without publishing:
|
|
301
763
|
|
|
302
764
|
```sh
|
|
303
765
|
npm pack --pack-destination "$(mktemp -d)"
|
|
304
|
-
npx --yes --package=/path/to/metergraph-cli-0.
|
|
766
|
+
npx --yes --package=/path/to/metergraph-cli-0.2.0-preview.1.tgz -- metergraph --version
|
|
305
767
|
```
|
|
306
768
|
|
|
307
769
|
Do not commit tarballs or other generated files.
|
|
@@ -310,8 +772,9 @@ Do not commit tarballs or other generated files.
|
|
|
310
772
|
|
|
311
773
|
The source of truth is the public repository
|
|
312
774
|
[github.com/metergraph/cli](https://github.com/metergraph/cli), licensed Apache-2.0.
|
|
313
|
-
|
|
314
|
-
|
|
775
|
+
`0.2.0-preview.1` is published on the `next` npm tag; `latest` remains on
|
|
776
|
+
`0.1.0`. The hosted service supports sign in, Metadata reads and ingest bootstrap.
|
|
777
|
+
Subsequent releases must pass the checks below before publication.
|
|
315
778
|
|
|
316
779
|
Releases are manual. The `Release CLI` workflow (`.github/workflows/release.yml`) runs
|
|
317
780
|
only when a maintainer starts it from `main`. It does not run on tags, pushes or a
|
|
@@ -343,12 +806,12 @@ commit:
|
|
|
343
806
|
- If `main` moves after you copy the SHA, the run fails. Start a new run with the new
|
|
344
807
|
head. To release an older state, land it on `main` first.
|
|
345
808
|
|
|
346
|
-
### First package bootstrap
|
|
809
|
+
### First package bootstrap (completed for 0.1.0)
|
|
347
810
|
|
|
348
811
|
npm trusted publishing is configured on a package that already exists, so the very
|
|
349
|
-
first version
|
|
350
|
-
|
|
351
|
-
|
|
812
|
+
first version could not come from this workflow. The steps below describe the
|
|
813
|
+
completed bootstrap of `0.1.0`; they are not part of subsequent releases. No npm
|
|
814
|
+
token or secret is stored here.
|
|
352
815
|
|
|
353
816
|
1. Confirm the intended npm maintainer accounts and that `metergraph-cli` is
|
|
354
817
|
available. The first approved publish establishes package ownership.
|
|
@@ -377,15 +840,13 @@ Trusted publishing requires npm 11.5.1 or newer. The publish job checks this bef
|
|
|
377
840
|
publishes. After the trusted publisher works, consider restricting the package to
|
|
378
841
|
trusted publishing so that long lived tokens cannot publish it.
|
|
379
842
|
|
|
380
|
-
###
|
|
843
|
+
### Release configuration
|
|
381
844
|
|
|
382
|
-
|
|
383
|
-
maintainer still has to:
|
|
845
|
+
Before an automated publish, confirm the following settings are still in place:
|
|
384
846
|
|
|
385
|
-
-
|
|
386
|
-
-
|
|
387
|
-
-
|
|
388
|
-
- set the repository variable `METERGRAPH_CLI_PUBLISH_ENABLED` to `true`.
|
|
847
|
+
- the [trusted publisher](#trusted-publishing) matches this repository and workflow;
|
|
848
|
+
- the `npm-release` environment has required reviewers;
|
|
849
|
+
- the repository variable `METERGRAPH_CLI_PUBLISH_ENABLED` is `true`.
|
|
389
850
|
|
|
390
851
|
Until all of these are done, leave `publish` false.
|
|
391
852
|
|
|
@@ -404,7 +865,13 @@ Releases from the workflow should show a provenance attestation that names
|
|
|
404
865
|
|
|
405
866
|
## Security
|
|
406
867
|
|
|
407
|
-
|
|
868
|
+
Report security issues privately through
|
|
869
|
+
[GitHub private vulnerability reporting](https://github.com/metergraph/cli/security/advisories/new)
|
|
870
|
+
for `metergraph/cli`. Do not open a public issue, and do not include real credentials,
|
|
871
|
+
tokens or customer data in a report. The security policy and the CLI's security
|
|
872
|
+
properties are in `SECURITY.md` in the
|
|
873
|
+
[source repository](https://github.com/metergraph/cli); it is not shipped in the npm
|
|
874
|
+
package.
|
|
408
875
|
|
|
409
876
|
## License
|
|
410
877
|
|