Skip to content

Vscode extension#63

Draft
PieterjanDeClippel wants to merge 35 commits into
masterfrom
vscode-extension
Draft

Vscode extension#63
PieterjanDeClippel wants to merge 35 commits into
masterfrom
vscode-extension

Conversation

@PieterjanDeClippel

@PieterjanDeClippel PieterjanDeClippel commented Apr 5, 2026

Copy link
Copy Markdown
Member

PieterjanDeClippel and others added 30 commits April 3, 2026 14:09
Replace Community.VisualStudio.Toolkit with direct VS SDK APIs, add
ProvideAutoLoad so the package loads when a solution is opened, and
move the menu item from Tools to View. Developers must check the
Deploy checkbox in Configuration Manager for the VSIX project.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove debug Console.WriteLine calls from SparkMiddleware that caused
  hangs when hosted without a console
- Don't redirect stdout/stderr in VS extension to prevent pipe buffer
  deadlock with SPA middleware's Angular CLI output
- Set WorkingDirectory to source project dir and ASPNETCORE_ENVIRONMENT
  to Development for Angular CLI dev server support
- Add Job Object process management to ensure cleanup on VS exit
- Copy SPA dist files to output directory for non-Development mode
- Register Spark actions in SparkEditor

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 10 Actions classes for SparkEditor entities (PersistentObjects,
  Attributes, Queries, CustomActions, ProgramUnits, etc.)
- Add Spark output pane to VS extension for server logging
- Update solution file

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…elect

- Rename MintPlayer.Spark.Models -> MintPlayer.Spark.Core
- Move ReferenceAttribute, LookupReferenceAttribute, FromIndexAttribute
  from Abstractions to Core
- Add [Reference] attributes to ProgramUnit, SparkQuery,
  CustomActionDefinition, Right model properties
- Add translatedString dataType to GetDataType() in ModelSynchronizer,
  EntityMapper, PersistentObjectExtensions
- Update SparkEditor model JSONs: 13 translatedString, 6 Reference,
  6 LookupReference datatype corrections
- Add 5 transient LookupReference classes (ProgramUnitType,
  QueryRenderMode, AttributeDataType, ShowedOnOptions, SelectionRuleOptions)
- Add Multiselect to ELookupDisplayType enum
- Fix SparkEditorFileService.LoadPersistentObject ID comparison
- ng-spark: translatedString rendering in detail/form/query views
- ng-spark: multiselect dropdown for flags enum (ShowedOn) with
  bsItemTemplate for translated labels
- Update @mintplayer/ng-bootstrap to 21.12.10

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Override ToString() on TranslatedString to return the first translation
instead of the CLR type name. Also handle TranslatedString objects in the
frontend referenceAttrValue pipe using resolveTranslation().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Change AttributeDefinition.LookupReferenceType from a plain string field
to a Reference attribute backed by a new LookupReferenceDef entity type.
The Actions class uses LookupReferenceDiscoveryService to dynamically
enumerate available lookup references in the project.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ifecycle

The WPF Unloaded event fires on visual-tree changes (auto-hide, layout
reorganization), not just window close. Opening a document tab could
trigger it, killing the SparkEditor backend and causing ERR_CONNECTION_REFUSED
on webview reload. Replace with IVsSolutionEvents.OnBeforeCloseSolution
which fires exactly once when the solution closes — cross-platform via
VS SDK, no dependency on Windows Job Objects.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ude/worktrees/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Implement save/delete for all 10 entity types in SparkEditorFileService
  using JsonNode for stable, git-friendly JSON output (attributes sorted
  by name, arrays by order, object keys alphabetically)
- Add OnSaveAsync/OnDeleteAsync to all 10 Actions classes with entity
  mapping via IEntityMapper and auto GUID generation
- Add FileSystemWatcher with 300ms debounce and self-write suppression
- Add WebSocket endpoint at /spark/editor/file-events for pushing file
  change notifications to the Angular frontend
