metergraph-cli 0.0.0-stage → 0.1.0
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/LICENSE +201 -0
- package/README.md +410 -2
- package/assets/skill/SKILL.md +57 -0
- package/assets/skill/manifest.json +9 -0
- package/bin/metergraph.js +11 -0
- package/package.json +44 -4
- package/src/args.js +180 -0
- package/src/cli.js +90 -0
- package/src/constants.js +81 -0
- package/src/doctor.js +198 -0
- package/src/http.js +129 -0
- package/src/origin.js +37 -0
- package/src/output.js +274 -0
- package/src/skill-bundle.js +53 -0
- package/src/skill.js +449 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
package/README.md
CHANGED
|
@@ -1,3 +1,411 @@
|
|
|
1
|
-
#
|
|
1
|
+
# metergraph-cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The Metergraph command line tool. This is a **development preview** (version 0.1.0).
|
|
4
|
+
|
|
5
|
+
Install the preview channel with npm or run it directly:
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npx --yes metergraph-cli@next --help
|
|
9
|
+
npx --yes metergraph-cli@next doctor --json
|
|
10
|
+
npm install -g metergraph-cli@next
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The installed command is `metergraph`. Pin `metergraph-cli@0.1.0` when you need
|
|
14
|
+
this exact preview. Authentication and hosted setup are not included yet.
|
|
15
|
+
|
|
16
|
+
This preview does two things:
|
|
17
|
+
|
|
18
|
+
- `doctor` checks whether a Metergraph service is reachable, healthy and supported.
|
|
19
|
+
- `skill install` and `skill update` copy the Metergraph agent skill bundled with the
|
|
20
|
+
CLI into one coding agent's project skill directory.
|
|
21
|
+
|
|
22
|
+
It does not sign in or connect a workspace, and it does not query workspace
|
|
23
|
+
telemetry or send application data. Sign in, workspace binding and hosted setup commands are planned as separate
|
|
24
|
+
follow-up releases and are not part of this package yet.
|
|
25
|
+
|
|
26
|
+
## Requirements
|
|
27
|
+
|
|
28
|
+
| | Supported |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| Node.js | 22 and 24 |
|
|
31
|
+
| Operating systems | Linux, macOS and Windows (each in the CI matrix) |
|
|
32
|
+
| Runtime dependencies | None |
|
|
33
|
+
|
|
34
|
+
## Commands
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
metergraph --help [--json]
|
|
38
|
+
metergraph help doctor [--json]
|
|
39
|
+
metergraph --version [--json]
|
|
40
|
+
metergraph doctor [--url ORIGIN] [--timeout-ms N] [--json]
|
|
41
|
+
metergraph help skill [--json]
|
|
42
|
+
metergraph skill install --client CLIENT --runtime RUNTIME [--project DIR] [--json]
|
|
43
|
+
metergraph skill update --client CLIENT --runtime RUNTIME [--project DIR] [--json]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`--help`, `--version` and the `skill` commands work offline and make no network
|
|
47
|
+
requests.
|
|
48
|
+
|
|
49
|
+
### doctor
|
|
50
|
+
|
|
51
|
+
`doctor` sends three unauthenticated, read-only `GET` requests to one origin, in order,
|
|
52
|
+
and stops at the first problem:
|
|
53
|
+
|
|
54
|
+
1. `/healthz` must answer `200` with the JSON body `{"ok": true}`.
|
|
55
|
+
2. `/v1/deployment` must answer `200` with a JSON `deployment_profile` this CLI supports.
|
|
56
|
+
3. `/v1/agent/capabilities` must answer `401` with a `WWW-Authenticate: Bearer` challenge.
|
|
57
|
+
|
|
58
|
+
Options:
|
|
59
|
+
|
|
60
|
+
| Option | Default | Notes |
|
|
61
|
+
| --- | --- | --- |
|
|
62
|
+
| `--url ORIGIN` | `https://app.metergraph.dev` | Bare origin only, see [Safe origins](#safe-origins). |
|
|
63
|
+
| `--timeout-ms N` | `5000` | Whole number from 100 to 30000. Covers the whole probe, not each request. |
|
|
64
|
+
| `--json` | off | Print exactly one JSON line on stdout and nothing on stderr. |
|
|
65
|
+
|
|
66
|
+
A healthy, supported service exits with code **3, `authentication_required`**. That is
|
|
67
|
+
the best result this preview can report: the service is reachable, but this CLI holds
|
|
68
|
+
no credentials, so `authenticated` is always `false` and `workspace` is always `null`.
|
|
69
|
+
A reachable service is not a working workspace connection. To connect an application,
|
|
70
|
+
follow the [connection guide](https://www.metergraph.dev/docs/guides/agent-access/).
|
|
71
|
+
|
|
72
|
+
`doctor` never opens a browser, never prompts and never reads stdin, so it is safe in
|
|
73
|
+
scripts and CI.
|
|
74
|
+
|
|
75
|
+
### skill install and skill update
|
|
76
|
+
|
|
77
|
+
`skill install` copies the Metergraph skill bundled with this CLI into one client's
|
|
78
|
+
native project skill directory. Both `--client` and `--runtime` are required, so the
|
|
79
|
+
command never guesses where the skill will be used.
|
|
80
|
+
|
|
81
|
+
| `--client` | Client | Skill file written | Client documentation |
|
|
82
|
+
| --- | --- | --- | --- |
|
|
83
|
+
| `codex` | Codex | `.agents/skills/metergraph/SKILL.md` | [Build skills](https://learn.chatgpt.com/docs/build-skills) |
|
|
84
|
+
| `claude` | Claude Code | `.claude/skills/metergraph/SKILL.md` | [Skills](https://code.claude.com/docs/en/skills) |
|
|
85
|
+
| `cursor` | Cursor | `.cursor/skills/metergraph/SKILL.md` | [Skills](https://cursor.com/docs/skills) |
|
|
86
|
+
|
|
87
|
+
Each client has its own directory, so installing for several clients never makes one
|
|
88
|
+
overwrite another.
|
|
89
|
+
|
|
90
|
+
| Option | Default | Notes |
|
|
91
|
+
| --- | --- | --- |
|
|
92
|
+
| `--client CLIENT` | required | `codex`, `claude` or `cursor`. |
|
|
93
|
+
| `--runtime RUNTIME` | required | `local` when the client runs on this machine, `cloud` when it runs in a cloud environment with a shell and a checkout of the project. Recorded, not detected. |
|
|
94
|
+
| `--project DIR` | current directory | Must be an existing directory. Symbolic links in this path are resolved once; nothing below it is followed. |
|
|
95
|
+
| `--json` | off | Print exactly one JSON line on stdout and nothing on stderr. |
|
|
96
|
+
|
|
97
|
+
What it writes, and nothing else:
|
|
98
|
+
|
|
99
|
+
1. The skill file in the table above, plus any of its missing parent directories.
|
|
100
|
+
2. `.metergraph/skill-installations.json`, a small ownership receipt. For each client it
|
|
101
|
+
records the relative skill path, the skill name, the source revision and SHA-256,
|
|
102
|
+
and the runtimes requested. It contains no credentials, user names or absolute
|
|
103
|
+
paths, so it is safe to commit.
|
|
104
|
+
|
|
105
|
+
Ownership rules:
|
|
106
|
+
|
|
107
|
+
- `install` never replaces a skill it did not install, even one with identical bytes.
|
|
108
|
+
- Running `install` again on an unchanged skill it installed changes nothing.
|
|
109
|
+
- A skill it installed that was edited since is never overwritten, by `install` or by
|
|
110
|
+
`update`. Restore or remove the file first.
|
|
111
|
+
- `update` is the only way to replace an older revision this CLI installed. There is no
|
|
112
|
+
force option.
|
|
113
|
+
- A skill file this CLI installed that has gone missing is written again.
|
|
114
|
+
- Symbolic links and other non-regular entries on the skill or receipt path are
|
|
115
|
+
refused.
|
|
116
|
+
- Files are written to an exclusive temporary file and renamed into place, under a lock
|
|
117
|
+
file, `.metergraph/skill-installations.lock`. The receipt is written only after the
|
|
118
|
+
skill file, and a failed receipt write puts the skill file back as it was. If the
|
|
119
|
+
process is killed between the two writes, the skill is left without a receipt entry,
|
|
120
|
+
so later runs refuse to touch it, and the lock stays until you delete it.
|
|
121
|
+
- It never changes client settings, MCP configuration, `AGENTS.md`, `CLAUDE.md` or any
|
|
122
|
+
other file, and keeps the permissions of a file it replaces.
|
|
123
|
+
|
|
124
|
+
`--runtime cloud` writes the same project file. A cloud client sees it only through
|
|
125
|
+
its own checkout of the project, so commit the file if you installed it elsewhere.
|
|
126
|
+
Writing a skill file in a cloud checkout does not connect MCP, sign in or copy anything
|
|
127
|
+
from your own machine. Local skills do not sync to desktop or cloud apps on their own.
|
|
128
|
+
|
|
129
|
+
Clients and runtimes that cannot load project skill files get a pointer to the
|
|
130
|
+
[connection guide](https://www.metergraph.dev/docs/guides/agent-access/) with exit code
|
|
131
|
+
6, and nothing is written: `--client claude-desktop`, `--client chatgpt` and
|
|
132
|
+
`--runtime cloud-no-shell` (a cloud runtime without a shell or project checkout).
|
|
133
|
+
|
|
134
|
+
A successful run exits `0` with `discovery: "pending"` and `authenticated: false`.
|
|
135
|
+
Writing the file does not prove that a client has loaded it. Start or reload the client
|
|
136
|
+
in the project and check that it lists the `metergraph` skill. The skill itself is
|
|
137
|
+
instructions for the agent; it holds no credentials and does not connect a workspace.
|
|
138
|
+
|
|
139
|
+
#### Bundled skill source
|
|
140
|
+
|
|
141
|
+
`assets/skill/SKILL.md` is a byte-for-byte copy of the public skill at
|
|
142
|
+
<https://www.metergraph.dev/SKILL.md>. The source has no version number of its own, so
|
|
143
|
+
`assets/skill/manifest.json` records its source URL, size and SHA-256, and a revision
|
|
144
|
+
derived from that hash (`sha256-` followed by the first 12 hex digits). The package
|
|
145
|
+
version is not the skill version. At runtime the CLI checks the bundled file against a
|
|
146
|
+
hash pinned in its code and in the manifest, and refuses to write anything if either
|
|
147
|
+
does not match. It never downloads the skill or runs a remote script. A new skill
|
|
148
|
+
revision ships only in a new CLI release; `skill update` then upgrades projects that
|
|
149
|
+
hold an unchanged earlier revision.
|
|
150
|
+
|
|
151
|
+
## Exit codes
|
|
152
|
+
|
|
153
|
+
Exit codes are stable. Changing one is a breaking change.
|
|
154
|
+
|
|
155
|
+
| Code | Outcome | Meaning |
|
|
156
|
+
| --- | --- | --- |
|
|
157
|
+
| 0 | `ok` | Command succeeded. `doctor` does not return this in this preview. For `skill`, the file is in place; discovery is still pending. |
|
|
158
|
+
| 1 | `internal_error` | Unexpected failure inside the CLI. |
|
|
159
|
+
| 2 | `invalid_input` | Unknown command or argument, or an invalid option value. No request was made. |
|
|
160
|
+
| 3 | `authentication_required` | Service is reachable, healthy and supported, and requires authentication. No workspace is connected. |
|
|
161
|
+
| 4 | `connection_failed` | The origin could not be reached, the connection failed, or the probe timed out. |
|
|
162
|
+
| 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. |
|
|
164
|
+
| 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. |
|
|
167
|
+
|
|
168
|
+
## JSON output
|
|
169
|
+
|
|
170
|
+
With `--json`, every command prints one line with the same top-level keys:
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"schema_version": 1,
|
|
175
|
+
"command": "doctor",
|
|
176
|
+
"ok": false,
|
|
177
|
+
"outcome": "authentication_required",
|
|
178
|
+
"exit_code": 3,
|
|
179
|
+
"data": {
|
|
180
|
+
"origin": "https://app.metergraph.dev",
|
|
181
|
+
"reachable": true,
|
|
182
|
+
"healthy": true,
|
|
183
|
+
"deployment_profile": "managed",
|
|
184
|
+
"profile_status": "supported",
|
|
185
|
+
"authentication_required": true,
|
|
186
|
+
"authenticated": false,
|
|
187
|
+
"workspace": null,
|
|
188
|
+
"checks": [
|
|
189
|
+
{ "name": "health", "path": "/healthz", "result": "pass", "http_status": 200, "reason": null },
|
|
190
|
+
{ "name": "deployment", "path": "/v1/deployment", "result": "pass", "http_status": 200, "reason": null },
|
|
191
|
+
{ "name": "capabilities", "path": "/v1/agent/capabilities", "result": "pass", "http_status": 401, "reason": "bearer_token_required" }
|
|
192
|
+
],
|
|
193
|
+
"next_action": { "kind": "connection_guide", "url": "https://www.metergraph.dev/docs/guides/agent-access/" }
|
|
194
|
+
},
|
|
195
|
+
"error": {
|
|
196
|
+
"code": "authentication_required",
|
|
197
|
+
"reason": "bearer_token_required",
|
|
198
|
+
"message": "The service is reachable and supported, and it requires authentication. No workspace is connected."
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
(Shown formatted here. The CLI prints it on a single line.)
|
|
204
|
+
|
|
205
|
+
- `ok` is `true` only when `outcome` is `ok`. When `ok` is `false`, `error.code` equals
|
|
206
|
+
`outcome` and `error.reason` is a fixed token such as `timeout`, `invalid_url`,
|
|
207
|
+
`unrecognized_profile` or `response_too_large`.
|
|
208
|
+
- `profile_status` is `supported`, `unrecognized`, `unavailable` (the server has no
|
|
209
|
+
`/v1/deployment` endpoint) or `unknown` (not checked).
|
|
210
|
+
- Checks that did not run have `result: "skipped"`.
|
|
211
|
+
- `--help --json` includes the command list and the exit code table.
|
|
212
|
+
|
|
213
|
+
A successful `skill install`:
|
|
214
|
+
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"schema_version": 1,
|
|
218
|
+
"command": "skill install",
|
|
219
|
+
"ok": true,
|
|
220
|
+
"outcome": "ok",
|
|
221
|
+
"exit_code": 0,
|
|
222
|
+
"data": {
|
|
223
|
+
"client": "claude",
|
|
224
|
+
"runtime": "local",
|
|
225
|
+
"path": ".claude/skills/metergraph/SKILL.md",
|
|
226
|
+
"status": "installed",
|
|
227
|
+
"source": {
|
|
228
|
+
"name": "metergraph",
|
|
229
|
+
"revision": "sha256-90f7d8d78a5b",
|
|
230
|
+
"sha256": "90f7d8d78a5b0b7a57436f194222f0c73310b0b04201c297c8fbf0b00ad6bb3f"
|
|
231
|
+
},
|
|
232
|
+
"discovery": "pending",
|
|
233
|
+
"authenticated": false,
|
|
234
|
+
"next_action": {
|
|
235
|
+
"kind": "reload_client",
|
|
236
|
+
"message": "Start or restart Claude Code in this project, then confirm that it lists the metergraph skill."
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
"error": null
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
- `status` is `installed`, `updated` or `reused` (already in place, nothing rewritten).
|
|
244
|
+
- `path` is always relative to the project. Absolute paths are never printed.
|
|
245
|
+
- On failure `status` and `discovery` are `null`, and `error.reason` is a fixed token
|
|
246
|
+
such as `not_owned`, `modified`, `update_required`, `not_installed`, `unsafe_path`,
|
|
247
|
+
`receipt_invalid`, `locked`, `invalid_project`, `client_not_supported`,
|
|
248
|
+
`write_failed` or `bundled_skill_invalid`.
|
|
249
|
+
|
|
250
|
+
Without `--json`, results are printed as text on stdout and usage errors go to stderr.
|
|
251
|
+
|
|
252
|
+
## Safe origins
|
|
253
|
+
|
|
254
|
+
`--url` accepts only a bare origin, with an optional trailing slash:
|
|
255
|
+
|
|
256
|
+
- `https://` origins on any host, for example `https://metergraph.example.com`.
|
|
257
|
+
- `http://` only for `localhost`, `127.0.0.1` and `[::1]`, with an optional port.
|
|
258
|
+
|
|
259
|
+
Usernames, passwords, paths, queries and fragments are rejected before any request is
|
|
260
|
+
made. Invalid values and unknown arguments are not printed back, because a mistyped
|
|
261
|
+
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 [SECURITY.md](SECURITY.md).
|
|
263
|
+
|
|
264
|
+
## Deployment profiles
|
|
265
|
+
|
|
266
|
+
The CLI recognizes these `deployment_profile` values: `local`, `managed` and
|
|
267
|
+
`byoc-core`. Managed staging uses the `managed` profile. Any other value is reported as `unsupported` and is not echoed. A server
|
|
268
|
+
without `/v1/deployment`, such as a self-hosted open source server, is reported as
|
|
269
|
+
`unsupported` with `profile_status: "unavailable"` until a dedicated adapter ships. The
|
|
270
|
+
CLI never assumes such a server is hosted.
|
|
271
|
+
|
|
272
|
+
## What doctor does not do
|
|
273
|
+
|
|
274
|
+
- It reads no credentials from environment variables, files, arguments or cookies, and
|
|
275
|
+
sends no `Authorization` or `Cookie` header.
|
|
276
|
+
- It follows no redirects.
|
|
277
|
+
- It reads at most 32 KiB of any response body and stops at the `--timeout-ms` limit.
|
|
278
|
+
- It never prints response bodies, response headers, authentication challenges,
|
|
279
|
+
server-supplied URLs or error text from the network stack.
|
|
280
|
+
- It makes no model provider calls, sends no usage data and reads no stored traces.
|
|
281
|
+
|
|
282
|
+
## What skill install does not do
|
|
283
|
+
|
|
284
|
+
- It makes no network requests and no model provider calls. The skill comes from this
|
|
285
|
+
package, not from a download.
|
|
286
|
+
- It does not sign in, store credentials, configure MCP or edit client settings.
|
|
287
|
+
- It does not claim a client has loaded the skill. `discovery` stays `pending`.
|
|
288
|
+
- It never prints file contents, absolute paths or raw error text.
|
|
289
|
+
|
|
290
|
+
## Development
|
|
291
|
+
|
|
292
|
+
```sh
|
|
293
|
+
npm test # unit tests and CLI subprocess tests against loopback servers
|
|
294
|
+
npm run test:package # npm pack into a temporary directory, clean install, run the installed bin
|
|
295
|
+
node bin/metergraph.js --help
|
|
296
|
+
node bin/metergraph.js doctor --url http://127.0.0.1:8080 --json
|
|
297
|
+
node bin/metergraph.js skill install --client claude --runtime local --project /path/to/project --json
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
To try a packed artifact without publishing:
|
|
301
|
+
|
|
302
|
+
```sh
|
|
303
|
+
npm pack --pack-destination "$(mktemp -d)"
|
|
304
|
+
npx --yes --package=/path/to/metergraph-cli-0.1.0.tgz -- metergraph --version
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Do not commit tarballs or other generated files.
|
|
308
|
+
|
|
309
|
+
## Releasing
|
|
310
|
+
|
|
311
|
+
The source of truth is the public repository
|
|
312
|
+
[github.com/metergraph/cli](https://github.com/metergraph/cli), licensed Apache-2.0.
|
|
313
|
+
The first preview uses the `next` npm tag. Subsequent releases must pass the
|
|
314
|
+
checks below before publication.
|
|
315
|
+
|
|
316
|
+
Releases are manual. The `Release CLI` workflow (`.github/workflows/release.yml`) runs
|
|
317
|
+
only when a maintainer starts it from `main`. It does not run on tags, pushes or a
|
|
318
|
+
schedule. It:
|
|
319
|
+
|
|
320
|
+
1. checks that `commit_sha` equals the commit the run started from (see
|
|
321
|
+
[Exact revision rule](#exact-revision-rule)), that it is on `main`, and that
|
|
322
|
+
`version` equals `package.json`;
|
|
323
|
+
2. asks the npm registry for that exact version and continues only on a `404`. An
|
|
324
|
+
existing version, any other status or a network failure stops the run;
|
|
325
|
+
3. runs `npm test` and `npm run test:package` at that commit;
|
|
326
|
+
4. packs the tarball and records its SHA-256;
|
|
327
|
+
5. only if `publish` is true, waits for approval on the `npm-release` environment,
|
|
328
|
+
checks out the same commit again, verifies the checksum and runs
|
|
329
|
+
`npm publish --provenance` for that exact tarball.
|
|
330
|
+
|
|
331
|
+
Leave `publish` false for a dry run that validates and packs without publishing.
|
|
332
|
+
|
|
333
|
+
### Exact revision rule
|
|
334
|
+
|
|
335
|
+
npm provenance records the commit that triggered the workflow (`GITHUB_SHA`) as the
|
|
336
|
+
source of the package. To keep that statement true, the workflow only releases that
|
|
337
|
+
commit:
|
|
338
|
+
|
|
339
|
+
- `commit_sha` must be the full 40 character SHA of the current head of `main`, and it
|
|
340
|
+
must equal `GITHUB_SHA` for the run. Older commits on `main` are rejected even though
|
|
341
|
+
they are ancestors of `main`.
|
|
342
|
+
- Both the validate job and the publish job check out that commit and confirm it.
|
|
343
|
+
- If `main` moves after you copy the SHA, the run fails. Start a new run with the new
|
|
344
|
+
head. To release an older state, land it on `main` first.
|
|
345
|
+
|
|
346
|
+
### First package bootstrap
|
|
347
|
+
|
|
348
|
+
npm trusted publishing is configured on a package that already exists, so the very
|
|
349
|
+
first version cannot come from this workflow. Creating the package is a one time,
|
|
350
|
+
human step that a Metergraph maintainer must approve and perform. Nothing in this
|
|
351
|
+
repository automates it, and no npm token or secret is stored here.
|
|
352
|
+
|
|
353
|
+
1. Confirm the intended npm maintainer accounts and that `metergraph-cli` is
|
|
354
|
+
available. The first approved publish establishes package ownership.
|
|
355
|
+
2. Run the `Release CLI` workflow with `publish` false. Download the
|
|
356
|
+
`metergraph-cli-release` artifact and check its SHA-256 against the run summary.
|
|
357
|
+
3. From a maintainer machine with npm two-factor authentication, publish that exact
|
|
358
|
+
tarball manually using `npm publish /path/to/metergraph-cli-0.1.0.tgz --access public
|
|
359
|
+
--tag next --provenance=false --ignore-scripts`. This bootstrap version has no
|
|
360
|
+
provenance attestation. Use a new version for the first trusted release.
|
|
361
|
+
4. Configure trusted publishing as described below.
|
|
362
|
+
|
|
363
|
+
### Trusted publishing
|
|
364
|
+
|
|
365
|
+
After the package exists, follow the official npm guide,
|
|
366
|
+
[Trusted publishing for npm packages](https://docs.npmjs.com/trusted-publishers/), and
|
|
367
|
+
add a GitHub Actions trusted publisher with exactly these values:
|
|
368
|
+
|
|
369
|
+
| Field | Value |
|
|
370
|
+
| --- | --- |
|
|
371
|
+
| Organization or user | `metergraph` |
|
|
372
|
+
| Repository | `cli` |
|
|
373
|
+
| Workflow filename | `release.yml` |
|
|
374
|
+
| Environment name | `npm-release` |
|
|
375
|
+
|
|
376
|
+
Trusted publishing requires npm 11.5.1 or newer. The publish job checks this before it
|
|
377
|
+
publishes. After the trusted publisher works, consider restricting the package to
|
|
378
|
+
trusted publishing so that long lived tokens cannot publish it.
|
|
379
|
+
|
|
380
|
+
### Remaining maintainer setup
|
|
381
|
+
|
|
382
|
+
The source repository and license are settled. Before any automated release, a
|
|
383
|
+
maintainer still has to:
|
|
384
|
+
|
|
385
|
+
- complete the [first package bootstrap](#first-package-bootstrap);
|
|
386
|
+
- configure the [trusted publisher](#trusted-publishing);
|
|
387
|
+
- create the `npm-release` environment with required reviewers;
|
|
388
|
+
- set the repository variable `METERGRAPH_CLI_PUBLISH_ENABLED` to `true`.
|
|
389
|
+
|
|
390
|
+
Until all of these are done, leave `publish` false.
|
|
391
|
+
|
|
392
|
+
### After a release
|
|
393
|
+
|
|
394
|
+
After each release, confirm from a clean machine, replacing `VERSION`:
|
|
395
|
+
|
|
396
|
+
```sh
|
|
397
|
+
npx --yes metergraph-cli@VERSION --version --json
|
|
398
|
+
npx --yes metergraph-cli@VERSION doctor --json
|
|
399
|
+
npm view metergraph-cli@VERSION dist.attestations
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Releases from the workflow should show a provenance attestation that names
|
|
403
|
+
`metergraph/cli` and the released commit. The bootstrap version will not.
|
|
404
|
+
|
|
405
|
+
## Security
|
|
406
|
+
|
|
407
|
+
See [SECURITY.md](SECURITY.md).
|
|
408
|
+
|
|
409
|
+
## License
|
|
410
|
+
|
|
411
|
+
Apache-2.0. See [LICENSE](LICENSE).
|