Skip to content

CLI: manifest command; defineSettings({ contributed: false }) for sections an extension only reads - #52

Merged
kkdev92 merged 2 commits into
mainfrom
feat/cli-manifest-4.1.0
Aug 29, 2026
Merged

CLI: manifest command; defineSettings({ contributed: false }) for sections an extension only reads#52
kkdev92 merged 2 commits into
mainfrom
feat/cli-manifest-4.1.0

Conversation

@kkdev92

@kkdev92 kkdev92 commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Summary

vscode-ext-kit manifest <entry> brings the manifest check to the command line. It compares the plan an extension compiles at import time with its package.json — the same comparison assertManifestMatches makes in a test — and reports every disagreement at once, as text or JSON, exiting 1 when there is one.

npx vscode-ext-kit manifest ./out/extension.js            # every disagreement with package.json
npx vscode-ext-kit manifest ./out/extension.js --apply    # add the commands and settings it is missing

--apply adds what the manifest is missing and the source can supply: commands and settings, complete in everything mechanical (id, type, default, enum, scope) and with placeholder titles and descriptions marked TODO, so generated text cannot quietly become user-facing documentation. What a person has to decide is reported and left alone: a view needs a container the declaration does not name, a drifted default has two candidates, and an entry only the manifest has may be there on purpose. The file is written back in its own indentation.

A gap the command found: defineSettings({ contributed: false })

Running the command against a real extension turned up one disagreement that was not a mistake in the manifest. The extension declares editor.tabSize — VS Code's setting — so it can read it through the same typed accessor as its own settings. Nothing in the declaration said the section was not the extension's to contribute, so the check asked package.json for it, and --apply would have added it.

defineSettings now takes contributed: false for a section the extension only reads. describePlan carries the answer (SettingsSectionDescription.contributed), and diffManifest, assertManifestMatches and the command line leave such a section out of the comparison. The default is true, so existing declarations mean what they always did.

This is a small addition to the public API rather than a CLI-only workaround, because whether a section is the extension's is a fact only the declaration knows.

What changed

  • bin/vscode-ext-kit.mjs: the manifest subcommand (--manifest, --format text|json, --apply); --format is now validated per command; the usage text covers both commands.
  • defineSettings: contributed?: boolean (default true), carried on the definition and in the plan.
  • describePlan: SettingsSectionDescription.contributed.
  • diffManifest / assertManifestMatches: skip settings groups declared with contributed: false.
  • verify:package: runs manifest from the installed tarball, the first check that resolves the package's ./testing entry through a real install.
  • Docs: README "Command Line", the guide's settings sample (with an editor section declared as read-only) and its plan section, CHANGELOG.

Verification

  • npm run quality: 1080 tests, TypeDoc clean.
  • npm run verify:package: both CLI commands work from the installed package.
  • Against a real extension (47 commands, 10 settings, 3 views): the command reported exactly the editor.tabSize case; with contributed: false on that declaration and a rebuild, manifest ok: 47 command(s), 10 setting(s), 3 view(s) agree. The extension's own typecheck, 236 unit and 35 integration tests pass against the tarball.

🤖 Generated with Claude Code

`vscode-ext-kit manifest <entry>` compares the plan an extension compiles
with its package.json — the comparison `assertManifestMatches` makes in
a test — and reports every disagreement, as text or JSON, exiting 1
when there is one. `--apply` adds what the manifest is missing and the
source can supply: commands and settings, complete in everything
mechanical, with placeholder titles and descriptions a person has to
replace. What a person has to decide is reported and left alone: a view
needs a container the declaration does not name, a drifted default has
two candidates, an entry only the manifest has may be there on purpose.

Running it against a real extension found a gap in the declarations:
`editor.tabSize` belongs to VS Code, and an extension that declares it
to read it through the same typed accessor was indistinguishable from
one that owns it — so the check asked package.json for it.
`defineSettings` now takes `contributed: false` for a section the
extension only reads. `describePlan` carries the answer, and
`diffManifest`, `assertManifestMatches` and the command line leave such
a section out of the comparison.

`verify:package` runs the new command from the installed tarball, which
is the first place the package's `./testing` entry is resolved through
a real install rather than this repository's layout.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread bin/vscode-ext-kit.mjs Fixed
Checking that the file exists and then reading it leaves a window in
which it can change; CodeQL calls it js/file-system-race. The read is
the only check that means anything, so a missing file is now recognised
from the read's own ENOENT.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kkdev92
kkdev92 merged commit 2a015ec into main Aug 29, 2026
10 checks passed
@kkdev92
kkdev92 deleted the feat/cli-manifest-4.1.0 branch August 29, 2026 16:03
@kkdev92 kkdev92 mentioned this pull request Aug 29, 2026
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.

2 participants