Skip to content

Stabilize CI verification on develop#69

Merged
pallyoung merged 176 commits into
mainfrom
develop
May 31, 2026
Merged

Stabilize CI verification on develop#69
pallyoung merged 176 commits into
mainfrom
develop

Conversation

@pallyoung
Copy link
Copy Markdown
Contributor

Summary

  • Align brittle web assertions with the current UI text and preview behavior.
  • Fix server-side pane layout and search glob type issues that blocked the build.
  • Keep Vue language server resolution working across path styles.

Test Plan

  • pnpm ci:verify

pallyoung added 30 commits May 24, 2026 00:52
…endency-installer-into-develop

# Conflicts:
#	packages/server/src/commands/index.ts
pallyoung added 28 commits May 29, 2026 02:20
…sing

The npm cmd-shim hard-codes `%~dp0\node.exe`, which only exists when
node was installed alongside the shim directory (fnm / nvs / nvm-windows).
Users on the official MSI, Chocolatey, or Scoop installer hit ENOENT
because `%APPDATA%\npm\node.exe` is not a real file, surfacing as
"Terminal spawn failed: File not found" when launching agent terminals.

Verify the parsed node path on disk and, if missing, fall back to a
`node` resolved via PATH (mirroring the shim's own IF EXIST / ELSE
dispatch). Only if neither succeeds do we hand the shim to `cmd.exe`.
Volar 3.x removed its embedded TypeScript service and now expects the LSP
client to relay `tsserver/request` notifications to a TypeScript Language
Server with `@vue/typescript-plugin` loaded. Previously vue installs failed
their verify step on Windows and, once installed, returned empty hovers
because no companion bridge existed. This wires up the full path:

- fix(server): make `checkCommandAvailable` fall back to `fs.existsSync`
  (with PATHEXT) for absolute paths. Windows `where.exe` parses `C:` as a
  `path:pattern` separator and rejects absolute paths, which had been
  failing every managed LSP install at the verify step.
- feat(server): spawn a `typescript-language-server` companion alongside
  Volar for vue sessions, configured with `@vue/typescript-plugin` so
  tsserver can answer `_vue:*` commands. Forward Volar's
  `tsserver/request` notifications via `workspace/executeCommand
  ("typescript.tsserverRequest", ...)` and unwrap the tsserver wire
  response (Volar expects `body`, not the `{seq,type,success,body}`
  wrapper).
- feat(server): fan hover / definition / references / typeDefinition /
  declaration out to both Volar and the companion, then merge results.
  Volar 3 deliberately ships without a TS-semantic hover plugin and
  relies on the editor to combine both ends.
- feat(server): expose `CODER_STUDIO_VUE_TSSERVER_BRIDGE=off` so the
  bridge can be disabled when triaging issues.
- feat(web): enrich the Monaco Vue grammar — embed `typescript`/
  `javascript` inside `<script>` (auto-detected via `lang=`), embed
  `css`/`scss`/`less` inside `<style>`, and recognise directive
  shorthand (`v-...`, `:...`, `@...`, `#...`) plus mustache interpolation
  in `<template>`.

Adds bridge + vue-spec unit tests plus an end-to-end Node probe under
`scripts/probe-vue-bridge.mjs` that exercises the live Volar + tsls
handshake (useful for future protocol regressions).
…nion lifecycle

The Vue LSP work fixed a Windows `where.exe` regression that affected
every managed LSP (python / go / rust / vue) at the verify step, but
no test actually exercised the real `checkCommandAvailable` against
an absolute path. Add coverage to lock that fix in and fill a few
adjacent gaps.

- add `lsp-tools/install-manager.integration.test.ts`: drives the
  install manager with the real `checkCommandAvailable` (not the
  mocked one used in the unit tests) for every managed serverKind,
  with a stubbed `runCommand` that writes a fake executable to the
  expected absolute path. Verifies the verify step succeeds when the
  file is on disk and fails cleanly when it isn't.
