Salamatrix framework gap analysis
Status date: 2026-08-08
Source vision: <https://krtkovo.eu/salamander/framework.html>
This audit compares the framework vision with the implementation in this repository. It distinguishes working code from API placeholders, samples, and catalog metadata. The target is not to reproduce the complete native Plugin SDK in scripting languages. It is the middle extensibility layer described by the vision: persistent lightweight extensions with commands, UI, events, storage, and a shared Salamander object model.
Status labels in the matrix are deliberately requirement-level, rather than commit-level: Implemented means the scoped vision item is covered by working code and a focused test; MVP means the public slice works end-to-end but the vision still calls for a broader surface; Partial means substantial pieces exist but the current slice is not yet a coherent user-facing feature; Missing means there is no implementation of the requested surface yet.
Executive summary
The repository already contains a real Salamatrix foundation, not only a design:
SALAMATRIX.SPLis a load-on-start Automation Framework provider.- The core has a process-local, versioned service registry with provider
- Native and Automation callers share the first
Salamatrix.UI, Salamatrix.Runtimeis a registered broker with versioned adapterSalamander.UI.progress(...),Salamander.Commands.execute(...), and the- Salamatrix owns the schema-1 extension-package manifest parser and package
Salamander.Sidesexposes Left, Right, Source, and Target plus safe tabSalamatrix.StorageandSalamander.Storageprovide typed, synchronized,Salamatrix.Extensionsnow provides an owner-aware lifecycle registry, and- The Plugin Manager has an enabled Extension Runtimes catalog source and
- Manifest extensions carry their package SVG identity icon (plus an optional
ownership and short consumer leases.
Salamatrix.Commands, Salamatrix.FileOperations, and Salamatrix.Sides services.
descriptors, registration, enumeration, and lookup.
three interactive file-operation wrappers work through the Salamatrix bridge.
root contract; Automation supplies only the compatibility/runtime bridge that discovers entry points and starts workers.
snapshots, paths, and activation to Automation scripts.
persistent namespaces isolated by manifest extension id.
the Salamatrix package manager owns extension roots, recursive manifest discovery, publication and worker lifecycle. Automation no longer publishes manifest packages.
Salamatrix has a distinct Automation Framework capability flag.
dark-mode variant) into the existing Plugin Manager list and toolbar image lists. Every manifest command may override those two SVG assets for its own toolbar button; no separate Extension Manager is introduced.
The repository now covers the scoped first-version middle layer, including the lightweight Viewer and flat FS roles. It is no longer only an MVP/PoC for this scope. The remaining work below is hardening, richer variants, or intentionally out of the v1 boundary rather than a missing basic extension role. In particular:
- Automation keeps the legacy ActiveScript compatibility path, while the
- JavaScript has both the legacy Windows JScript fallback and an independent
- The first modern side/tab model is exposed through the native SDK,
- Modern manifest-backed scripts run through the shared worker bootstrap;
- The strict schema-1/schema-2 manifest parser validates package/runtime identity,
- Schema 2 adds bounded
viewers[]andfileSystems[]contributions. Viewer - Persistent workers may register multiple commands. The selected command ID
- Manifest packages with multiple command records now publish every declared
- Runtime and manifest commands now carry append-only
enabled/visible - Persistent process sessions now publish richer lifecycle diagnostics without
- The shared native UI service exposes progress, input-box, and a reusable
Salamatrix.AIhas a provider-neutral contract. The standalone
standalone JavaScript/Node, CPython, PowerShell, PHP CLI, and Lua .spl providers use the shared SMX1 worker bootstrap and host-call/UI bindings. Dependency environments, richer values, and long-lived event queues remain.
modern Node adapter. Python, PowerShell, and PHP have independent process adapters; bundled interpreters and managed dependency environments remain optional future work.
Salamatrix, and Automation without raw core pointers. Item snapshots, selection/focus mutation, view settings, tab creation/closing, and change events remain broader follow-up work.
discovery registers the complete batch first, resolves declared extension dependencies in bounded passes, and retries activation after a later runtime/plugin configuration change. One-shot scripts still cannot remain alive after their execution ends. If a required separately installed runtime or manifest dependency is missing, discovery keeps the extension in a visible waiting state and reactivates it after the requirement appears.
minimum runtime version, safe entry points, package-owned and per-command icon/optional iconDark SVG paths, capabilities, an optional event allow-list, typed settings/defaults, dependencies, and multiple command records. Dependency declarations are resolved against the owner-aware extension registry and unresolved packages stay visible as waiting-for-dependency. Package-owned BCP-47 locale resources may localize the extension name, declared command titles, and setting presentation text; settings migrations/files and richer handler lifecycle metadata are still missing.
masks and optional names are registered through the native Viewer role, so configuration identifies the concrete extension Viewer. The flat salamatrix: FS accepts runtime-provided items and package SVG icons, performs periodic refresh, executes a default item action, builds native context menus, exposes Directory Line breadcrumbs and .., and honors the configured title path mode. Complex transfers and hierarchical FS semantics are outside the deliberately Hyper-V-Machines-level v1 role.
now follows menu activation through the native host and external runtime bootstrap into Salamander.command_id, so one entry point can dispatch distinct handlers without relying on the first command as a fallback. The selected manifest handler is also exposed as Salamander.command_handler.
command into the existing Plugin Manager/menu/toolbar path when their persistent worker activates; handler dispatch remains explicit in the worker via the command context.
state metadata. All five modern workers can update that state through the shared setState host call, and the existing Plugin Manager/menu/toolbar path refreshes without adding a public vtable method.
changing the session ABI: cached process id/exit code, explicit host stop, failed nonzero exits, and bounded diagnostic messages are available in the Automation bridge and all five standalone providers.
IDialog/IControl contract for modern workers and native plugins. The native implementation now covers the complete DemoPlug gallery: labels, text boxes, check/radio buttons, combo boxes, ordinary buttons, ListView, TreeView, TabControl, folder/file pickers, group boxes, host static text and hyperlinks, progress bars, arrow/text-arrow/color-arrow buttons, and toolbar headers. Node, Python, PowerShell, PHP, Lua, Automation JScript, and DemoPlug each construct the same 463 x 236 capabilities dialog themselves through Salamatrix.UI and identify their runtime/extension in a Created by group. The package-owned dialog dispatcher is implemented in Salamatrix rather than Automation, including cleanup and change-event delivery. DPI/accessibility polish and migration of legacy Forms wrappers remain.
SalamatrixAI.SPL registers the optional bounded local command provider, owns the interactive chat window, and publishes the localized Ask Salamatrix AI... menu command with a stable fallback caption; Automation remains a shared-service/API consumer and keeps its legacy scripting/runtime role without owning an AI menu or chat flow. The provider exchanges one bounded JSON request/response and enforces the two-minute ceiling; the optional Salamatrix AI Local LLaMA.SPL companion registers a server-free local.bundled provider and launches its separately installed llama.cpp CLI/model assets. The main SalamatrixAI.SPL remains model-free, so users can install only another provider. The Local LLaMA Configuration page launches a pinned downloader for the official CPU x64 llama.cpp release and a selectable Qwen2.5-Coder GGUF model: recommended 1.5B or lightweight English-prompt-only 0.5B. Both downloads retain SHA-256 checks and third-party license files; the binary and models are no longer staged into the plugin package. Its response contract now also permits an explicit canImplement:false plus a validated missingCapabilities list, so unsupported requests can be explained instead of being forced into invented API calls.
Requirement matrix
| Vision area | Status | Current implementation | Missing work |
|---|---|---|---|
| Three extensibility levels | MVP | Native plugins, one-shot Automation scripts, and persistent manifest-backed workers now share an owner-aware lifecycle catalog; registration activates persistent workers and the host-call dispatcher binds commands, sides, storage, event subscriptions, and UI calls. Extension host callbacks now hold owner-aware unload leases. Persistent teardown in both Salamatrix and the Automation compatibility bridge closes new callback admission, stops the worker, and joins its pump while the UI thread services only synchronous sent host calls; neither path releases a live session after a timeout. The append-only IRuntimeSession::GetDiagnostic contract reports bounded running/stopped/exited/failed lifecycle state, cached process id/exit code, and diagnostic text without exposing process handles. After the splash screen closes, the visible main window is covered by one localized startup progress window while load-on-start plugins and extensions initialize; Salamatrix reports the current package and distinct discovery, extension, FS, menu, activation, toolbar, and Viewer registration phases through a temporary host-owned service. The matching shutdown service keeps one localized dialog visible across the complete close sequence, identifies each native plug-in, and reports each Salamatrix package while toolbar contributions and extension registrations are removed, runtime sessions and extension windows are stopped, services are released, panels are closed, configuration is saved, and shutdown is finalized. |
Structured per-extension startup failure details, timed unload diagnostics, and richer lifecycle diagnostics; no separate Extension Manager is planned. |
| Shared cross-runtime API | MVP | The Salamatrix service layer, versioned ABI, SMX1 transport, and Python/PowerShell/PHP/JavaScript worker facades use the same host method vocabulary, including commands, sides, file operations, storage, events, clipboard, UI, and AI. Storage now preserves string, boolean, and signed 64-bit integer values across the host boundary and exposes typed storage.keys() enumeration with deterministic JSON ordering. |
Broader runtime-neutral value model, complete object model, and formal error/threading rules. |
| Left/Right/Source/Target sides | MVP | Salamatrix.Sides and all modern workers resolve all four references and expose active tabs, bounded path/type, selected-item snapshots, focused-item metadata, item name/path/extension/size/attributes/UTC write time and hidden/link/offline/size-valid flags, and active/source/target/locked/detached flags without raw core pointers. Modern workers now also enumerate tabs, activate a tab, change the active-side path, request a side refresh, select individual/all items, and move focus by stable panel index. |
View mode/tree state and item change events. |
| Tabs and detached windows | MVP | SDK snapshots and opaque process-local ids expose tab count, index, path/type, active/source/target/locked/detached flags, activation, path changes, refresh, selection/focus, and snapshot-derived lifecycle events. Sides schema 1.3 now publishes append-only create/close/reorder/move/detach methods, the host bridge validates decimal tab ids and side/index inputs, and all five worker facades expose the same contract. Isolated process-runtime coverage uses an explicit SALAMATRIX_WORKER_ROOT built from provider workers. | Direct core load/version negotiation, colors, richer detached-window operations, and persistence semantics. |
| Existing Salamander commands | MVP | The stable catalog now covers view/edit/open, rename, copy/move, email/delete/properties, case/attribute/space operations, refresh, directory creation, drive info, directory sizes, and disconnect; execution still uses Salamander's normal enablement and dialogs. | Parameterized command calls, richer synchronous/modal results, state/change notifications, and non-modal operation handles. |
| Programmatic file operations | MVP | IFileOperationsService and all modern worker bindings expose interactive rename/copy/move/delete/create-directory/refresh/properties workflows. |
Typed source/target values, progress/cancellation handles, and final structured results without requiring the native dialog. |
| Lightweight Viewer role | Implemented | Manifest schema 2 accepts bounded viewers[] contributions with optional display names. Salamatrix registers each enabled contribution separately through the native Viewer association path during Connect, independently of runtime-provider startup order; Configuration lists every extension/Viewer identity as its own Associated viewer choice and persists that identity with the association. The host passes the chosen identity through versioned Viewer invocation data, so a concrete extension Viewer manually associated with *.* or selected as an alternate Viewer by Alt+F3 dispatches that exact handler instead of re-matching the file against its original manifest mask. The shared dispatcher supplies path, window geometry/show state, always-on-top state, and enumeration context through the cross-runtime Salamander.invocation object. Newly discovered masks are forced exactly once and later user removals remain respected. |
Optional signature/content sniffing and framework-owned modeless rendering controls; new associations still require a Salamander restart because viewer masks are a connect-time host contract. |
| Flat file-system role | Implemented | Manifest schema 2 accepts bounded fileSystems[] providers, actions, and up to 16 localized detailed-view columns. The framework-owned salamatrix: native FS lists providers and atomically collects up to 4096 flat runtime items through the capability-gated salamander.fileSystem.addItem or batch addItems call. Batch publication uses one worker/host round-trip for the complete snapshot. The native FS renders and sorts text/numeric custom column values, resolves validated light/dark SVG item icons inside the package, refreshes on a bounded timer, and builds a native Unicode action context menu with localized titles, separators, and per-action refresh control; only an explicitly default action runs on Enter. Runtime listing runs asynchronously behind a per-open-FS snapshot cache; the UI listing path returns immediately, displays the panel throbber while the initial empty cache is loading, and posts the completed snapshot without creating a refresh loop. Provider executions are serialized where they share package dispatch state, and close joins the worker while dispatching sent UI-thread calls. Provider contents begin with ..; Directory Line exposes clickable root/provider segments; full, shortened, and directory-only title modes are honored. All five workers expose equivalent single-item and batch publication semantics and all five bundled demos implement equivalent Viewer/FS handlers. |
Complex hierarchy, copy/move/delete/upload, free-space/search/security integration, and multi-selection batch actions are intentionally outside the Hyper-V-Machines-level v1 role. |
| Extension command registration | MVP | Discovery-time metadata gives a script stable identity/caption/placement hints, and a persistent worker can register/unregister multiple owner-scoped commands with synthetic native menu ids, context masks, native menu hotkeys, toolbar contributions, optional handler names, and append-only enabled/visible state. Manifest command records are now published automatically with their initial state, while worker setState updates the existing Plugin Manager/menu/toolbar path and removal triggers a menu/toolbar rebuild. A manifest command may alternatively declare a fixed path; the host then changes the active panel directly without starting a runtime worker and enforces panels.write. Each selected runtime command propagates its ID and handler into the worker as Salamander.command_id/Salamander.command_handler, so one entry point can dispatch distinct handlers. |
Enable/visible callbacks, command palette integration, richer handler lifecycle metadata, and richer ownership/unload leases. |
| Plugin and context menu placement | MVP | Metadata booleans and context masks are applied to Automation menu items and persistent registrations. | Independent placement contributions, icons, and dynamic menu APIs beyond the current MVP surface. |
| Toolbar and shortcuts | Partial | Dynamically registered extension commands now pass Salamander hotkeys through the normal menu-extension path, contribute toolbar buttons, and honor per-command enabled/visible state. Native/runtime registrations use core-owned DPI-aware image lists; manifests may provide package-wide SVG icon and optional dark-mode iconDark, or override them on each commands[] item. If the selected iconDark is missing or invalid, the core generates a dark-friendly raster variant from the normal icon and also creates the disabled/gray image. Dynamic placement is now serialized with stable extension/plugin keys instead of transient runtime ids. |
Explicit placement/conflict UX, command palette integration, richer state callbacks/change notifications, and richer toolbar metadata. |
| Events | MVP | Salamatrix.Events maps host lifecycle/settings/configuration/color/panel events, successful shared-Sides path/selection/tab/refresh operations, core path/selection/tab notifications, and core filesystem-change notifications (fileChanged, including the affected path and recursive-scope flag) to unsubscribe-safe native callbacks; successive tab snapshots add tabCreated, tabClosed, tabReordered, windowDetached, and windowAttached with changedTabId, tabIndex, and previousTabIndex, delivered before legacy tabChanged. Automation exposes subscribe/unsubscribe with copied payloads and preserves the V1 payload prefix. Manifest-backed extensions may declare an event allow-list, which the host enforces before creating a subscription. Persistent worker sessions now enqueue bounded event frames instead of writing from the core callback directly into a potentially back-pressured pipe. | Typed create/rename/delete classification, UI-thread marshalling for richer event payloads, coalescing, event replay, richer direct window lifecycle hooks, and unload-safe leases across modern runtimes. |
| Per-extension storage | Implemented | Salamatrix.Storage persists isolated manifest-id namespaces with UTF-8 strings, signed 64-bit integers, booleans, delete/clear, validation, and synchronized access. Manifest packages may declare typed settings with optional defaults; the host materializes missing defaults without overwriting user values and exposes storage.schema() to every modern worker. The SMX1 host dispatcher and Python/PowerShell/PHP/JavaScript/Lua workers preserve all three value types instead of coercing settings to strings. The Plugin Manager can now edit the declared scalar settings through the shared UI service. Versioned manifest migrations apply typed rename/remove operations before defaults and persist their bounded migration version. Legacy global persistence remains for compatibility. |
Settings files/enumeration, quotas, transactional batches, and uninstall retention/deletion policy. |
| Shared UI framework | MVP | Salamatrix.UI provides a reusable native IDialog/IControl model and NativeDialog implementation for labels, text boxes, check/radio buttons, combo boxes, ordinary buttons, native ListView/TreeView/TabControl controls, editable folder/file pickers, group boxes, CGUIStaticTextAbstract, CGUIHyperLinkAbstract, CGUIProgressBarAbstract, arrow/text-arrow/color-arrow buttons, and CGUIToolbarHeaderAbstract. Explicit layouts, item/column/selection binding, validation, change events, hyperlink actions, tooltips, static-text style/path flags, known and indeterminate progress, color values, and toolbar-header masks cross the same SMX1 package-host dispatcher. JavaScript, Python, PowerShell, PHP, and Lua facades forward an equivalent option set; Automation exposes a thin COM dialog adapter and native plugins use IUIService directly. Each bundled demo and DemoPlug independently constructs the same capabilities dialog and its runtime/extension identity group; none depends on a prebuilt Automation-owned gallery. The native implementation applies the selected Salamander dark scheme, keyboard traversal, initial focus, per-monitor WM_DPICHANGED scaling, and bounded accessibility metadata/tooltip fallback. Progress-dialog, immediate UI, clipboard, and picker services remain on the same framework-owned surface. See doc/salamatrix-ui.md. |
Richer notification actions/stacking, virtualized data, full accessible roles/UI Automation and screen-reader audit, interactive per-monitor GUI testing, reentrancy policy, and migration of legacy Forms wrappers. |
| Manifest/package | Implemented | Strict UTF-8 JSON parsing accepts compatible schema 1 and final schema 2 through the canonical schema key and the supported schemaVersion compatibility alias; it rejects conflicting values when both are present. It validates package/runtime identity and minimum version, safe entry points, package-owned SVG assets, capabilities, typed settings/defaults and migration chains, dependencies, locale resources, up to 64 command records, up to 16 Viewer contributions, and up to 16 flat FS providers with bounded actions, custom columns, and refresh intervals. Discovery materializes settings migrations/defaults, resolves package dependencies, restores persisted enabled state, activates eligible workers, and publishes the result through the owner-aware Extensions registry. Salamatrix Studio scaffolds schema: 2, accepts both compatible keys, and preserves Viewer/FS records. |
Signed packages, transactional install/update/rollback, dependency acquisition prompts, and uninstall retention policy remain distribution hardening rather than missing runtime capability. |
| Runtime adapters | MVP | Salamatrix.Runtime registers/enumerates versioned adapters and executes manifest entry points through structured requests/results. Automation registers only legacy ActiveScript adapters; modern CPython, PowerShell, PHP CLI, Node, and Lua runtimes are supplied through independent .spl providers using the same broker. All five standalone providers have Debug and Release x64 projects, with deferred registration when Salamatrix loads later; Lua additionally passes an isolated SMX1 demo call sequence without starting Salamander. The isolated process-runtime contract test runs with an explicit SALAMATRIX_WORKER_ROOT, exercises Python/PowerShell/PHP host-worker lifecycle and UI calls, and verifies GetDiagnostic running/stopped/exited/failed state, cached process id/exit code, and diagnostic message. A native regression reproduces the shutdown deadlock topology with a pump thread blocked in synchronous SendMessage and verifies that the UI-thread join dispatches that callback before releasing the session. Manifest publication checks the requested adapter and minimum version, marks unavailable extensions as waiting, and retries them after a broker refresh. |
Direct standalone .spl load test through Salamander, startup failure capture before a session exists, cancellation beyond process termination, debugging, dependency environments, and richer dependency policy. |
| JavaScript runtime | Process MVP | Windows JScript remains the compatibility fallback for legacy .js; JavaScriptRuntime.SPL now discovers Node via SALAMATRIX_NODE, node.exe, or node, owns the dependency-free SMX1 .mjs worker, and registers JavaScript.Node independently of Automation. The worker now exposes the same host API surface as Python/PowerShell/PHP, including convenience dialog controls, native dialogs, and event subscriptions. Debug and Release x64 builds are verified. |
Explicit .js/.mjs precedence with the legacy fallback, package deployment policy, and richer value bindings. |
| Python runtime | Process MVP | ActivePython COM compatibility remains; Python.CPython discovers python.exe/python3.exe or SALAMATRIX_PYTHON, runs .py entries out of process, and the optional worker bootstrap exposes the shared SMX1 Salamander API including multiple command registration. A standalone PythonRuntime.SPL project owns the same adapter/worker, unregisters it through the broker, and now passes a Debug x64 build. |
Richer UI/value bindings, environment/dependency policy, and bundled runtime. |
| PowerShell runtime | Process MVP | PowerShell discovers pwsh.exe/powershell.exe or SALAMATRIX_POWERSHELL, runs .ps1 entries out of process, and ships the same SMX1 worker bootstrap/API shape including multiple command registration. A standalone PowerShellRuntime.SPL project owns the adapter/worker and broker registration path and now passes a Debug x64 build. |
Richer UI/value bindings, environment policy, cancellation/error mapping, and bundled runtime. |
| PHP runtime | Process MVP | Legacy PHPScript remains; PHP.CLI discovers php.exe or SALAMATRIX_PHP, runs .php entries out of process, and ships the same SMX1 worker bootstrap/API shape including multiple command registration. A standalone PHPRuntime.SPL project owns the adapter/worker and broker registration path and now passes a Debug x64 build. |
Richer UI/value bindings, dependency policy, and support decision/bundled runtime. |
| Lua runtime | Process MVP | Lua prefers an explicit SALAMATRIX_LUA override, otherwise uses the bundled vcpkg-built Lua 5.5.0 interpreter, with PATH discovery as a compatibility fallback. It runs .lua entries out of process and ships a dependency-free Lua SMX1 worker with the common Salamander facade. The runtime package contains lua.exe, lua.dll, the full MIT notice, and the worker; Release x64 build, PE/package verification, syntax loading, and an isolated storage/notification SMX1 call sequence pass. |
Direct provider load through Salamander, debugger integration, and dependency environment policy. |
| Extension management | Partial | The existing Plugin Manager remains the single management surface: it shows ordinary .SPL plugins and now appends discovered manifest-extension rows from Salamatrix.Extensions with name, state, version, runtime, entry point, and manifest ID details. Extension rows use the package SVG icon, prefer iconDark in dark mode, and derive a dark-friendly bitmap from the normal icon when the dark asset is absent or invalid. Their Functions detail is driven by Extensions 1.4 contribution flags and identifies manifest commands[] as Menu Extension, viewers[] as File Viewer, and fileSystems[] as File System (FS). Missing runtime adapters are shown as runtime unavailable; unresolved manifest dependencies are shown as dependency unavailable; a user-deactivated extension is explicitly shown as disabled. Its existing Activate/Deactivate action persists the enabled state in the extension's isolated Storage namespace, stops the worker before disabling, and reactivates it after re-enabling. Configure opens a Salamatrix.UI native dialog for up to 24 declared string/integer/boolean settings, uses localized labels and visible groups, applies bounded width/multiline layout metadata, and writes typed values into the extension's isolated Storage namespace. Rows are still not treated as loadable .SPL files. No separate Extension Manager is planned. |
Remove, package install/uninstall, settings help/tooltips and richer layout semantics, more than 24 settings, and richer runtime/status details in the existing Plugin Manager. |
| Permissions/capabilities | MVP | Manifest capabilities are enforced by the framework-owned package dispatcher for commands, interactive file operations, flat FS item publication, sides read/write, storage, events, UI, clipboard, and runtime discovery. The file-system capability gates addItem and addItems; panel mutations require panels.write; legacy manifests without a capabilities list remain compatible. |
Explicit user grant/revocation UI, filesystem/network/process sandbox policy, effect audit trail, and richer package UX. |
| AI automation assistant | MVP | Salamatrix.AI provides provider registration, structured generation validation, parsed effect flags, runtime/existing-script/feedback hints, explicit unsupported-capability responses, a safe generate/preview seam, and focused Salamander.ai.api(topic) retrieval. The separately installable SalamatrixAI.SPL owns the bounded local command provider, the optional native WinHTTP local model provider, and an interactive multiline chat with Ask/Preview/Run/Save actions; follow-up prompts carry the previous script as repair context. The optional Salamatrix AI Local LLaMA.SPL companion owns the server-free local.bundled llama.cpp CLI provider and its separately installed CPU/model assets. The chat enumerates providers, shows ready/unavailable status, and supports explicit selection or automatic fallback. Its dynamic Menu Extension publishes the sole localized command for opening the chat, and its shutdown path validates the borrowed AI service identity before unregistering providers so framework-first unload cannot dereference a stale pointer. A shared static validator checks response shape, capabilities, effects, runtime identity, undeclared external/network operations, and the optional canImplement/missingCapabilities fields; bounded GenerateWithRepair is used by the standalone chat and shared Automation AI host/API consumers. When Automation is loaded, Salamatrix.ScriptRunner routes Run through the same capability-aware SMX1 host dispatcher as regular extensions; Automation does not publish an Ask-AI menu or own the chat flow. The full API description now also carries live native service contract versions, the currently registered runtime adapter inventory, and schema fragments supplied by the native command, file-operation, UI, sides, events, storage, extensions, and runtime contracts. |
Complete method/field schema coverage without hand-maintained fragments, model variants, and remote providers. |
| Testing | Initial | Standalone /W4 /WX tests cover the strict manifest parser (including localized setting metadata, layout validation, and initial command state), Storage persistence, Events subscribe/publish/self-unsubscribe/capacity/payload validation, Extensions registration/lifecycle/ownership and legacy setting-schema prefixes, the local owned-service registry, runtime raw-JSON context and AI service contracts (including focused API slices), the synchronous-host-callback runtime-pump join regression, and integration tests for Python/PowerShell/PHP process execution, output capture, timeout, editable file-picker protocol calls with flat filter/save options, command enabled/visible state changes, persistent-session lifecycle diagnostics for running/stopped/exited/failed workers, native dialog host calls, and deterministic UI layout/DPI metrics. The explicit SALAMATRIX_WORKER_ROOT run uses isolated copies of provider worker assets and passes without starting Salamander. Worker syntax checks cover Python, PowerShell, PHP, Node, and Lua; all five demos expose the same explicit gallery geometry. Release x64 builds of Salamatrix, Automation (including its COM type library), and DemoPlug cover the native API additions. A fast source-contract regression test locks key Plugin Manager, AI, service-lifetime, runtime-shutdown, and dynamic-menu paths. |
Direct core-registry runtime tests, automated pixel/accessibility testing of the capabilities gallery, interactive per-monitor GUI tests, extension fixtures, lifecycle/unload integration tests, startup-failure fixtures, and end-to-end Salamander API adapter tests. |
Persistent runtime shutdown crash regression (2026-08-09)
Two x64 crash reports identified one teardown race, not a manifest schema compatibility failure. One fault returned from a PowerShell worker pump into a freed IRuntimeSession; the other executed a queued main-thread host callback after salamatrix.spl had already been unloaded. Both were enabled by a five-second pump-thread wait followed by session release (and, in Automation, forced thread termination) while the pump could be synchronously blocked in InvokeOnMainThread/SendMessage.
Salamatrix Framework 0.6 and Automation 2.4 now mark the session as stopping before removing its bindings, reject newly arriving host/event/dialog calls, stop the worker, and retain the session and module until the pump has actually returned. When teardown runs on Salamander's UI thread, the shared join helper dispatches only nonqueued synchronous sent messages, avoiding the circular UI-thread/pump-thread wait without consuming posted application work.
A follow-up close-time report from the same build exposed a separate native UI lifetime bug: a long-lived notification popup survived framework release, and USER32 later dispatched WM_WINDOWPOSCHANGING to Salamatrix::UI::NotificationWindowProc at RVA 0x5D5B0 after salamatrix.spl had been unloaded. Salamatrix Framework 0.7 tracks every notification HWND alongside modeless native dialogs, destroys those windows synchronously during CPluginInterface::Release, and unregisters their window class before the module can unload. The PR-running native UI test creates a long-timeout notification and verifies that the shutdown hook leaves no window of that class alive.
Current verification snapshot
The newest implementation commits include d5f7e56d9 (runtime-built Salamatrix.UI capabilities dialogs), 4a380ef3c (editable native FilePicker and standalone worker parity), 89a1d4fbf (isolated process runtime verification), a6a8cedc8 (Plugin Manager settings configuration), 9aa3cbf84 (per-command SVG toolbar artwork), and 6e1711cd8 (dialog FolderPicker). They were compiled into isolated Debug x64 output directories; the user's locally running Salamander process was never started, stopped, or otherwise controlled by this work.
d5f7e56d9: Node, Python, PowerShell, PHP, Lua, Automation JScript, and
DemoPlug now build the complete capabilities dialog themselves. Salamatrix, Automation, and DemoPlug Release x64 builds passed; all five worker/demo syntax checks passed; and the isolated Python/PowerShell/PHP processruntime_tests.exe run completed with All process runtime tests passed. using only copied standalone provider worker assets. No Salamander process was started or controlled, so live pixel, DPI, dark-mode, and interaction verification remains manual.
The current implementation separates the optional Salamatrix AI Local LLaMA.SPL companion from the model-free SalamatrixAI.SPL. Its configuration downloader is syntax-checked and pins the official llama.cpp CPU x64 archive and both selectable Qwen GGUF models by SHA-256; the plugin build contains only the downloader script, not the binary or model. A live model download was intentionally stopped at the 120-second command limit in this environment; no Salamander process was started or controlled.
a6a8cedc8: Automation, Salamatrix, the core Salamander executable, and9aa3cbf84: strict manifest parser tests and Automation Debug x64 build6e1711cd8: Salamatrix, Automation, and all four standalone runtime- The Python/PowerShell/PHP process-runtime integration executable built, but
Extensions native tests passed.
passed.
provider Debug x64 projects passed; runtime-protocol tests passed; Python, PowerShell, PHP, and Node worker syntax checks passed.
its invocation was previously skipped because this environment did not set SALAMATRIX_WORKER_ROOT. That gap is now closed: on 2026-07-26 the build\verification\folder-picker\process-tests\processruntime_tests.exe executable passed with exit code 0 when SALAMATRIX_WORKER_ROOT pointed to the isolated build\verification\process-runtime-worker-root containing only copied Python, PowerShell, and PHP bootstrap files. The run exercised interpreter discovery, one-shot and persistent SMX1 sessions, host calls, typed storage, commands, events, clipboard, file/folder pickers, native dialog controls, shutdown, output capture, and timeout coverage without starting or controlling Salamander.
At the previous pause point all Salamatrix source and documentation changes were committed. The pre-existing worktree-only .gitignore change keeps the two syntax-check artifacts out of source control: src/plugins/automation/runtime/__pycache__/ and src/plugins/pythonruntime/runtime/__pycache__/. They are not source changes and are not staged.
On 2026-07-26, the append-only lifecycle diagnostic contract was verified by an isolated Debug x64 rebuild of the process test, protocol test, and all four standalone provider projects. With SALAMATRIX_WORKER_ROOT set to build\verification\runtime-diagnostics\worker-root, the process-runtime executable passed with exit code 0; its one-shot worker reported running, then exited with exit code 0. The run also exposed stale typed-storage/schema methods in the standalone Python worker, which were brought back to parity before the passing rerun.
The UI slice was verified on 2026-07-26 with an isolated Debug x64 Salamatrix.SPL rebuild and the standalone ui_layout_tests.exe. The test passed picker geometry checks plus 96-to-144 DPI and 144-to-96 DPI scaling checks. No GUI Salamander process was started or controlled.
The current runtime baseline was rebuilt from the current source into build\verification\current-runtime-baseline. Its process-runtime executable passed with SALAMATRIX_WORKER_ROOT explicitly set to an isolated root containing only the Python, PowerShell, and PHP workers copied from their standalone runtime-provider projects. The run returned exit code 0 and no Salamander process was started or controlled.
The current worktree was audited again after the SalamatrixAI workflow changes: build\verification\worker-root-current was created as an isolated root from the Python, PowerShell, and PHP worker files in this checkout. The existing Debug x64 process-runtime executable from the parent-revision baseline was run with that root in SALAMATRIX_WORKER_ROOT and returned exit code 0. It covered the same host-call, persistent-session, UI, storage, event, picker, AI preview, shutdown, output-capture, and timeout paths; Node was additionally syntax checked with node --check. This validates the current worker assets and SMX1 contract, while a fresh current-source Debug x64 rebuild remains dependent on the unavailable Visual C++/MSBuild toolchain in this environment.
Existing implementation evidence
Core service and plugin integration
src/plugins/shared/spl_gen.hdeclaresRegisterService,src/zip.cppcontains the fixed-size process registry, its critical-sectionsrc/plugins/shared/spl_base.hdefinessrc/plugins/salamatrix/salamatrix.cppcreates persistentsrc/plugins/salamatrixai/is a separately buildable/installable provider- Automation additionally publishes the optional
Salamatrix.ScriptRunner src/vcxproj/salamand.slnbuilds Salamatrix as part of the main solution.
UnregisterService, QueryService, and the appended owner-aware register/unregister/acquire/release methods. Its appended toolbar contract accepts package-owned SVG paths (normal plus optional dark-mode variant), while the core renders those files through NanoSVG into the shared toolbar image lists. When the optional dark asset is absent, the core derives a dark-friendly bitmap from the normal SVG while preserving alpha and color information.
guard, lease table, unload gate, and condition-variable wait for active consumers.
FUNCTION_AUTOMATIONFRAMEWORK.
RuntimeServices, registers the provider, and requests load on startup.
plugin. It registers local.command plus the optional local.ollama WinHTTP provider under Salamatrix.AI and exposes the shared native chat dialog; it is not a dependency of Automation.
service. This is the non-privileged bridge used by the AI plugin to execute a saved script through the ordinary extension host dispatcher.
Runtime provider packaging boundary
The runtime broker is already a host service rather than an Automation-private API: IRuntimeService::RegisterAdapter and UnregisterAdapter accept adapter objects from any loaded plugin, and runtime descriptors are enumerated through the same service by native callers and workers. The standalone PythonRuntime.SPL, PowerShellRuntime.SPL, PHPRuntime.SPL, and JavaScriptRuntime.SPL projects now own their provider adapters, interpreter discovery, and worker bootstrap. Their standalone Windows projects pass isolated Debug x64 builds, and the worker package gate verifies their bootstrap/export boundary without launching Salamander. Final loading and GUI behavior still require the target machine; Automation retains only its legacy ActiveScript engines and consumes the broker like every other plugin.
Shared services already working
src/plugins/salamatrix/salamatrix_ui.hadapts the existing Salamandersrc/plugins/salamatrix/salamatrix_commands.hexposes the small stablesrc/plugins/salamatrix/salamatrix_sides.hexposes runtime-neutral sides andsrc/plugins/salamatrix/salamatrix_storage.howns validated, synchronized,src/plugins/salamatrix/salamatrix_events.howns host event mapping and- The standalone runtime provider projects own bounded out-of-process
src/plugins/salamatrix/salamatrix_runtime_protocol.hdefines the boundedsrc/plugins/automation/scriptlist.cppowns the lifecycle callback and thesrc/plugins/automation/salamatrixbridge.cppis a consumer-only bridge.src/plugins/automation/salamatrixaut.cppimplements the COM/Automationsrc/plugins/automation/salamander.idlpublishes theUI,Commands,
progress implementation.
command catalog and interactive rename/copy/move routing.
panel-tab snapshots over the new core SDK methods.
typed per-extension storage and its versioned configuration blob.
unsubscribe-safe callback dispatch.
CPython, PowerShell, PHP CLI, and Node adapters; Automation retains only transitional source/test implementations while consuming the broker.
incremental SMX1 worker framing and its message vocabulary; the Automation bridge now supplies the first host-call dispatcher over that boundary.
initial runtime.ready, commands, sides, and string-storage dispatch.
wrappers.
FileOperations, Sides, Events, and isolated Storage namespaces.
Script discovery and manifest parsing
src/plugins/salamatrix/salamatrix_manifest.cppcontains the strict,src/plugins/automation/scriptlist.cpprecursively discovers legacy- The same file resolves manifest runtime id/minimum version through the broker
src/plugins/automation/sample-scripts/Salamatrix Progress Demo/is the
independently tested schema-1 JSON parser and validated package model; Automation consumes its framework header without owning the parser.
ActiveScript files, registered runtime-adapter entry points, and valid manifest entry points even when their extension has no COM association.
before execution. Inline Salamatrix.Command* metadata remains supported.
first manifest-based sample.
Existing legacy Automation value
The new platform should preserve these working capabilities:
- active left/right/source/target panel path, focused item, all items, selected
- message/input/error/question/overwrite dialogs, progress and wait windows;
- modal Forms with Label, TextBox, CheckBox, and Button;
- file viewing, path normalization, mask matching, tracing, sleep/cancel;
- basic global persistent values;
- JScript and VBScript, plus third-party
IActiveScriptengines where
items, selection manipulation, and panel path changes;
available.
Important implementation risks found by the audit
1. The core service registry still exposes borrowed interface pointers to callers, but provider ownership and short consumer leases now prevent new acquisitions during unload and wait for active calls before removal. The extension lifecycle registry has the same owner-aware callback behavior; unload diagnostics are still minimal. 2. Runtime provider registration is still an explicit plugin-lifetime contract; unload diagnostics and a user-facing dependency view remain. 3. Posted Commands/FileOperations report ok when a command was accepted, not when the modal operation completed successfully. cancel is not observable. 4. The command catalog currently maps both Move and MoveRename to the same native command and contains only three unique operations. 5. The manifest parser retains every validated command and the Automation menu surface iterates all registered runtime command contributions; remaining work is richer independent placement/toolbar metadata rather than dropping additional commands. 6. Discovery and execution now go through runtime adapters. The v1 compatibility callback still keeps old ActiveScript hosting inside Automation; modern process cancellation is currently stop/termination based. 7. Long-lived script callbacks still require richer UI-thread, reentrancy, cancellation, and exception rules; host callbacks now reject new calls during extension deactivation and hold an unload lease while active. 8. A language process must never receive raw C++/COM implementation pointers. Out-of-process adapters need a versioned RPC/value protocol, while in-process adapters need ABI-stable interfaces.
Recommended implementation order
Phase 0: make the foundation safe
1. Route extension discovery and execution through the existing Salamatrix.Runtime broker. Implemented. 2. Add provider ownership/leases, diagnostics, and lifecycle rules to runtime and core services. Provider ownership and short leases are implemented; richer diagnostics remain. 3. Replace the manifest text scanner with a real parser and validate a versioned schema.
Phase 1: complete the useful common object model
1. Publish Salamatrix.Sides with Left, Right, Source, and Target. Implemented. 2. Add side and tab snapshots/handles: path, active tab, tabs, focused/selected items, view mode, tree visibility, detached state. Implemented for tab identity, enumeration, path, activation, active/source/target/locked/ detached state, side path changes, refresh, selection mutation, and focus; item/view details remain. 3. Add clipboard and panel refresh. 4. Expand stable Commands and implement synchronous, programmatic file operations. 5. Add isolated per-extension storage. Implemented for typed key/value persistence; settings schemas, quotas, migrations, and uninstall policy remain.
Phase 2: make extensions persistent
1. Extension instances and lifecycle: discover, load, activate, deactivate, unload. The owner-aware Salamatrix.Extensions registry and persistent IRuntimeSession activation seam are implemented; host dispatch and worker bindings remain. 2. Command contribution service independent of menu/toolbar/hotkey placement. 3. Event service with a small first set: startup/shutdown, active side/tab, path, selection, tab create/close. Implemented for host lifecycle, settings/configuration/colors, panel swap, active-panel events, successful shared-Sides path/selection/tab/refresh operations, and core path/selection/tab notifications; persistent instance queues now use bounded worker-session frames. File-operation and window lifecycle hooks remain. 4. Package state in the existing Plugin Manager.
Phase 3: runtimes
1. Keep current Automation as the legacy-wsh compatibility adapter. 2. Add a modern bundled JavaScript adapter as the default lightweight runtime. 3. Add PowerShell and CPython adapters as separate runtime components. 4. Add PHP only after the common out-of-process protocol is proven; it should reuse the same protocol rather than introduce a fourth binding architecture. 5. Run the same runtime contract suite against every adapter.
An out-of-process JSON-RPC-style transport is the safest common denominator for CPython, PowerShell, and PHP. The host owns all Salamander objects and returns serializable handles/snapshots; runtimes send typed API requests. A bundled JavaScript engine may be in-process for size and speed but should implement the same logical contract.
Phase 4: shared UI
The native dialog/control surface, explicit layout, collection binding, pickers, validation/events, and the complete DemoPlug control gallery are now implemented through one framework-owned service. The five worker runtimes, Automation JScript, and native DemoPlug independently exercise that surface; the old Automation Forms classes remain compatibility wrappers rather than the owner of modern dialogs. Continue with automated dark-mode/DPI interaction, full UI Automation roles and screen-reader testing, virtualized collections, richer notifications, reentrancy rules, and localization guidance for extension-authored text. See doc/salamatrix-ui.md for the current contract and examples.
Phase 5: AI assistant
Start only after the common API is useful without AI:
1. Generate a machine-readable API schema from the real contracts. 2. Define a provider-neutral model interface and structured result containing title, description, required capabilities, estimated effects, and script. 3. Implement Ask -> Preview -> Validate -> Run -> Save. 4. Add static validation and a repair loop against the exact installed API version. 5. Add an external local provider first, then an optional bundled local backend. 6. Treat the AI as a script author with no privileged control path.
First implementation slice
The first code slice following this audit is implemented:
- publish
Salamatrix.Runtimeas a real service; - allow runtime adapters to register versioned runtime ids and file/language
- make Automation advertise its legacy Active Scripting adapter through that
- expose runtime availability in diagnostics;
- make registration failure transactional.
metadata;
broker;
The second code slice is also implemented:
- replace raw scalar scanning with a strict schema-1 UTF-8 JSON parser;
- validate runtime/minimum version, safe entry points, capabilities, and the
- discover manifest entry points independently of ActiveScript associations;
- route manifest execution through a structured runtime-adapter request/result;
- execute existing JScript/VBScript compatibility engines through the broker;
- add a standalone manifest parser test target and invalid-manifest fixtures.
complete commands array;
The third code slice is also implemented:
- append versioned tab snapshot and activation methods to the native plugin SDK
- assign every live panel tab an opaque 64-bit lifetime id;
- publish
Salamatrix.Sideswith Left/Right/Source/Target resolution, tab - expose the service to scripts as
Salamander.Sides,Side, andTab - represent ids as decimal strings and revalidate each operation by id so stale
- compile the main executable, Salamatrix, and Automation in Debug x64, Debug
and raise the SDK requirement to 105;
snapshots, paths, activation, and active-tab path changes;
Automation objects;
script objects fail safely;
Win32, and Release x64.
The fourth code slice is also implemented:
- publish
Salamatrix.Storageas a transactionally registered service; - isolate namespaces by the validated manifest extension id instead of asking
- support UTF-8 strings, signed 64-bit integers, booleans, delete, and clear
- persist one bounded, versioned, fully validated configuration blob through
- expose
Salamander.Storage.has/get/set/remove/clearonly to manifest - add
/W4 /WXtests for isolation, validation, types, mutation, save/load
scripts to invent collision-resistant prefixes;
through a synchronized runtime-neutral contract;
the plugin registry abstraction;
extensions and preserve the old global API for loose-script compatibility;
round-trip, unchanged saves, and corrupt data.
The fifth code slice is also implemented:
- publish
Salamatrix.Eventswith lifecycle, settings/configuration, colors, - map the existing Salamander plugin
Eventcallback into copied, - dispatch matching callbacks outside the registry lock so self-unsubscribe and
- expose
Salamander.Events.subscribe/unsubscribewith decimal opaque ids and - add
/W4 /WXtests for event delivery, self-unsubscribe, capacity, and invalid
panel-swap, and active-panel event kinds;
runtime-neutral payloads containing panel/tab/path context;
reentrant subscription are safe;
automatic cleanup when the one-shot Automation root is released;
payload/kind handling.
The sixth code slice is also implemented:
- publish
Salamatrix.Extensionsas a bounded, owner-aware lifecycle registry; - track explicit discovered/activating/active/deactivating/inactive/failed
- register valid manifest-backed Automation scripts at load/refresh and remove
- retain and stop a persistent
IRuntimeSessionfrom the owning script during - add
/W4 /WXtests for registration, duplicate-owner rules, lifecycle state
states and invoke lifecycle callbacks outside the registry lock;
them before their CScriptInfo owners are deleted;
activate/deactivate and destruction;
transitions, validation, and owner cleanup.
This slice intentionally stops before host API dispatch. The registry and session are the stable seam for the next runtime-host work.
The seventh code slice is now implemented:
- extend the runtime request/result contract with working-directory, timeout,
- register optional out-of-process
Python.CPython,PowerShell, andPHP.CLI - execute entries through non-shell
CreateProcessW, drain stdout/stderr, - document the remaining persistent worker/RPC boundary instead of treating a
process/exit, and bounded output fields;
adapters from Automation using explicit environment overrides or PATH;
terminate timed-out children, and surface structured failure/exit results;
one-shot CLI process as a full Salamander-aware runtime.
The transport foundation is covered by a standalone /W4 /WX test for partial frames, round trips, malformed ids, newline rejection, and the 1 MiB limit.
The eighth code slice is now implemented:
- add
IRuntimeSessionand optionalIRuntimeAdapter::StartPersistent(); - implement bidirectional persistent process sessions with bounded frame reads,
- connect manifest lifecycle activation/deactivation to session ownership;
- start and join a bounded host pump thread so worker frames are processed in
- verify a Python echo worker end to end through
SMX1frames.
CRLF-tolerant worker output, safe stop/Release cleanup, and timeout-aware liveness checks;
normal plugin operation;
This does not pretend that modern Python or PowerShell support is complete. It creates the contract those adapters need and removes the current architectural assumption that every script file must map directly to an IActiveScript COM CLSID.
The ninth code slice is now implemented:
- add a host-dispatch callback to the persistent runtime request;
- bind
runtime.ready,salamander.commands.execute, - bind event subscribe/unsubscribe and push matching
eventframes, plus a - ship language-specific bootstrap scripts that expose the same
Salamander - add bounded JSON string-member extraction tests and verify the Automation
salamander.sides.activeTab, and string salamander.storage.get/set calls;
parented message-box call;
object model and route calls/events over SMX1;
plugin plus the Python worker round trip.
The tenth code slice is now implemented:
- add stable toolbar contribution keys to the appended native toolbar ABI;
- persist extension toolbar placement in the existing toolbar configuration,
- resolve persisted entries by manifest/plugin identity rather than transient
- derive a dark-mode bitmap from the normal extension SVG when an extension
- keep icon rendering and placement shared between native plugins and all
while retaining automatic defaults for older configurations;
process-local command ids;
does not ship a separate iconDark asset.
runtime-backed extensions.
The eleventh code slice is now implemented:
- connect the AI service to the live runtime broker;
- publish versions of all native Salamatrix service contracts in the machine-
- publish the current runtime adapter inventory (id, language, extensions,
- cover the generated metadata with the runtime protocol test target.
readable API description;
version, and availability) for prompt construction;
The twelfth code slice is now implemented:
- let the native command, file-operation, UI, sides, events, storage,
- aggregate those fragments into the AI service's machine-readable schema;
- validate the resulting
nativeContractsJSON object in the runtime protocol
extensions, and runtime services publish compact schema fragments next to their actual contracts;
tests.
The thirteenth code slice is now implemented:
- add a common AI response validator for capabilities, estimated effects,
- expose the validator and a bounded
GenerateWithRepairloop through the - use the same repair-aware generation path in the standalone Salamatrix AI
- cover valid, unsupported-capability, and unsafe-script responses in the
runtime identity, and undeclared external/network operations;
provider-neutral AI ABI, preserving compatibility defaults for older services;
chat and both Automation AI consumers;
runtime protocol tests.
The fourteenth code slice is now implemented:
- extend schema-1 manifests with an optional
eventsdeclaration; - validate event names and reject duplicates during strict manifest parsing;
- enforce the declared allow-list at the persistent worker host boundary while
- cover declared, absent, unknown, and duplicate event declarations in the
preserving unrestricted event subscriptions for legacy manifests and generated one-shot AI scripts;
manifest parser tests.
The fifteenth code slice is now implemented:
- represent an unavailable requested runtime with the ABI-safe
- have Automation check the shared runtime broker for the adapter and minimum
- keep waiting extensions visible in the existing Plugin Manager and annotate
- make activation a safe no-op while the dependency is absent, then clear the
- cover registration, blocked activation, and reactivation in the extension
ExtensionFlagRuntimeUnavailable flag and ExtensionStateWaitingForRuntime;
version while publishing manifest extensions;
their runtime/function status without offering an install flow;
waiting state and activate through the existing same-owner refresh when the standalone runtime plugin registers;
lifecycle test.
The sixteenth code slice is now implemented:
- retain the selected runtime command ID in the Automation execution context;
- pass that ID through the Python, PowerShell, PHP, and Node worker bootstrap
- expose it consistently as
Salamander.command_id(with JavaScript's - publish the field in the AI/API description so generated extensions can
- cover the end-to-end Python one-shot path and re-run all worker syntax and
command lines for both the Automation compatibility broker and standalone runtime providers;
camel-case alias commandId as well);
dispatch manifest or dynamically registered handlers explicitly;
provider Debug builds.
The seventeenth code slice is now implemented:
- retain all validated manifest command records (up to the native runtime
- publish each declared command with its own plugin/context/toolbar placement
- keep the manifest command surface stable across worker teardown and restore
- allow the worker to add or remove dynamic commands alongside manifest-owned
- preserve the selected command context for all of these entries through the
command limit) instead of applying only the first record;
and requires event masks when the persistent extension activates;
its default command metadata on the next activation;
commands without losing the package identity;
existing Salamander.command_id worker field.
The eighteenth code slice is now implemented:
- extend the versioned runtime request with an optional
CommandHandlerfield; - resolve the selected manifest command's declared
handlerby command ID; - pass that handler through the Automation broker and all four standalone
- expose the value consistently as
Salamander.command_handler(plus
worker providers using the bounded --command-handler/-CommandHandler bootstrap argument;
JavaScript's camel-case alias) and cover the Python one-shot path in the process-runtime integration test.
The nineteenth code slice is now implemented:
- retain an optional handler name on every native runtime command record;
- extend
Salamander.commands.register(...)in Python, PowerShell, PHP, and - persist dynamic handler names through native command activation and expose
- publish the handler field in the live AI/API command schema and verify the
JavaScript with the common optional handler argument;
the selected value through the same Salamander.command_handler field;
worker-to-host registration payload in the Python bootstrap integration test.
The twentieth code slice is now implemented:
- add the ABI-safe
fileChangedevent kind without extending the events vtable; - forward Salamander core
AcceptChangeOnPathNotificationcallbacks through - expose the event consistently to modern workers, Automation, manifest event
- cover subscription acceptance and path/scope delivery in the native Events
Salamatrix with the UTF-8 affected path and recursive-scope flag;
allow-lists, and the live AI/API schema;
test suite.
The twenty-first code slice is now implemented:
- add the append-only UI 1.1 notification contract and native timed popup;
- expose
Salamander.ui.notify(message, title, timeout)consistently to - keep notification calls non-modal and bounded (default five seconds,
- cover the worker-to-host notification call in the Python bootstrap test.
Python, PowerShell, PHP, JavaScript, native Automation adapters, and the live AI/API schema;
maximum ten minutes) while allowing click-to-dismiss;
The twenty-second code slice is now implemented:
- validate an optional manifest
dependenciesarray (bounded, identifier-only, - register the complete manifest batch before activation, resolve dependency
- make activation a safe no-op while a dependency is absent and surface the
- cover dependency parsing, blocked activation, and same-owner reactivation in
case-insensitive unique ids) and retain it with the discovered script;
chains in bounded passes, and represent unresolved dependencies with the ABI-safe waitingForDependency state/flag;
reason in the existing Plugin Manager alongside runtime-unavailable status;
the manifest and Extensions test suites.
The twenty-third code slice is now implemented:
- append the Extensions 1.1
disabledstate andSetExtensionDisabledAPI - persist the manifest extension's enabled choice in its isolated
- make Plugin Manager Deactivate stop the worker first, then persist and show
- cover disabled registration, safe no-op activation, re-enable, and
without changing the existing descriptor layout;
salamatrix.enabled Storage key, where no key remains backwards-compatible as enabled;
disabled; Activate clears that state and starts the ordinary lifecycle;
re-disable transitions in the Extensions lifecycle test.
The twenty-fourth code slice is now implemented:
- append the ABI-safe Extensions 1.2 settings-schema contract with bounded
- publish manifest setting declarations from Automation after each successful
- use the shared
Salamatrix.UIdialog/control API from Plugin Manager's - cover schema registration, retrieval, duplicate rejection, and the
string/integer/boolean setting records, without changing the descriptor layout;
extension registration;
Configure action to edit typed per-extension values (with a deliberate 24-setting fixed-layout limit);
Extensions 1.2 service build alongside Automation, Salamatrix, and core Salamander Debug x64 builds.
The twenty-fifth code slice is now implemented:
- allow every manifest
commands[]record to declare a package-contained SVG - validate the command artwork with the same safe-relative-path and SVG-only
- preserve package artwork as the compatibility fallback and retain core dark
- cover valid and invalid command artwork through the strict manifest parser
icon and optional dark-mode iconDark asset;
rules as package artwork, resolve it during discovery, and prefer it for its specific toolbar button;
icon generation when no valid dark asset is supplied;
test and build Automation Debug x64.
The twenty-sixth code slice is now implemented:
- add a native
FolderPickercontrol toSalamatrix.UIdialogs; it opens the - expose it to every modern worker facade as Python
add_folder_picker, - include the control in the runtime and AI API schemas so the local script
- build Salamatrix and Automation Debug x64, run the API protocol test, and
standard folder browser, returns its selected UTF-8 path through IControl, and raises the standard control-change event;
PowerShell AddFolderPicker, PHP addFolderPicker, and Node addFolderPicker, with the raw runtime protocol kind folderpicker also accepted;
helper can generate it;
syntax-check all four runtime worker implementations. The process-runtime integration run was completed later with an explicit isolated SALAMATRIX_WORKER_ROOT; its result is recorded in the twenty-seventh slice below.
The twenty-seventh code slice is now implemented:
- add the append-only
filepickercontrol kind to the shared native dialog; - expose
add_file_picker/AddFilePicker/addFilePickerin the Python, - extend the host mapping and the cross-runtime process test to cover the new
- fix typed-storage/schema drift in the standalone PowerShell and PHP worker
- rebuild Salamatrix, Automation, all four standalone provider projects, the
its edit control keeps a UTF-8 path value while the adjacent browse button opens the wide Win32 file dialog with heap-backed path storage rather than a new MAX_PATH dependency;
PowerShell, PHP, and Node workers and publish the control in the runtime and AI API schemas;
control for Python, PowerShell, and PHP;
assets, which the isolated provider-root test exposed after the first attempt;
runtime protocol test, and the process-runtime test into build\verification\editable-file-picker; the protocol test and the process-runtime test both passed, with the latter returning exit code 0 under an explicit isolated SALAMATRIX_WORKER_ROOT.
The twenty-eighth code slice is now implemented:
- extend manifest setting declarations with validated label, description,
- allow selected package locale resources to translate setting presentation
- append presentation fields to
ExtensionSettingInfo, but accept and return - publish the metadata through
storage.schema()and the existing Plugin - cover parser validation, localized settings, the new registry fields, and
group, order, width, and multiline metadata while keeping the storage key stable;
text in addition to extension names and command titles;
the legacy 1.2 prefix by honoring caller StructSize, preserving the existing ABI and service vtable;
Manager's Configure dialog, including localized labels/groups and bounded multiline/width layout;
legacy setting-schema callers. The isolated parser/registry tests and Automation plus Salamatrix Debug x64 builds passed under build\verification\manifest-settings; no Salamander process was started or controlled.
The twenty-ninth code slice is now implemented:
- add initial
enabled/visiblestate to manifest and runtime command - expose
setState/set_state/SetState/setStatethrough the common worker - cover manifest state parsing, the runtime API schema, and state changes from
- build Automation, Salamatrix, all four standalone provider projects, and the
metadata while keeping the public service/vtable prefixes unchanged;
facades, apply the state in Automation's existing menu and toolbar path, and trigger the normal Plugin Manager/menu refresh;
Python, PowerShell, and PHP in the isolated process-runtime test;
focused tests into build\verification\command-state. The explicit SALAMATRIX_WORKER_ROOT process run, all worker syntax checks, and the parser/protocol tests passed; no Salamander process was started or controlled.
The thirtieth code slice is now implemented:
- complete the append-only
IRuntimeSession::GetDiagnosticimplementation in - preserve cached process id and exit code after handle teardown, distinguish
- extend the process-runtime test with running/stopped/process-id assertions
- build Automation, the process-runtime test, and all four standalone
the Automation process bridge and all four standalone runtime providers;
running, explicit host stop, clean exit, and nonzero failed exit, and expose bounded diagnostic text without changing any public vtable prefix;
and a deterministic nonzero-exit failure fixture;
providers into build\verification\runtime-lifecycle. The explicit SALAMATRIX_WORKER_ROOT run passed with exit code 0; no Salamander process was started or controlled.
The thirty-first code slice is now implemented:
- append
filterandsavefile-picker options to the shared native control - keep the SMX1 wire contract flat (
kind,text,filter, andsave) and - update the Automation host mapping, all four standalone worker assets, the
- rebuild Salamatrix, Automation, all four standalone providers, and the
contract without changing existing enum values, vtable prefixes, or control layout prefixes; save selects the native GetSaveFileNameW path and filter uses the UTF-8 pipe-separated Win32 filter format;
preserve positional compatibility in the Python and Node helpers by placing the new optional values after the existing layout argument;
runtime/AI schema fragments, and the Python/PowerShell/PHP process bootstrap assertions for both option values;
focused tests into build\verification\file-picker-options; UI layout, runtime protocol, worker syntax, and explicit SALAMATRIX_WORKER_ROOT process-runtime tests passed with exit code 0. No Salamander process was started or controlled.
The thirty-second code slice is now implemented:
- append tabCreated, tabClosed, tabReordered, windowDetached, and
- infer lifecycle transitions from per-side heap-backed tab snapshots on
- bridge changedTabId, tabIndex, and previousTabIndex into Automation's SMX1
- extend the existing Plugin Manager manifest event allow-list and the
- build the focused tests, Automation, Salamatrix, and all four standalone
windowAttached as event kinds 16–20 without changing the existing event enum prefix, service vtable, or V1 EventPayload prefix;
PLUGINEVENT_TABCHANGED, establish an explicit baseline for empty sides, and publish inferred lifecycle events before the legacy tabChanged;
JSON event frame while retaining safe defaults for older V1 payloads;
Salamatrix/AI event schemas, with deterministic native, manifest, and schema tests;
providers into build\verification\tab-lifecycle; all passed, as did the explicit worker-root process-runtime run and all four worker syntax checks. No Salamander process was started or controlled.
The thirty-third code slice is implemented and verified:
- a deterministic Python bootstrap scenario verifies the fixed host/worker tab
- the published Sides schema advertises version 1.3 and all five append-only
- core, Automation host, Salamatrix, events, runtime protocol, process-runtime,
- all four worker syntax checks pass. The process-runtime test passed with an
mutation contract: createTab returns a decimal string tab id and closeTab, reorderTab, moveTab, and setDetached return their exact response shapes; each dispatcher path is counted once;
mutation methods;
extension-manifest, and all four standalone provider projects pass isolated Debug x64 verification under build\verification\tab-object-model;
explicit provider worker root in SALAMATRIX_WORKER_ROOT; no Salamander process was started or controlled.
The thirty-fourth code slice is implemented and verified:
- classify Salamatrix Framework, JavaScript/Python/PowerShell/PHP runtime
- expose SalamatrixAI's Menu Extension capability in the existing Plugin
- make SalamatrixAI shutdown unload-safe when Salamatrix Framework unloads
- add a deterministic source-contract regression script and rebuild both the
- the regression script, core Debug x64 build, and SalamatrixAI Debug x64 build
providers, and SalamatrixAI by stable registry-key prefixes with display-name fallbacks, preserving the ordinary Automation Framework label for unrelated plugins;
Manager and publish a localized command that opens the local-model chat;
first by querying the current SALAMATRIX_SERVICE_AI record and checking pointer identity before provider unregistration, then clearing all borrowed service pointers;
Salamatrix core and SalamatrixAI into build\verification\regressions;
passed. No Salamander process was started or controlled.
The thirty-fifth code slice is implemented and verified:
- extend schema-1 manifests with bounded
settingsVersionand - apply migrations through an internal host helper before settings defaults,
- wire the helper into Automation's manifest discovery and add a standalone
- rebuild the manifest parser tests, migration tests, and Automation Debug x64
settingsMigrations metadata for typed string/integer/boolean rename and remove operations, with strict conflict, bounds, reserved-key, and complete chain validation;
persist the reserved salamatrix.settings.version, preserve existing destinations, support retries after partial failures, and never downgrade a higher stored version; no public SDK vtable or struct layout changes;
migration test executable covering typed values, chains, no-op removals, destination preservation, retry behavior, and version stamping;
plugin into isolated build\verification\manifest-migrations-current, build\verification\settings-migrations-current, and build\verification\automation-migrations-current outputs; all passed.
The thirty-sixth code slice is implemented and verified:
- add standalone, non-GUI assertions for Salamatrix.UI accessibility metadata:
- rebuild and run the UI layout/DPI test executable in isolated
- rebuild
Salamatrix.SPLitself in isolated
default ControlOptions values remain null, explicit UTF-8 values are retained, and the append-only IControl default accessors return empty strings for older control implementations;
build\verification\ui-accessibility-final2 output; all assertions passed;
build\verification\salamatrix-accessibility-final2 output after fixing the helper's private-implementation scope; the Debug x64 build passed.
The thirty-seventh code slice is implemented and verified:
- add ABI-safe
GetKeyCount/GetKeyAtstorage enumeration with typed UTF-8 - add
storage.keys()/Storage.Keys()/storage->keys()/Storage.keys()to - add direct storage unit coverage and persistent Python/PowerShell/PHP
- rebuild storage, Automation, and process-runtime tests in isolated
- rerun the process-runtime executable with explicit
key metadata and the salamander.storage.keys host method;
the Python, PowerShell, PHP, and Node worker facades;
bootstrap assertions for string, boolean, and integer key types;
build\verification\storage-enumeration-final, build\verification\storage-enumeration-automation-final, and build\verification\storage-keys-process-teststests outputs; all passed;
SALAMATRIX_WORKER_ROOT=build\verification\storage-keys-worker-root; all process runtime tests passed without starting Salamander.
The previous storage-table note that listed key enumeration as missing is superseded by this thirty-seventh slice. Remaining storage gaps are settings files, quotas, transactional batches, and uninstall retention/deletion policy.
The thirty-eighth code slice is implemented and verified:
- remove Automation's
CmdAskAssistantmenu command, enablement path, and - remove the Automation-only AI menu localization and helper implementation
- keep the standalone
SalamatrixAI.SPLmenu extension as the sole native - extend the source-contract regression test to assert that Automation no
- rebuild the affected Debug x64 projects and run the regression test in an
interactive generation/preview/run/save/package flow, so Automation remains the independent legacy JS/VBScript and shared runtime-client plugin;
while preserving the Salamatrix.AI bridge/API used by runtime scripts and the Salamatrix.ScriptRunner compatibility service;
owner of the localized chat-opening command;
longer publishes or dispatches an AI menu command while the standalone AI command still calls ShowChat;
isolated verification output; no Salamander process was started or controlled.
The thirty-ninth code slice is implemented and verified:
- make the standalone
SalamatrixAI.SPLmenu caption explicitly - strengthen the source-contract regression test to validate the standalone
- rebuild
SalamatrixAI.SPLDebug x64 into
Ask Salamatrix AI... in its own resource and use the same text as a bounded fallback when localized resource lookup returns NULL or empty;
resource text, fallback, BuildMenu command insertion, and the existing ExecuteMenuItem to ShowChat path;
build\verification\ask-ai-menu-ai-final2 and rerun the regression test; no Salamander process was started or controlled.
The fortieth code slice is implemented and verified:
- synchronize the shared Salamatrix native UI with Salamander's explicit
- apply the existing
win32-darkmodelibpath to Salamatrix dialog trees, - give SalamatrixAI the shared
src/res/sal_r.icoartwork, conventional - add source-contract coverage and third-party attribution, then build the
Windows Dark Mode (experimental) configuration and current scheme colors at provider startup and when WM_SETTINGCHANGE/WM_THEMECHANGED arrives;
controls, title bars, and Unicode message boxes without changing any public SDK/vtable prefix;
versinfo.rh2/versinfo.rc2 metadata, and the common project homepage; apply the same homepage to all four independent runtime .SPL providers;
Salamatrix Framework, SalamatrixAI, and all four runtime providers into isolated build\verification\ai-darkmode-* and build\verification\metadata-* outputs. The source regression test and all six Debug x64 builds passed; no Salamander process was started or controlled.
The forty-first code slice is implemented and verified:
- audit commit
4a2bca820dcd238abc3855f900d4a92ab37acc9fand restore the - keep Automation independent as the legacy JavaScript/VBScript plugin and
- add the append-only
IScriptRunner::RefreshExtensionsmethod so the AI - add source-contract coverage for the complete migration and rebuild both
removed AI assistant workflow in the standalone SalamatrixAI.SPL plugin: panel context, localized prompts/status text, temporary script creation, bounded repair/refinement, clipboard preview, save/run actions, and runtime extension-package export;
shared runtime client: its removed AI command, resources, helpers, and dispatch path remain absent while its Salamatrix.AI and Salamatrix.ScriptRunner compatibility services remain available;
package export requests a refresh through the shared service and the existing Plugin Manager can discover the package without a new Extension Manager or runtime installer;
affected Debug x64 projects into isolated build\verification\ai-restored-logic-final and build\verification\automation-restored-logic-final outputs. The source regression test and both builds passed; no Salamander process was started or controlled.
The forty-second code slice is implemented and verified:
- diagnose the shutdown crash from
ACE187E9236B11B2-AS50SAM0.13X64-260726-101224.TXT: - add an unload guard to all four standalone runtime providers. Each provider
- extend the source-contract regression test for JavaScript, Python,
a runtime provider called UnregisterAdapter through a stale borrowed Salamatrix.Runtime broker after the Framework provider had already been unloaded;
queries the current SALAMATRIX_SERVICE_RUNTIME, compares it with the registration's original service pointer, and only then calls Unregister(). If the service is gone or replaced, it clears local registration state without dereferencing the stale broker;
PowerShell, and PHP and rebuild all four Debug x64 .SPL providers into isolated build\verification\shutdown-guard-* outputs. The regression test and all four builds passed; no Salamander process was started or controlled.
The forty-third code slice is implemented and verified:
- make
salamatrix_runtime.hself-contained for its dark-mode API calls by - preserve projects that define
USE_DARKMODELIB=1and provide a fallback of - rebuild the
demoplugDebug x64 plugin into isolated
including the shared darkmode.h declarations directly;
0 for consumers that only use the header and do not inherit Salamatrix's precompiled header;
build\verification\demoplug-darkmode-header; compilation and linking passed. No Salamander process was started or controlled.
The forty-fourth code slice is implemented and verified:
- wire SalamatrixAI's existing
IDI_PLUGINICONresource to numeric ID 1030, - keep the shared
src/res/sal_r.icoicon for Salamatrix Framework and - extend the source-contract test for numeric icon identity, AI icon-list
load it during CPluginInterface::Connect, and publish it through the normal Plugin Manager icon-list callbacks;
SalamatrixAI only; remove it from the JavaScript, Python, PowerShell, and PHP runtime resource scripts so those providers retain the default Plugin Manager icon;
registration, and default runtime icon scope; rebuild SalamatrixAI and all four runtimes into isolated build\verification\icon-scope-* outputs. The test and all five builds passed; no Salamander process was started or controlled.
The forty-fifth code slice is implemented and verified:
- initialize
SalamanderGUIfromCSalamanderPluginEntryAbstractin - make the standalone AI dynamic menu command use the public
- extend the source-contract regression test for entry GUI initialization,
SalamatrixAI.SPL before the normal Plugin Manager connect lifecycle; the existing Connect() icon-list registration can therefore publish src/res/sal_r.ico instead of silently taking the null-GUI path;
MENU_SKILLLEVEL_ALL contract and report CmdOpenAssistant as enabled even while the optional Salamatrix Framework services are still being resolved; execution retains lazy service lookup and the existing user-facing fallback when the Framework is unavailable, so Plugin Manager keyboard shortcuts dispatch the same command as the menu item;
all-skill-level menu insertion, and enabled command state; rebuild the SalamatrixAI.SPL Debug x64 artifact in isolated build\verification\ai-menu-icon-fix output. The regression test and build passed; no Salamander process was started or controlled.