Skip to content

feat(sdk/typescript): add harness provider preflight - #1069

Merged
santoshkumarradha merged 3 commits into
Agent-Field:mainfrom
remote-controlled-man:codex/agentfield-685-ts-doctor
Sep 24, 2026
Merged

santoshkumarradha merged 3 commits into
Agent-Field:mainfrom
remote-controlled-man:codex/agentfield-685-ts-doctor

Conversation

@remote-controlled-man

Copy link
Copy Markdown
Contributor

Summary

Add an offline TypeScript harness-provider health API through harnessDoctor() and Agent.harnessDoctor(), with structured version, installation, auth-signal, and issue data for every supported provider. Provider execution now fails before launch with the actionable typed HarnessProviderUnavailable error, including when a CLI disappears between preflight and spawn.

This is the TypeScript follow-up to the Python implementation in #756. The Go SDK remains a separate follow-up under #685.

Design notes

  • HarnessProviderUnavailable.missingAuthEnv is part of the typed error contract for parity with the merged Python implementation (feat(harness): add Python provider preflight #756), but is intentionally never populated: the doctor's auth signal is advisory (auth: "unknown") because a CLI may hold a local login with no environment variable set, so no preflight path fails on missing auth configuration. The field keeps the error forward-compatible with a future opt-in strict-auth check without changing current behavior.
  • On Windows, the version probe executes resolved .cmd/.bat shims through cmd.exe /d /s /c because Node refuses to spawn batch files without a shell (CVE-2024-27980); POSIX probes execute the resolved path directly. A failed probe still marks the provider unusable — the batch routing removes a false negative for npm shim installs rather than weakening the health signal. Note the provider spawn path itself still launches the configured bare binary name (a pre-existing Windows shim gap this PR does not claim to fix; tracked as a follow-up).

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Docs only
  • Tests only
  • CI / tooling
  • Breaking change

Test plan

  • cd sdk/typescript && npm run lint
  • cd sdk/typescript && npm run build
  • cd sdk/typescript && npx vitest run --config vitest.config.ts tests/harness_doctor.test.ts tests/harness_cli.test.ts tests/harness_agent_wiring.test.ts (34 passed)
  • Affected doctor, CLI, Agent, factory, and provider suites (140 passed across 10 files)
  • Full configured suite excluding one unchanged Windows-only baseline assertion (1002 passed, 1 skipped across 89 passing files)
  • Full configured coverage with the same exclusion (91.68% statements, 82.55% branches, 94.42% functions, 93% lines)
  • Manual emitted-API offline check against the installed Codex CLI on Windows: harnessDoctor(['codex']) resolved codex.cmd, probed the real version codex-cli 0.153.4 through cmd.exe, and reported usable: true with no issues

On this Windows host, the unfiltered npm test result was 1002 passed and 1 failed (1003 total). The failure is the pre-existing path-separator assertion tests/harness_runner.test.ts > run with schema injects suffix and parses output, which expects / while Windows returns \\; neither that test nor src/harness/runner.ts is changed by this PR, and the failure reproduces in isolation. No paid provider/liveness calls were run.

Test coverage

  • I ran tests for the surface(s) I changed locally.
  • New code paths are covered by tests in this PR (no bare additions).
  • If I removed code, I updated coverage-baseline.json in this PR only if the removal caused a legitimate regression and I called it out in the summary above. (No baseline change was needed.)
  • The coverage gate check is green in CI before requesting review.

Checklist

Related issues / PRs

Part of #685.

Follows #756.

…inary

harnessDoctor passed the bare provider name to the version probe while
findExecutable had already resolved a PATHEXT-qualified path. On Windows
the bare name misses npm shims (ENOENT) and spawning a resolved .cmd/.bat
without a shell is rejected by Node (EINVAL, CVE-2024-27980), so shim-based
providers like codex always reported version_probe_failed and usable=false.

Probe the resolved absolute path instead, and route Windows batch shims
through cmd.exe /d /s /c with the outer-quote form so paths with spaces
survive. POSIX behavior is unchanged: the same file that findExecutable
verified is executed directly. The VersionProbe contract now documents
that command[0] is the resolved path.
Copilot AI lite review requested due to automatic review settings September 22, 2026 10:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@CLAassistant

CLAassistant commented Sep 22, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@santoshkumarradha santoshkumarradha left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The focused TypeScript tests, lint, build, and diff checks pass locally. I found one API-contract issue in the new doctor options that needs a small fix before this is ready.

Comment thread sdk/typescript/src/harness/availability.ts Outdated
@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Performance

SDK Memory Δ Latency Δ Tests Status
TS 474 B +35% 1.96 µs -2% ✓ ✗

⚠ Regression detected:

  • TypeScript memory: 350 B → 474 B (+35%)

@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

📊 Coverage gate

Thresholds from .coverage-gate.toml: per-surface ≥ 84%, aggregate ≥ 85%, max per-surface regression ≤ 1.0 pp, max aggregate regression ≤ 0.50 pp.

Surface Current Baseline Δ
control-plane 87.90% 87.40% ↑ +0.50 pp 🟡
sdk-go 93.20% 92.00% ↑ +1.20 pp 🟢
sdk-python 94.72% 93.73% ↑ +0.99 pp 🟢
sdk-typescript 91.83% 90.42% ↑ +1.41 pp 🟢
web-ui 84.77% 84.79% ↓ -0.02 pp 🟡
aggregate 85.92% 85.75% ↑ +0.17 pp 🟡

✅ Gate passed

No surface regressed past the allowed threshold and the aggregate stayed above the floor.

@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

📐 Patch coverage gate

Threshold: 80% on lines this PR touches vs origin/main (from .coverage-gate.toml:thresholds.min_patch).

Surface Touched lines Patch coverage Status
control-plane 0 — ➖ no changes
sdk-go 0 — ➖ no changes
sdk-python 0 — ➖ no changes
sdk-typescript 120 92.00% ✅
web-ui 0 — ➖ no changes

✅ Patch gate passed

Every surface whose lines were touched by this PR has patch coverage at or above the threshold.

…tion

harnessDoctor resolved binaries against process.env even when callers
supplied HarnessDoctorOptions.env, so a report could mix installation
state from the process environment with authentication state from the
custom one. Binary discovery (PATH lookup and Windows PATHEXT matching)
now uses the same env as the offline auth signal.

Addresses PR Agent-Field#1069 review feedback.
@remote-controlled-man

Copy link
Copy Markdown
Contributor Author

Fixed in 67b5bee: resolveBinary now receives the caller-supplied env (so PATH and PATHEXT both come from HarnessDoctorOptions.env), and the doctor uses one environment end to end. Added three focused tests, including a reference-identity assertion that the resolver receives options.env. Focused suite 17/17, affected harness suites 161/161, full core suite 1023/1024 (the single failure is the pre-existing Windows path-separator assertion in harness_runner.test.ts, unchanged from base).

@santoshkumarradha santoshkumarradha left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing the environment propagation. The custom PATH and PATHEXT coverage addresses the issue, and the focused tests, lint, build, TypeScript CI, CLA, and required coverage checks are all green.

@santoshkumarradha
santoshkumarradha added this pull request to the merge queue Sep 24, 2026
Merged via the queue into Agent-Field:main with commit 5b0bf9b Sep 24, 2026
19 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.

4 participants