- add two Vue companion lifecycle tests in `lsp/session.test.ts`:
  primary exit must SIGTERM the companion, and explicit `stop()` must
  bring both children down so idle TTL cleanup doesn't leak processes.
- fix pre-existing Windows-flaky cases:
  - `install-manager.test.ts > returns missing_prerequisite ...` now
    pins `platform: "linux"` so `getManagedPrerequisites` doesn't
    silently add `python` as a fallback on win32.
  - `install-manager.test.ts > downloads rust-analyzer ...` computes
    `executablePath` with the platform-aware `.exe` suffix.
  - `lsp/document-store.test.ts`: gate three POSIX-only assertions
    (`/repo` style absolute paths, `symlinkSync` requiring
    elevated privileges) via `it.skip` on win32.

Suite is now green on Windows: 105 passed + 3 POSIX-only skipped.
A run of cross-language smoke tests (python, go, rust, vue) on a real
Windows host turned up three classes of failures that all looked like
"LSP unavailable" / "request timed out" but actually pointed at three
different gaps in our probe + timeout logic. Fix them together so the
Install / Retry flow tells the user something true.

- `resolveManagedPythonCommand` now actively probes `<candidate>
  --version` on win32. The zero-byte Microsoft Store app execution
  aliases at `%LOCALAPPDATA%\Microsoft\WindowsApps\python(3).exe` pass
  `where.exe` but silently exit when invoked; before this change the
  install would crash opaquely at `python -m venv ...`. Now the prereq
  check rejects the stub and the UI shows `missing_prerequisite:
  python3, python`.
- `LspToolManager.resolve` runs the same `--version` probe before
  accepting a system-PATH command on win32. This handles the
  symmetric case for rust-analyzer: `~/.cargo/bin/rust-analyzer.exe`
  is a rustup proxy that prints "Unknown binary 'rust-analyzer.exe'"
  to stderr and exits when the `rust-analyzer` rustup component is
  not installed. Before this fix the manager picked the broken proxy
  as the system source, never fell through to the managed download,
  and waited for an initialize response that never came.
- `LspSession` now distinguishes `initializeTimeoutMs` (default
  `requestTimeoutMs * 10`, raised to 60_000 in `server.ts`) from
  `requestTimeoutMs` (raised from 2_000 to 8_000). rust-analyzer's
  `initialize` returns within ~70ms but background workspace indexing
  can take 25s on a real repo; the single 2-second budget would kill
  the child mid-init on cold start and never recover. Hover /
  definition keep the short fail-fast budget so the editor's
  "Loading..." popup doesn't linger when the server is wedged.

Adds 11 unit tests covering the stub rejection paths and the
initialize-vs-request timeout split, plus a `lsp-test/` directory of
single-file fixtures (probe.{py,go,rs,vue}) for repeating the same
smoke check by hand. Files an issue at
`docs/issue/rust-analyzer-indexing-no-progress-feedback.md` describing
the remaining UX gap — rust-analyzer silently returns `null` for
hover/definition during its first ~25s of indexing, and we don't yet
surface its `$/progress` notifications in the LSP status notice.

Test sweep on Windows host: 16 server LSP test files, 118 passed + 3
POSIX-only skipped.
…ayout

- Replace single-column agent card grid with left-right two-panel layout
- Agent panel: compact button list with icon + name + arrow
- File Editor panel: dashed drop zone for drag-to-open files
- Center the component within the draft pane
- Add footer description line
- Collapse to stacked layout in narrow containers
- Remove unused kicker, description, and meta styles
- Add panel padding and vertical divider between Agent/File Editor panels
- Add horizontal divider rule for stacked narrow layout
- Remove CTA text from provider buttons (not in design)
- Lower responsive breakpoint from 36rem to 28rem so side-by-side layout persists longer
- Add border-left rule to base CSS block for consistency
@pallyoung pallyoung merged commit 4409663 into main May 31, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant