Skip to content

Commit e67cc89

Browse files
Merge pull request erikdarlingdata#3276 from erikdarlingdata/dev
Release v3.7.0
2 parents 4bb851a + 3de8902 commit e67cc89

884 files changed

Lines changed: 150386 additions & 10071 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/build/SKILL.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
name: build
3+
description: Build and locate the PerformanceMonitor executables
4+
argument-hint: [lite|darling|viewer|dashboard|installer]
5+
disable-model-invocation: false
6+
---
7+
8+
# Build PerformanceMonitor
9+
10+
Build a component of PerformanceMonitor and report the result. All paths are relative to the repository root.
11+
12+
## Arguments
13+
14+
`$ARGUMENTS` specifies which component to build:
15+
16+
| Argument | Project | Output TFM |
17+
|---|---|---|
18+
| `lite` | `Lite/PerformanceMonitorLite.csproj` | `net10.0-windows` |
19+
| `darling` or `service` | `Darling/PerformanceMonitor.Darling.Service/PerformanceMonitor.Darling.Service.csproj` | `net10.0` |
20+
| `viewer` | `Darling/PerformanceMonitor.Darling.Viewer/PerformanceMonitor.Darling.Viewer.csproj` | `net10.0-windows` |
21+
| `dashboard` or `full` | `deprecated/Dashboard/Dashboard.csproj` | DEPRECATED since v3.3.0 |
22+
| `installer` | `deprecated/Installer/PerformanceMonitorInstaller.csproj` | DEPRECATED since v3.3.0 |
23+
| (empty) | build whatever is in the current working directory, or ask | |
24+
25+
Lite, the Darling service, and the Darling Viewer are the shipping artifacts. The full Dashboard and the CLI Installer moved to `deprecated/` in v3.3.0. They still build and their tests still run in CI, but they ship no release artifacts and get bug-fix support only.
26+
27+
## Steps
28+
29+
1. Map `$ARGUMENTS` to the project path above.
30+
2. Run `dotnet build <path>`, Debug configuration by default.
31+
3. Report the result:
32+
- **success**: show the output path (e.g. `Lite/bin/Debug/net10.0-windows/`) and the executable name
33+
- **failure**: show the error messages clearly and suggest fixes
34+
4. Do NOT automatically launch the executable. Just say where it is.
35+
36+
## Notes
37+
38+
- Use `dotnet build` with paths relative to the repository root. Do NOT `cd` into directories.
39+
- If the build fails because the exe is locked by a running instance, kill it (`taskkill /F /PID <pid>`) and rebuild.
40+
- If a project path cannot be determined, run `git ls-files "*.csproj"` to list the real projects. Stale `bin/` and `obj/` folders are left behind at the old top-level `Dashboard/` and `Installer/` paths and are not projects.

