Skip to content

feat(vscode): #2869 plugin updates - #2912

Merged
markscott-ms merged 5 commits into
finos:mainfrom
fidelity-contributions:feat/issue-2869-calm-vs-code-plugin-updates
Aug 6, 2026
Merged

feat(vscode): #2869 plugin updates#2912
markscott-ms merged 5 commits into
finos:mainfrom
fidelity-contributions:feat/issue-2869-calm-vs-code-plugin-updates

Conversation

@byrash

@byrash byrash commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Description

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update
  • 🎨 Code style/formatting changes
  • ♻️ Refactoring (no functional changes)
  • ⚡ Performance improvements
  • ✅ Test additions or updates
  • 🔧 Chore (maintenance, dependencies, CI, etc.)

Affected Components

  • CLI (cli/)
  • Schema (calm/)
  • CALM AI (calm-ai/)
  • CALM Hub (calm-hub/)
  • CALM Hub UI (calm-hub-ui/)
  • CALM Server (calm-server/)
  • CALM Widgets (calm-widgets/)
  • Documentation (docs/)
  • Shared (shared/)
  • VS Code Extension (calm-plugins/vscode/)
  • Dependencies
  • CI/CD

Commit Message Format ✅

Testing

  • I have tested my changes locally
  • I have added/updated unit tests
  • All existing tests pass

Checklist

  • My commits follow the conventional commit format
  • I have updated documentation if necessary
  • I have added tests for my changes (if applicable)
  • My changes follow the project's coding standards

@byrash
byrash requested a review from a team as a code owner July 29, 2026 12:38
@github-actions github-actions Bot added config docs Improvements of additions to documentation labels Jul 29, 2026

@markscott-ms markscott-ms left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few initial comments @byrash

  1. Consider submitting the docs change and calm-plugins/vscode change in two separate PRs, with docs PR to be merged after vscode extension is published.

As this is a significant change, it may be a number of days until a new VSCode release is published to the VSCode Marketplace. Docs will get immediately pushed on merge to the CALM website. We should try to align docs merge to the VSCode release publishing. Happy to discuss.

  1. The root package-lock.json is out of sync and so all CI builds are failing.

  2. Worth reviewing in Office Hours tomorrow?

@markscott-ms markscott-ms mentioned this pull request Jul 29, 2026
4 tasks
@LeighFinegold

LeighFinegold commented Jul 29, 2026

Copy link
Copy Markdown
Member

A few initial comments @byrash

  1. Consider submitting the docs change and calm-plugins/vscode change in two separate PRs, with docs PR to be merged after vscode extension is published.

As this is a significant change, it may be a number of days until a new VSCode release is published to the VSCode Marketplace. Docs will get immediately pushed on merge to the CALM website. We should try to align docs merge to the VSCode release publishing. Happy to discuss.

  1. The root package-lock.json is out of sync and so all CI builds are failing.
  2. Worth reviewing in Office Hours tomorrow?

I must admit I didn't know we were going to override the existing plugin code completely on day1 (I guess still awaiting for the prev meeting office transcription and videos to be fixed where maybe that was communicated).

Before we published this straight out, I would like the group to consider more code rationalisation alongside calm-studio before republishing based on discussion with @byrash and @gjs-opsflo.

Would also likely rebuild locally and then test the experience doesn't break for some of the internal architectures we maintain etc. - although perhaps companies can control what version are available internally.

@byrash

byrash commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

A few initial comments @byrash

  1. Consider submitting the docs change and calm-plugins/vscode change in two separate PRs, with docs PR to be merged after vscode extension is published.

As this is a significant change, it may be a number of days until a new VSCode release is published to the VSCode Marketplace. Docs will get immediately pushed on merge to the CALM website. We should try to align docs merge to the VSCode release publishing. Happy to discuss.

  1. The root package-lock.json is out of sync and so all CI builds are failing.
  2. Worth reviewing in Office Hours tomorrow?

I must admit I didn't know we were going to override the existing plugin code completely on day1 (I guess still awaiting for the prev meeting office transcription and videos to be fixed where maybe that was communicated).

Before we published this straight out, I would like the group to consider more code rationalisation alongside calm-studio before republishing based on some early discussion with @byrash and @gjs-opsflo.

Would also likely rebuild locally and then test the experience doesn't break for some of the internal architectures we maintain etc. - although perhaps companies can control what version are available internally.

Thanks @LeighFinegold , yes please test and let us know if you see any issues, happy to resolve and open for any feedback. Thank You.

@LeighFinegold

LeighFinegold commented Jul 29, 2026

Copy link
Copy Markdown
Member

Thanks @LeighFinegold , yes please test and let us know if you see any issues, happy to resolve and open for any feedback. Thank You.

@byrash - the new canvas is genuinely impressive, and I'm excited about the visual-editor direction. I wasn't on the last office hours but what was stated on the Monthly I fully support the agreed plan i.e. editable capability built into CALM Hub (deployment-configurable) the VS Code plugin kept in parity with it, and AI capabilities to follow. This PR is clearly a good step toward that.

One thing worth keeping in mind for the parity goal: the VS Code plugin historically wasn't a CALM Hub-style editor. It was a pre-publish authoring & documentation workflow, i.e. the place you shaped, validated and documented a model before publishing it to CALM Hub. The concrete workflow this supported is git-first: people author CALM in their own git repo (hand-edit the JSON, review in PRs, validate in CI, generate docs) and then publish the finished model to CALM Hub.

So "parity with CALM Hub's editable capability" covers the editing half, but doesn't automatically preserve that author-before-publish, git-first flow. Interestingly it points in a natural direction: the emerging CALM workspace that @willosborne introduced and therefore we would work in a way to leverage the same code to do in the tool i.e. via publish button.

A few things are clearly deliberate and fine if this is the direction: viewing becomes editing, the tool now writes back into the source model (worth a round-trip safety check here, not just on formatting/comments/unknown fields but on referential integrity, since canvas edits regenerate relationship ids), the visual UI becomes the primary surface (hand-editing JSON still works, just syncs on save rather than live-as-you-type), plus the rebrand and new shortcut (Cmd/Ctrl+Shift+K instead of C).

The differences below are the ones I'd love your read on, because they seem to be removed with no direct replacement. The first two are the significant ones; the rest are likely minor.

Major:

  • Docify / documentation-website generation was the only thing that turned a model into a human-readable doc, so dropping it takes CALM's "documents" story out of the authoring flow right as it's being designed (Documents vs Decorators Design Discussion: Documents vs Decorators #2791, Knowledge Decorator / OKF Design Discussion: Introduce a Knowledge Decorator for Architecture Documentation (Open Knowledge Framework) #2866). Parity idea: a live text/markdown editing + preview panel that also renders SAD (Solution Architecture Document) content, sitting alongside the "Generate Solution Design document" action already in this PR. Worth landing this (in Hub, or retained here) before it replaces the published extension, so we never ship with no doc-generation path at all.
  • CALM flows: the canvas doesn't visualise or let you author flows (the old flow-focused view is gone). Flows already in the file are passed through on save rather than deleted, but because canvas edits regenerate relationship ids, existing flows can be silently left pointing at ids that no longer exist. Flow visualisation is also a known want for CALM Hub (Visualize Flow Sequence Diagrams in CalmHub #2537) (it was just awaiting the decorator vs document decision), so this is a natural parity item to line up.

Likely minor:

  • Problems-panel validation: now in-diagram badges using the extension's own bundled rules (could differ from the official CALM validator)
  • Searchable model outline / sidebar
  • Drill-down into a linked/detailed model (incl. resolving references to local copies)
  • Template preview
  • YAML models (JSON only now)
  • File recognition: only specific name patterns match, so a plain architecture.json or generic JSON under calm/ is no longer picked up
  • Existing settings: old config keys are replaced, so saved settings quietly stop applying
  • Docs: README/guides still describe the old features and reference a "Live Docify" screenshot this PR removes

My point is just simply it be nice to ensure atleast this parity of the missing parts before publishing (perhaps taking into account the work @rocketstack-matt is doing with claude-design as shown on #2904 ), further clean-up and consolidate the code => I will be a very happy maintainer :D

@byrash

byrash commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @LeighFinegold , yes please test and let us know if you see any issues, happy to resolve and open for any feedback. Thank You.

@byrash - the new canvas is genuinely impressive, and I'm excited about the visual-editor direction. I wasn't on the last office hours but what was stated on the Monthly I fully support the agreed plan i.e. editable capability built into CALM Hub (deployment-configurable) the VS Code plugin kept in parity with it, and AI capabilities to follow. This PR is clearly a good step toward that.

One thing worth keeping in mind for the parity goal: the VS Code plugin historically wasn't a CALM Hub-style editor. It was a pre-publish authoring & documentation workflow, i.e. the place you shaped, validated and documented a model before publishing it to CALM Hub. The concrete workflow this supported is git-first: people author CALM in their own git repo (hand-edit the JSON, review in PRs, validate in CI, generate docs) and then publish the finished model to CALM Hub.

So "parity with CALM Hub's editable capability" covers the editing half, but doesn't automatically preserve that author-before-publish, git-first flow. Interestingly it points in a natural direction: the emerging CALM workspace that @willosborne introduced and therefore we would work in a way to leverage the same code to do in the tool i.e. via publish button.

A few things are clearly deliberate and fine if this is the direction: viewing becomes editing, the tool now writes back into the source model (worth a round-trip safety check here, not just on formatting/comments/unknown fields but on referential integrity, since canvas edits regenerate relationship ids), the visual UI becomes the primary surface (hand-editing JSON still works, just syncs on save rather than live-as-you-type), plus the rebrand and new shortcut (Cmd/Ctrl+Shift+K instead of C).

The differences below are the ones I'd love your read on, because they seem to be removed with no direct replacement. The first two are the significant ones; the rest are likely minor.

Major:

  • Docify / documentation-website generation was the only thing that turned a model into a human-readable doc, so dropping it takes CALM's "documents" story out of the authoring flow right as it's being designed (Documents vs Decorators Design Discussion: Documents vs Decorators #2791, Knowledge Decorator / OKF Design Discussion: Introduce a Knowledge Decorator for Architecture Documentation (Open Knowledge Framework) #2866). Parity idea: a live text/markdown editing + preview panel that also renders SAD (Solution Architecture Document) content, sitting alongside the "Generate Solution Design document" action already in this PR. Worth landing this (in Hub, or retained here) before it replaces the published extension, so we never ship with no doc-generation path at all.
  • CALM flows: the canvas doesn't visualise or let you author flows (the old flow-focused view is gone). Flows already in the file are passed through on save rather than deleted, but because canvas edits regenerate relationship ids, existing flows can be silently left pointing at ids that no longer exist. Flow visualisation is also a known want for CALM Hub (Visualize Flow Sequence Diagrams in CalmHub #2537) (it was just awaiting the decorator vs document decision), so this is a natural parity item to line up.

Likely minor:

  • Problems-panel validation: now in-diagram badges using the extension's own bundled rules (could differ from the official CALM validator)
  • Searchable model outline / sidebar
  • Drill-down into a linked/detailed model (incl. resolving references to local copies)
  • Template preview
  • YAML models (JSON only now)
  • File recognition: only specific name patterns match, so a plain architecture.json or generic JSON under calm/ is no longer picked up
  • Existing settings: old config keys are replaced, so saved settings quietly stop applying
  • Docs: README/guides still describe the old features and reference a "Live Docify" screenshot this PR removes

My point is just simply it be nice to ensure atleast this parity of the missing parts before publishing (perhaps taking into account the work @rocketstack-matt is doing with claude-design as shown on #2904 ), further clean-up and consolidate the code => I will be a very happy maintainer :D

Thanks @LeighFinegold , that's really insightful feedback; Agree with you.

We would love to have docify integrated to Canvas, we will get a new PR post this and wanted to use SVG instead of mermaid. We want single source of truth while supporting machine readability with WYSIWYG view point. OKF format is pretty newly introduced and we are open to purse that route as well. However at this juncture markdown is our preferred route and if OKF comes along we more than happy to adhere to that spec and make everything work for both Humans & Machines.

Flow diagrams is a gray area for me. We can attempt to have it done in next iteration, also one more thing we discussed in WG is sequence digram support @willosborne had noted that closet for that is Flow diagrams, however it lacks few capabilities to fully represent sequence diagrams. We would love to enhance that and add it, in future iterations.

Was wondering if you capability matrix recorded to show what was in old Plugin to discuss further in our WG to see what this plugin brings and what it removes and may be we could create tickets for missing capabilities and continue to improve the plugin further.

Overall idea is

On authors /manages CALM in VS Code using Plugin optionally leveraging AI to accelerate --> go through standard SDLC processes (Potentially either using GitOps or Transient Storing capability in Calm Hub) --> Calm Hub ( Editing / Viewing / Record Keeping ) <-- External Sources Referring to Calm Hub as a system of record

Open to discuss.
Thank You.

@apurvagandhi
apurvagandhi force-pushed the feat/issue-2869-calm-vs-code-plugin-updates branch from 611777d to a7ff62c Compare July 29, 2026 16:23
@byrash

byrash commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

A few initial comments @byrash

  1. Consider submitting the docs change and calm-plugins/vscode change in two separate PRs, with docs PR to be merged after vscode extension is published.

As this is a significant change, it may be a number of days until a new VSCode release is published to the VSCode Marketplace. Docs will get immediately pushed on merge to the CALM website. We should try to align docs merge to the VSCode release publishing. Happy to discuss.

  1. The root package-lock.json is out of sync and so all CI builds are failing.
  2. Worth reviewing in Office Hours tomorrow?

@markscott-ms all these are now addressed. Another PR for docs in on the way. Thank You

@markscott-ms markscott-ms changed the title Feat/issue 2869 calm vs code plugin updates feat(vscode): #2869 plugin updates Jul 29, 2026
@LeighFinegold

LeighFinegold commented Jul 29, 2026

Copy link
Copy Markdown
Member

Was wondering if you capability matrix recorded to show what was in old Plugin to discuss further in our WG to see what this plugin brings and what it removes and may be we could create tickets for missing capabilities and continue to improve the plugin further.

To be honest, https://marketplace.visualstudio.com/items?itemName=FINOS.calm-vscode-plugin how a reasonable overview.

Take a look at #1565 (comment) which introduced live docify. On that video you can see how a user can navigate the architecture and create live documents as well and as typing narrative content, they can leverage to specific points of the model. This experience can be improved perhaps with views raised on #2344 and I can somewhat visualise how we can create editor tools to aid in this as well.

#2063 (comment) - example of the validation panel, but I can see how in this new world, validation might be highlighted now on the components.

I will say there were other things like theming (for which I think you had a good take on in relation you want certain boxes to be in company themed colours) rather than what @markscott-ms had done in the old plugin - which was to align them to the different themes in vscode.

There are some concepts in the "old" plugin and even cli that might not stay in long term as well. Like scaffolding a website to provide some precursor starter documents to then convert into a docusaurus website vs exposing react-controls + docusaurus plugin @gjs-opsflo raised.


We can attempt to have it done in next iteration, also one more thing we discussed in WG is sequence digram support @willosborne had noted that closet for that is Flow diagrams, however it lacks few capabilities to fully represent sequence diagrams. We would love to enhance that and add it, in future iterations.

That's the same comment on #2537 which I linked. I want to clarify that I don't think you need to add to this PR or be the one to plug the parity gap. For starters, the PR is pretty big as is and the sooner the PR is in the sooner we can converge.

  • @aidanm3341 has indicated interest to do this one post conclusion on flows still being a separate exposed endpoint on CalmHub as won't be considered a decorator.
  • feat(vscode): #2869 plugin updates #2912 (comment) just indicates there are functional gaps and if we agree to drop and publish as is, we just need to communicate as such to all consumers.

@markscott-ms

Copy link
Copy Markdown
Contributor

(For the record I have zero issue with any improvements to theming - my change was to take the diagram rendering from a plain black/white default to something a little more inviting - and with appropriately accessible colours for light mode and dark mode)

As @LeighFinegold has indicated (and I implied in my initial comment), it may be worth getting this PR merged, and then iterated on collectively to get feature parity (or non-parity acknowledged), and produce a 1.0.0 (so maybe not bump the version from 0.7.0 to 1.0.0 in this PR 😄)

@github-actions github-actions Bot added cli Affects `cli` code calm-hub Affects `calm-hub` calm-hub-ui Affects `calm-hub-ui` labels Jul 30, 2026
@byrash
byrash force-pushed the feat/issue-2869-calm-vs-code-plugin-updates branch from bf2d577 to 611777d Compare July 30, 2026 12:35
@apurvagandhi
apurvagandhi force-pushed the feat/issue-2869-calm-vs-code-plugin-updates branch from 611777d to b4c42db Compare July 30, 2026 12:40
@byrash

byrash commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

Now version is moved to 1.0.0-beta as discussed in WG. Thank You.

@LeighFinegold

Copy link
Copy Markdown
Member

@byrash, if internal policies mean you can't get to the fixes quickly, a maintainer can help by patching the build on top of your work. I've put together an example here:

LeighFinegold#28

It keeps all of your commits intact. I used git worktree to branch off your PR head, merged in the latest main, and only added fix-ups on top. CI is green there. The fixes I applied are explained on the PR, and you can view the commits.

Happy to open this against the main repo or hand the branch over, whatever works best for you.

@byrash

byrash commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

LeighFinegold#28

Thanks @LeighFinegold Please do the required.

byrash added 2 commits August 4, 2026 14:05
- CALM Canvas v1.0.0 - visual architecture editor with ReactFlow
- Handle complex diagrams with containers
- Fix race conditions with state and opening building blocks
- Support edge connection display types (straight, elbow, curved)
- Support resizing of containers & nodes
- Show all fields of interfaces
- Bug fixes: solution canvas controls hydration, edge interactions,
  custom relationship types, path traversal attack, z-index,
  sanitize urls, dispose file watcher, allow all calm file types,
  escape script blocks, safe dispose in canvas panel
@apurvagandhi
apurvagandhi force-pushed the feat/issue-2869-calm-vs-code-plugin-updates branch from a8649cd to 3d23457 Compare August 4, 2026 18:47
@byrash

byrash commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review feedback from #2930 and also uptook changes @LeighFinegold have done to help us fix build. Thank You.

@markscott-ms

Copy link
Copy Markdown
Contributor

@byrash it looks like there are some conflicts to resolve (GitHub isn't telling me what)

@byrash

byrash commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

@byrash it looks like there are some conflicts to resolve (GitHub isn't telling me what)

Done. Merged main branch and conflict is gone. Thank You. @markscott-ms

Comment thread calm-plugins/vscode/package.json Outdated

@markscott-ms markscott-ms left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review

Reviewed the full diff. Overall: this is a strong direction and I'm happy for it to land as a pre-release (we will need to change to 0.9.0 due to VSCode Extension publishing rules for pre-release versions). Everything below is written up as follow-up work rather than merge blockers — I'd just like the higher-priority items tracked as issues against the beta so they're closed out before we promote this to a stable release.


Overview

This is a ground-up replacement of the VS Code extension rather than an incremental update. The MVVM architecture (tree view, preview panels, docify/template/model tabs, timeline, CLI integration, @finos/calm-shared dependency, integration tests, screenshot harness) is removed and replaced with CALM Canvas: a ReactFlow visual editor (React 19 + Vite + Zustand + Tailwind) with drill-down navigation, extension packs, pattern/template/standards pickers, and a Copilot Chat spec-generation hook.

Scope: 262 files, +16.1k/−32.3k. New source ~9.0k lines, ~2.1k lines of test. Version reset to 1.0.0-beta, displayName → "CALM Canvas".


What's done well

  • CSP is properly constructed — nonce-based, default-src 'none', localResourceRoots scoped to dist/webview, and < escaping on the injected JSON.
  • Path traversal is explicitly considered in both drillInto (allowlisted roots, blocked attempts logged) and saveBuildingBlock (separator stripping + .. rejection), with an overwrite confirmation.
  • The passthrough for unrecognised relationship-types, and its explanatory comment, show exactly the right instinct about preserving user data.
  • Extension pack registry, icon packs, and the validation rule engine are cleanly separated and reasonably well tested.
  • Several tricky async hazards are handled deliberately: loadGeneration invalidating in-flight timers, the scanReady/webviewReady handshake, and the file-watcher-plus-onDidSaveTextDocument belt-and-braces with a good comment explaining why both are needed.

Priority 1 — worth doing before the beta gets wide use

1. Silent data loss on the canvas→file round-trip

handleCanvasChanged (canvas-panel.ts) replaces the entire document with JSON.stringify(flowToCalm(...)). But flowToCalm (calm-editor-transformer.ts:60-80) rebuilds each node from a fixed whitelist:

const calmNode = { 'unique-id', 'node-type', name, description };
if (data.interfaces) ; if (data.controls) ; if (data.details) ; if (data.metadata) ;

calm-parser.ts:96-104 captures the same fixed set. Any other CALM node property — data-classification, run-as, instance, future 1.2+ fields, custom keys — is dropped the moment the user nudges a node. Relationships have a passthrough for unknown types; nodes have no equivalent.

Three related paths:

  • Empty/nodeless documentloadArchitecture calls setLastParsedArch(null) (App.tsx:145,153). With lastParsedArch === null the "preserve extra fields" block is skipped entirely, so adding the first node destroys $schema, top-level name/description, flows, adrs, etc.
  • metadata as an arrayflowToCalm guards !Array.isArray(rawMetadata) and then writes arch.metadata = { ...existingMetadata, _layout }, so an array-valued metadata is silently replaced by an object.
  • Parse failure leaves a stale model armedloadArchitecture's catch only console.errors (App.tsx:167). If the user hand-edits the JSON into a transiently invalid state and saves, the canvas keeps the previous model and the next canvas interaction overwrites their in-progress file.

Suggested direction: merge emitted nodes over the originals by unique-id rather than rebuilding them; keep lastParsedArch even when nodes is empty; enter a read-only/error state when parsing fails. Longer term, a targeted edit rather than a full-range WorkspaceEdit would also stop us destroying key order and formatting and creating one undo entry per nudge.

2. Test coverage is inverted relative to risk

2,147 test lines against 8,967 source lines, and the tests sit almost entirely on the pure/static parts (validation.test.ts 535, types.test.ts 259, pack registries). Currently zero tests on:

File Lines
webview/App.tsx 1041
extension/webview/canvas-panel.ts 563
webview/transforms/calm-parser.ts 429
webview/transforms/calm-editor-transformer.ts 218
webview/stores/sync-bridge.ts 126
extension/services/sync-coordinator.ts 39

calm-parser and calm-editor-transformer are pure functions that overwrite the user's file — they're the easiest and most valuable things here to test. A round-trip property test (parse(x) → flowToCalm → deep-equal x across the fixture corpus) would catch every item in §1. Note test:coverage was also dropped from package.json.

3. Nothing type-checks in CI

tsconfig.json sets noEmit: true, and tsconfig.extension.json / tsconfig.webview.json are added — but no script invokes tsc. esbuild and Vite both strip types without checking them, so ~9k lines of new TypeScript have no type gate. Suggest adding:

"typecheck": "tsc -p tsconfig.extension.json && tsc -p tsconfig.webview.json"

and wiring it into build-vscode-extension.yml.

4. CI gates removed without replacement

  • The integration-test matrix job is gone, including the explicitly-commented regression gate for #2361 (1.115.0 known-good / 1.116.0 blank-paint regression). The new webview is a different renderer, so re-pointing the gate rather than dropping it seems right.
  • build-vscode-screenshots.yml and the screenshots/ harness are removed.

The remaining gate is npm run test:vscode, which per §2 doesn't cover the new surface. Worth a note in the description on what replaces these.

5. Documentation is unchanged

README.md, AGENTS.md, CLAUDE.md, DEVELOPER.md, and docs/ have zero diff, but every feature they document (tree view, preview tabs, docify, timeline, MVVM layering, the calm.* commands) is gone. calm-plugins/vscode/AGENTS.md in particular will actively mislead future contributors and agents. The PR body ticks "Documentation update" — nothing was updated. (KNOWN - separate PR to avoid pre-publishing updated docs)


Priority 2

  • CSP allows 'unsafe-eval' (html-provider.ts:38). Nothing obvious in ReactFlow / React 19 / Zustand needs it. If it's for a dev-mode Vite path, gate it; otherwise drop it.
  • VSIX ships unminified with sourcemaps. esbuild.mjs honours --production, but no script passes it — build, package, and vscode:prepublish all call bare node esbuild.mjs. vite.webview.config.ts sets minify: false, sourcemap: true. React 19 + ReactFlow unminified is a multi-MB marketplace payload.
  • Makefile bump targets corrupt the version. With version: "1.0.0-beta", bump-patch computes +"0-beta" + 1NaN and writes 1.0.NaN to package.json. make package and make install both run bump-patch first, so the documented local flow breaks on first use.
  • Schemas are committed as symlinks (src/core/schemas/*.json../../../../../calm/release/1.2/meta/*.json, mode 120000). These break on Windows checkouts without Developer Mode / core.symlinks=true. A build-time copy step (as the removed scripts/copy-calm-assets.js did) is safer. Also worth noting this hard-pins validation to release 1.2 with no path to draft schemas.
  • Sizeable blocks are copied from CalmStudio rather than shared. core/validation.ts, core/aigf/*, and extensions/packs/* carry SPDX-FileCopyrightText: … CalmStudio Contributors, tab indentation (vs 4-space elsewhere here), .js import extensions, a stale comment in catalogue.ts referencing tsconfig.base.json (not present in this package), and an aigf/types.ts reference to a NOTICE file that also isn't here. Either extract to a shared workspace package or fix the headers/comments so they describe this codebase.
  • lastParsedArch is module-level mutable state (calm-editor-transformer.ts:12). It's the anchor for all field preservation and it's mutated by drill-down navigation — a null or wrong-level value is exactly the §1 trigger. Making it an explicit parameter to flowToCalm would remove a whole class of bug.

Priority 3 — small stuff

  • workspace-asset-service.ts:120-121'building-blocks/**/*.{calm.json,architecture.json}' is listed twice, creating duplicate watchers and double rescans.
  • WorkspaceAssetService's workspaceRoot constructor param is never used (getRoots() reads workspaceFolders directly).
  • SyncCoordinator.canvasChanged() unconditionally returns true, so the caller's if (!…) return; is vestigial. The fixed 1000 ms suppression window is also a timing heuristic that will misfire on slow disks — a content hash comparison would be deterministic.
  • path.resolve(externalPath.trim()) resolves a relative calm.externalAssetsPath against the extension host's cwd; the setting is documented as absolute, so worth validating and rejecting relative paths.
  • The containment check uses canonical.startsWith(root + path.sep) — correct, but case-sensitive, so it will reject legitimate paths on Windows/macOS.
  • Undeclared eslint dependencies: the new config imports @eslint/js, eslint-plugin-react-hooks, and typescript-eslint. None are declared in this package or at root — they resolve only via npm hoisting from calm-hub-ui. Worth adding to this package's devDependencies.
  • lint-fix and test:coverage scripts were dropped, so root npm run lint-fix --workspaces now silently skips this package.
  • Root package.json adds three @docusaurus/* overrides, unrelated to #2869 and affecting the docs build — worth splitting out or calling out in the description.
  • Root test:vscode still runs build:shared first, but @finos/calm-shared is no longer a dependency.
  • Test files use .test.ts; the repo convention (and every removed test) is .spec.ts.
  • sample.calm.json at the package root looks like a scratch file — AGENTS.md asks for these under sandbox/.
  • Vendor-specific packs (fluxnova, opengris) are baked into an otherwise vendor-neutral FINOS extension — worth confirming that's intentional.

Summary

Happy for this to go in. Given the size, the two things I'd most like to see land early in the follow-up sequence are the round-trip data-loss fixes with tests on calm-parser/calm-editor-transformer (§1, §2) and a typecheck step in CI (§3) — those two together de-risk most of the rest.

@byrash

byrash commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Documentation Update PR #2937 for code changes in here. Thanks!

@byrash

byrash commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Code review

Reviewed the full diff. Overall: this is a strong direction and I'm happy for it to land as a pre-release (we will need to change to 0.9.0 due to VSCode Extension publishing rules for pre-release versions). Everything below is written up as follow-up work rather than merge blockers — I'd just like the higher-priority items tracked as issues against the beta so they're closed out before we promote this to a stable release.

Overview

This is a ground-up replacement of the VS Code extension rather than an incremental update. The MVVM architecture (tree view, preview panels, docify/template/model tabs, timeline, CLI integration, @finos/calm-shared dependency, integration tests, screenshot harness) is removed and replaced with CALM Canvas: a ReactFlow visual editor (React 19 + Vite + Zustand + Tailwind) with drill-down navigation, extension packs, pattern/template/standards pickers, and a Copilot Chat spec-generation hook.

Scope: 262 files, +16.1k/−32.3k. New source ~9.0k lines, ~2.1k lines of test. Version reset to 1.0.0-beta, displayName → "CALM Canvas".

What's done well

  • CSP is properly constructed — nonce-based, default-src 'none', localResourceRoots scoped to dist/webview, and < escaping on the injected JSON.
  • Path traversal is explicitly considered in both drillInto (allowlisted roots, blocked attempts logged) and saveBuildingBlock (separator stripping + .. rejection), with an overwrite confirmation.
  • The passthrough for unrecognised relationship-types, and its explanatory comment, show exactly the right instinct about preserving user data.
  • Extension pack registry, icon packs, and the validation rule engine are cleanly separated and reasonably well tested.
  • Several tricky async hazards are handled deliberately: loadGeneration invalidating in-flight timers, the scanReady/webviewReady handshake, and the file-watcher-plus-onDidSaveTextDocument belt-and-braces with a good comment explaining why both are needed.

Priority 1 — worth doing before the beta gets wide use

1. Silent data loss on the canvas→file round-trip

handleCanvasChanged (canvas-panel.ts) replaces the entire document with JSON.stringify(flowToCalm(...)). But flowToCalm (calm-editor-transformer.ts:60-80) rebuilds each node from a fixed whitelist:

const calmNode = { 'unique-id', 'node-type', name, description };
if (data.interfaces) ; if (data.controls) ; if (data.details) ; if (data.metadata) ;

calm-parser.ts:96-104 captures the same fixed set. Any other CALM node property — data-classification, run-as, instance, future 1.2+ fields, custom keys — is dropped the moment the user nudges a node. Relationships have a passthrough for unknown types; nodes have no equivalent.

Three related paths:

  • Empty/nodeless documentloadArchitecture calls setLastParsedArch(null) (App.tsx:145,153). With lastParsedArch === null the "preserve extra fields" block is skipped entirely, so adding the first node destroys $schema, top-level name/description, flows, adrs, etc.
  • metadata as an arrayflowToCalm guards !Array.isArray(rawMetadata) and then writes arch.metadata = { ...existingMetadata, _layout }, so an array-valued metadata is silently replaced by an object.
  • Parse failure leaves a stale model armedloadArchitecture's catch only console.errors (App.tsx:167). If the user hand-edits the JSON into a transiently invalid state and saves, the canvas keeps the previous model and the next canvas interaction overwrites their in-progress file.

Suggested direction: merge emitted nodes over the originals by unique-id rather than rebuilding them; keep lastParsedArch even when nodes is empty; enter a read-only/error state when parsing fails. Longer term, a targeted edit rather than a full-range WorkspaceEdit would also stop us destroying key order and formatting and creating one undo entry per nudge.

2. Test coverage is inverted relative to risk

2,147 test lines against 8,967 source lines, and the tests sit almost entirely on the pure/static parts (validation.test.ts 535, types.test.ts 259, pack registries). Currently zero tests on:

File Lines
webview/App.tsx 1041
extension/webview/canvas-panel.ts 563
webview/transforms/calm-parser.ts 429
webview/transforms/calm-editor-transformer.ts 218
webview/stores/sync-bridge.ts 126
extension/services/sync-coordinator.ts 39
calm-parser and calm-editor-transformer are pure functions that overwrite the user's file — they're the easiest and most valuable things here to test. A round-trip property test (parse(x) → flowToCalm → deep-equal x across the fixture corpus) would catch every item in §1. Note test:coverage was also dropped from package.json.

3. Nothing type-checks in CI

tsconfig.json sets noEmit: true, and tsconfig.extension.json / tsconfig.webview.json are added — but no script invokes tsc. esbuild and Vite both strip types without checking them, so ~9k lines of new TypeScript have no type gate. Suggest adding:

"typecheck": "tsc -p tsconfig.extension.json && tsc -p tsconfig.webview.json"

and wiring it into build-vscode-extension.yml.

4. CI gates removed without replacement

  • The integration-test matrix job is gone, including the explicitly-commented regression gate for CALM Preview shows blank pane after upgrading to VSCode 1.116 #2361 (1.115.0 known-good / 1.116.0 blank-paint regression). The new webview is a different renderer, so re-pointing the gate rather than dropping it seems right.
  • build-vscode-screenshots.yml and the screenshots/ harness are removed.

The remaining gate is npm run test:vscode, which per §2 doesn't cover the new surface. Worth a note in the description on what replaces these.

5. Documentation is unchanged

README.md, AGENTS.md, CLAUDE.md, DEVELOPER.md, and docs/ have zero diff, but every feature they document (tree view, preview tabs, docify, timeline, MVVM layering, the calm.* commands) is gone. calm-plugins/vscode/AGENTS.md in particular will actively mislead future contributors and agents. The PR body ticks "Documentation update" — nothing was updated. (KNOWN - separate PR to avoid pre-publishing updated docs)

Priority 2

  • CSP allows 'unsafe-eval' (html-provider.ts:38). Nothing obvious in ReactFlow / React 19 / Zustand needs it. If it's for a dev-mode Vite path, gate it; otherwise drop it.
  • VSIX ships unminified with sourcemaps. esbuild.mjs honours --production, but no script passes it — build, package, and vscode:prepublish all call bare node esbuild.mjs. vite.webview.config.ts sets minify: false, sourcemap: true. React 19 + ReactFlow unminified is a multi-MB marketplace payload.
  • Makefile bump targets corrupt the version. With version: "1.0.0-beta", bump-patch computes +"0-beta" + 1NaN and writes 1.0.NaN to package.json. make package and make install both run bump-patch first, so the documented local flow breaks on first use.
  • Schemas are committed as symlinks (src/core/schemas/*.json../../../../../calm/release/1.2/meta/*.json, mode 120000). These break on Windows checkouts without Developer Mode / core.symlinks=true. A build-time copy step (as the removed scripts/copy-calm-assets.js did) is safer. Also worth noting this hard-pins validation to release 1.2 with no path to draft schemas.
  • Sizeable blocks are copied from CalmStudio rather than shared. core/validation.ts, core/aigf/*, and extensions/packs/* carry SPDX-FileCopyrightText: … CalmStudio Contributors, tab indentation (vs 4-space elsewhere here), .js import extensions, a stale comment in catalogue.ts referencing tsconfig.base.json (not present in this package), and an aigf/types.ts reference to a NOTICE file that also isn't here. Either extract to a shared workspace package or fix the headers/comments so they describe this codebase.
  • lastParsedArch is module-level mutable state (calm-editor-transformer.ts:12). It's the anchor for all field preservation and it's mutated by drill-down navigation — a null or wrong-level value is exactly the §1 trigger. Making it an explicit parameter to flowToCalm would remove a whole class of bug.

Priority 3 — small stuff

  • workspace-asset-service.ts:120-121'building-blocks/**/*.{calm.json,architecture.json}' is listed twice, creating duplicate watchers and double rescans.
  • WorkspaceAssetService's workspaceRoot constructor param is never used (getRoots() reads workspaceFolders directly).
  • SyncCoordinator.canvasChanged() unconditionally returns true, so the caller's if (!…) return; is vestigial. The fixed 1000 ms suppression window is also a timing heuristic that will misfire on slow disks — a content hash comparison would be deterministic.
  • path.resolve(externalPath.trim()) resolves a relative calm.externalAssetsPath against the extension host's cwd; the setting is documented as absolute, so worth validating and rejecting relative paths.
  • The containment check uses canonical.startsWith(root + path.sep) — correct, but case-sensitive, so it will reject legitimate paths on Windows/macOS.
  • Undeclared eslint dependencies: the new config imports @eslint/js, eslint-plugin-react-hooks, and typescript-eslint. None are declared in this package or at root — they resolve only via npm hoisting from calm-hub-ui. Worth adding to this package's devDependencies.
  • lint-fix and test:coverage scripts were dropped, so root npm run lint-fix --workspaces now silently skips this package.
  • Root package.json adds three @docusaurus/* overrides, unrelated to CALM VS Code Plugin Updates #2869 and affecting the docs build — worth splitting out or calling out in the description.
  • Root test:vscode still runs build:shared first, but @finos/calm-shared is no longer a dependency.
  • Test files use .test.ts; the repo convention (and every removed test) is .spec.ts.
  • sample.calm.json at the package root looks like a scratch file — AGENTS.md asks for these under sandbox/.
  • Vendor-specific packs (fluxnova, opengris) are baked into an otherwise vendor-neutral FINOS extension — worth confirming that's intentional.

Summary

Happy for this to go in. Given the size, the two things I'd most like to see land early in the follow-up sequence are the round-trip data-loss fixes with tests on calm-parser/calm-editor-transformer (§1, §2) and a typecheck step in CI (§3) — those two together de-risk most of the rest.

@markscott-ms all valid & great feedback. We can create issues for these items and let's address in parts before we can release. Thank You.

@markscott-ms

Copy link
Copy Markdown
Contributor

Feature analysis: main vs this PR

Purpose: this is a basis for discussion, not a verdict. I've inventoried what the extension does on main and what it does on this branch, so we can have an explicit conversation about what we actually want to carry forward. Several of the things listed as "lost" below may well be things we're happy to lose — that's the discussion. What I wanted to avoid was losing them without noticing.

The two extensions share almost nothing but a name. main is a read-only companion — it watches the files you edit and renders, validates and documents them. This PR is a visual editor — the canvas is the primary surface and it writes back to your files. Nearly every difference below follows from that inversion.


At a glance

main This PR
Commands contributed 4 1
Activity-bar view container ✅ CALM sidebar ❌ removed
Config settings 7 3 (all new)
Activation onStartupFinished workspaceContains:**/*.{calm,architecture,template,solution,standard,guideline}.json
Writes to user files never yes — full-document rewrite
Renderer Mermaid + ELK/Dagre, svg-pan-zoom ReactFlow + React 19
@finos/calm-shared ✅ (validation, docify, loaders) ❌ dropped
Diagnostics collection ✅ 2 0
Hover provider ✅ 1 ❌ 0
CodeLens provider ✅ 1 ✅ 1
Terminal invocations (CLI) 7 0

Removed

1. Real-time validation in the Problems panel — the one I'd most want us to discuss.

main's ValidationService creates a DiagnosticCollection, validates on open/save/editor-switch with a 100 ms debounce and version tracking, uses @finos/calm-shared's validate + enrichWithDocumentPositions + parseDocumentWithPositions, and reports to the Problems panel with click-to-navigate to the exact line.

This PR has zero createDiagnosticCollection calls. It does ship a new Ajv engine (core/validation.ts), but that engine's only consumer is webview/utils/validation.tsValidationBadge.tsx. Validation is now canvas-only badges: no line positions, no Problems panel, and nothing at all if you never open the canvas. Schema errors also lose their document position — schemaErrorToIssue yields an instancePath, not a line.

2. Tree View / Model Elements sidebar — the viewsContainers.activitybar entry, the calmSidebar view, and both calm.searchTreeView / calm.clearTreeViewSearch commands. Structured browsing of Nodes/Relationships/Flows, search-and-filter across large models, and two-way reveal between tree ↔ editor ↔ preview. The new NodePalette is a creation palette, not a model browser — different job.

3. Timeline navigationdetectCalmTimeline, timeline tree items, milestone click-through to detailed architectures, current-moment star marker. Referenced across 10 files on main; no trace here. All timeline fixtures deleted.

4. Docify / documentation generationdocify-service, docifier-factory, docify-processor, html-builder, template-processor, template-service, the docify preview tab, live-refresh mode, HTML and Markdown output, custom Handlebars templates, and the whole templates/ bundle. calm.docify.theme (4 themes + auto) goes with it.

The replacement is requestGenerateSpec, which shells the user into Copilot Chat with a prompt string. That's a different thing in kind: needs Copilot installed, non-deterministic output, and references .github/agents/calm-prompts/solution-design-creation.md — a path with no guaranteed existence. Worth noting it is guarded (showWarningMessage if the chat command is missing). But there's no non-AI documentation path left at all, which feels like a deliberate decision we should make explicitly rather than by omission.

5. calm.createWebsite — the Docusaurus scaffolding command with its form controller, path resolver, scaffold runner and post-creation handler (~8 files). No equivalent. This is why createTerminal drops 7 → 0.

6. Mermaid preview — live Mermaid rendering, the ELK/Dagre layout-engine choice (calm.preview.layout), pan/zoom, diagram controls, and per-template layout-engine frontmatter overrides. ReactFlow + dagre/elkjs replaces the rendering, but there's no user-facing layout-engine setting and no Mermaid output anywhere.

7. Multi-document navigation via calm.urlMapping — the detailed-architecture URL→local-path mapping file and NavigationService. Drill-down here is a different mechanism: relative paths plus a recursive building-blocks/**/<stem>.calm.json glob. It doesn't resolve detailed-architecture URLs at all, so an existing workspace with a mapping file loses drill-through.

8. calm.schemas.additionalFolders — the local-schema-folder setting for schema developers, indexed by $id. Also gone: CalmSchemaRegistry and the bundled release + draft schema copy (copy-calm-assets.js + copyfiles over calm/release/**/meta and calm/draft/**/meta). This PR symlinks release 1.2 only — no draft, no multi-version.

9. YAML CALM document supportmain's file-types.ts accepts .json, .yaml and .yml, and calm.files.globs defaults include calm/**/*.y?(a)ml. This PR's CALM_FILE_SUFFIXES is six .json suffixes, so YAML models are invisible to the extension.

Full disclosure: I didn't know we supported YAML CALM documents until I ran this comparison. That rather undercuts treating it as an obvious must-restore — if none of us knew, it's plausible nobody's using it. I'd rather we decide deliberately whether YAML is something CALM tooling supports than have it quietly persist or quietly vanish. Genuine open question.

10. Configurable file discoverycalm.files.globs and calm.template.globs replaced by hard-coded suffixes and hard-coded asset globs (building-blocks/, patterns/, templates/, standards/, guidelines/). Workspaces not laid out that way get nothing. Arguably a reasonable opinionated-convention trade; worth being explicit that it is a trade.

11. Template files as first-class — front-matter parsing to find a template's architecturePath/urlMappingPath, and FileType.TemplateFile. .template.json is still an activation suffix, but it's opened as an architecture on the canvas, which isn't the same feature.

12. Hover provider (CALM id: <x> tooltips).

13. Integration test suite (@vscode/test-electron, the 1.115/1.116/stable matrix gating #2361) and the screenshot harness with its CI workflow.


Not a loss

The keybinding change. ctrl+shift+cctrl+shift+k. No complaints from me — ctrl+shift+c is VS Code's default for Open New External Terminal, and it fired a terminal at me often enough to be a nuisance. Good change, and ctrl+shift+k is also properly scoped with a when clause on the CALM filename pattern, which the old binding wasn't (it was bare editorTextFocus).


Added

1. A visual editor. The headline, and genuinely new capability — main could never create or modify a model. Drag-and-drop node creation, edge drawing, containment via drag-into-container, inline property editing, delete, and a 50-entry undo/redo stack (App.tsx:110-119, ctrl/cmd+Z).

2. Extension packs — ~130 node types across 10 packs (aws 34, ai 16, azure 15, gcp 15, k8s 14, fluxnova 10, core 9, identity/messaging/opengris 8 each), each with SVG icons, colour schemes, badges, container semantics and defaultChildren. Filterable via two new settings: calm.packs.enabled, calm.packs.excludeNodes.

3. Workspace asset scanning — a new WorkspaceAssetService discovering and hot-reloading (500 ms debounce) four asset classes from the workspace and an external shared folder (calm.externalAssetsPath, the third new setting):

  • building-blocks/** → reusable governed nodes with a read-only drill-down view
  • patterns/**/*.pattern.jsonPatternPicker
  • templates/**/*.template.jsonTemplatePicker
  • standards/**/*.md, guidelines/**/*.mdStandardsPanel, with YAML front-matter controls converted into CALM control maps and prose fetched on demand

4. Drill-down navigation with a breadcrumb stack — double-click into a building block, read-only banner, breadcrumb back up, root document restored at index 0.

5. Rich CALM property editing that main had no way to offer: InterfaceList, ControlsList, EdgeProperties (protocol, description, direction, line style, routing), CustomMetadata, NodeAppearance.

6. BuildingBlockCreator — extract the current canvas into a reusable building block written to building-blocks/ (with ../separator sanitisation and an overwrite prompt).

7. Layout persistence — node positions and sizes round-tripped through metadata._layout so diagrams survive reload.

8. CodeLens on CALM documents — a "View in CALM Canvas" affordance, plus editor-title, editor-context and explorer-context menu entries (main had editor-context only).

9. Bidirectional file↔canvas syncSyncCoordinator (extension side, 1 s suppression window) and suppressFileUpdatesUntil + loadGeneration (webview side), with a workspace-wide file watcher plus onDidSaveTextDocument.


Roughly equivalent

  • Diagram export — both do SVG + PNG via native save dialog with a pre-filled <name>-diagram.<ext>. main exported from Mermaid at 2× pixel ratio; this uses html-to-image's toSvg. main's naming included a diagram index (-diagram-<n>), a Mermaid-preview concept that doesn't apply to a single canvas.
  • Schema validation exists in both, but see Setup monorepo #1 — the delivery mechanism regressed from Problems-panel diagnostics to canvas badges.

One separate observation

core/aigf/catalogue.ts (998 lines of FINOS AI Governance Framework risks/mitigations), mappings.ts (130), types.ts, plus two test files — is entirely unreferenced. Its only export path is core/index.ts, and nothing imports core/index.ts. The sole live consumer of anything under core/ is webview/utils/validation.tscore/validation.ts.

So ~1,200 lines of the new surface, including a test pair, is currently dead code carried over from CalmStudio. Wiring AIGF into the controls/standards panels sounds genuinely interesting and is presumably the intent — but until then it inflates the diff and the apparent test coverage without shipping anything.


Questions for discussion

Net: this trades six read-only analysis features (Problems-panel validation, tree navigation, timeline, docify, website scaffolding, Mermaid preview) for one large authoring capability plus a governed-asset ecosystem. For a 1.0.0-beta under a new name, a reset is defensible. But I'd like us to answer these deliberately rather than by default:

  1. Do we want Problems-panel diagnostics back? My instinct is yes — the engine already exists in core/validation.ts, so it's mostly a DiagnosticCollection plus position mapping. It's also the one feature that works without opening the canvas at all.
  2. Do we support YAML CALM documents, as a project? See Fix #8 by removing non industry specific from model #9 — I didn't know we did. Either answer is fine, I'd just like it decided.
  3. Tree view, timeline, docify, website scaffolding — deliberate strategy change, or casualties? They read as intentional to me, but they're documented on the marketplace listing today, so whatever we decide needs to reach the README and a breaking-change note.
  4. calm.urlMapping / detailed-architecture navigation — is building-block drill-down the intended successor, or do both need to exist?
  5. AIGF — wire it up in a follow-up, or drop it from this PR and bring it back with the feature?

Nothing here is a merge blocker from my side — flagging it so the removals are choices we've made rather than things we discover later.

@markscott-ms
markscott-ms merged commit 56b6111 into finos:main Aug 6, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

calm-hub Affects `calm-hub` calm-hub-ui Affects `calm-hub-ui` cli Affects `cli` code config docs Improvements of additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants