diff --git a/.github/workflows/llm-lint.yml b/.github/workflows/llm-lint.yml index 3b65786..27f9633 100644 --- a/.github/workflows/llm-lint.yml +++ b/.github/workflows/llm-lint.yml @@ -112,7 +112,25 @@ jobs: - name: Enforce assembly warning policy run: pwsh -NoProfile -File scripts/lint-assembly-warnings.ps1 + - name: Resolve the harness self-test scope + id: self-test-scope + shell: bash + env: + BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }} + run: | + set -euo pipefail + if [ -n "${BASE_SHA}" ] && [ "${BASE_SHA}" != "0000000000000000000000000000000000000000" ] && ! git cat-file -e "${BASE_SHA}^{commit}" 2>/dev/null; then + git fetch --depth=1 origin "${BASE_SHA}" || true + fi + verdict="$(pwsh -NoProfile -File scripts/should-run-self-tests.ps1 -BaseSha "${BASE_SHA:-}")" + echo "self-tests=${verdict}" >> "${GITHUB_OUTPUT}" + + # The self-tests only verify the harness surface (scripts, .llm, CI and + # devcontainer wiring, package manifests). Skip them when that surface + # is untouched; every surface change still runs the full suite on both + # operating systems. - name: Run harness self-tests + if: steps.self-test-scope.outputs.self-tests != 'skip' run: pwsh -NoProfile -File scripts/tests/run-all.ps1 - name: Enforce .llm file length limit diff --git a/.llm/context.md b/.llm/context.md index ab9a2c2..7ed4f1e 100644 --- a/.llm/context.md +++ b/.llm/context.md @@ -137,6 +137,9 @@ See the generated [Skills Index](./skills/index.md). Regenerate it after adding ### Validation Ladder (Run After Each Change) +Per-iteration speed: run `npm run check:fast` first (formats and lints only the files changed since `origin/main`, and skips harness self-tests when their surface is unchanged). +The full ladder below gates review. + ```bash dotnet tool restore dotnet tool run csharpier -- format Editor Runtime Tests diff --git a/.llm/references/forbidden-patterns.md b/.llm/references/forbidden-patterns.md index ba36e22..685ee4d 100644 --- a/.llm/references/forbidden-patterns.md +++ b/.llm/references/forbidden-patterns.md @@ -36,5 +36,6 @@ Patterns that must not appear in this codebase, with the compliant alternative. | Static mutable state with no documented reason or teardown reset | document why it is static, weak-key by lifecycle owner, unregister on every removal path, and reset it in the owning window's `Cleanup()` (`AssetGuidTypeIndex.Shared` suspension reset and the theme-selection ownership registry are the precedents) | static editor state outlives windows and strands cross-window state (PR #122 review finding) | | `using` directives above the `namespace` declaration | place them inside the namespace block; file-level usings are sanctioned only for namespaceless assembly-attribute files and `[assembly: ...]` preambles like `InternalsVisibleTo` (`npm run lint:csharp-usings` enforces this, `:fix` moves the simple cases) | one namespace-scoped convention keeps the file header stable and the rule mechanically checkable (#124) | | A guard that reads a machine-readable config resolves only part of a construct, such as the first `{a,b}` alternative, a nested group, or one level of a nested mapping | resolve every alternative and nesting level, or refuse the pattern with the file and line that uses it | a partially-read rule still matches its own representative path, so the guard passes while the real configuration disagrees; refusing beats guessing (PR #131 review finding in `scripts/lint-line-endings.js`) | +| Passing a changed-path list (diff, status, hook payload) straight into a file-argument tool — formatter, linter, packager | keep group triggers on the full changed list, but filter every file-argument invocation to paths that still exist on disk (`Test-Path` against the repo root) | deletions and rename old-paths appear in `git diff --name-only` but not on disk, so one ordinary delete or rename makes the tool fail and the whole check useless afterwards (PR #164 Bugbot finding in `scripts/fast-check.ps1`) | | A guard that names the argument forms it rejects and passes everything it does not name | require the exact arguments the policy permits, and report the file with every argument found | a switch the reader does not recognize turns off the policy the guard claims to enforce, so `-nowarn:1701` or `-warnaserror-` in a `csc.rsp` passed the guard that owns warnings-as-errors (`scripts/lint-assembly-warnings.ps1`, #132) | | Pixel or region validation that records UI Toolkit subtrees without checking whether they render | filter candidates through a rendered check before measuring — `display:none` ancestor chain, resolved per-element visibility, and positive area (`DocsImageCapture.IsRenderedForCapture` precedent) | a `display:none` subtree reports laid-out children but paints nothing, so its clamped one-pixel sample always fails and rejects a faithful capture; persisted namespace collapse makes hidden rows a normal host state (PR #140 review finding) | diff --git a/.llm/skills/ship-changes/SKILL.md b/.llm/skills/ship-changes/SKILL.md index bf19d54..21c8f35 100644 --- a/.llm/skills/ship-changes/SKILL.md +++ b/.llm/skills/ship-changes/SKILL.md @@ -13,6 +13,7 @@ Run the narrowest sufficient layer; escalate on failure: | Layer | Scope | Command | | --- | --- | --- | +| Fast check | changed files | `npm run check:fast` | | Pre-commit hook | staged files | automatic (`pre-commit` + `.pre-commit-config.yaml`) | | C# member layout | all C# types | `npm run lint:csharp-member-order` | | Markdown formatting | tracked Markdown | `npm run format:md:check` | diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ec5c26..ef9b809 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### Fixed +- Fix the docs copy to match the window: a processor without an `Accepts` list is never offered, pane widths always save in editor preferences, and persistence docs use the + on-screen **Persist State in Settings Asset** label. The settings tooltip now names the correct save location. (#153, #149) - `BaseDataObject` asset ids no longer change on validation: an asset keeps its authored id, and only an empty id fills from the asset GUID. Created and cloned assets still get a fresh id (#137). diff --git a/Editor/DataVisualizer/Data/DataVisualizerSettings.cs b/Editor/DataVisualizer/Data/DataVisualizerSettings.cs index 2bb5503..244c059 100644 --- a/Editor/DataVisualizer/Data/DataVisualizerSettings.cs +++ b/Editor/DataVisualizer/Data/DataVisualizerSettings.cs @@ -15,7 +15,9 @@ public sealed class DataVisualizerSettings : ScriptableObject public string DataFolderPath => _dataFolderPath; - [Tooltip("If true, window state (selection, order, collapse) is saved in a special ScriptableObject. If false, state is saved within this settings asset file.")] + [Tooltip( + "If true, window state (selection, order, collapse) is saved within this settings asset file. If false, state is saved as JSON to a per-user file in Unity's persistent data path." + )] public bool persistStateInSettingsAsset; [Tooltip("If true, when selecting an Object, it will be selected in the Inspector.")] diff --git a/README.md b/README.md index b57377b..63ff23c 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ -# Data Visualizer +# DxVisualizer > **🤖 AI Assistance Disclosure** > > The early versions of Data Visualizer were heavily human-authored. More recent development has been a mix of human effort and AI assistance: human authors lead design, > architecture, and review, while AI tools assist with feature development, bug detection, performance optimization, and documentation. -Data Visualizer streamlines working with ScriptableObject-heavy systems by centralizing asset management, inspection, and batch operations in a single window. Instead of hunting +DxVisualizer streamlines working with ScriptableObject-heavy systems by centralizing asset management, inspection, and batch operations in a single window. Instead of hunting through the Project panel and repeatedly switching contexts, you get a namespace-organized view of all your data types with inline editing, batch operations, and workflow automation. -Data Visualizer is free forever: no subscriptions, no paid upgrades, no feature-gated tiers. The full source is MIT-licensed, and every capability documented here ships in the free +DxVisualizer is free forever: no subscriptions, no paid upgrades, no feature-gated tiers. The full source is MIT-licensed, and every capability documented here ships in the free package. This guide captures the key points from the companion [video walkthrough](https://youtu.be/3oUxUSKNyhw) while keeping the instructions project-agnostic. A browsable version of this @@ -17,8 +17,8 @@ documentation, with per-topic pages, is published at