fix(cli): harden adf-patch / serve / hook error paths surfaced by telemetry triage#195
Open
stackbilt-admin wants to merge 2 commits into
Open
fix(cli): harden adf-patch / serve / hook error paths surfaced by telemetry triage#195stackbilt-admin wants to merge 2 commits into
stackbilt-admin wants to merge 2 commits into
Conversation
A malformed `--ops` element (e.g. `[null]` or a non-object) crashed the before-capture pass with an uncaught TypeError instead of a clean error, because `captureOpBefore` ran before `applyPatches` validated the ops. Surfaced by sweeping local `.charter/telemetry` across org repos — a live TypeError in `adf patch --ops` had gone unreported for months. Validate the parsed ops against a Zod `PatchOperationArraySchema` right after JSON.parse, before any capture. Malformed ops now produce a clean CLIError naming the offending `ops[i]`; the target file is left untouched. The schema lives in the CLI (keeps `@stackbilt/adf` zero-dep) with a compile-time drift guard asserting `z.infer` stays mutually assignable with adf's public `PatchOperation` type — so the two cannot silently diverge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two error-path gaps found via local telemetry triage: - `serve`: when `--ai-dir` (or its manifest) is missing, the error now echoes the resolved path. Repos showed `serve --name --ai-dir` rejected and retried-then-abandoned because the message never said which path was checked. - `hook install`: filesystem failures creating/writing the hook file, and git failures resolving the hooks dir, escaped as raw Errors. Both are now wrapped into a CLIError with an actionable message. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Origin
Found by sweeping local
.charter/telemetry/events.ndjsonacross org repos that run the Charter CLI. Telemetry records command metadata only (no content); the actionable signal is the exit code +errorName— an uncaught throw (TypeError/Error/unnamed) at exit 2 is a real crash, aCLIErroris a clean rejection.Changes, by confidence
adf patch --ops[null], non-object) crashedcaptureOpBeforewith an uncaughtTypeErrorbecause it ran beforeapplyPatchesvalidated. Now validated against a ZodPatchOperationArraySchemaat the parse boundary → cleanCLIError, file untouched. Reproduced the exact crash before & after.serve --ai-dir--ai-dir/manifest path, so a wrong path is obvious instead of retried blind.hook installfs.mkdirSync/writeFileSyncand git-dir resolution failures escaped as rawError; both now wrap into aCLIError. The widened guard makes "hook install yields clean errors, not raw throws" true regardless of which surface fails.stamp-policiesDesign notes
@stackbilt/adfzero-dep. A compile-time drift guard assertsz.inferstays mutually assignable with adf's publicPatchOperationtype — they can't silently diverge. Migrating the schema into@stackbilt/adfas source-of-truth is a deliberate follow-up, not folded in here.zod ^3.24.1declared in the CLIpackage.json(was already imported but undeclared).Verification
tsc --noEmitcleanadf-patchrepro cases, bothserveguards, and bothhookfailure surfaces (thehookwrite-failure test uses a real fs failure, not a mock)🤖 Generated with Claude Code