Skip to content

feat(cli): print, draw and check the plan an extension compiles - #49

Merged
kkdev92 merged 1 commit into
mainfrom
feat/plan-cli-4.1.0
Aug 29, 2026
Merged

feat(cli): print, draw and check the plan an extension compiles#49
kkdev92 merged 1 commit into
mainfrom
feat/plan-cli-4.1.0

Conversation

@kkdev92

@kkdev92 kkdev92 commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Summary

describePlan (#46) made the plan readable as data. This makes it reachable from a shell:

npx vscode-ext-kit plan ./out/extension.js                    # the plan as JSON
npx vscode-ext-kit plan ./out/extension.js --format mermaid   # modules, services and their edges
npx vscode-ext-kit plan ./out/extension.js --format dot       # the same, for Graphviz
npx vscode-ext-kit plan ./out/extension.js --check            # exit 1 with every problem preflight found

The entry module is the extension's own — ESM source or the CommonJS bundle it ships — and the plan is whatever defineExtension compiled when that module was evaluated. Export the result as app, or name the export with --export.

How it evaluates an extension outside VS Code

vscode exists only inside an extension host, so the tool evaluates the entry with a stand-in: a proxy that answers every property and does nothing. That is enough because nothing in this package touches VS Code before activatedefineExtension compiles the plan and stops — and an extension's module-scope code is held to the same rule by the framework's design. ESM imports are redirected by a module-resolution hook; CommonJS require('vscode'), which is what a bundled extension does, by Node's CommonJS resolver. Both paths land on the same stand-in, so a production bundle reads the same way an unbundled entry does.

The consequence for authors is the one the framework already asks for: keep VS Code reads inside activate or a handler. Module-scope code that reads a VS Code value gets a proxy instead of a crash, and the failure surfaces where it belongs — in a real host.

Output

  • json — exactly what describePlan returns; deterministic, so it can be committed and diffed.
  • mermaid / dot — one subgraph per module holding its services (with lifetime), commands, hosted services, watchers and views; dependency edges between them; framework services something depends on in a subgraph of their own, so no edge points at nothing.
  • --check — a one-line summary and exit 0, or the list of preflight problems (code, subject, module, message) on stderr and exit 1. Exit 2 is a usage or load error.

Where it lives, and how it is checked

The tool is bin/vscode-ext-kit.mjs, outside src/, which may not touch Node. verify:package now runs it from the installed tarball against a plan written in the throwaway consumer project, so the one place the stand-in meets a real install is exercised on every run. A test suite drives it as a child process across every format and exit code.

It was also run against a published extension's real CommonJS bundle, unmodified, and read the plan out of it.

Compatibility

Additive: a bin entry, bin/ in files. No runtime code changes.

🤖 Generated with Claude Code

`describePlan` made the plan readable as data; this makes it reachable
without writing code. `vscode-ext-kit plan <entry>` evaluates an extension's
entry module and prints what it registers -- as JSON, as a Mermaid or
Graphviz graph of modules, services and the edges between them, or, with
`--check`, as an exit code and the list of problems preflight found.

The entry module is evaluated with a stand-in for `vscode`, because the real
module only exists inside an extension host. That works because nothing in
this package touches VS Code before `activate`; an extension's own
module-scope code is held to the same rule, which the framework already asks
of it. ESM imports of `vscode` are redirected by a resolution hook, CommonJS
`require('vscode')` -- what a bundled extension does -- by Node's CommonJS
resolver, so both an unbundled entry and a production bundle read the same
way.

The tool lives in `bin/`, outside the runtime core, which may not touch Node.
`verify:package` runs it from the installed tarball against a plan the
throwaway consumer wrote, so the one place the stand-in meets a real install
is checked on every run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kkdev92
kkdev92 merged commit 403cecc into main Aug 29, 2026
10 checks passed
@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.

1 participant