.claude/skills/duckdb/SKILL.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
name: duckdb
3+
description: Query the Lite app's DuckDB database safely while the collector is running
4+
argument-hint: [SQL query or description of what to look up]
5+
disable-model-invocation: false
6+
---
7+
8+
# Query Lite's DuckDB Database
9+
10+
Safely query the PerformanceMonitor Lite DuckDB database using Python. This skill exists because DuckDB only allows one read-write connection at a time. When Lite is running (collecting data), it holds the write connection. External readers MUST connect in read-only mode.
11+
12+
## Database Location
13+
14+
Since the #1832 fix (data moved OUT of Velopack's install root, which Setup.exe deletes), the store lives at:
15+
```
16+
%LOCALAPPDATA%\PerformanceMonitorLite-Data\monitor.duckdb
17+
```
18+
Builds from BEFORE that fix (3.3.0 and earlier) keep it at the old path, and the file only moves when a fixed build first runs:
19+
```
20+
%LOCALAPPDATA%\PerformanceMonitorLite\monitor.duckdb
21+
```
22+
**Check the -Data path first; fall back to the old path if it does not exist.**
23+
24+
## How to Query (ALWAYS use this pattern)
25+
26+
Use Python with the `duckdb` module. **ALWAYS connect in read-only mode.**
27+
28+
```python
29+
python -c "
30+
import duckdb, os
31+
la = os.environ['LOCALAPPDATA']
32+
p = la + '/PerformanceMonitorLite-Data/monitor.duckdb'
33+
if not os.path.exists(p):
34+
p = la + '/PerformanceMonitorLite/monitor.duckdb'
35+
con = duckdb.connect(p, read_only=True)
36+
result = con.execute('YOUR SQL HERE').fetchall()
37+
for row in result:
38+
print(row)
39+
con.close()
40+
"
41+
```
42+
43+
## CRITICAL RULES
44+
45+
1. **ALWAYS use `read_only=True`** -- without this, the connection will be blocked by Lite's write lock and hang or fail
46+
2. **NEVER use `duckdb.connect()` without `read_only=True`** -- the default is read-write which WILL conflict with the running app
47+
3. **Use forward slashes** in the path (Python on Windows handles this fine)
48+
4. **Close the connection** when done -- don't leave read locks dangling
49+
5. **Use Python** -- duckdb 1.4.4 is installed
50+
51+
## Common Queries
52+
53+
List all tables:
54+
```sql
55+
SELECT table_name FROM information_schema.tables WHERE table_schema = 'main' ORDER BY table_name;
56+
```
57+
58+
List columns for a table:
59+
```sql
60+
SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'TABLE_NAME' ORDER BY ordinal_position;
61+
```
62+
63+
List all views:
64+
```sql
65+
SELECT table_name FROM information_schema.tables WHERE table_type = 'VIEW' ORDER BY table_name;
66+
```
67+
68+
Row counts:
69+
```sql
70+
SELECT table_name, estimated_size FROM duckdb_tables() ORDER BY estimated_size DESC;
71+
```
72+
73+
## DuckDB vs SQL Server Syntax Notes
74+
75+
- String concatenation: `||` (not `+`)
76+
- ILIKE for case-insensitive LIKE
77+
- `EPOCH_MS(timestamp_col)` to convert to epoch
78+
- `strftime('%Y-%m-%d %H:%M:%S', ts)` for formatting
79+
- No `TOP N` -- use `LIMIT N` instead
80+
- `EXCLUDE` clause: `SELECT * EXCLUDE (col1, col2) FROM table`
81+
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
name: maintenance
3+
description: Quarterly maintenance pass (every 1-3 months) — dependency/security audit, build health, and repo hygiene for PerformanceMonitor and PerformanceStudio
4+
argument-hint: [optional: deps | build | all]
5+
disable-model-invocation: false
6+
---
7+
8+
# Routine Maintenance Pass
9+
10+
A repeatable every-1-3-months health check for the .NET desktop + SQL-monitoring repos
11+
(PerformanceMonitor = WPF, PerformanceStudio = Avalonia; same dependency/build/release shape).
12+
`$ARGUMENTS` optionally scopes it (`deps`, `build`, or `all` — default `all`).
13+
14+
Work top to bottom. Do read-only scans first and report findings; make fixes on a feature
15+
branch/worktree (branch protection: never commit to `dev`/`main`), build + test, then PR to `dev`.
16+
Low-risk patch/minor bumps can go in one PR; majors and anything release-critical get their own.
17+
18+
## A. Dependencies & Security
19+
20+
> **Scope — scan every project, not just the solution.** A repo's `.sln` may not list every project. PerformanceStudio's `PlanViewer.sln` omits `server/PlanShare.csproj` and the SSMS VSIX (`PlanViewer.Ssms`, `PlanViewer.Ssms.Installer`), so the `dotnet list <Solution>.sln …` scans and the solution build all silently skip them. Run the checks against those projects too. The net472 VSIX is old-style, so `dotnet list` is unreliable on it — read its `<PackageReference>`s by hand (its `Microsoft.VSSDK.BuildTools` is intentionally held on the 17.x line; 18.x is un-restorable from nuget.org and targets VS 18, not VS 2022). Where the `.sln` covers all projects, the solution is enough.
21+
22+
1. **Outdated packages.** `dotnet list <Solution>.sln package --outdated`
23+
- Take low-risk **patch/minor** bumps (Microsoft.Extensions.*, Test.Sdk, etc.).
24+
- **Majors get their own effort** — especially the update framework (Velopack: bump the library AND the `vpk` CLI pin in the release workflow — `.github/workflows/release.yml` for PerformanceStudio — together; validate the in-app + Setup.exe update path) and anything release-critical.
25+
- **Engine-wrapped bindings** (e.g. DuckDB.NET) trail the native engine — bump when the binding catches up, and validate behavior (for DuckDB run `tools/CompactionRepro` re: the parquet-COPY memory-limit floor before changing the version).
26+
- After version edits, **if the repo uses lock files** (`packages.lock.json` — PerformanceMonitor does; PerformanceStudio does not), regenerate them: `dotnet restore <Solution>.sln --force-evaluate` (CI restores `--locked-mode`).
27+
28+
2. **Vulnerable packages (security).** `dotnet list <Solution>.sln package --vulnerable --include-transitive`
29+
- Must be **zero**. Any hit (incl. transitive) is urgent — bump or pin to a fixed version. This catches CVEs the `--outdated` check does not.
30+
- **Code-level pass, not just packages:** run the `security-review` skill/agent on the diff since the last maintenance pass. These apps have real attack surface beyond their dependencies — PerformanceStudio's MCP server opens a local network listener, both store DB credentials (Windows Credential Manager), and both parse untrusted input (e.g. execution-plan XML). Triage anything it flags.
31+
- **Calibrate severity to the deployment.** PerformanceStudio runs on a single-user personal laptop, and its MCP tools are strictly read-only (no arbitrary SQL, no writes/config changes). So loopback-bound / opt-in / local-IPC findings — the MCP listener, the named-pipe single-instance server — are **Low/informational here, not High**: there's no other local user or attacker to exploit them, and read-only tools can at most leak data they already return. Reserve High for *remotely reachable* vectors (e.g. a missing `Host`/`Origin` check that allows DNS rebinding) or credential disclosure. This calibration would change only if Studio shipped the MCP server enabled-by-default or ran on a shared/multi-user host. Don't re-raise the same local-IPC findings at High each pass.
32+
33+
3. **Deprecated packages.** `dotnet list <Solution>.sln package --deprecated` — replace anything abandoned.
34+
35+
4. **Framework / runtime currency.** Confirm the TFM is on a **supported, released** .NET (do NOT move to a preview). Take the latest servicing patch of the current major. WPF/Avalonia track the runtime/their own NuGet — check both.
36+
37+
5. **CI tool & action pins.** In `.github/workflows/*.yml`: confirm `uses:` actions are on current majors, and that any `dotnet tool install` is **version-pinned to match its library** (e.g. `vpk --version` must equal the Velopack PackageReference). Bump GitHub Actions that are behind / deprecated.
38+
39+
6. **Dependabot (optional — not a finding).** Two separate features: *security alerts* (passive CVE notifications that close the gap between manual `--vulnerable` passes — mild value) and *version-update PRs* (automated bump PRs — redundant and noisy once you do periodic manual sweeps). For PerformanceStudio, Erik relies on the manual passes; treat Dependabot as **optional and do not report it as a finding**. If alerts are ever wanted they're a one-toggle enable (repo Settings → Code security, no config file); the version-update PRs aren't wanted.
40+
41+
## B. Code & Build Health
42+
43+
7. **Zero-warning build.** Build the whole solution and capture warnings — the standard is **0**:
44+
```
45+
dotnet build <Solution>.sln -c Debug --nologo 2>&1 | Select-String ": warning "
46+
```
47+
- Kill the running app(s) first OR build in a worktree — a running Dashboard/Lite/Studio locks its `bin` DLLs (MSB3021). Note: an incremental no-op build emits no warnings; force a clean compile of any project you're checking.
48+
- Fix each warning honestly (don't add to `NoWarn` to silence). Remove dead code (e.g. an unused test seam → CS0649).
49+
50+
8. **NoWarn review.** Scan each csproj `<NoWarn>`: every suppressed rule should have a reason (these repos keep inline comments). Remove suppressions that no longer fire; don't let the list grow silently. Most existing CA suppressions are intentional high-count ones — leave those.
51+
52+
9. **Stale markers.** `grep -rE "\b(TODO|FIXME|HACK|XXX)\b" --include=*.cs` — resolve or file an issue; a `// TODO: restore to X` next to a non-X value may mean the comment is the leftover (ask before flipping).
53+
54+
10. **Git repo hygiene.**
55+
- **Line endings / `.gitattributes`.** If the repo has no `.gitattributes`, line endings drift (CRLF/LF mixed, `core.autocrlf=false`) and bulk edits balloon diffs. Add one and run a **dedicated** `git add --renormalize .` commit (its own PR, when no other work is in flight — it touches nearly every file).
56+
- **Stale branches & worktrees.** `git worktree list` — remove leftover worktrees (anything under `.claude/worktrees/` or other agent/isolation worktrees) with `git worktree remove`. Then `git fetch --prune` to drop stale remote-tracking refs, and audit: `git branch --merged origin/dev` (local branches already in dev — safe to delete) and `git branch -r` (remote branches from closed/merged PRs). Delete merged/dead branches; **keep intentionally-parked ones** (note which and why — e.g. a blocked-upgrade branch like `upgrade/avalonia-12`). For branches *you didn't create*, surface and confirm before deleting rather than assuming abandoned. Confirm open PRs are still wanted.
57+
58+
## C. App data & runtime hygiene (lighter)
59+
60+
11. **Retention / archive end-to-end.** Confirm the app's data retention/purge and (Lite) parquet archiving actually prune old data, and logs rotate. A new time-series table must be registered for retention/archive or it grows forever.
61+
62+
12. **Perf regression spot-check.** Re-run the UI-latency-under-load harness if available; watch known hot spots (e.g. the Lite Blocking tab render hitch). Quick collector-health pass.
63+
64+
## D. Release & platform currency (lighter)
65+
66+
13. **Release infra freshness.** Test servers online/patched; signing cert (SignPath) not near expiry; cloud creds (`az`/`aws`) valid; the `release-checklist` skill still accurate.
67+
- **Cross-platform publish smoke.** `dotnet publish` the desktop app for the non-Windows runtimes it ships (PerformanceStudio: `linux-x64`, `osx-arm64`/`osx-x64`) and confirm each still produces a runnable app. The Avalonia/SkiaSharp native pins are fragile — the Linux `SkiaSharp.NativeAssets.Linux` pin exists to guard GitHub issue #139 — and a Windows-only build won't catch a broken Linux/macOS runtime.
68+
69+
14. **SQL Server / cloud drift + bundled tools.** New SQL Server CU/version, new DMVs/columns, Azure SQL DB / RDS changes (cloud collector paths have a bug history); refresh bundled community procs (sp_WhoIsActive, sp_BlitzLock, sp_HealthParser, sp_HumanEventsBlockViewer).
70+
71+
## Output
72+
73+
Report per section: ✅ clean / ⚠️ findings (with the fix made or recommended). Group merged PRs and
74+
"parked" items (e.g. a major bump deferred) so the next pass knows where things stand.

0 commit comments

Comments
 (0)