metergraph-cli 0.2.3 → 0.2.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 +78 -14
- package/assets/skill/SKILL.md +124 -31
- package/assets/skill/manifest.json +3 -3
- package/assets/skills/manifest.json +31 -31
- package/assets/skills/metergraph-analyze/SKILL.md +161 -58
- package/assets/skills/metergraph-candidates/SKILL.md +50 -8
- package/assets/skills/metergraph-evals/SKILL.md +83 -16
- package/assets/skills/metergraph-investigate/SKILL.md +90 -34
- package/assets/skills/metergraph-iterate/SKILL.md +82 -12
- package/assets/skills/metergraph-local-bundle/SKILL.md +146 -128
- package/assets/skills/metergraph-model-swap/SKILL.md +142 -20
- package/assets/skills/metergraph-onboarding/SKILL.md +93 -49
- package/assets/skills/metergraph-report/SKILL.md +60 -15
- package/assets/skills/metergraph-workloads/SKILL.md +97 -13
- package/native/README.md +85 -0
- package/native/anchored-fs.c +243 -0
- package/native/bin/anchored-fs-darwin-arm64 +0 -0
- package/native/bin/anchored-fs-darwin-x64 +0 -0
- package/native/bin/anchored-fs-linux-arm64 +0 -0
- package/native/bin/anchored-fs-linux-x64 +0 -0
- package/native/build.mjs +55 -0
- package/native/manifest.json +9 -0
- package/native/targets.mjs +24 -0
- package/package.json +10 -3
- package/src/action-help.js +130 -0
- package/src/agent-key.js +21 -14
- package/src/anchored-fs.js +163 -0
- package/src/args.js +125 -17
- package/src/auth-binding.js +12 -7
- package/src/auth-callback.js +10 -2
- package/src/auth-login.js +111 -28
- package/src/auth-oauth.js +89 -45
- package/src/auth-session.js +19 -12
- package/src/auth-store.js +28 -7
- package/src/cli.js +52 -8
- package/src/constants.js +37 -9
- package/src/experiments-output.js +7 -6
- package/src/experiments.js +26 -17
- package/src/output.js +274 -79
- package/src/read-contract.js +42 -8
- package/src/read-output.js +66 -13
- package/src/read.js +90 -15
- package/src/repository-identity.js +2 -2
- package/src/setup-env-git.js +1 -1
- package/src/setup-env.js +16 -9
- package/src/setup-interactive.js +19 -4
- package/src/setup-refusal.js +2 -2
- package/src/setup-state.js +9 -4
- package/src/setup.js +15 -3
- package/src/skill-bundle.js +2 -2
- package/src/skill-trusted.js +56 -0
- package/src/skill.js +28 -9
- package/src/style.js +33 -7
- package/src/tools-output.js +73 -0
- package/src/tools.js +249 -0
- package/src/trace-contract.js +1 -1
- package/src/transport.js +21 -0
- package/src/verify-output.js +2 -2
- package/src/verify.js +5 -2
package/src/output.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { actionHelpData, displayOptions } from "./action-help.js";
|
|
1
2
|
import { PRICING_OPTIONS } from "./pricing-args.js";
|
|
2
3
|
import {
|
|
3
4
|
CONNECTION_GUIDE_URL,
|
|
@@ -28,7 +29,7 @@ import {
|
|
|
28
29
|
SUPPORTED_PROFILES,
|
|
29
30
|
VERSION,
|
|
30
31
|
} from "./constants.js";
|
|
31
|
-
import { PLAIN, fields, headline, paragraph, render, section, steps, toneFor } from "./style.js";
|
|
32
|
+
import { PLAIN, fields, headline, paragraph, render, section, steps, toneFor, workspaceShown } from "./style.js";
|
|
32
33
|
|
|
33
34
|
// Every JSON result, success or failure, has the same top-level keys:
|
|
34
35
|
// schema_version, command, ok, outcome, exit_code, data, error
|
|
@@ -49,7 +50,20 @@ export function envelope({ command, outcome, data = null, reason = null, message
|
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
export function toJsonLine(result) {
|
|
52
|
-
return `${
|
|
53
|
+
return `${jsonText(result)}\n`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// JSON.stringify escapes C0 controls but leaves C1 controls (a terminal may
|
|
57
|
+
// read U+009B as an escape sequence) and bidirectional overrides as they are.
|
|
58
|
+
// Inside a JSON string \uXXXX means the same character, so escaping them
|
|
59
|
+
// changes nothing a parser sees and keeps them away from the terminal.
|
|
60
|
+
const TERMINAL_UNSAFE = /[\u061c\u007f-\u009f\u200e\u200f\u2028\u2029\u202a-\u202e\u2066-\u2069]/g;
|
|
61
|
+
|
|
62
|
+
export function jsonText(value, indent = undefined) {
|
|
63
|
+
return JSON.stringify(value, null, indent).replace(
|
|
64
|
+
TERMINAL_UNSAFE,
|
|
65
|
+
(character) => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`,
|
|
66
|
+
);
|
|
53
67
|
}
|
|
54
68
|
|
|
55
69
|
const DOCTOR_OPTIONS = [
|
|
@@ -126,9 +140,14 @@ const AGENT_PATH_HELP = [
|
|
|
126
140
|
" SSH, cloud workspace or CI A person creates a coding-agent key with Metadata access",
|
|
127
141
|
" on the Keys page and saves it as the secret",
|
|
128
142
|
" METERGRAPH_AGENT_TOKEN; then status --json, usage --json",
|
|
129
|
-
"
|
|
143
|
+
" A key, no saved sign in The same: reads use METERGRAPH_AGENT_TOKEN, or",
|
|
130
144
|
" --agent-token-file PATH, after verifying the workspace",
|
|
131
|
-
"
|
|
145
|
+
" Evaluations and analyses A workspace owner creates a key with the Debug role and",
|
|
146
|
+
" Allow evaluation writes, Allow evaluation previews and",
|
|
147
|
+
" Allow analysis starts; the same METERGRAPH_AGENT_TOKEN",
|
|
148
|
+
" serves the reads. status --json reports the role and each",
|
|
149
|
+
" permission in data.access",
|
|
150
|
+
"Never pass a key as an argument. Replay keys are refused.",
|
|
132
151
|
];
|
|
133
152
|
|
|
134
153
|
const CONFIG_DIR_OPTION = {
|
|
@@ -144,14 +163,34 @@ const LOGIN_OPTIONS = [
|
|
|
144
163
|
name: "--runtime",
|
|
145
164
|
value: "RUNTIME",
|
|
146
165
|
summary:
|
|
147
|
-
"Required. Where this terminal runs, not which Metergraph service. local: your own machine, " +
|
|
166
|
+
"Required for scripts; inferred as local in an interactive local terminal. Where this terminal runs, not which Metergraph service. local: your own machine, " +
|
|
148
167
|
"including for the hosted service. cloud, cloud-no-shell: a cloud sandbox; get the connection guide.",
|
|
149
168
|
},
|
|
150
169
|
{ name: "--url", value: "ORIGIN", summary: `Origin to sign in to. Default ${DEFAULT_ORIGIN}.` },
|
|
151
170
|
{
|
|
152
171
|
name: "--workspace",
|
|
153
|
-
value: "
|
|
154
|
-
summary:
|
|
172
|
+
value: "SLUG",
|
|
173
|
+
summary:
|
|
174
|
+
"The workspace to sign in to, by its slug (on its Settings page) or its name. A service that can, offers " +
|
|
175
|
+
"approval for that workspace alone; sign in fails unless the browser grants it.",
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: "--role",
|
|
179
|
+
value: "ROLE",
|
|
180
|
+
summary:
|
|
181
|
+
"metadata (default): usage, cost and trace questions, no captured content. debug: also reads captured " +
|
|
182
|
+
"prompts and responses through Agent Access; the --allow-* options add workflow permissions to it.",
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: "--allow-evaluation-writes",
|
|
186
|
+
value: null,
|
|
187
|
+
summary: "With --role debug: Allow evaluation writes. Only a workspace owner approves the workflow permissions.",
|
|
188
|
+
},
|
|
189
|
+
{ name: "--allow-evaluation-previews", value: null, summary: "With --role debug: Allow evaluation previews." },
|
|
190
|
+
{
|
|
191
|
+
name: "--allow-analysis-starts",
|
|
192
|
+
value: null,
|
|
193
|
+
summary: "With --role debug: Allow analysis starts, which replays captured prompts on model providers and spends money.",
|
|
155
194
|
},
|
|
156
195
|
{ name: "--project", value: "DIR", summary: "Existing project directory to bind. Default: the current directory." },
|
|
157
196
|
CONFIG_DIR_OPTION,
|
|
@@ -173,8 +212,9 @@ const LOGOUT_OPTIONS = [
|
|
|
173
212
|
];
|
|
174
213
|
|
|
175
214
|
const LOGIN_USAGE =
|
|
176
|
-
"metergraph login --runtime local [--url ORIGIN] [--workspace
|
|
177
|
-
"[--
|
|
215
|
+
"metergraph login --runtime local [--url ORIGIN] [--workspace SLUG] [--role metadata|debug] " +
|
|
216
|
+
"[--allow-evaluation-writes] [--allow-evaluation-previews] [--allow-analysis-starts] [--project DIR] " +
|
|
217
|
+
"[--config-dir DIR] [--timeout-ms N] [--signup] [--no-browser] [--reconnect] [--json]";
|
|
178
218
|
const LOGOUT_USAGE = "metergraph logout [--project DIR] [--config-dir DIR] [--json]";
|
|
179
219
|
const SETUP_USAGE = "metergraph setup --runtime local (--client codex|claude|cursor | --skip-skill) " +
|
|
180
220
|
"[--url ORIGIN] [--workspace UUID] [--project DIR] [--config-dir DIR] [--env-file .env] " +
|
|
@@ -217,19 +257,21 @@ const READ_BASE_OPTIONS = [
|
|
|
217
257
|
name: "--url",
|
|
218
258
|
value: "ORIGIN",
|
|
219
259
|
summary:
|
|
220
|
-
"Where a
|
|
260
|
+
"Where a coding-agent key is sent when the project is not bound. Default METERGRAPH_URL, else the hosted service. " +
|
|
221
261
|
"A bound project's origin cannot be changed here.",
|
|
222
262
|
},
|
|
223
263
|
{
|
|
224
264
|
name: "--workspace",
|
|
225
|
-
value: "
|
|
226
|
-
summary:
|
|
265
|
+
value: "SLUG",
|
|
266
|
+
summary:
|
|
267
|
+
"The workspace the credential must be for, by its slug or name (or ID). Without it, an unbound key's own " +
|
|
268
|
+
"workspace is used.",
|
|
227
269
|
},
|
|
228
270
|
{
|
|
229
271
|
name: "--agent-token-file",
|
|
230
272
|
value: "PATH",
|
|
231
273
|
summary:
|
|
232
|
-
"Private (0600) file holding a coding-agent key with Metadata
|
|
274
|
+
"Private (0600) file holding a coding-agent key with the Metadata or Debug role. Used instead of a saved sign in. " +
|
|
233
275
|
"Without it, METERGRAPH_AGENT_TOKEN is used when this project has no saved sign in on this machine.",
|
|
234
276
|
},
|
|
235
277
|
];
|
|
@@ -259,11 +301,29 @@ const EXPERIMENTS_OPTIONS = [
|
|
|
259
301
|
name: "--agent-token-file",
|
|
260
302
|
value: "PATH",
|
|
261
303
|
summary:
|
|
262
|
-
"Private (0600) file holding a coding-agent key. For list, estimate and get: a key with Metadata
|
|
304
|
+
"Private (0600) file holding a coding-agent key. For list, estimate and get: a key with the Metadata or Debug role. " +
|
|
263
305
|
"For start: a key with Debug access and Allow analysis starts, used for that one request.",
|
|
264
306
|
},
|
|
265
307
|
JSON_OPTION,
|
|
266
308
|
];
|
|
309
|
+
const TOOLS_USAGE = [
|
|
310
|
+
"metergraph tools list [--name TOOL] [read options] [--json]",
|
|
311
|
+
"metergraph tools call TOOL [--args JSON | --args-file PATH] [--yes] [read options] [--json]",
|
|
312
|
+
];
|
|
313
|
+
const TOOLS_OPTIONS = [
|
|
314
|
+
{ name: "--name", value: "TOOL", summary: "list only: show one tool, with its input schema under --json." },
|
|
315
|
+
{ name: "--args", value: "JSON", summary: "call only: the tool's arguments as one JSON object. Default {}." },
|
|
316
|
+
{ name: "--args-file", value: "PATH", summary: "call only: a file holding the arguments as one JSON object, up to 1 MiB." },
|
|
317
|
+
{
|
|
318
|
+
name: "--yes",
|
|
319
|
+
value: null,
|
|
320
|
+
summary:
|
|
321
|
+
"call only: run a tool that writes, starts work or calls a model provider. Pass it only after the person " +
|
|
322
|
+
"has approved this exact call.",
|
|
323
|
+
},
|
|
324
|
+
...READ_BASE_OPTIONS,
|
|
325
|
+
JSON_OPTION,
|
|
326
|
+
];
|
|
267
327
|
const DAYS_OPTION = {
|
|
268
328
|
name: "--days",
|
|
269
329
|
value: "N",
|
|
@@ -291,21 +351,23 @@ const limitOption = (fallback, extra = "") => ({
|
|
|
291
351
|
summary: `Rows to return, 1 to ${READ_MAX_LIMIT}. Default ${fallback}.${extra}`,
|
|
292
352
|
});
|
|
293
353
|
const READ_BASE_USAGE =
|
|
294
|
-
"[--url ORIGIN] [--workspace
|
|
354
|
+
"[--url ORIGIN] [--workspace SLUG] [--agent-token-file PATH] [--project DIR] [--config-dir DIR] [--timeout-ms N] [--json]";
|
|
295
355
|
const REFUSED_NOTE =
|
|
296
356
|
"--environment, --workload, --since, --until, --sql, --query, --content, --include-content, --debug and --replay " +
|
|
297
357
|
"are recognized and refused with exit code 6 before any request, except --environment, --since and --until on usage.";
|
|
298
358
|
|
|
299
359
|
// The read commands. Each uses the project's saved Metadata grant or a
|
|
300
|
-
// coding-agent key with Metadata
|
|
301
|
-
// the verified origin and never opens a browser.
|
|
360
|
+
// coding-agent key with the Metadata or Debug role, makes GET requests to fixed
|
|
361
|
+
// paths on the verified origin and never opens a browser.
|
|
302
362
|
export const READ_HELP = Object.freeze([
|
|
303
363
|
{
|
|
304
364
|
name: "status",
|
|
305
365
|
usage: `metergraph status ${READ_BASE_USAGE}`,
|
|
306
366
|
summary:
|
|
307
367
|
"Show whether this project is configured, the service is reachable and reports the bound deployment " +
|
|
308
|
-
"profile, and the grant is verified for the bound workspace, with its Metadata capabilities. " +
|
|
368
|
+
"profile, and the grant is verified for the bound workspace, with its Metadata capabilities. Reports " +
|
|
369
|
+
"the credential's role (Metadata or Debug) and its workflow permissions (Allow evaluation writes, Allow " +
|
|
370
|
+
"evaluation previews, Allow analysis starts) in data.access, and how to grant them. " +
|
|
309
371
|
"Never claims application traffic is verified.",
|
|
310
372
|
options: [...READ_BASE_OPTIONS, JSON_OPTION],
|
|
311
373
|
},
|
|
@@ -449,8 +511,8 @@ function optionLines(options, minimum) {
|
|
|
449
511
|
return options.map((option, index) => ` ${flags[index].padEnd(width)}${option.summary}`);
|
|
450
512
|
}
|
|
451
513
|
|
|
452
|
-
export function helpData(topic) {
|
|
453
|
-
|
|
514
|
+
export function helpData(topic, action = null) {
|
|
515
|
+
const data = {
|
|
454
516
|
topic,
|
|
455
517
|
usage: [
|
|
456
518
|
"metergraph --help [--json]",
|
|
@@ -465,6 +527,7 @@ export function helpData(topic) {
|
|
|
465
527
|
VERIFY_USAGE,
|
|
466
528
|
...READ_HELP.map((entry) => entry.usage),
|
|
467
529
|
...EXPERIMENTS_USAGE,
|
|
530
|
+
...TOOLS_USAGE,
|
|
468
531
|
],
|
|
469
532
|
commands: [
|
|
470
533
|
{ name: "pricing", summary: "Public model discovery, lookup and calculation. Current market board; historical charts in local reference mode.",
|
|
@@ -492,7 +555,7 @@ export function helpData(topic) {
|
|
|
492
555
|
{
|
|
493
556
|
name: "skills install",
|
|
494
557
|
summary:
|
|
495
|
-
"Copy the Metergraph workflow skills bundled with this CLI, such as
|
|
558
|
+
"Copy the Metergraph workflow skills bundled with this CLI, such as model swap, into one " +
|
|
496
559
|
"client's project skill directory. Never replaces a skill it did not install. No network requests, no sign in.",
|
|
497
560
|
options: SKILL_OPTIONS,
|
|
498
561
|
},
|
|
@@ -525,13 +588,13 @@ export function helpData(topic) {
|
|
|
525
588
|
name: "setup",
|
|
526
589
|
summary: "Guide browser sign in and workspace choice, approve an ingest-only key, and install the selected client skill. Does not verify application traffic.",
|
|
527
590
|
options: [
|
|
528
|
-
{ name: "--runtime", value: "RUNTIME", summary: "
|
|
591
|
+
{ name: "--runtime", value: "RUNTIME", summary: "Local terminal: inferred automatically. Scripts: required. Other runtimes get a handoff." },
|
|
529
592
|
{ name: "--url", value: "ORIGIN", summary: "Deployment origin. Defaults to an existing project binding, else the hosted origin." },
|
|
530
593
|
{ name: "--workspace", value: "UUID", summary: "Expected workspace; the browser must approve this exact workspace." },
|
|
531
594
|
{ name: "--project", value: "DIR", summary: "Project directory. Default: current directory." },
|
|
532
595
|
CONFIG_DIR_OPTION,
|
|
533
596
|
{ name: "--env-file", value: "FILE", summary: "Project-relative env file. Default: .env." },
|
|
534
|
-
{ name: "--client", value: "CLIENT", summary: "
|
|
597
|
+
{ name: "--client", value: "CLIENT", summary: "codex, claude or cursor. A local interactive setup asks when omitted." },
|
|
535
598
|
{ name: "--skip-skill", value: null, summary: "Explicitly leave client skill installation pending." },
|
|
536
599
|
{ name: "--timeout-ms", value: "N", summary: "Time to wait for browser approval." },
|
|
537
600
|
{ name: "--signup", value: null, summary: "Start at hosted sign up when the project needs login." },
|
|
@@ -559,6 +622,13 @@ export function helpData(topic) {
|
|
|
559
622
|
"reads; start needs a key with Debug access and Allow analysis starts and spends within the server's budget.",
|
|
560
623
|
options: EXPERIMENTS_OPTIONS,
|
|
561
624
|
},
|
|
625
|
+
{
|
|
626
|
+
name: "tools",
|
|
627
|
+
summary:
|
|
628
|
+
"List the Agent Access tools this credential can use and call one, as an MCP client would. A tool that " +
|
|
629
|
+
"writes, starts work or calls a model provider runs only with --yes.",
|
|
630
|
+
options: TOOLS_OPTIONS,
|
|
631
|
+
},
|
|
562
632
|
...READ_HELP.map(({ name, summary, options, examples }) => ({
|
|
563
633
|
name,
|
|
564
634
|
summary,
|
|
@@ -576,12 +646,34 @@ export function helpData(topic) {
|
|
|
576
646
|
meaning: EXIT_CODE_MEANINGS[outcome],
|
|
577
647
|
})),
|
|
578
648
|
};
|
|
649
|
+
if (action) data.action = { name: action, ...actionHelpData(topic, action, data.commands) };
|
|
650
|
+
return data;
|
|
579
651
|
}
|
|
580
652
|
|
|
581
|
-
export function helpText(topic, style = PLAIN) {
|
|
653
|
+
export function helpText(topic, style = PLAIN, action = null, advanced = false) {
|
|
582
654
|
const lines = [];
|
|
655
|
+
if (action) {
|
|
656
|
+
const entry = actionHelpData(topic, action, helpData(topic).commands);
|
|
657
|
+
if (entry) return formatHelp([
|
|
658
|
+
`Usage: ${entry.usage}`, "", entry.summary, "", "Examples:",
|
|
659
|
+
...entry.examples.map(example => ` ${example}`), "", "Options:",
|
|
660
|
+
...optionLines(displayOptions(entry.options, topic, action, advanced), 20), "", entry.note, "",
|
|
661
|
+
...(advanced ? [] : [`Connection settings: metergraph ${topic} ${action} --help --advanced`]),
|
|
662
|
+
], style);
|
|
663
|
+
}
|
|
664
|
+
if (topic === "exit-codes") {
|
|
665
|
+
lines.push("Exit codes:", "", "For scripts. Human output describes the result and what to do next.", "");
|
|
666
|
+
for (const [outcome, code] of Object.entries(EXIT_CODES)) {
|
|
667
|
+
lines.push(` ${String(code).padEnd(4)}${outcome}`, ...paragraph(style, EXIT_CODE_MEANINGS[outcome], " "), "");
|
|
668
|
+
}
|
|
669
|
+
return formatHelp(lines, style);
|
|
670
|
+
}
|
|
671
|
+
if (topic === "agents") return formatHelp([
|
|
672
|
+
"Connect a coding agent", "", ...AGENT_PATH_HELP, "", ...AGENT_APPROVAL_HELP,
|
|
673
|
+
"", 'Use --json for structured results. Run "metergraph help exit-codes" for scripting outcomes.',
|
|
674
|
+
], style);
|
|
583
675
|
if (topic === "pricing") {
|
|
584
|
-
return `Usage: metergraph pricing models|lookup|calculate|cost|history|market [options] [--json]
|
|
676
|
+
return formatHelp(`Usage: metergraph pricing models|lookup|calculate|cost|history|market [options] [--json]
|
|
585
677
|
|
|
586
678
|
Public catalog prices. No account, project or token is required.
|
|
587
679
|
models [--model ID] [--provider ID | --channel ID] [--region ID] [--limit 1..100]
|
|
@@ -615,7 +707,7 @@ Public API: GET /v1/pricing/models; POST /v1/pricing/lookup and /calculate.
|
|
|
615
707
|
No credentials, traces, prompts or responses are loaded from project files.
|
|
616
708
|
The CLI constructs metadata-only provider-format traces from the supplied counts.
|
|
617
709
|
See docs/pricing.md for the supported contract, limitations and reference previews.
|
|
618
|
-
|
|
710
|
+
`.split("\n"), style);
|
|
619
711
|
}
|
|
620
712
|
if (topic === "doctor") {
|
|
621
713
|
lines.push(
|
|
@@ -654,15 +746,18 @@ See docs/pricing.md for the supported contract, limitations and reference previe
|
|
|
654
746
|
lines.push(
|
|
655
747
|
"Opens your browser on the service's own sign in and workspace consent pages, then",
|
|
656
748
|
"binds this project to the workspace you approve. The CLI receives a delegated grant",
|
|
657
|
-
`limited to the Metadata
|
|
658
|
-
"
|
|
749
|
+
`limited to the Metadata role (${METADATA_SCOPE}), or with --role debug to the Debug role and`,
|
|
750
|
+
"the workflow permissions the --allow-* options name, which only a workspace owner approves.",
|
|
751
|
+
"It verifies the workspace, profile and scope with the service before saving anything. Your",
|
|
752
|
+
"browser keeps its own sign in. Signing in again with another role or other permissions",
|
|
753
|
+
"replaces the grant.",
|
|
659
754
|
"The grant is saved in your private config directory; the project gets only",
|
|
660
755
|
".metergraph/project.json, which holds no credentials.",
|
|
661
756
|
"",
|
|
662
757
|
"Login does not create an application ingest key, and no manual API key is required.",
|
|
663
|
-
"The service records the grant as
|
|
664
|
-
"
|
|
665
|
-
"
|
|
758
|
+
"The service records the grant as an OAuth connection, separate from any API or ingest",
|
|
759
|
+
"key you manage. Login reads no telemetry or content and never asks for Replay access.",
|
|
760
|
+
"Rerunning it on a signed in project with the same role and permissions changes nothing.",
|
|
666
761
|
"",
|
|
667
762
|
);
|
|
668
763
|
} else {
|
|
@@ -683,6 +778,28 @@ See docs/pricing.md for the supported contract, limitations and reference previe
|
|
|
683
778
|
"Opening requires a server link that selects the verified workspace; older links get a manual handoff.",
|
|
684
779
|
"", "Options:");
|
|
685
780
|
lines.push(...optionLines(VERIFY_OPTIONS, 22));
|
|
781
|
+
} else if (topic === "tools") {
|
|
782
|
+
lines.push(
|
|
783
|
+
"Usage:",
|
|
784
|
+
...TOOLS_USAGE.map((usage) => ` ${usage}`),
|
|
785
|
+
"",
|
|
786
|
+
"Every Agent Access tool the service offers this credential, through its MCP endpoint, with the same",
|
|
787
|
+
"saved sign in or coding-agent key as the read commands and the same checks first. The service decides",
|
|
788
|
+
"which tools a credential sees: a Metadata credential gets the Metadata tools; the Debug role adds trace",
|
|
789
|
+
"content and evaluation reads, and Allow evaluation writes, Allow evaluation previews and Allow analysis",
|
|
790
|
+
"starts add the tools they name. Replay keys are refused.",
|
|
791
|
+
"",
|
|
792
|
+
"list prints the tools with whether each only reads. Under --json each carries its title, description",
|
|
793
|
+
"and input schema. call sends one tools/call with --args or --args-file and prints the tool's structured",
|
|
794
|
+
"result in data.result. A tool the service does not mark read-only, or marks as calling a model provider,",
|
|
795
|
+
"needs --yes: without it the command exits 18 (action_required, confirmation_required) and sends",
|
|
796
|
+
"nothing. Pass --yes only after the person has approved that exact call. A refusal by the tool exits 19",
|
|
797
|
+
"(refused) with the service's error in data.tool_error; a write whose answer was lost exits 20",
|
|
798
|
+
"(unconfirmed).",
|
|
799
|
+
"",
|
|
800
|
+
"Options:",
|
|
801
|
+
);
|
|
802
|
+
lines.push(...optionLines(TOOLS_OPTIONS, 22));
|
|
686
803
|
} else if (topic === "experiments") {
|
|
687
804
|
lines.push(
|
|
688
805
|
"Usage:",
|
|
@@ -697,12 +814,12 @@ See docs/pricing.md for the supported contract, limitations and reference previe
|
|
|
697
814
|
"same arguments, so it starts exactly what was priced; poll it with get until it is terminal.",
|
|
698
815
|
"Each start creates a new experiment, so a start that succeeded is never retried.",
|
|
699
816
|
"",
|
|
700
|
-
"list, estimate and get use this project's saved
|
|
817
|
+
"list, estimate and get use this project's saved sign in or a coding-agent key, as the read",
|
|
701
818
|
"commands do, and never read inputs, outputs or tracked field values; those are in the dashboard.",
|
|
702
|
-
"start needs a coding-agent key with Debug
|
|
703
|
-
"owner can grant, in --agent-token-file or METERGRAPH_AGENT_TOKEN.
|
|
704
|
-
"
|
|
705
|
-
"
|
|
819
|
+
"start needs a coding-agent key with the Debug role and Allow analysis starts, which only a",
|
|
820
|
+
"workspace owner can grant, in --agent-token-file or METERGRAPH_AGENT_TOKEN.",
|
|
821
|
+
"The CLI checks the key before it sends the one start request. The service then replays the",
|
|
822
|
+
"sampled calls' captured prompts on each treatment's provider within its budget.",
|
|
706
823
|
"",
|
|
707
824
|
"Options:",
|
|
708
825
|
);
|
|
@@ -715,10 +832,10 @@ See docs/pricing.md for the supported contract, limitations and reference previe
|
|
|
715
832
|
entry.summary,
|
|
716
833
|
"",
|
|
717
834
|
"Uses this project's saved Metadata grant (see \"metergraph help login\"), or, where there is none on",
|
|
718
|
-
"this machine, a coding-agent key
|
|
719
|
-
"
|
|
720
|
-
"and nothing is read until the service shows
|
|
721
|
-
"expected workspace. Sends GET requests only, to fixed paths on that origin, follows no redirects and",
|
|
835
|
+
"this machine, a coding-agent key from METERGRAPH_AGENT_TOKEN or --agent-token-file, with the",
|
|
836
|
+
"Metadata role or the Debug role. A key is sent only after the origin answers as a supported",
|
|
837
|
+
"Metergraph service, and nothing is read until the service shows one of those roles (never",
|
|
838
|
+
"Replay) and the expected workspace. Sends GET requests only, to fixed paths on that origin, follows no redirects and",
|
|
722
839
|
"reads bounded responses. Never opens a browser, signs in, writes project files or the key, reads",
|
|
723
840
|
"retained content, replays or calls a model provider. It may refresh its own saved grant, and the",
|
|
724
841
|
"service may record the access (for example last used times); it never changes workspace",
|
|
@@ -764,7 +881,7 @@ See docs/pricing.md for the supported contract, limitations and reference previe
|
|
|
764
881
|
"Copies the Metergraph workflow skills bundled with this CLI into one client's project",
|
|
765
882
|
"skill directory, one folder per skill, and records ownership of each in",
|
|
766
883
|
".metergraph/skills/NAME.json. The skills come from https://github.com/metergraph/skills",
|
|
767
|
-
"at the commit this release pins. They cover investigation and
|
|
884
|
+
"at the commit this release pins. They cover investigation and model swap:",
|
|
768
885
|
"choose a workload, choose traces and models, define the eval, run the analysis,",
|
|
769
886
|
"summarize the report and rerun. The setup skill is installed by \"metergraph skill\".",
|
|
770
887
|
"",
|
|
@@ -788,45 +905,110 @@ See docs/pricing.md for the supported contract, limitations and reference previe
|
|
|
788
905
|
"Discovery stays pending until the client itself loads the skills.",
|
|
789
906
|
);
|
|
790
907
|
} else {
|
|
791
|
-
|
|
792
|
-
`metergraph ${VERSION} (preview)`,
|
|
793
|
-
"",
|
|
794
|
-
"Usage:",
|
|
795
|
-
" metergraph --help [--json] Show this help",
|
|
796
|
-
" metergraph --version [--json] Show the CLI version",
|
|
797
|
-
" metergraph doctor [options] Check a Metergraph service, read only",
|
|
798
|
-
" metergraph skill install|update Install or update the agent skill in a project",
|
|
799
|
-
" metergraph skills install|update|list Workflow skills, such as the model-swap loop",
|
|
800
|
-
" metergraph login [options] Sign in and bind a project to a workspace",
|
|
801
|
-
" metergraph logout [options] Revoke and remove a project's sign in",
|
|
802
|
-
" metergraph setup [options] Approve and write a private ingest key",
|
|
803
|
-
" metergraph verify [options] Find one exact processed trace",
|
|
804
|
-
" metergraph status [options] Show configured, reachable and verified state",
|
|
805
|
-
" metergraph context [options] Show the verified workspace",
|
|
806
|
-
" metergraph capabilities [opts] Show the agent reads offered to this grant",
|
|
807
|
-
" metergraph usage [options] Daily usage per route, Metadata only",
|
|
808
|
-
" metergraph routes [options] Routes and evaluation contract versions",
|
|
809
|
-
" metergraph traces [options] One page of trace metadata",
|
|
810
|
-
" metergraph experiments list|estimate|start|get Replay a workload on other models",
|
|
811
|
-
" metergraph pricing <action> Public lookup, cost, history and market board",
|
|
812
|
-
"",
|
|
813
|
-
'Run "metergraph help doctor" for doctor options.',
|
|
814
|
-
'Run "metergraph help skill" for skill options.',
|
|
815
|
-
'Run "metergraph help skills" for workflow skill options.',
|
|
816
|
-
'Run "metergraph help login" or "metergraph help logout" for sign in options.',
|
|
817
|
-
'Run "metergraph help verify" for exact-trace verification options.',
|
|
818
|
-
'Run "metergraph help COMMAND" for status, context, capabilities, usage, routes or traces.',
|
|
819
|
-
'Run "metergraph help experiments" for experiment options.',
|
|
820
|
-
"",
|
|
821
|
-
...AGENT_PATH_HELP,
|
|
822
|
-
);
|
|
908
|
+
return rootHelp(style);
|
|
823
909
|
}
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
910
|
+
// Reference material is opt-in; everyday help stays focused on this command.
|
|
911
|
+
return commandHelp(topic, lines, style, advanced);
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
function commandHelp(topic, lines, style, advanced) {
|
|
915
|
+
const optionsAt = lines.indexOf("Options:");
|
|
916
|
+
if (optionsAt < 0) return formatHelp(lines, style);
|
|
917
|
+
const optionsEnd = lines.indexOf("", optionsAt + 1);
|
|
918
|
+
const usageEnd = lines.indexOf("");
|
|
919
|
+
const examples = {
|
|
920
|
+
setup: ["metergraph setup", "metergraph setup --runtime local --client codex --json --no-browser"],
|
|
921
|
+
login: ["metergraph login", "metergraph login --runtime local --no-browser"],
|
|
922
|
+
logout: ["metergraph logout"], doctor: ["metergraph doctor"],
|
|
923
|
+
verify: ["metergraph verify --trace-id TRACE_ID --since START_ISO_TIME --until END_ISO_TIME"],
|
|
924
|
+
status: ["metergraph status"], context: ["metergraph context"], capabilities: ["metergraph capabilities"],
|
|
925
|
+
usage: ["metergraph usage --days 7"], routes: ["metergraph routes"], traces: ["metergraph traces --limit 10"],
|
|
926
|
+
skill: ["metergraph skill install --client codex"], skills: ["metergraph skills list"],
|
|
927
|
+
experiments: ["metergraph experiments list", "metergraph experiments estimate --help"],
|
|
928
|
+
}[topic] ?? [];
|
|
929
|
+
const notes = lines.slice(usageEnd + 1, optionsAt);
|
|
930
|
+
const command = helpData(topic).commands.find(entry => entry.name === topic);
|
|
931
|
+
const options = command ? ["Options:", ...optionLines(displayOptions(command.options, topic, null, advanced), 22)]
|
|
932
|
+
: lines.slice(optionsAt, optionsEnd < 0 ? lines.length : optionsEnd);
|
|
933
|
+
const synopsis = {
|
|
934
|
+
setup: "metergraph setup [--client CLIENT | --skip-skill] [options]",
|
|
935
|
+
login: "metergraph login [--runtime local] [options]",
|
|
936
|
+
logout: "metergraph logout [options]",
|
|
937
|
+
verify: "metergraph verify (--trace-id ID | --request-id ID) --since TIME --until TIME [options]",
|
|
938
|
+
...Object.fromEntries(READ_HELP.map(entry => [entry.name, `metergraph ${entry.name} [options]`])),
|
|
939
|
+
}[topic];
|
|
940
|
+
return formatHelp([
|
|
941
|
+
...(synopsis ? [`Usage: ${synopsis}`] : lines.slice(0, usageEnd)), "", "Examples:", ...examples.map(example => ` ${example}`),
|
|
942
|
+
...(topic === "setup" || topic === "login" ? ["", "Local terminals guide missing choices. Scripts require explicit flags.",
|
|
943
|
+
"With --json --no-browser, a step that needs browser approval exits 18 (action_required) with the URL in " +
|
|
944
|
+
"data.next_action.url; approve it, then run the same command again."] : []),
|
|
945
|
+
"", ...options,
|
|
946
|
+
...(advanced ? ["", "Details", ...notes, ...lines.slice(optionsEnd < 0 ? lines.length : optionsEnd)]
|
|
947
|
+
: ["", `Connection settings and details: metergraph ${topic} --help --advanced`]),
|
|
948
|
+
], style);
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
function rootHelp(style) {
|
|
952
|
+
const groups = [
|
|
953
|
+
["Get started", [
|
|
954
|
+
["setup", "Connect your app and install an agent skill"],
|
|
955
|
+
["login", "Sign in to a workspace"],
|
|
956
|
+
["status", "Check this project's connection"],
|
|
957
|
+
]],
|
|
958
|
+
["Explore", [
|
|
959
|
+
["usage", "View costs and token usage"],
|
|
960
|
+
["traces", "Browse trace metadata"],
|
|
961
|
+
["routes", "List routes and evaluation contracts"],
|
|
962
|
+
["experiments", "Estimate and run model comparisons"],
|
|
963
|
+
["tools", "List and call the tools your coding agent can use"],
|
|
964
|
+
["pricing", "Look up public model prices; no account needed"],
|
|
965
|
+
]],
|
|
966
|
+
["Manage", [
|
|
967
|
+
["verify", "Verify one processed trace"],
|
|
968
|
+
["doctor", "Check service health"],
|
|
969
|
+
["context", "Show the connected workspace"],
|
|
970
|
+
["capabilities", "Show available workspace reads"],
|
|
971
|
+
["skill", "Install or update the setup skill"],
|
|
972
|
+
["skills", "Install, update or list workflow skills"],
|
|
973
|
+
["logout", "Sign out of this project"],
|
|
974
|
+
]],
|
|
975
|
+
];
|
|
976
|
+
const lines = [style.bold("Metergraph") + " " + style.dim(`${VERSION} · preview`),
|
|
977
|
+
"Understand your AI usage and compare models.", "", "Usage: metergraph <command> [options]", ""];
|
|
978
|
+
for (const [title, commands] of groups) {
|
|
979
|
+
lines.push(section(style, title), ...fields(style, commands), "");
|
|
827
980
|
}
|
|
828
|
-
|
|
829
|
-
|
|
981
|
+
lines.push(section(style, "Try it"),
|
|
982
|
+
" metergraph setup --runtime local --client codex",
|
|
983
|
+
" metergraph pricing models --limit 10", "",
|
|
984
|
+
'Run "metergraph <command> --help" for options and examples.',
|
|
985
|
+
'Use --json for scripts; --version to show the version.',
|
|
986
|
+
'Scripting reference: metergraph help exit-codes.',
|
|
987
|
+
'Connecting a cloud agent? Run "metergraph help agents".');
|
|
988
|
+
return formatHelp(lines, style);
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
function formatHelp(lines, style) {
|
|
992
|
+
return render(lines.flatMap((line) => {
|
|
993
|
+
if (!line) return [""];
|
|
994
|
+
if (line.length <= style.width && !/^(Usage|Options|Examples|Exit codes):/.test(line)) return [line];
|
|
995
|
+
if (/^(Usage|Options|Examples|Exit codes):/.test(line)) {
|
|
996
|
+
const [first, ...rest] = paragraph(style, line, "");
|
|
997
|
+
return [style.bold(first), ...rest];
|
|
998
|
+
}
|
|
999
|
+
// Preserve option and command columns, with a hanging indent on small terminals.
|
|
1000
|
+
const row = /^( \S.*?) {2,}(\S.*)$/.exec(line);
|
|
1001
|
+
if (row && Number.isFinite(style.width)) {
|
|
1002
|
+
const prefix = row[1] + " ";
|
|
1003
|
+
if (prefix.length > style.width / 2) {
|
|
1004
|
+
return [row[1], ...paragraph(style, row[2], " ")];
|
|
1005
|
+
}
|
|
1006
|
+
const wrapped = paragraph(style, row[2], " ".repeat(prefix.length));
|
|
1007
|
+
return [prefix + wrapped[0].trimStart(), ...wrapped.slice(1)];
|
|
1008
|
+
}
|
|
1009
|
+
return paragraph(style, line.trimStart(), line.match(/^ */)[0]);
|
|
1010
|
+
}));
|
|
1011
|
+
|
|
830
1012
|
}
|
|
831
1013
|
|
|
832
1014
|
export function skillText(result, message, style = PLAIN) {
|
|
@@ -987,6 +1169,8 @@ export function doctorText(result, style = PLAIN) {
|
|
|
987
1169
|
// Fixed text for every login, logout and session reason. Reasons shared
|
|
988
1170
|
// with doctor fall back to its wording.
|
|
989
1171
|
const AUTH_MESSAGES = {
|
|
1172
|
+
local_docker_transport_required:
|
|
1173
|
+
"Local credentials and consent require a verified Docker transport. This CLI has no configured Docker transport; nothing was sent. Update the local bundle and use its Docker-mediated bin/agent-key command, or connect this CLI to an authenticated HTTPS deployment.",
|
|
990
1174
|
runtime_not_supported:
|
|
991
1175
|
"--runtime says where this terminal runs, not which Metergraph service you sign in to. " +
|
|
992
1176
|
"A cloud runtime is a remote sandbox, and sign in needs a browser on the same machine as the CLI, " +
|
|
@@ -1021,6 +1205,7 @@ const AUTH_MESSAGES = {
|
|
|
1021
1205
|
oauth_metadata_missing: "This service does not support CLI sign in yet. Nothing was written.",
|
|
1022
1206
|
metadata_scope_unsupported:
|
|
1023
1207
|
"This service does not offer Metadata-only access for the CLI yet. The CLI does not fall back to broader access.",
|
|
1208
|
+
debug_scope_unsupported: "This service does not offer Debug access for CLI sign in. Nothing was saved.",
|
|
1024
1209
|
endpoint_not_allowed: "The service advertised an authorization endpoint outside its own origin or known paths.",
|
|
1025
1210
|
resource_mismatch: "The service's protected resource does not match this origin.",
|
|
1026
1211
|
issuer_mismatch: "The service's authorization issuer does not match this origin.",
|
|
@@ -1037,6 +1222,14 @@ const AUTH_MESSAGES = {
|
|
|
1037
1222
|
client_mismatch: "The issued grant is for a different client. Nothing was saved.",
|
|
1038
1223
|
scope_mismatch: "The issued grant is not limited to exactly the Metadata scope. It was not kept.",
|
|
1039
1224
|
workspace_mismatch: "The browser granted a different workspace than --workspace. It was not kept.",
|
|
1225
|
+
workspace_hint_ambiguous:
|
|
1226
|
+
"More than one of your workspaces has the name --workspace gave, so the consent page offered no approval. " +
|
|
1227
|
+
"Nothing was granted.",
|
|
1228
|
+
workspace_hint_unknown:
|
|
1229
|
+
"None of your workspaces has the slug or name --workspace gave, so the consent page offered no approval. " +
|
|
1230
|
+
"Nothing was granted.",
|
|
1231
|
+
workspace_name_unsupported:
|
|
1232
|
+
"This service cannot match a workspace by name. Use its slug, which its Settings page shows. Nothing was sent.",
|
|
1040
1233
|
workspace_context_mismatch: "The service reported a different workspace than the grant names. It was not kept.",
|
|
1041
1234
|
profile_mismatch: "The service reported a different deployment profile than before sign in. It was not kept.",
|
|
1042
1235
|
deployment_profile_mismatch:
|
|
@@ -1047,6 +1240,8 @@ const AUTH_MESSAGES = {
|
|
|
1047
1240
|
"The grant would allow content, replay or provider access, which login never accepts. It was not kept.",
|
|
1048
1241
|
access_rejected: "The service refused the new grant. Nothing was saved.",
|
|
1049
1242
|
invalid_project: "--project must name an existing directory.",
|
|
1243
|
+
secure_writes_unavailable:
|
|
1244
|
+
"Secure automatic file writes are unavailable on this platform or the bundled filesystem helper failed verification. Nothing was written.",
|
|
1050
1245
|
invalid_config_dir: "METERGRAPH_CONFIG_DIR must be an absolute path.",
|
|
1051
1246
|
unsafe_path: "A path in .metergraph is a symbolic link or is not a regular file or directory. Nothing was changed.",
|
|
1052
1247
|
binding_invalid: "The project binding .metergraph/project.json is not valid. Nothing was changed.",
|
|
@@ -1123,7 +1318,7 @@ export function authText(result, message, style = PLAIN) {
|
|
|
1123
1318
|
const lines = [headline(style, toneFor(result.outcome), title, result.outcome), ""];
|
|
1124
1319
|
const rows = [
|
|
1125
1320
|
["Origin", report.origin],
|
|
1126
|
-
["Workspace", report.workspace
|
|
1321
|
+
["Workspace", workspaceShown(report.workspace)],
|
|
1127
1322
|
["Profile", report.deployment_profile || null],
|
|
1128
1323
|
];
|
|
1129
1324
|
if (login && result.ok) {
|