Skip to content

Allow comments in providers.json, and make robust to unknown fields - #53

Merged
wch merged 11 commits into
mainfrom
parse-jsonc
Aug 9, 2026
Merged

Allow comments in providers.json, and make robust to unknown fields#53
wch merged 11 commits into
mainfrom
parse-jsonc

Conversation

@wch

@wch wch commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Allow comments in providers.json, and make robust to unknown fields

Before this change, providers.json was handled pretty strictly: if there were any comments, or any fields that weren't specified in schema, then the code would return an empty {} object to represent the configuration.

This PR allows providers.json reads to preserve valid provider settings when the file contains JSONC syntax or an unknown or invalid provider block. Reads now return structured, sourced issue snapshots for anything they skip, while mutations remain strict so a programmatic rewrite can never silently delete configuration it does not understand.

Changes

  • Parse user-authored provider configuration as JSONC and preserve unsafe object keys through validation.
  • Salvage valid root, built-in provider, and custom provider entries at whole-block granularity with explicit diagnostics for every discarded value.
  • Add report-first resolve, load, and watch APIs while retaining the existing catalog-only compatibility APIs and logging behavior.
  • Emit complete, structurally deduplicated issue snapshots for file, environment, legacy Positron, resolver, and watcher paths.
  • Keep mutations strict and byte-preserving when the current file contains invalid or unknown configuration.
  • Report JSONC syntax errors as 1-based line/column (handling LF, CRLF, and CR line endings) instead of raw character offsets, on both the read and mutation paths.
  • Classify every whole-source failure — an unparseable or unreadable file, a whole-file salvage degrade (non-object root/providers, unsupported version), an invalid env fragment, or malformed legacy enforced settings — as an error-severity issue with an empty path, while per-key salvage drops remain warnings scoped to the dropped key. Hosts can therefore surface only whole-source failures in the UI and keep validation drops log-only.

wch added 11 commits August 8, 2026 15:00
Whole-source failures (user-file JSONC syntax errors, non-ENOENT read
errors, env-fragment parse/validation failures) now produce
error-severity issues instead of warnings; per-key salvage drops stay
warnings. parseJsonc reports syntax errors as 1-based line/column
(computed from the text, since jsonc-parser only carries offsets) on
both the tolerant and strict paths. Whole-source failure messages are
reworded to be source-agnostic ("Invalid JSONC: ...", "Could not read
the file: ...") so hosts can compose a "Failed to load <path>" prefix
from source identity. Hosts surface only error-severity issues in the
UI; warning-severity drops are log-only because providers.json is
shared across consumers with different provider vocabularies.
Review follow-up: the host error-only UI filter relied on a
severity/scope contract the producers did not consistently satisfy.
Whole-file salvage degrades (non-object root/providers, unsupported
version), schema-invalid env fragments, and malformed legacy
POSITRON_ENFORCED_SETTINGS all discard their entire source but arrived
as warnings (hidden by the filter) or with per-key paths (misrendered
as per-key drops). Whole-source failures now uniformly emit
error-severity issues with an empty path; offending key paths stay in
the message prose. Also fixes lineColumnAt to treat CR and CRLF as
line breaks, matching jsonc-parser.
Review follow-up: recoverValidStack drops an entire overlay at merge
time but emitted a warning with a Zod path, invisible under the hosts'
error-only UI filters. The whole-source contract (error severity,
empty path, detail in message prose) was recreated by open-coded
objects and path-taking local helpers at four sites, which is why
producers kept missing it. Add wholeSourceIssue/sourcedWholeSourceIssue
in config-issue.ts, convert all five call sites (file read/parse, env
fragments, salvage degrades and seal failure, legacy enforced settings,
resolver overlay drops), and delete the local helpers so the
error-with-a-path combination is unrepresentable.
ConfigIssue is now a discriminated union: the error branch (whole-source
failures) types its path as readonly [], so an error with a non-empty
path is unrepresentable at the type level rather than by convention.
SourcedConfigIssue becomes an intersection over the union.
@wch
wch merged commit 5b367fa into main Aug 9, 2026
4 checks passed
@wch
wch deleted the parse-jsonc branch August 9, 2026 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant