Conversation
Enable the analyzers that ship with the pinned .NET SDK and add a root .editorconfig that defines formatting, naming, and IDE style explicitly. Every rule reports as a warning at this layer so the diagnostic backlog is visible without blocking the build. Add scripts/Test-DotNetQuality.ps1 as the single quality entry point shared by local development, CI, and the future pre-push hook, and invoke it from the Windows test job. Add CONTRIBUTING.md and a pull request template, which the repository previously lacked. GenerateDocumentationFile is required for build-time IDE0005, so CS1591 is suppressed rather than satisfied with low-value XML comments. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 331d9f1d-2f78-491c-8347-19969cb5ce11
Apply the outstanding whitespace and style fixes, then promote the IDE style and naming rules from warning to error so CI rejects future drift. The code changes are behavior preserving: indentation in ProgramTests, two collection expressions, and the diagnostic log's lock object moving from `object` to `System.Threading.Lock`. The lock field is only ever used in `lock` statements, so the new type introduces no Monitor-based behavior change. Also refine the style policy so it only enforces rules that add value. `var` versus explicit type, throw expressions, conditional expressions over guard clauses, and IDE0058 discards are left to the author, because forcing them produced worse code in this codebase rather than better. Test-DotNetQuality.ps1 now also verifies whitespace and style. It remains check-only and never rewrites source, including in CI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 331d9f1d-2f78-491c-8347-19969cb5ce11
* improve: harden native library loading All ten P/Invokes in the launcher target kernel32.dll. Without an explicit search path the loader also probes the application and current directories, so a planted kernel32.dll next to openclaw.exe could be loaded instead of the system one. Restrict DLL resolution to System32 for the whole assembly. Also stop marshalling the CreateProcessW command line through a StringBuilder. CreateProcessW may write to that buffer, so it now receives an explicitly null-terminated char array sized from the built command line. The buffer is never read back. Promote CA5392 and CA1838 to errors now that both are clear, and add a regression test that launches a real child process with an argument containing spaces and embedded quotes to prove the command line still arrives intact. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 331d9f1d-2f78-491c-8347-19969cb5ce11 * fix: keep child command text free of fixture paths The real-child argument test interpolated the fixture output path into a single-quoted PowerShell literal. A temporary root containing an apostrophe (for example C:\Users\O'Connor) terminated that literal early and turned the remaining path into PowerShell syntax, so the test failed for a reason unrelated to argument marshalling. Pass the output path to the child as environment data and keep the command text fixed. The spaced and embedded-quote payload still travels on the command line, so the marshalling assertion is unchanged, and the case is now covered for both a plain fixture subdirectory and one containing spaces and an apostrophe. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 331d9f1d-2f78-491c-8347-19969cb5ce11 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 331d9f1d-2f78-491c-8347-19969cb5ce11
Narrow the launcher's implementation types to internal and make every string comparison in the test suite explicit and culture-independent, then promote the contract and globalization analyzer families to errors. Internalizing the seven implementation-only types removes the ambiguity about what this executable's supported surface is. Because these types are no longer externally visible, the six CA1062 public-argument-validation findings disappear without adding guard clauses that would have become dead weight. The test project keeps full access through the existing InternalsVisibleTo entry. The CA1307 findings were all Assert.Contains calls matching literal English fragments of diagnostic and exception messages. StringComparison.Ordinal is the semantically correct choice: these assertions want exact, invariant substring matching, not culture-sensitive collation. CA1062, CA1307, CA1308, and CA1515 are now errors. CA1308 and CA1062 have zero findings and act as forward guards. CA1515 is disabled for the test project because xUnit 2.x only discovers public test classes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 331d9f1d-2f78-491c-8347-19969cb5ce11
Make every await in the launcher explicit about continuation scheduling and replace the remaining synchronous calls inside async methods, then promote the async analyzer family to errors. The launcher is a console executable with no SynchronizationContext, so ConfigureAwait(false) is a no-op at runtime today. It is applied anyway because the rule protects future code: if this assembly is ever consumed from a context-capturing host, or a UI-hosted setup surface is added, the absence of an explicit choice becomes a deadlock risk rather than a style question. Making the intent explicit at every await costs nothing now and removes an entire defect class later. CA1849 flagged two genuine synchronous calls on async paths: the clawctl --version write to the output TextWriter, and File.ReadAllText in the interop argument-delivery test. Both now use their asynchronous overloads, and the test threads its existing timeout token through the read so a hung file operation fails the test rather than hanging the run. CA2007 does not apply to the test project; the SDK excludes it automatically for projects that reference a test framework, so no ConfigureAwait noise is added to test code. Validated on this branch: static analysis gate clean, 53 tests pass, and win-x64 NativeAOT publish succeeds with no IL, trim, or AOT warnings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 331d9f1d-2f78-491c-8347-19969cb5ce11
Give every disposable in the test suite an explicit scope, document the one deliberate broad catch, sharpen a private return type, and promote the remaining lifetime and design analyzer families to errors. After this change the branch builds with zero warnings. The three CA2000 findings were StringWriter instances in tests that were never disposed. They are now scoped with using declarations. This is small but real: undisposed writers accumulate across a run and mask genuine ownership mistakes in the same files later. CA1031 flagged the last-chance catch in Main. That catch is correct and deliberate. Every other catch in this assembly already uses an exception filter to name the failures it expects; Main is the process boundary, and narrowing it would trade a logged diagnostic, a readable error message, and a deterministic exit code 1 for an unhandled-exception crash. The rule is suppressed at that single method with that rationale rather than repository wide, so any new broad catch elsewhere still fails the build. CA1859 flagged FindPathCandidates returning IReadOnlyList<string> from a private helper that always produces a List<string>. The interface added no contract value across a private call and cost an interface dispatch on the PATH scan; the concrete type is now returned directly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 331d9f1d-2f78-491c-8347-19969cb5ce11
* chore: enforce the complete .NET quality gate Turn on TreatWarningsAsErrors now that the branch builds warning-free, and add an opt-in pre-push hook so contributors can get the CI answer before pushing. The per-rule error entries the earlier layers added only cover diagnostics somebody has already looked at. The gap they leave is everything nobody has classified yet: a new compiler warning, a new analyzer from an SDK bump, a rule that changes default severity. Those arrive as warnings and get scrolled past. TreatWarningsAsErrors turns each one into a decision at the moment it appears. The explicit .editorconfig severities stay as readable policy history. NuGet audit advisories are excluded from the gate. NU1901 through NU1904 report published vulnerabilities, so one can appear against a dependency graph nobody touched and break main with no committed change and no fix available inside the failing build. They remain visible as warnings and are triaged as security work rather than treated as build breaks. The hook is deliberately small and deliberately opt in. hooks/pre-push is tracked, carries a marker identifying it as repository-owned, and runs only Test-DotNetQuality.ps1, so it cannot drift from what CI does. Install-GitHooks.ps1 copies it into the current clone and -Remove deletes it. Neither direction touches global Git configuration or core.hooksPath; installation stops if core.hooksPath is set rather than writing a hook Git would silently ignore, refuses to overwrite a pre-push hook it did not write, and removal only deletes a hook carrying the marker. Both are idempotent. The hook is a latency shortcut, not a policy boundary. It is local to one clone and `git push --no-verify` skips it; required CI checks remain authoritative. That is stated in the hook, the installer, and CONTRIBUTING so nobody mistakes it for enforcement. Test-GitHooks.Tests.ps1 covers install, repeated install, removal, repeated removal, unmanaged-hook conflict in both directions, and the core.hooksPath refusal. The pass and fail cases are end to end: they build a throwaway repository with a local bare remote and a stub quality script, then perform a real git push, proving Git invokes the hook and that its exit code decides whether the push lands. Nothing runs against this clone. CI runs the suite alongside the existing policy suites. Validated on this branch: quality gate clean, 53 tests pass, all three PowerShell suites pass, win-x64 NativeAOT publish succeeds with no IL, trim, or AOT warnings, and an injected #warning fails the build as CS1030. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 331d9f1d-2f78-491c-8347-19969cb5ce11 * fix: install the pre-push hook where Git looks for it The installer composed its destination from git rev-parse --absolute-git-dir plus 'hooks'. In a linked worktree that is the worktree's private directory, which Git never consults for hooks, so installation reported success and no push ever ran the quality gate. Ask Git for the hooks directory instead, with rev-parse --git-path hooks, and use that answer for both installation and removal. A clone has one hooks directory shared by all of its worktrees, so say so in the installer output and in CONTRIBUTING. The hook suite now runs every existing case against both an ordinary clone and a linked worktree. In the worktree layout the two work trees carry opposite stub exit codes, so the real pushes prove Git ran the pushing worktree's quality script. Two further cases cover the shared destination and clone-wide removal. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 331d9f1d-2f78-491c-8347-19969cb5ce11 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 331d9f1d-2f78-491c-8347-19969cb5ce11
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7cb16ef4-e347-4342-a67e-385a8721db1c
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7cb16ef4-e347-4342-a67e-385a8721db1c
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a35bc4fd-e612-4be2-8166-7c100e8cf3ef
The signing script previously skipped both architecture directories when the artifact root was not CI-shaped, then reported success after creating and discarding a certificate. Validate the expected architecture directories before creating signing material so a no-op cannot look like a signed result. Add a regression test that runs the script against an empty artifact root and verifies the failure message, non-zero exit, absence of output, and absence of a newly created publisher certificate. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 97c31f3f-0c7b-43e8-b979-6418dcb7fedc
…openclaw#29) * Parse clawctl arguments with System.CommandLine Replace the hand-written clawctl parser and help renderer with a declarative System.CommandLine tree. The `openclaw` entrypoint is unchanged and still forwards its argument vector to the OpenClaw CLI without parsing it. - Add ClawCtlCommandLine: a root command plus a `setup` subcommand, with Node prerequisite and install guidance in the command descriptions so help is generated from one source instead of hand-formatted. - Delete ClawCtlCommand and its enum/parse-result/exact-token matcher rather than leaving a second dispatch model beside the library. - Rewrite Program.RunControlAsync around the tree. Disable the library's default exception handler so operational failures keep reaching the host's diagnostic boundary, and leave ProcessTerminationTimeout null so it does not compete with the Node job object for process lifetime. The setup action's cancellation token now flows into the Node resolver. - Replace the `Action<string> writeError` seam with an injected TextWriter and drop the direct Console.Error write from the control dispatcher. - Report the launcher assembly version through a custom version action. The built-in one reports the entry assembly, which under a test or scenario host is not the launcher. - Disable response-file expansion. A leading `@` is an unrecognized argument for clawctl and stays uninterpreted through `openclaw`. Completion is kept. Invalid management input now exits 1, the library's parse-error code, instead of the previous 2. Add Test-NativeAotCli.Tests.ps1 and run it in CI. The xUnit suite runs under a JIT test host, so it cannot observe the root command name that System.CommandLine derives from native argv[0], and a successful AOT publish is not execution evidence. The script publishes win-x64 NativeAOT into a temporary directory it owns, runs the binary as clawctl.exe, and removes it afterwards. Node-dependent scenarios stay in xUnit with an injected runtime so the gate does not depend on the agent's installed Node version. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 79e90679-15f4-4fd5-a669-d70d363a9c34 * Cover the completion directive and version precedence The only completion test used the in-process GetCompletions API, which no shell can reach. Cover the `[suggest]` directive through the real control dispatcher instead, since that is the path a completion client actually calls. Also record that `--version` now wins over trailing arguments. The old parser rejected the combination; the library's version action clears parse errors, so `clawctl --version bogus` prints the version and exits 0. That is stock System.CommandLine behavior, not a local choice, but it is a visible change to this CLI's contract and was previously untested. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 79e90679-15f4-4fd5-a669-d70d363a9c34 * fix: exit the NativeAOT clawctl gate with its own status The gate's final assertion runs clawctl with an argument that must be rejected, so $LASTEXITCODE is 1 when the script ends. GitHub Actions exits a pwsh step with that value, so the step failed even though every assertion passed. The job printed "NativeAOT clawctl checks completed successfully." immediately before reporting exit code 1. Exit 0 explicitly after cleanup. Assertion failures throw and never reach that line, so the gate still fails when it should: verified by injecting a pattern that cannot match, which exits 1 with the offending output. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 79e90679-15f4-4fd5-a669-d70d363a9c34 * Isolate the NativeAOT command-line gate from the user profile The native gate published the production launcher and ran its `Main`. `Main` creates the diagnostic log through `HostDiagnosticLog.Create()`, which resolves `%LOCALAPPDATA%\OpenClawGatewayMSIX` rather than anything relative to the publish directory, so every gate run appended startup and exit records to the developer's real log. Publishing into a temporary directory did not redirect that, and green CI never revealed it. Extract the startup path into `Program.RunAsync(args, HostStartup)` and leave `Main` as the production adapter that supplies the real collaborators. `HostStartup` carries the entrypoint, the diagnostic factory, the base directory, the writers, and the existing Node and launch seams, so startup can be driven with fixture-owned storage. Replace the gate's subject with a NativeAOT scenario driver in `tests/OpenClaw.Launcher.AotSmoke`. It runs the same `RunAsync` under the `clawctl.exe` name with an explicit temporary log path, in-memory writers, and delegates that cannot start a real process, so native coverage still includes startup logging and the error boundary. The script now also runs the driver under a wrong executable name and requires a nonzero exit, so the alias check cannot pass vacuously. Add JIT regressions for the same seam: diagnostics routed to a test path, a handled operational failure reporting that path and exiting 1, a failed diagnostic factory warning once and continuing, and `openclaw` forwarding arguments verbatim while returning the child's exit code. A read-only before/after observation of the normal unpackaged log across a full gate run showed an unchanged length, timestamp, and SHA-256. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 79e90679-15f4-4fd5-a669-d70d363a9c34 * Keep the NativeAOT scenario fixtures out of %TEMP% CodeQL treats `Path.GetTempPath()` as a user-controlled source, because `TMP` is an environment variable a caller controls. The scenario driver is a plain console executable rather than a test-framework project, so it is not classified as test code, and its fixture roots flowed into `HostOptions.Parse` and the driver's own file writes as eight new high-severity `cs/path-injection` alerts on the pull request. Build the fixture roots under `AppContext.BaseDirectory` instead. The gate script already publishes into a directory it owns and deletes, so the scenarios stay isolated without reading an environment variable, and the alerts have no source. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 79e90679-15f4-4fd5-a669-d70d363a9c34 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 79e90679-15f4-4fd5-a669-d70d363a9c34
Carry the upstream toolchain version through payload metadata and MSIX composition. Validate bundled executables without launching staged images, repair invalid caches under a cross-session installation lock, reclaim interrupted staging, and expose bundled tools only to the child PATH. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Preserve the System.CommandLine startup and NativeAOT gates while routing setup to bundled-runtime preparation and keeping openclaw arguments transparent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* chore(ci): finalize Artifact Signing setup * docs: name the dedicated packaging signer * docs: use the MSIX signing identity name * fix(ci): recurse into signing artifact folders
* feat(ci): publish durable signed MSIX releases * feat(ci): publish multi-architecture MSIX bundle * fix(ci): authorize exact MSIX bundle contents * fix(ci): use explicit zero-version signing proof
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com> Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
feat: bundle Node.js runtime in the Gateway MSIX
…-identity fix: release dashboard rejects matching packaged gateway
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Attach runtime and payload matrices, clipboard checks, regression results, and authenticated Control UI screenshots. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Consume the host's semantic widget theme in the sandboxed Gateway Isolation tab while retaining system-theme fallbacks for older Control UI builds. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Apply forwarded typography, strong colors, and radii so custom Control UI themes remain visually cohesive inside the sandboxed Gateway Isolation tab. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use Windows Launcher for the user-facing plugin, tab, and page title while retaining the gateway-isolation implementation identity and reported status terminology. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Remove unsupported mutation guidance, validate and apply generic host theme tokens, and replace stale fallback proof with exact-head validation harnesses. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Make the isolation mode assembly-internal and update current-main test seams for the added launch argument. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Pin automatic payload builds to the merged openclaw/openclaw#145409 commit and make browser proof cleanup resilient on Windows. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This reverts commit 5ef558a.
This reverts commit e2789b1.
ChazGo
force-pushed
the
chazgo-themed-windows-launcher-plugin
branch
from
September 14, 2026 23:36
84511b0 to
1d44895
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why is this change being made?
The Windows package needs a packaging-owned Control UI surface for launcher diagnostics because Gateway isolation mode is selected and reported by the Windows launcher, not by the generic OpenClaw runtime.
The plugin consumes the generic selected-theme forwarding merged in openclaw/openclaw#145409 at commit
f65ecca89667b8a55d9f88d76c487f0a0ab11da8. Full selected-theme cohesion requires that core commit or newer. Older compatible hosts and direct page opens retain the browser or OS light/dark fallback.This is a separate alternative to openclaw#28. It does not modify or reuse that pull request.
What changed?
gateway-isolation.Windows Launcher.Gateway Isolationwhile retaining the existing CLI command and Copy control.openclaw:widget-thememessages only fromwindow.parent, including semantic colors, text and border strength, focus, fonts, and standard and pill radii.prefers-color-schemefallback and fail-closed invalid launcher modes.sandbox="allow-scripts"and noallow-same-origin.How was the change tested?
koffiARM64 install attempted a local native rebuild on this machine. The repository's synthetic x64/ARM64 payload coverage remains part of the validation path.This proof is expanded-layout browser validation, not installed MSIX validation.
Default Claw themes
Imported custom themes