Skip to content

fix: Use TypeScript private keyword instead of ES #private fields#127

Merged
benbrandt merged 3 commits intoagentclientprotocol:mainfrom
chazcb:fix/use-private-keyword-for-monorepo-compat
Apr 21, 2026
Merged

fix: Use TypeScript private keyword instead of ES #private fields#127
benbrandt merged 3 commits intoagentclientprotocol:mainfrom
chazcb:fix/use-private-keyword-for-monorepo-compat

Conversation

@chazcb
Copy link
Copy Markdown
Contributor

@chazcb chazcb commented Apr 20, 2026

Summary

  • Replaces ES #private fields with TypeScript's private keyword in all classes: AgentSideConnection, ClientSideConnection, TerminalHandle, and the internal Connection class
  • ES #private fields appear in .d.ts declarations and use nominal identity, causing type mismatches when multiple copies of the package exist (common in pnpm monorepos)
  • TypeScript's private keyword keeps these fields out of the declarations entirely, fixing the issue
  • Note: This trades runtime encapsulation for compile-time only. The fields become regular JS properties at runtime, but they are internal implementation details not intended for consumer use.

Fixes #126

Test plan

  • tsc builds successfully with no type errors
  • All 94 tests pass
  • .d.ts output no longer contains #private for exported classes

🤖 Generated with Claude Code

chazcb and others added 2 commits April 20, 2026 14:33
… in exported classes

ES private fields (`#field`) are included in `.d.ts` declarations and use
nominal identity, which causes type incompatibilities when multiple copies
of the package exist in a monorepo (e.g. pnpm installs). Switching to
TypeScript's `private` keyword keeps these fields out of the declarations
entirely, fixing the issue.

Fixes agentclientprotocol#126

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… keyword

For consistency with the exported classes, also converts the internal
Connection class from ES #private fields/methods to TypeScript private.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@benbrandt
Copy link
Copy Markdown
Member

benbrandt commented Apr 21, 2026

I think we only need to change the private members and not the methods if I understand the symptom correctly?

These are the only # in the .d.ts?

export declare class AgentSideConnection {
    #private;

export declare class TerminalHandle {
    #private;
 
export declare class ClientSideConnection implements Agent {
    #private;

declare class Connection {
    #private;

@chazcb
Copy link
Copy Markdown
Contributor Author

chazcb commented Apr 21, 2026

I think we only need to change the private members and not the methods if I understand the symptom correctly?

These are the only # in the .d.ts?

export declare class AgentSideConnection {
    #private;

export declare class TerminalHandle {
    #private;
 
export declare class ClientSideConnection implements Agent {
    #private;

declare class Connection {
    #private;

I was thinking we should go for consistency throughout, but agree we can just change the public interface. If you feel strongly about it I'll back out the changes to the internals

@benbrandt benbrandt enabled auto-merge (squash) April 21, 2026 14:42
@benbrandt benbrandt merged commit c6e6ee2 into agentclientprotocol:main Apr 21, 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.

Private class fields cause type incompatibility with duplicate package instances

2 participants