docs/design/lightweight-jsonc-settings-editor.md
The ACP runtime statically imports the settings and trusted-folders writers. Both writers currently depend on comment-json, whose parser cluster contributes 304,770 bytes to the ACP startup closure. Those modules are parsed and evaluated before the ACP child can answer initialize, even though most startups do not write either file.
Issue #7264 candidate 6 proposes loading that parser lazily or replacing it with a lighter parser. The write APIs and their callers are synchronous, and standalone distributions do not ship arbitrary JavaScript dependencies outside the bundle, so a runtime require() or dynamic import would either widen the API or break first use. jsonc-parser is already present in the development dependency graph, has a small bundle footprint, and offers synchronous parse and path-edit APIs.
comment-json and esprima from the ACP static startup closure.Rename the legacy camel-case utility to a kebab-case JSONC editor module. The module keeps the existing file-level update API and applyUpdates helper, and adds two synchronous in-memory operations:
jsonc-parser.modify().Objects are diffed recursively so unchanged comments and layout remain untouched. Arrays and scalar values are replaced atomically. Before deleting a property, an inline comment on the same line is removed with that property; otherwise jsonc-parser can attach the comment to the preceding property. The complete output is parsed again and compared with the intended value before any caller writes it.
Duplicate object keys need explicit handling because jsonc-parser evaluates the last value while modify() targets the first matching property. Before applying object-path updates, earlier duplicate properties along those paths are removed so the effective last property remains. Comments owned by removed duplicate occurrences are removed with them. This avoids returning success while leaving the effective value unchanged.
New files continue to use two-space JSON. Existing files retain detected tabs or spaces, LF or CRLF, final-newline state, and a leading BOM.
trustedFolders reuses the in-memory parser and editor after taking its existing lock and re-reading the file. It still validates the disk state and proposed state, writes through atomicWriteFileSync() with mode 0o600, forceMode: true, and noFollow: true, updates memory only after the write succeeds, and releases the lock in finally.
jsonc-parser becomes a direct CLI production dependency and comment-json is removed. Source imports use the public package entry so unbundled compiled output remains directly runnable by Node. The esbuild configuration aliases that entry to the package's ESM build because the Node-oriented bundle otherwise selects its UMD entry, whose relative CommonJS requires do not survive the split ESM bundle. The fast-path bundle guard forbids comment-json, esprima, and the jsonc-parser UMD build in the ACP static closure.
false return and stderr diagnostics on parse or validation failure.import('comment-json')Rejected because the public write path is synchronous and has synchronous migration, UI, ACP, and daemon callers. Converting the call graph to async is wider than this optimization.
createRequire()Rejected because esbuild would leave the dependency outside the bundle while standalone archives do not include arbitrary JavaScript packages in lib/node_modules. A packaged first write could fail at runtime.
JSON.stringify()Rejected because it would discard user comments and formatting during normal settings updates.
Rejected because jsonc-parser already provides the required parse tree and edit primitives with a substantially smaller, maintained implementation.
comment-json nor esprima is in the ACP static closure.channel.initialize P50 by 35.39 ms, process-to-first-session P50 by 38.00 ms, and process-to-first-session-complete P50 by 48.51 ms. It won 28 of 30 cold pairs for each primary metric, with paired-mean 95% bootstrap intervals entirely below zero.comment-json, esprima, or jsonc-parser UMD input.