Skip to content

Commit 1c2a98e

Browse files
committed
OX-02 P14: the real Visual Studio acceptance, and the live jobs in CI
- scripts/vs/prepare_vs_fixture.py: packs Owen.Build/Owen.TypedBuilder and creates a restored, never-built solution outside the checkout. - scripts/vs/owen-vs-acceptance.ps1: installs the VSIX into a dedicated root suffix with VSIXInstaller, opens the solution, and drives the IDE: unsaved edits via DTE, the Error List read with UI Automation, navigation by double-click, Owen's squiggles from the opt-in tagger trace; K1/K2/P9/K3, repeated-edit latency, UI-thread max, no save, no build. (Shape ADAPTED from Snipper's vs-smoke.ps1, MIT.) - ci.yml: owen-live (ubuntu+windows) and owen-visual-studio (windows, real VS). - The probe workflow is retired (runs 37163037704/37163398893/37163671022 recorded). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011ZFvhLx1fM9Gerg4dKsZcL
1 parent 44a25a2 commit 1c2a98e

6 files changed

Lines changed: 491 additions & 131 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3487,6 +3487,79 @@ jobs:
34873487
- name: The extension gate (pack, isolated consumer A-H, mutations M1-M7)
34883488
run: python scripts/owen_extension_gate.py
34893489

3490+
# OX-02 (docs/notes/owen-visual-studio-preregistration.md): live Owen diagnostics in the IDE.
3491+
# The extractor run in-process over an overlay is byte-identical to the command line; the
3492+
# `owen serve` service, as Owen.VisualStudio uses it, answers unsaved edits (K1-K8), agrees
3493+
# with `dotnet build` on saved sources (P10), stays inside its latency/memory budget, and its
3494+
# client half survives the service dying (K6). Both platforms: the VSIX host is Windows-only,
3495+
# the service is not.
3496+
owen-live:
3497+
name: Owen live service (in-process extractor, owen serve, build/live parity)
3498+
strategy:
3499+
fail-fast: false
3500+
matrix:
3501+
os: [ubuntu-latest, windows-latest]
3502+
runs-on: ${{ matrix.os }}
3503+
defaults:
3504+
run:
3505+
shell: bash
3506+
steps:
3507+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
3508+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
3509+
with:
3510+
python-version: "3.13"
3511+
- uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4
3512+
with:
3513+
dotnet-version: "8.0.x"
3514+
- uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 # master, 2026-07-10
3515+
with:
3516+
toolchain: stable
3517+
- name: The extractor as a library (E1-E4)
3518+
run: python tests/check_extractor_in_process.py
3519+
- name: The live gate (L0, S, K1-K8, P10, T, C, G)
3520+
run: python scripts/owen_live_gate.py
3521+
3522+
# OX-02 P14: the real Visual Studio run. The hosted image carries Visual Studio with the
3523+
# extension workload; the VSIX is built with its MSBuild, installed into a dedicated root
3524+
# suffix, and the IDE is driven (DTE for edits, UI Automation for the Error List, Owen's
3525+
# opt-in trace for the squiggles) on a solution that is restored and never built.
3526+
owen-visual-studio:
3527+
name: Owen.VisualStudio in a real Visual Studio (unsaved edit -> squiggle + Error List)
3528+
runs-on: windows-latest
3529+
timeout-minutes: 60
3530+
steps:
3531+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
3532+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
3533+
with:
3534+
python-version: "3.13"
3535+
- uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 # master, 2026-07-10
3536+
with:
3537+
toolchain: stable
3538+
- name: Build the Rust core
3539+
shell: bash
3540+
run: cargo build -p own-cli --release --manifest-path rust/Cargo.toml
3541+
- name: Prepare the solution (packed Owen.Build + Owen.TypedBuilder; restored, not built)
3542+
shell: bash
3543+
run: python scripts/vs/prepare_vs_fixture.py --out "$RUNNER_TEMP/vsfx" --rust-core "$PWD/rust/target/release/own-cli.exe"
3544+
- name: Build the VSIX
3545+
shell: powershell
3546+
run: |
3547+
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
3548+
$msbuild = & $vswhere -latest -products * -requires Microsoft.Component.MSBuild -find "MSBuild\**\Bin\MSBuild.exe" | Select-Object -First 1
3549+
& $msbuild frontend\roslyn\Owen.VisualStudio\Owen.VisualStudio.csproj /restore /p:Configuration=Release /p:DeployExtension=false /v:m
3550+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
3551+
Get-ChildItem -Recurse frontend\roslyn\Owen.VisualStudio -Filter *.vsix | ForEach-Object { $_.FullName }
3552+
- name: The acceptance in Visual Studio
3553+
shell: powershell
3554+
run: |
3555+
$vsix = (Get-ChildItem -Recurse frontend\roslyn\Owen.VisualStudio -Filter Owen.VisualStudio.vsix | Select-Object -First 1).FullName
3556+
scripts\vs\owen-vs-acceptance.ps1 -Vsix $vsix -Fixture "$env:RUNNER_TEMP\vsfx\fixture.json" -Out "$env:RUNNER_TEMP\vs-evidence"
3557+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
3558+
if: always()
3559+
with:
3560+
name: owen-visual-studio-evidence
3561+
path: ${{ runner.temp }}/vs-evidence/
3562+
34903563
# Alpha gate A (issue #202): the single delightful command, proven end-to-end
34913564
# on a clean runner — install -> check -> findings. Packaging only, no
34923565
# analysis-behaviour change: the underlying project stays OwnSharp.Cli

‎.github/workflows/owen-vs-probe.yml‎

Lines changed: 0 additions & 24 deletions
This file was deleted.

‎frontend/roslyn/Owen.VisualStudio/OwenLiveMonitor.cs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,7 @@ public OwenLiveMonitor(VisualStudioWorkspace workspace, ITableManagerProvider ta
5252
{
5353
_workspace = workspace;
5454
_errorList = new OwenErrorListSource(tables.GetTableManager(StandardTables.ErrorsTable));
55-
_engine = new LiveEngine(SnapshotAsync, AnalyzerFor, OwenLog.Write, TimeSpan.FromMilliseconds(250))
56-
{
57-
IgnoreVersions = Environment.GetEnvironmentVariable("OWEN_LIVE_MUTATION") == "M1",
58-
};
55+
_engine = new LiveEngine(SnapshotAsync, AnalyzerFor, OwenLog.Write, TimeSpan.FromMilliseconds(250));
5956
_engine.Published += OnPublished;
6057
_workspace.WorkspaceChanged += OnWorkspaceChanged;
6158
OwenLog.Write("Owen live analysis loaded");
@@ -116,7 +113,10 @@ private void OnWorkspaceChanged(object sender, WorkspaceChangeEventArgs e)
116113
{
117114
var request = LiveRequestFile.For(key);
118115
if (LiveRequestFile.TryRead(request) == null)
116+
{
117+
OwenTrace.Event("no-request", new { key, request });
119118
return null;
119+
}
120120
var project = _workspace.CurrentSolution.Projects.FirstOrDefault(
121121
p => string.Equals(p.FilePath, key, StringComparison.OrdinalIgnoreCase));
122122
if (project == null)

0 commit comments

Comments
 (0)