@yawlabs/mcp 0.62.0 → 0.63.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/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  All notable changes to `@yawlabs/mcp` (formerly `@yawlabs/mcph`) are documented here. This project uses [semantic versioning](https://semver.org) and a script-gated release flow: `./release.sh <version>` runs lint + tests + build, bumps, tags, publishes to npm, and creates the GitHub release.
4
4
 
5
+ ## 0.63.0 -- CLI hardening: flag parsing, exit-code consistency, secret-file perms, dispatch error handling
6
+
7
+ A full-pass sweep of the `yaw-mcp` subcommand surface. Every change is a fix, a hardening, or additive; there are no breaking changes to the MCP server or the public CLI contract.
8
+
9
+ - **Value-taking flags no longer swallow a following flag.** `login --key`, `secrets set --value`, `try --base`, and `add --catalog` reject a dash-prefixed token instead of storing it as the value -- e.g. `login --key --json` no longer POSTs `"--json"` as the license key, and `try slug --base --dry-run` no longer silently drops `--dry-run` and wires the trial for real. (`--value` points at `--stdin` for a genuinely dash-leading secret.)
10
+ - **`--help` / exit-code consistency.** `yaw-mcp audit --help` and `compliance --help` now print usage to stdout and exit 0 like every other subcommand (compliance previously forwarded `--help` into an `npx` download); `compliance` with no target exits 2 (arg error) instead of 1.
11
+ - **Uncaught command rejections are handled.** Every subcommand funnels through a shared dispatcher `.catch` that prints `yaw-mcp <cmd>: <message>` and exits 1, instead of dumping a raw Node stack and bypassing the logger (reachable e.g. via `secrets` against a corrupt vault).
12
+ - **Secret-bearing files are born 0600.** `atomicWriteFile` gained a creation-mode option; the token config, team session cookie, encrypted vault, and the install config backup are now written owner-only rather than sitting at the default umask in the window before the post-hoc chmod. `install --dry-run` redacts the token in the config dump, and `--token` carries a process-table exposure note.
13
+ - **`doctor`:** `--json` now runs the same expired-trial GC as the text path, and the snapshot carries the `trials` + `backgroundPosters` sections (it was not the "1:1 mirror" its comment claimed). The header documents the config read-modify-write side effect and the now-unreachable exit code 1.
14
+ - **Completion drift guard made real.** Shell completion now offers `foundry`, and the completion test asserts coverage against the real dispatch table (extracted to `src/subcommands.ts`) instead of a hand-maintained list that had silently diverged.
15
+ - **`secrets`:** `get` documents that it prints cleartext (with an interactive-TTY stderr warning); Ctrl-D at the passphrase prompt cancels instead of submitting a partial passphrase; `pull` empty-remote `--json` carries the same hint as the prose path.
16
+ - **`compliance --publish`** projects the report to an explicit allowlist before upload (no echoed env/argv/stack leaks), and the suite child's stdout is capped (16 MB) behind a wall-clock watchdog.
17
+ - **`upgrade`:** the `_npx` marker now requires the full npm-cache hex context, so a user project path that merely contains a `_npx` segment is no longer misclassified as an npx run; the 1->2 exit sequence for non-runnable methods (binary/dev-checkout) is documented.
18
+ - **`add`** trims whitespace-only `--env` values so a blank-ish required secret is never persisted to bundles.json. Did-you-mean now includes `help`, gates its substring tier for very short queries, and a leading-dash near-miss (`--versionn`) suggests the flag instead of silently booting the MCP server.
19
+ - **deps:** `esbuild` override pinned to `^0.28.1`.
20
+
5
21
  ## 0.62.0 -- verifiable-signal routing: graded reward, miss tracking, and an eval foundry
6
22
 
7
23
  Lands #25, #26, and #27. The dispatch router's learning signal moves from a binary "any non-error reply counts as success" to a sound, quality-graded reward, plus the surrounding machinery to manufacture and verify that signal. All of the new behavior is additive and the new knobs are off by default, so existing setups are unchanged.
@@ -9,12 +9,12 @@ import { join } from "path";
9
9
  // src/atomic-write.ts
10
10
  import { mkdir, rename, unlink, writeFile } from "fs/promises";
11
11
  import path from "path";
12
- async function atomicWriteFile(filePath, contents, encoding = "utf8") {
12
+ async function atomicWriteFile(filePath, contents, encoding = "utf8", mode) {
13
13
  const dir = path.dirname(filePath);
14
14
  const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
15
15
  await mkdir(dir, { recursive: true });
16
16
  try {
17
- await writeFile(tmp, contents, encoding);
17
+ await writeFile(tmp, contents, mode === void 0 ? { encoding } : { encoding, mode });
18
18
  await rename(tmp, filePath);
19
19
  } catch (err) {
20
20
  await unlink(tmp).catch(() => void 0);
@@ -144,7 +144,7 @@ async function loadStoredState(filePath) {
144
144
  async function saveStoredState(filePath, state) {
145
145
  cachedState = { filePath, state };
146
146
  try {
147
- await atomicWriteFile(filePath, JSON.stringify(state, null, 2));
147
+ await atomicWriteFile(filePath, JSON.stringify(state, null, 2), "utf8", 384);
148
148
  if (process.platform !== "win32") {
149
149
  try {
150
150
  await chmod(filePath, 384);