- Add SparkFileWatchService (Angular) with exponential backoff reconnection
- Wire up file watching lifecycle in Program.cs and shell component
- Add PRD document (docs/PRD-SparkEditor-CRUD.md)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of sorting attributes by name, arrays by order, and object keys
alphabetically, preserve the existing order from the file and append new
items at the end. This avoids reshuffling the entire JSON when an item's
order field changes — only the changed value appears in the git diff.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SavePersistentObject was replacing the entire persistentObject node
including embedded arrays with empty ones. Now carries over existing
tabs, groups, and attributes arrays from the file, since those are
managed by their own SaveAttribute/DeleteAttribute methods.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The global _isWriting boolean suppressed FileSystemWatcher events for
ALL files when ANY file was being written by the editor. Replaced with
a per-file ConcurrentDictionary<string, byte> that only suppresses
events for the specific file being written. Also removed the semaphore
from the write path since it was being released in a fire-and-forget
Task.Delay, creating a race condition.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaced separate Model/ and root watchers with a single watcher per
target path using IncludeSubdirectories=true. This detects files
created in Model/ even if that directory didn't exist at startup,
and catches new files added via external editors like Notepad.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add SparkDataRefreshService to @mintplayer/ng-spark that components
subscribe to via effect(). When the SparkEditor's file watcher detects
an external change, the shell calls refreshService.refresh() which
causes SparkPoDetailComponent to re-fetch its item and
SparkQueryListComponent to re-execute its query.

Also filter out temp files (~RF*.TMP) from the WebSocket endpoint
to avoid noise from editors like Notepad.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 4.4.1: Single recursive watcher instead of two separate watchers
- 4.4.3: Per-file suppression set instead of global _isWriting flag
- 4.4.4: Add temp file filtering, SparkDataRefreshService, component
  refresh via effect() pattern
- 4.2.1: Document that SavePersistentObject preserves embedded arrays
- 6.1: Replace SemaphoreSlim approach with simpler concurrency model

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
LastName doesn't exist on VPerson (the projection type from People_Overview
index), causing a 500 when executing the GetPeople query. FullName is the
correct projected field for sorting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three bugs prevented computed index fields from reaching the API response:

1. IndexRegistry.RegisterProjection looked up by indexType.Name ("People_Overview")
   but the index was registered with slashes ("People/Overview"), so projections
   were never linked. Fixed by matching on the Type object instead of the name.

2. RavenDbStorageProvider registered index names without the underscore-to-slash
   convention. Fixed to apply Replace("_", "/") consistently.

3. session.Query<VPerson, People_Overview>() loads underlying documents, not
   stored index fields. Added ProjectInto<T>() inside RavenDbSparkSession.Query<T>(Type)
   so all callers get projection automatically and can't forget it.

Also adds ISparkSession.Query<T>(Type indexType) overload with implementations
in both RavenDB and FileSystem providers, and updates DatabaseAccess and
QueryExecutor to use type-based index lookup instead of name-based.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BrandColor and AccentColor lost their custom renderer when the attribute
renderer system was refactored. Added renderer components and registered
them via provideSparkAttributeRenderers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The SparkEditor schema defined these as editable attributes but the CLR
class lacked matching properties, so the EntityMapper silently skipped
them during save.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… entities

The PersistentObject.Name wrapper field requires a plain string, but the
create/edit components were passing raw form values — which for
translatedString attributes (e.g. LanguageDef.Name) sent a JSON object,
causing a 500 deserialization error. Extract resolveDisplayName() utility
that respects displayFormat/displayAttribute and resolves TranslatedString
values to strings. Also fix error alerts rendering [object Object] by
adding the resolveTranslation pipe, and improve error extraction to show
server-side Problem Details messages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PieterjanDeClippel and others added 5 commits April 4, 2026 22:23
The TranslatedString editor only showed "en" because the framework's
CultureLoader reads from the SparkEditor's own App_Data/culture.json
(which doesn't exist), not the target app's. Override ICultureLoader
with SparkEditorCultureLoader that reads languages from the target app
via SparkEditorFileService.LoadAllLanguages(). Registered as Scoped so
it reloads on every request, reflecting newly added languages immediately.
"en" is always included as a fallback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SparkLanguageService.loadCulture() was private and only called once in
the constructor. After adding a new language, the TranslatedString editor
still showed stale languages until a full page refresh. Made loadCulture()
public and call it from SparkPoFormComponent.loadAvailableLanguages() so
the editor always fetches the latest languages from the server.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…json

Same issue as culture: the framework's TranslationsLoader reads from the
SparkEditor's own App_Data/translations.json (which doesn't exist), so
UI keys like "save", "cancel", "edit" returned the raw key. Override
ITranslationsLoader with SparkEditorTranslationsLoader that reads from
the target app's translations.json via SparkEditorFileService.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of overriding ITranslationsLoader to read from the target app,
simply add the standard UI translation keys (save, cancel, edit, etc.)
to the SparkEditor's own App_Data/translations.json. Removes the unused
SparkEditorTranslationsLoader.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

VS + vscode extension

1 participant