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 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
- # Temporary Holding Version
1
+ # metergraph-cli
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
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).