Three follow-ups to PR #24168 found during live E2E testing on TS/bash files:
1. typescript-language-server now installs the typescript SDK (tsserver)
alongside it. Without that sibling install, initialize() failed with
"Could not find a valid TypeScript installation" and the server was
marked broken — no diagnostics ever reached the agent. New extra_pkgs
field on INSTALL_RECIPES makes that explicit and reusable for future
peer-dep cases.
2. _check_lint now treats "linter command exists on PATH but cannot
actually run" as skipped instead of error. The motivating case is
npx tsc when typescript is not in node_modules — npx prints its
"This is not the tsc command you are looking for" banner and exits
non-zero, which previously blocked the LSP semantic tier (gated on
success or skipped). Pattern-matched per base command (npx,
rustfmt, go) so genuine lint errors still flow through normally.
3. hermes lsp status now surfaces a Backend warnings section when
bash-language-server is installed but shellcheck is missing. The
server itself spawns fine but bash-language-server delegates
diagnostics to shellcheck — without it on PATH the integration
looks alive but never reports any problems. Same warning is
logged once at server spawn time.
Validation:
- 12 new tests in tests/agent/lsp/test_install_and_lint_fixes.py:
* recipe carries typescript SDK
* _install_npm passes both pkg + extras to npm CLI
* backwards compat: recipes without extras still work
* _backend_warnings quiet when bash absent / both present
* _backend_warnings fires when bash installed without shellcheck
* status output includes the Backend warnings section
* _looks_like_linter_unusable catches the npx tsc banner
* real TS type errors not misclassified as unusable
* unfamiliar linters fall through normally
* _check_lint returns skipped on npx tsc unusable
* _check_lint returns error on real tsc type errors
- Full lsp + file_operations test suite: 245/245 pass
- Live E2E:
* try_install("typescript-language-server") installs both packages
into node_modules
* write_file(bad.ts, ...) returns lint=skipped + lsp_diagnostics
with two real TS errors (was lint=error, no lsp_diagnostics)
* hermes lsp status renders the shellcheck warning when bash is
installed but shellcheck is not on PATH