@qoder-ai/qoder-agent-sdk 1.0.14 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +128 -0
  2. package/dist/core/constants.d.ts +2 -2
  3. package/dist/core/deferred-transport.d.ts +23 -0
  4. package/dist/core/errors.d.ts +0 -8
  5. package/dist/core/process-transport.d.ts +3 -0
  6. package/dist/core/runtime-launch-options.d.ts +4 -1
  7. package/dist/core/transport.d.ts +2 -4
  8. package/dist/index.d.ts +10 -11
  9. package/dist/index.js +27 -22
  10. package/dist/mcp/sdk-mcp-server.d.ts +13 -1
  11. package/dist/mcp/tool-policy.d.ts +6 -0
  12. package/dist/protocol/agents.d.ts +0 -3
  13. package/dist/protocol/common.d.ts +0 -9
  14. package/dist/protocol/control.d.ts +41 -11
  15. package/dist/protocol/index.d.ts +4 -3
  16. package/dist/protocol/index.js +1 -1
  17. package/dist/protocol/mcp.d.ts +29 -0
  18. package/dist/protocol/messages.d.ts +34 -18
  19. package/dist/protocol/model-prompt-patches.d.ts +18 -0
  20. package/dist/protocol/version.d.ts +1 -1
  21. package/dist/query/query-runner.d.ts +14 -5
  22. package/dist/session/session-fork.d.ts +1 -27
  23. package/dist/session/session-import.d.ts +10 -0
  24. package/dist/session/session-manager.d.ts +3 -1
  25. package/dist/session/session-materializer.d.ts +15 -0
  26. package/dist/session/session-store.d.ts +45 -0
  27. package/dist/session/transcript-mirror.d.ts +25 -0
  28. package/dist/session/transcript-paths.d.ts +1 -2
  29. package/dist/types/common.d.ts +1 -1
  30. package/dist/types/control.d.ts +1 -1
  31. package/dist/types/hooks.d.ts +1 -1
  32. package/dist/types/index.d.ts +1 -2
  33. package/dist/types/mcp.d.ts +9 -3
  34. package/dist/types/messages.d.ts +21 -2
  35. package/dist/types/options.d.ts +48 -10
  36. package/dist/types/session.d.ts +17 -7
  37. package/dist/types/settings.d.ts +19 -232
  38. package/package.json +4 -14
  39. package/dist/bridge/bridge-api.d.ts +0 -14
  40. package/dist/bridge/bridge-session.d.ts +0 -6
  41. package/dist/bridge/ccr-client.d.ts +0 -72
  42. package/dist/bridge/index.d.ts +0 -9
  43. package/dist/bridge/index.js +0 -3
  44. package/dist/bridge/sse-transport.d.ts +0 -37
  45. package/dist/browser/browser-query.d.ts +0 -24
  46. package/dist/browser/index.d.ts +0 -14
  47. package/dist/browser/index.js +0 -9
  48. package/dist/browser/websocket-transport.d.ts +0 -40
  49. package/dist/direct-connect/direct-connect-transport.d.ts +0 -31
  50. package/dist/direct-connect/url-parser.d.ts +0 -14
  51. package/dist/embed/embed.d.ts +0 -2
  52. package/dist/embed/embed.js +0 -1
  53. package/dist/embed/extract-from-bunfs.d.ts +0 -5
  54. package/dist/types/bridge.d.ts +0 -62
  55. package/dist/types/browser.d.ts +0 -26
@@ -1,72 +0,0 @@
1
- /**
2
- * CCRClient — Manages the write path to the CCR server.
3
- * Handles event upload, heartbeat, state reporting, and epoch management.
4
- */
5
- export interface CCRClientOptions {
6
- sessionUrl: string;
7
- getAuthHeaders: () => Record<string, string>;
8
- heartbeatIntervalMs?: number;
9
- onEpochMismatch?: () => void;
10
- onAuthFailure?: () => void;
11
- }
12
- export declare class CCRClient {
13
- private sessionUrl;
14
- private getAuthHeaders;
15
- private heartbeatIntervalMs;
16
- private heartbeatTimer?;
17
- private writeQueue;
18
- private flushTimer?;
19
- private initialized;
20
- private workerEpoch?;
21
- private onEpochMismatch?;
22
- private onAuthFailure?;
23
- private consecutiveAuthFailures;
24
- private closed;
25
- constructor(options: CCRClientOptions);
26
- /**
27
- * Initialize the worker with the given epoch.
28
- */
29
- initialize(epoch: number): Promise<void>;
30
- isInitialized(): boolean;
31
- /**
32
- * Write an event to the CCR server.
33
- */
34
- writeEvent(payload: unknown): Promise<void>;
35
- /**
36
- * Schedule a flush of the write queue (coalescing with 100ms delay).
37
- */
38
- private scheduleFlush;
39
- /**
40
- * Flush all queued events to the server.
41
- */
42
- private flushWriteQueue;
43
- /**
44
- * Send heartbeat to keep the worker alive.
45
- */
46
- private sendHeartbeat;
47
- /**
48
- * Report worker state to the server.
49
- */
50
- reportState(state: 'idle' | 'running' | 'requires_action'): Promise<void>;
51
- /**
52
- * Report worker metadata.
53
- */
54
- reportMetadata(metadata: Record<string, unknown>): Promise<void>;
55
- /**
56
- * Report event delivery status.
57
- */
58
- reportDelivery(eventId: string, status: 'received' | 'processing' | 'processed'): Promise<void>;
59
- /**
60
- * PUT /worker to update worker state.
61
- */
62
- private putWorker;
63
- private handleResponseStatus;
64
- /**
65
- * Flush all pending writes.
66
- */
67
- flush(): Promise<void>;
68
- /**
69
- * Close the client and stop heartbeat.
70
- */
71
- close(): void;
72
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * Bridge module — remote session management.
3
- *
4
- * Provides functions for creating remote sessions and attaching to them
5
- * via the bridge API (SSE transport for reads, CCR client for writes).
6
- */
7
- export { attachBridgeSession } from './bridge-session.js';
8
- export { createCodeSession, fetchRemoteCredentials } from './bridge-api.js';
9
- export type { SessionState, BridgeSessionHandle, AttachBridgeSessionOptions, RemoteCredentials, } from '../types/bridge.js';
@@ -1,3 +0,0 @@
1
- function P(o){if(typeof o!="object"||o===null)return;let e=o,s=e.subtype;if(typeof s=="string")return s;let a=e.type;return typeof a=="string"?a:void 0}var C=class{url;sessionId;getAuthHeaders;lastSequenceNum;seenSequenceNums=new Set;abortController=null;state="idle";onData;onEvent;onClose;onConnect;constructor(e){this.url=e.url,this.sessionId=e.sessionId,this.getAuthHeaders=e.getAuthHeaders??(()=>({})),this.lastSequenceNum=e.initialSequenceNum??0}getLastSequenceNum(){return this.lastSequenceNum}isTerminating(){return this.state==="closing"||this.state==="closed"}async connect(){if(this.state!=="idle"&&this.state!=="reconnecting")return;this.state="connecting";let e=10,s=0;for(;s<e&&!this.isTerminating();)try{this.abortController=new AbortController;let a=new URL(this.url);this.lastSequenceNum>0&&a.searchParams.set("from_sequence_num",String(this.lastSequenceNum));let i={...this.getAuthHeaders(),Accept:"text/event-stream"};this.lastSequenceNum>0&&(i["Last-Event-ID"]=String(this.lastSequenceNum));let n=await fetch(a.toString(),{headers:i,signal:this.abortController.signal});if(!n.ok){if(n.status===401||n.status===403){this.onClose?.(n.status);return}if(n.status===409){this.onClose?.(4090);return}throw new Error(`SSE connection failed: ${n.status}`)}if(this.state="connected",this.onConnect?.(),s=0,await this.readStream(n.body),this.isTerminating())return;this.state="reconnecting"}catch(a){if(this.isTerminating()||a.name==="AbortError")return;if(s++,s>=e){this.onClose?.();return}let i=Math.min(1e3*Math.pow(2,s-1),3e4);await new Promise(n=>setTimeout(n,i)),this.state="reconnecting"}}async readStream(e){let s=e.getReader(),a=new TextDecoder,i="",n="",d="";try{for(;;){let{done:c,value:p}=await s.read();if(c)break;i+=a.decode(p,{stream:!0});let S=i.split(`
2
- `);i=S.pop()??"";for(let f of S)if(f.startsWith("event: "))n=f.substring(7).trim();else if(f.startsWith("data: "))d=f.substring(6);else if(f.startsWith("id: ")){let b=parseInt(f.substring(4),10);isNaN(b)||(this.lastSequenceNum=Math.max(this.lastSequenceNum,b))}else f===""&&(n&&d&&this.handleSSEEvent(n,d),n="",d="")}}finally{s.releaseLock()}}handleSSEEvent(e,s){if(e==="client_event")try{let a=JSON.parse(s),i=a.sequence_num;if(i!==void 0){if(this.seenSequenceNums.has(i))return;if(this.seenSequenceNums.add(i),this.lastSequenceNum=Math.max(this.lastSequenceNum,i),this.seenSequenceNums.size>1e3){let d=[...this.seenSequenceNums].sort((c,p)=>c-p).slice(0,500);for(let c of d)this.seenSequenceNums.delete(c)}}this.onEvent?.(a),a.payload?.type&&this.onData?.(JSON.stringify(a.payload)+`
3
- `)}catch{}}close(){this.state="closing",this.abortController?.abort(),this.state="closed"}};var _=class{sessionUrl;getAuthHeaders;heartbeatIntervalMs;heartbeatTimer;writeQueue=[];flushTimer;initialized=!1;workerEpoch;onEpochMismatch;onAuthFailure;consecutiveAuthFailures=0;closed=!1;constructor(e){this.sessionUrl=e.sessionUrl,this.getAuthHeaders=e.getAuthHeaders,this.heartbeatIntervalMs=e.heartbeatIntervalMs??2e4,this.onEpochMismatch=e.onEpochMismatch,this.onAuthFailure=e.onAuthFailure}async initialize(e){this.workerEpoch=e,await this.putWorker({worker_status:"idle",worker_epoch:e}),this.heartbeatTimer=setInterval(()=>{this.sendHeartbeat().catch(()=>{})},this.heartbeatIntervalMs),this.initialized=!0}isInitialized(){return this.initialized}async writeEvent(e){this.writeQueue.push(e),this.scheduleFlush()}scheduleFlush(){this.flushTimer||(this.flushTimer=setTimeout(()=>{this.flushTimer=void 0,this.flushWriteQueue().catch(()=>{})},100))}async flushWriteQueue(){if(this.writeQueue.length===0||this.closed)return;let e=this.writeQueue.splice(0);try{let s=await fetch(`${this.sessionUrl}/worker/events`,{method:"POST",headers:{...this.getAuthHeaders(),"Content-Type":"application/json"},body:JSON.stringify({events:e})});this.handleResponseStatus(s.status)}catch{this.writeQueue.unshift(...e)}}async sendHeartbeat(){if(!this.closed)try{let e=await fetch(`${this.sessionUrl}/worker/heartbeat`,{method:"POST",headers:{...this.getAuthHeaders()}});this.handleResponseStatus(e.status),e.ok&&(this.consecutiveAuthFailures=0)}catch{}}async reportState(e){await this.putWorker({worker_status:e})}async reportMetadata(e){await this.putWorker({external_metadata:e})}async reportDelivery(e,s){if(!this.closed)try{await fetch(`${this.sessionUrl}/worker/events/${e}/delivery`,{method:"POST",headers:{...this.getAuthHeaders(),"Content-Type":"application/json"},body:JSON.stringify({status:s})})}catch{}}async putWorker(e){let s=await fetch(`${this.sessionUrl}/worker`,{method:"PUT",headers:{...this.getAuthHeaders(),"Content-Type":"application/json"},body:JSON.stringify(e)});this.handleResponseStatus(s.status)}handleResponseStatus(e){e===409&&this.onEpochMismatch?.(),(e===401||e===403)&&(this.consecutiveAuthFailures++,this.consecutiveAuthFailures>=10&&this.onAuthFailure?.())}async flush(){this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=void 0),await this.flushWriteQueue()}close(){this.closed=!0,this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=void 0),this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=void 0)}};async function H(o){let{sessionId:e,ingressToken:s,apiBaseUrl:a,epoch:i,initialSequenceNum:n=0,heartbeatIntervalMs:d=2e4,outboundOnly:c=!1,onInboundMessage:p,onPermissionResponse:S,canUseToolPreFilter:f,onPermissionResolved:b,onInterrupt:K,onSetModel:A,onSetMaxThinkingTokens:N,onSetPermissionMode:x,onClose:q}=o,k=`${a}/v1/code/sessions/${e}`,T=()=>({Authorization:`Bearer ${s}`}),E=new Set,I=new Set,v=new Map,y=new C({url:`${k}/worker/events/stream`,sessionId:e,getAuthHeaders:T,initialSequenceNum:n}),u=new _({sessionUrl:k,getAuthHeaders:T,heartbeatIntervalMs:d,onEpochMismatch:()=>q?.(4090),onAuthFailure:()=>q?.(401)});y.onData=t=>{try{let l=JSON.parse(t.trim());$(l,E,I,p,h=>{S?.(h),j(h)},M)}catch{}},y.onEvent=t=>{u.reportDelivery(t.event_id,"received").catch(()=>{})},y.onClose=t=>{q?.(t)};function M(t){let l=t.request,h=P(l);if(h==="interrupt"){K?.();let r={type:"control_response",response:{subtype:"success",request_id:t.request_id}};u.writeEvent(r).catch(()=>{})}else if(h==="set_model"){let r=l.model;A?.(r);let m={type:"control_response",response:{subtype:"success",request_id:t.request_id}};u.writeEvent(m).catch(()=>{})}else if(h==="set_max_thinking_tokens"){let r=l.tokens??null;N?.(r);let m={type:"control_response",response:{subtype:"success",request_id:t.request_id}};u.writeEvent(m).catch(()=>{})}else if(h==="set_permission_mode"){let r=l.mode,m=x?.(r),w=m&&!m.ok?{type:"control_response",response:{subtype:"error",request_id:t.request_id,error:m.error}}:{type:"control_response",response:{subtype:"success",request_id:t.request_id}};u.writeEvent(w).catch(()=>{})}else if(h==="can_use_tool"){let r=l,m=r.tool_name,w=r.input??{};if(v.set(t.request_id,m),!f)return;let O=new AbortController;Promise.resolve(f(m,w,{signal:O.signal,suggestions:r.permission_suggestions,blockedPath:r.blocked_path,decisionReason:r.decision_reason,title:r.title,displayName:r.display_name,description:r.description,toolUseID:r.tool_use_id,agentID:r.agent_id})).then(g=>{if(g===void 0)return;let R=g.behavior==="allow"?{...g,updatedInput:g.updatedInput??w,toolUseID:r.tool_use_id}:{...g,toolUseID:r.tool_use_id},U={type:"control_response",response:{subtype:"success",request_id:t.request_id,response:R}};v.delete(t.request_id),b?.(m,R),u.writeEvent(U).catch(()=>{})}).catch(g=>{let R={type:"control_response",response:{subtype:"error",request_id:t.request_id,error:g instanceof Error?g.message:String(g)}};v.delete(t.request_id),u.writeEvent(R).catch(()=>{})})}}function j(t){let l=t.response.request_id,h=v.get(l);if(!h||t.response.subtype!=="success")return;let r=t.response.response;!r||typeof r!="object"||!("behavior"in r)||(v.delete(l),b?.(h,r))}let D=i;if(D===void 0){let t=await fetch(`${k}/worker/register`,{method:"POST",headers:{...T()}});if(!t.ok)throw new Error(`Worker registration failed: ${t.status}`);D=(await t.json()).epoch}return await u.initialize(D),c||y.connect().catch(()=>{}),{get sessionId(){return e},getSequenceNum(){return y.getLastSequenceNum()},isConnected(){return u.isInitialized()},write(t){"uuid"in t&&t.uuid&&E.add(t.uuid),u.writeEvent(t).catch(()=>{})},sendResult(){u.writeEvent({type:"result_boundary"}).catch(()=>{})},sendControlRequest(t){u.writeEvent(t).catch(()=>{})},sendControlResponse(t){u.writeEvent(t).catch(()=>{})},sendControlCancelRequest(t){u.writeEvent({type:"control_cancel_request",request_id:t}).catch(()=>{})},async reconnectTransport(t){y.close(),u.close()},reportState(t){u.reportState(t).catch(()=>{})},reportMetadata(t){u.reportMetadata(t).catch(()=>{})},reportDelivery(t,l){u.reportDelivery(t,l).catch(()=>{})},async flush(){await u.flush()},close(){v.clear(),y.close(),u.close()}}}function $(o,e,s,a,i,n){if(o.type==="control_response"){i?.(o);return}if(o.type==="control_request"){n?.(o);return}o.uuid&&e.has(o.uuid)||o.uuid&&s.has(o.uuid)||(o.uuid&&s.add(o.uuid),o.type==="user"&&a?.(o))}async function F(o,e,s,a,i){try{let n=new AbortController,d=setTimeout(()=>n.abort(),a),c={title:s,bridge:{}};i?.length&&(c.tags=i);let p=await fetch(`${o}/v1/code/sessions`,{method:"POST",headers:{"x-api-key":e,"Content-Type":"application/json"},body:JSON.stringify(c),signal:n.signal});return clearTimeout(d),p.ok?(await p.json()).id??null:null}catch{return null}}async function B(o,e,s,a,i){try{let n=new AbortController,d=setTimeout(()=>n.abort(),a),c={"x-api-key":s,"Content-Type":"application/json"};i&&(c["X-Trusted-Device-Token"]=i);let p=await fetch(`${e}/v1/code/sessions/${o}/bridge`,{method:"POST",headers:c,body:JSON.stringify({}),signal:n.signal});return clearTimeout(d),p.ok?await p.json():null}catch{return null}}export{H as attachBridgeSession,F as createCodeSession,B as fetchRemoteCredentials};
@@ -1,37 +0,0 @@
1
- /**
2
- * SSETransport — Reads server-sent events from the CCR worker endpoint.
3
- *
4
- * Uses native fetch + ReadableStream to connect to the SSE endpoint.
5
- * Handles automatic reconnection with exponential backoff.
6
- * Tracks sequence numbers for resumable connections.
7
- */
8
- export interface SSETransportOptions {
9
- url: string;
10
- sessionId: string;
11
- getAuthHeaders?: () => Record<string, string>;
12
- initialSequenceNum?: number;
13
- }
14
- export declare class SSETransport {
15
- private url;
16
- private sessionId;
17
- private getAuthHeaders;
18
- private lastSequenceNum;
19
- private seenSequenceNums;
20
- private abortController;
21
- private state;
22
- onData?: (line: string) => void;
23
- onEvent?: (event: {
24
- event_id: string;
25
- sequence_num: number;
26
- payload: unknown;
27
- }) => void;
28
- onClose?: (code?: number) => void;
29
- onConnect?: () => void;
30
- constructor(options: SSETransportOptions);
31
- getLastSequenceNum(): number;
32
- private isTerminating;
33
- connect(): Promise<void>;
34
- private readStream;
35
- private handleSSEEvent;
36
- close(): void;
37
- }
@@ -1,24 +0,0 @@
1
- import { type WebSocketTransportOptions } from './websocket-transport.js';
2
- import type { SDKUserMessage } from '../types/messages.js';
3
- import type { CanUseTool } from '../types/permissions.js';
4
- import type { HookEvent, HookCallbackMatcher } from '../types/hooks.js';
5
- import type { McpServerConfig } from '../types/mcp.js';
6
- import type { Query } from '../types/options.js';
7
- export type BrowserQueryOptions = {
8
- prompt: AsyncIterable<SDKUserMessage>;
9
- websocket: WebSocketTransportOptions & {
10
- url: string;
11
- };
12
- abortController?: AbortController;
13
- canUseTool?: CanUseTool;
14
- hooks?: Partial<Record<HookEvent, HookCallbackMatcher[]>>;
15
- mcpServers?: Record<string, McpServerConfig>;
16
- jsonSchema?: Record<string, unknown>;
17
- };
18
- /**
19
- * Create a Qoder query using WebSocket transport in the browser.
20
- *
21
- * Only SDK MCP servers (in-process) are supported in the browser.
22
- * Process-based MCP servers require Node.js and are not available.
23
- */
24
- export declare function query(options: BrowserQueryOptions): Query;
@@ -1,14 +0,0 @@
1
- /**
2
- * Browser module — WebSocket-based Qoder query for browser environments.
3
- *
4
- * Re-exports commonly needed types from the main SDK alongside
5
- * browser-specific types and the browser query function.
6
- */
7
- export type { CanUseTool } from '../types/permissions.js';
8
- export type { HookCallbackMatcher, HookEvent } from '../types/hooks.js';
9
- export type { McpSdkServerConfigWithInstance, McpServerConfig } from '../types/mcp.js';
10
- export type { Query } from '../types/options.js';
11
- export type { SDKAssistantMessage, SDKMessage, SDKResultMessage, SDKSystemMessage, SDKSystemInitMessage, SDKSystemMessageBySubtype, SDKSystemMessageSubtype, SDKUserMessage, } from '../types/messages.js';
12
- export { createSdkMcpServer, tool } from '../mcp/sdk-mcp-server.js';
13
- export type { OAuthCredential, AuthMessage, WebSocketOptions, BrowserQueryOptions, } from '../types/browser.js';
14
- export { query } from './browser-query.js';
@@ -1,9 +0,0 @@
1
- import{McpServer as G}from"@modelcontextprotocol/sdk/server/mcp.js";function Z(r){if(!r.name||typeof r.name!="string"||r.name.trim()==="")throw new Error("[createSdkMcpServer] Server name must be a non-empty string.");let e=new G({name:r.name,version:r.version??"1.0.0"},{capabilities:{tools:r.tools&&r.tools.length>0?{}:void 0}});if(r.tools&&r.tools.length>0)for(let t of r.tools){if(!t.name||typeof t.name!="string"||t.name.trim()==="")throw new Error(`[createSdkMcpServer] Tool name must be a non-empty string in server "${r.name}".`);if(!t.description||typeof t.description!="string")throw new Error(`[createSdkMcpServer] Tool "${t.name}" must have a non-empty description string.`);try{e.registerTool(t.name,{description:t.description,inputSchema:t.inputSchema,...t.annotations?{annotations:t.annotations}:{}},t.handler)}catch(s){throw s instanceof Error&&s.message.includes("already registered")?new Error(`[createSdkMcpServer] Duplicate tool name "${t.name}" in server "${r.name}". Each tool name must be unique within a server.`):s}}return{type:"sdk",name:r.name,instance:e}}function Y(r,e,t,s,o){return{name:r,description:e,inputSchema:t,handler:s,annotations:o?.annotations}}var S=class{queue=[];readResolve;readReject;isDone=!1;errorValue;started=!1;returnCallback;constructor(e){this.returnCallback=e}[Symbol.asyncIterator](){if(this.started)throw new Error("Stream can only be iterated once");return this.started=!0,this}async next(){if(this.queue.length>0)return{done:!1,value:this.queue.shift()};if(this.isDone)return{done:!0,value:void 0};if(this.errorValue!==void 0)throw this.errorValue;return new Promise((e,t)=>{this.readResolve=e,this.readReject=t})}enqueue(e){if(!this.isDone)if(this.readResolve){let t=this.readResolve;this.readResolve=void 0,this.readReject=void 0,t({done:!1,value:e})}else this.queue.push(e)}done(){if(this.isDone=!0,this.readResolve){let e=this.readResolve;this.readResolve=void 0,this.readReject=void 0,e({done:!0,value:void 0})}}error(e){if(this.errorValue=e,this.readReject){let t=this.readReject;this.readResolve=void 0,this.readReject=void 0,t(e)}}async return(){return this.isDone=!0,this.returnCallback?.(),{done:!0,value:void 0}}async throw(e){return this.error(e),{done:!0,value:void 0}}};var X=3e4,ee=3e4,w=class{options;ws=null;ready=!1;readyResolve;readyReject;readyPromise;messages=new S;keepAliveTimer;exitError;initialized=!1;constructor(e){this.options=e,this.readyPromise=new Promise((t,s)=>{this.readyResolve=t,this.readyReject=s}),this.initialize()}initialize(){return this.initialized||(this.initialized=!0,this.open()),this.readyPromise}open(){let e=new globalThis.WebSocket(this.options.url);this.ws=e;let t=setTimeout(()=>{if(!this.ready){let s=new Error("WebSocket connection timeout");this.readyReject?.(s),e.close()}},ee);e.onopen=()=>{clearTimeout(t),this.ready=!0,this.readyResolve?.(),this.options.authMessage&&e.send(JSON.stringify(this.options.authMessage)+`
2
- `),this.keepAliveTimer=setInterval(()=>{e.readyState===WebSocket.OPEN&&e.send(JSON.stringify({type:"keep_alive"})+`
3
- `)},X)},e.onmessage=s=>{let o=String(s.data).split(`
4
- `);for(let n of o)if(n.trim())try{let i=JSON.parse(n);this.messages.enqueue(i)}catch{}},e.onerror=()=>{let s=new Error("WebSocket connection error");this.exitError=s,this.readyReject?.(s),this.messages.done()},e.onclose=s=>{this.ready=!1,this.keepAliveTimer&&(clearInterval(this.keepAliveTimer),this.keepAliveTimer=void 0),s.code!==1e3&&s.code!==1001&&(this.exitError=new Error(`WebSocket closed abnormally: ${s.code} ${s.reason}`)),this.messages.done()},this.options.abortController?.signal.addEventListener("abort",()=>{this.close()})}async write(e){this.ready||await this.readyPromise,this.ws?.send(e)}close(){this.keepAliveTimer&&(clearInterval(this.keepAliveTimer),this.keepAliveTimer=void 0),this.ws&&(this.ws.close(1e3),this.ws=null),this.messages.done()}isReady(){return this.ready}async*readMessages(){if(yield*this.messages,this.exitError)throw this.exitError}endInput(){}};var R=class extends Error{constructor(e="Operation was aborted"){super(e),this.name="AbortError"}};var M=class extends Error{timeoutMs;constructor(e){super(`resolveModel did not return within ${e}ms. Increase resolveModelTimeoutMs or ensure the callback resolves faster.`),this.name="ModelPolicyTimeoutError",this.timeoutMs=e}},C=class extends Error{cliProtocolVersion;sdkProtocolVersion;constructor(e,t){super(`Wire protocol major mismatch: CLI announced "${e}" but this SDK was built for "${t}". Upgrade either qodercli or @qoder-ai/qoder-agent-sdk so the major versions align.`),this.name="ProtocolVersionMismatchError",this.cliProtocolVersion=e,this.sdkProtocolVersion=t}};var x="1.0.0";function E(r,e,t,s){return new Promise((o,n)=>{if(!("id"in e&&e.id!==null)){try{t.onmessage?.(e)}catch(c){n(c);return}o({jsonrpc:"2.0"});return}let a=`${r}:${e.id}`;s.set(a,{resolve:o,reject:n}),t.onmessage?t.onmessage(e):(s.delete(a),n(new Error(`No message handler registered for MCP server "${r}"`)))})}function K(r,e,t){if("id"in e&&e.id!==null){let s=`${r}:${e.id}`,o=t.get(s);if(o)return o.resolve(e),t.delete(s),!0}return!1}function A(r,e,t){let s=0,o=`${r}:`,n=Array.from(t.entries());for(let i of n){let[a,c]=i;a.startsWith(o)&&(c.reject(e),t.delete(a),s++)}return s}function j(){return Math.random().toString(36).substring(2,15)}function O(r,e){let t="type"in e&&!("subtype"in e)?{...e,subtype:e.type}:e;return{type:"control_request",request_id:r,request:t}}function U(r,e){return{type:"control_response",response:{subtype:"success",request_id:r,response:e}}}function $(r,e,t){return{type:"control_response",response:{subtype:"error",request_id:r,error:e,...t?{code:t}:{}}}}function N(r){return typeof r=="object"&&r!==null&&r.type==="control_response"}function Q(r){return typeof r=="object"&&r!==null&&r.type==="control_request"}function z(r){return typeof r=="object"&&r!==null&&(r.type==="control_cancel_request"||r.type==="control_cancel")}function v(r){if(typeof r!="object"||r===null)return;let e=r,t=e.subtype;if(typeof t=="string")return t;let s=e.type;return typeof s=="string"?s:void 0}function J(r){if(typeof r!="object"||r===null)return!1;let e=r.type;return e==="keepalive"||e==="keep_alive"}function H(r){return typeof r=="object"&&r!==null&&r.type==="streamlined_text"}function F(r){return typeof r=="object"&&r!==null&&r.type==="streamlined_tool_use_summary"}function B(r){return typeof r=="object"&&r!==null&&r.type==="post_turn_summary"}function L(r){return typeof r=="object"&&r!==null&&r.type==="result"}var I=class r{static INITIALIZE_TIMEOUT_MS=12e4;transport;inputStream;pendingRequests=new Map;pendingInboundRequests=new Map;hooks;hookCallbacks=new Map;nextHookCallbackId=0;sdkMcpServers;sdkMcpTransports;pendingMcpResponses;isSingleTurn;canUseTool;abortController;jsonSchema;initConfig;onElicitation;onAuthExpired;fetchJobToken;diagnostics;controlRequestTimeoutMs;resolveModel;resolveModelTimeoutMs;initResponse;initializationPromise;resultMessage;readLoopPromise;closed=!1;authExpiredFired=!1;protocolHandshakeValidated=!1;firstResultReceived=!1;firstResultReceivedResolve;constructor(e,t,s,o,n,i,a,c,u,p,d,l,g,h,f,m,T){if(this.transport=e,this.isSingleTurn=t,this.canUseTool=s,this.hooks=o??{},this.abortController=n,this.sdkMcpServers=i??new Map,this.sdkMcpTransports=g??new Map,this.pendingMcpResponses=h??new Map,this.jsonSchema=a,this.initConfig=c??{},this.onElicitation=u,this.onAuthExpired=d,this.fetchJobToken=f,this.diagnostics=p,this.controlRequestTimeoutMs=l??6e4,this.resolveModel=m,this.resolveModelTimeoutMs=T??500,this.inputStream=new S(()=>{this.close().catch(()=>{})}),this.readLoopPromise=this.readMessages().catch(b=>{this.inputStream.error(b)}),this.initializationPromise=this.performInitialize(),this.initializationPromise.catch(()=>{}),this.abortController){let b=this.abortController.signal;b.aborted?this.close().catch(()=>{}):b.addEventListener("abort",()=>{this.close().catch(()=>{})},{once:!0})}}getRecord(e){return typeof e=="object"&&e!==null?e:void 0}normalizeLogPreview(e){let s=e.replace(/\s+/g," ").trim();return s.length>200?`${s.slice(0,200)}...`:s}extractMessagePreview(e){if(typeof e=="string")return this.normalizeLogPreview(e);if(Array.isArray(e)){for(let i of e){let a=this.extractMessagePreview(i);if(a)return a}return""}let t=this.getRecord(e);if(!t)return"";let s=t.text;if(typeof s=="string")return this.normalizeLogPreview(s);let o=this.extractMessagePreview(t.content);if(o)return o;let n=this.getRecord(t.message);return n?this.extractMessagePreview(n):""}getMessagePreviewSuffix(e){let t=this.extractMessagePreview(e);return t?` preview=${JSON.stringify(t)}`:""}getMessageType(e){let s=this.getRecord(e)?.type;return typeof s=="string"&&s?s:"unknown"}getMessageSubtype(e){let s=this.getRecord(e)?.subtype;return typeof s=="string"&&s?s:"none"}getMessageUuid(e){let s=this.getRecord(e)?.uuid;return typeof s=="string"&&s?s:"none"}recordInboundSessionMessage(e){this.diagnostics?.record(`[QueryRunner] inbound session_message received type=${this.getMessageType(e)} subtype=${this.getMessageSubtype(e)} uuid=${this.getMessageUuid(e)}${this.getMessagePreviewSuffix(e)}`)}recordOutboundSessionMessage(e){let t=this.getRecord(e)?.message,o=this.getRecord(t)?.content,n=Array.isArray(o)?o.length:0;this.diagnostics?.record(`[QueryRunner] outbound session_message sent type=${this.getMessageType(e)} uuid=${this.getMessageUuid(e)} content_blocks=${n}${this.getMessagePreviewSuffix(e)}`)}[Symbol.asyncIterator](){return this}async next(){return this.inputStream.next()}async return(){return await this.close(),{done:!0,value:void 0}}async throw(e){return await this.inputStream.throw(e),{done:!0,value:void 0}}async readMessages(){let e;try{for await(let t of this.transport.readMessages()){if(this.closed)break;if(N(t)){this.handleControlResponse(t);continue}if(Q(t)){this.handleControlRequest(t).catch(o=>{this.diagnostics?.record("[QueryRunner] Error handling control request:",o)});continue}if(z(t)){this.handleControlCancelRequest(t);continue}if(J(t)||H(t)||F(t)||B(t))continue;if(L(t)){let o=t;this.recordInboundSessionMessage(o),this.resultMessage=o,this.firstResultReceived=!0,this.firstResultReceivedResolve?.(),this.firstResultReceivedResolve=void 0,this.inputStream.enqueue(o),this.isSingleTurn&&this.transport.endInput();continue}let s=t;if(this.recordInboundSessionMessage(s),s.type==="system"&&s.subtype==="init")try{this.validateProtocolHandshake(s)}catch(o){throw this.inputStream.error(o),o}if(this.onAuthExpired&&!this.authExpiredFired){let o=!1;(s.type==="auth_status"&&s.error||s.type==="assistant"&&s.error==="authentication_failed")&&(o=!0),o&&(this.authExpiredFired=!0,Promise.resolve(this.onAuthExpired()).catch(i=>{this.diagnostics?.record("[QueryRunner] onAuthExpired callback threw:",i)}))}this.inputStream.enqueue(s)}}catch(t){e=t}finally{let t=e instanceof Error?e:new Error("Transport closed");this.firstResultReceivedResolve?.(),this.firstResultReceivedResolve=void 0;for(let[,s]of this.pendingRequests)s.reject(t);this.pendingRequests.clear(),e!==void 0?this.inputStream.error(e):this.inputStream.done()}}async request(e,t){let s=j(),o=O(s,e),n=t?.timeoutMs??this.controlRequestTimeoutMs,i=v(o.request)??"unknown",a=Date.now();return new Promise((c,u)=>{let p=null,d=()=>{p&&(clearTimeout(p),p=null)};this.pendingRequests.set(s,{resolve:l=>{d(),this.diagnostics?.record(`[QueryRunner] control_response received request_id=${s} subtype=${i} status=success duration_ms=${Date.now()-a}`),c(l)},reject:l=>{d(),this.diagnostics?.record(`[QueryRunner] control_response received request_id=${s} subtype=${i} status=error duration_ms=${Date.now()-a}`,l),u(l)}}),n>0&&Number.isFinite(n)&&(p=setTimeout(()=>{if(this.pendingRequests.has(s)){this.pendingRequests.delete(s),this.diagnostics?.record(`[QueryRunner] control_request timed out request_id=${s} subtype=${i} timeout_ms=${n}`);try{this.transport.write(JSON.stringify({type:"control_cancel_request",request_id:s})+`
5
- `)}catch(l){this.diagnostics?.record("[QueryRunner] Failed to send control_cancel_request on timeout:",l)}u(new Error(`Control request "${v(o.request)??"unknown"}" timed out after ${n}ms`))}},n));try{this.diagnostics?.record(`[QueryRunner] control_request sending request_id=${s} subtype=${i} timeout_ms=${n}`),this.transport.write(JSON.stringify(o)+`
6
- `),this.diagnostics?.record(`[QueryRunner] control_request sent request_id=${s} subtype=${i}`)}catch(l){d(),this.pendingRequests.delete(s),this.diagnostics?.record(`[QueryRunner] control_request send failed request_id=${s} subtype=${i}`,l),u(l)}})}handleControlResponse(e){let t=e.response,s=t.request_id,o=this.pendingRequests.get(s);if(!o){this.diagnostics?.record(`[QueryRunner] unmatched control_response received request_id=${s} status=${t.subtype}`);return}if(this.pendingRequests.delete(s),t.subtype==="success")o.resolve(t.response);else{let n=new Error(t.error);t.code&&(n.code=t.code),o.reject(n),this.processPendingPermissionRequests(t.pending_permission_requests)}}processPendingPermissionRequests(e){if(e)for(let t of e)v(t.request)==="can_use_tool"&&this.handleControlRequest(t).catch(s=>{this.diagnostics?.record("[QueryRunner] Error handling pending permission request:",s)})}async handleControlRequest(e){let t=e.request_id,s=v(e.request)??"unknown",o=Date.now(),n=new AbortController;this.pendingInboundRequests.set(t,{abortController:n}),this.diagnostics?.record(`[QueryRunner] inbound control_request received request_id=${t} subtype=${s}`);try{let i=await this.awaitAbortable(this.processControlRequest(e,n.signal),n.signal);if(!n.signal.aborted){let a=U(t,i);this.transport.write(JSON.stringify(a)+`
7
- `),this.diagnostics?.record(`[QueryRunner] inbound control_response sent request_id=${t} subtype=${s} status=success duration_ms=${Date.now()-o}`)}}catch(i){if(!n.signal.aborted){let{error:a,code:c}=oe(i),u=$(t,a,c);this.transport.write(JSON.stringify(u)+`
8
- `),this.diagnostics?.record(`[QueryRunner] inbound control_response sent request_id=${t} subtype=${s} status=error duration_ms=${Date.now()-o}`,i)}}finally{this.pendingInboundRequests.delete(t)}}handleControlCancelRequest(e){let t=this.pendingInboundRequests.get(e.request_id);t&&(t.abortController.abort(),this.pendingInboundRequests.delete(e.request_id))}throwIfAborted(e){if(e.aborted)throw new R}validateProtocolHandshake(e){if(this.protocolHandshakeValidated)return;this.protocolHandshakeValidated=!0;let t=e.protocol_version,s=x;if(!t){this.diagnostics?.record(`[QueryRunner] CLI did not announce protocol_version. This SDK was built for ${s}. Consider upgrading qodercli for the version handshake.`);return}let o=W(t),n=W(s);if(!o||!n){this.diagnostics?.record(`[QueryRunner] Could not parse protocol_version "${t}" or built-in "${s}"; skipping handshake.`);return}if(o.major!==n.major)throw new C(t,s);o.minor<n.minor&&this.diagnostics?.record(`[QueryRunner] CLI protocol_version ${t} is older than this SDK's ${s}. New optional fields may be absent.`)}async awaitAbortable(e,t){if(t.aborted)throw new R;return new Promise((s,o)=>{let n=()=>{o(new R)};t.addEventListener("abort",n,{once:!0}),e.then(i=>{t.removeEventListener("abort",n),s(i)},i=>{t.removeEventListener("abort",n),o(i)})})}async processControlRequest(e,t){this.throwIfAborted(t);let s=e.request,o=v(s),n=s;switch(o){case"fetch_job_token":{if(!this.fetchJobToken)throw new Error("job_token_unavailable: No fetchJobToken callback configured");let i=n.reason??"initial",a=n.session_id,c=e.request_id,u=await this.awaitAbortable(this.fetchJobToken({requestId:c,reason:i,sessionId:a},{signal:t}),t);if(!u?.token)throw new Error("job_token_unavailable: Host did not provide a Job Token");return this.diagnostics?.record(`[QueryRunner] fetch_job_token fulfilled: reason=${i}`),{token:u.token}}case"can_use_tool":{let i=n.tool_name,a=n.input??{};if(!this.canUseTool)throw new Error("canUseTool callback is not provided.");let c=n.tool_use_id,u=n.permission_suggestions??n.suggestions,p=n.blocked_path,d=n.decision_reason,l=n.title,g=n.display_name,h=n.description,f=n.agent_id,m=await this.awaitAbortable(this.canUseTool(i,a,{signal:t,suggestions:u,blockedPath:p,decisionReason:d,title:l,displayName:g,description:h,toolUseID:c,agentID:f}),t);if(m.behavior==="deny"&&!m.message)throw new Error("Permission deny result must include a message.");return m.behavior==="allow"?{...m,updatedInput:m.updatedInput??a,toolUseID:c}:{...m,toolUseID:c}}case"hook_callback":{let i=n.callback_id;if(!i)throw new Error("Hook callback missing callback_id");return this.invokeRegisteredHookCallback(i,n.input,n.tool_use_id,t)}case"mcp_message":{let i=n.server_name,a=n.message,c=this.sdkMcpTransports.get(i);if(!c)throw new Error(`Unknown in-process MCP server: ${i}`);return{mcp_response:await this.awaitAbortable(E(i,a,c,this.pendingMcpResponses),t)}}case"elicitation":case"elicitation_response":return this.onElicitation?await this.awaitAbortable(this.onElicitation({serverName:n.mcp_server_name??"",message:n.message??n.prompt??"",mode:n.mode,url:n.url,elicitationId:n.elicitation_id,requestedSchema:n.requested_schema,title:n.title,displayName:n.display_name,description:n.description},{signal:t}),t):{action:"cancel"};case"get_model_policy":{if(!this.resolveModel)return{type:"get_model_policy"};let i={purpose:n.purpose,sessionId:n.sessionId,turnIndex:n.turnIndex,availableModels:n.models??[]},a=this.resolveModelTimeoutMs,c=Promise.resolve(this.resolveModel(i)),u,p=new Promise((g,h)=>{u=setTimeout(()=>{h(new M(a))},a)}),d;try{d=await this.awaitAbortable(Promise.race([c,p]),t)}finally{clearTimeout(u)}let l={type:"get_model_policy",model:typeof d.model=="string"?d.model:d.model.model,parameters:d.parameters};if(typeof d.model!="string"){let{model:g,...h}=d.model;l.custom_model={...h,style:h.style??"openai"}}return l}default:throw new Error(`Unhandled control request subtype: ${o??"unknown"}`)}}async initialize(){return this.initializationPromise||(this.initializationPromise=this.performInitialize()),this.initializationPromise}async performInitialize(){let e={type:"initialize",modelPolicyProvider:this.resolveModel!==void 0,supportsCatalogReadyInitialize:!0,initializeTimeoutMs:r.INITIALIZE_TIMEOUT_MS},t={};for(let[o,n]of Object.entries(this.hooks)){if(!n||n.length===0)continue;let i=[];for(let a of n){let c=a.hooks.map(u=>{let p=`hook_${this.nextHookCallbackId++}`;return this.hookCallbacks.set(p,u),p});c.length!==0&&i.push({matcher:a.matcher,hookCallbackIds:c,timeout:a.timeout})}i.length>0&&(t[o]=i)}Object.keys(t).length>0&&(e.hooks=t),this.initConfig.systemPrompt!==void 0&&(e.systemPrompt=this.initConfig.systemPrompt),this.initConfig.appendSystemPrompt!==void 0&&(e.appendSystemPrompt=this.initConfig.appendSystemPrompt),this.initConfig.planModeInstructions!==void 0&&(e.planModeInstructions=this.initConfig.planModeInstructions),this.initConfig.agents&&(e.agents=this.initConfig.agents),this.initConfig.promptSuggestions!==void 0&&(e.promptSuggestions=this.initConfig.promptSuggestions),this.initConfig.enableFileCheckpointing!==void 0&&(e.enableFileCheckpointing=this.initConfig.enableFileCheckpointing),this.jsonSchema&&(e.jsonSchema=this.jsonSchema),this.sdkMcpServers.size>0&&(e.sdkMcpServers=Array.from(this.sdkMcpServers.keys()));let s=await this.request(e,{timeoutMs:r.INITIALIZE_TIMEOUT_MS});if(s&&typeof s=="object"){let o=s;this.initResponse=o}if(!this.initResponse)throw new Error("Failed to receive initialization response");return this.initResponse}async invokeRegisteredHookCallback(e,t,s,o){let n=this.hookCallbacks.get(e);if(!n)throw new Error(`Unknown hook callback: ${e}`);return await this.awaitAbortable(n(t,s,{signal:o}),o)??{continue:!0}}async initializationResult(){return this.initialize()}async streamInput(e){(async()=>{try{await this.initialize();let t=0;for await(let s of e){if(this.closed)break;t+=1,this.transport.write(JSON.stringify(s)+`
9
- `),this.recordOutboundSessionMessage(s)}t>0&&this.hasBidirectionalNeeds()&&await this.waitForFirstResult(),this.transport.endInput()}catch(t){this.diagnostics?.record("[QueryRunner] streamInput error:",t),this.inputStream.error(t instanceof Error?t:new Error(String(t))),this.transport.endInput()}})().catch(()=>{})}async interrupt(){await this.request({type:"interrupt"})}async setPermissionMode(e){await this.request({type:"set_permission_mode",mode:e==="yolo"?"bypassPermissions":e})}hasBidirectionalNeeds(){return this.sdkMcpTransports.size>0||Object.keys(this.hooks).length>0||this.canUseTool!==void 0||this.onElicitation!==void 0||this.fetchJobToken!==void 0||this.resolveModel!==void 0}waitForFirstResult(){return this.firstResultReceived||this.closed?Promise.resolve():new Promise(e=>{if(this.abortController?.signal.aborted){e();return}this.firstResultReceivedResolve=e,this.abortController?.signal.addEventListener("abort",()=>e(),{once:!0})})}async setModel(e){await this.request({type:"set_model",model:e??""})}async setProxy(e){await this.request({type:"set_proxy",proxy:e||null})}async generateSessionTitle(e,t){return(await this.request({type:"generate_session_title",description:e,...t?.persist!==void 0?{persist:t.persist}:{}}))?.title??null}async addDirectories(e){if(!Array.isArray(e))throw new Error("directories must be an array");return await this.request({type:"add_directories",directories:e})}async applyFlagSettings(e){await this.request({type:"apply_flag_settings",settings:e})}async supportedCommands(){return(await this.initializationResult()).commands??[]}async getAvailableModels(e){let t={subtype:"get_models",...e?.fetchStrategy?{fetchStrategy:e.fetchStrategy}:{},...e?.uid?{uid:e.uid}:{}};return(await this.request(t))?.models??[]}async listByokProviders(){try{return(await this.request({type:"get_byok_config"}))?.providers??null}catch{return null}}async validateByokModel(e){try{let t=await this.request({type:"validate_byok_model",provider:e.provider,model:e.model,api_key:e.api_key,...e.url!==void 0?{url:e.url}:{},...e.style!==void 0?{style:e.style}:{}});return typeof t?.success=="boolean"?t.success:null}catch{return null}}async supportedAgents(){return(await this.initializationResult()).agents??[]}async accountInfo(){try{let t=await this.request({type:"account_info"});if(t?.account)return t.account}catch{}return(await this.initializationResult()).account??{}}async mcpServerStatus(){return(await this.request({type:"mcp_status"}))?.servers??[]}async getContextUsage(){return await this.request({type:"get_context_usage"})}async getUsageInfo(){try{let e=await this.request({type:"get_usage_info"});return ne(e?.usage)}catch{return null}}async reloadPlugins(){return await this.request({type:"reload_plugins"})}async listPlugins(){return(await this.request({type:"list_plugins"})).plugins}async rewindFiles(e,t){let s={type:"rewind_files",user_message_id:e};t?.dryRun&&(s.dry_run=!0);let n=await this.request(s);if(!t?.dryRun&&n?.canRewind===!1)throw new Error(typeof n.error=="string"&&n.error.length>0?n.error:"Unable to rewind files.");return n}async seedReadState(e,t){await this.request({type:"seed_read_state",path:e,mtime:t})}async reconnectMcpServer(e){await this.request({type:"mcp_reconnect",serverName:e})}async toggleMcpServer(e,t){await this.request({type:"mcp_toggle",serverName:e,enabled:t})}async setMcpServers(e){return await this.request({type:"mcp_set_servers",servers:e})??{added:[],removed:[],errors:{}}}async injectMcpToken(e,t){await this.request({type:"mcp_inject_token",serverName:e,token:t})}async mcpAuthenticate(e,t){let s=await this.request({type:"mcp_authenticate",serverName:e,...t!==void 0?{redirectUri:t}:{}}),o=s?.requiresUserAction===!0,n=typeof s?.authUrl=="string"?s.authUrl:void 0;if(o&&n===void 0)throw new Error("mcp_authenticate response set requiresUserAction=true but did not include an authUrl");return o?{authUrl:n,requiresUserAction:!0}:{requiresUserAction:!1}}async mcpSubmitOAuthCallbackUrl(e,t){await this.request({type:"mcp_oauth_callback_url",serverName:e,callbackUrl:t})}async mcpClearAuth(e){await this.request({type:"mcp_clear_auth",serverName:e})}async close(){if(this.closed)return;this.closed=!0;for(let[,t]of this.pendingInboundRequests)t.abortController.abort();this.pendingInboundRequests.clear(),this.hookCallbacks.clear();let e=new Error("SDK closing");for(let[t,s]of this.sdkMcpTransports){try{await s.close()}catch(o){this.diagnostics?.record(`[QueryRunner] error closing SDK MCP transport "${t}":`,o)}A(t,e,this.pendingMcpResponses)}this.transport.close();try{await this.readLoopPromise}catch{}}async[Symbol.asyncDispose](){await this.close()}};function _(r){return typeof r=="object"&&r!==null}function te(r){return typeof r=="number"&&Number.isFinite(r)}function D(r){return Object.keys(r).length>0}function y(r,e,t){let s=e[t];te(s)&&(r[t]=s)}function k(r,e,t){let s=e[t];typeof s=="string"&&(r[t]=s)}function P(r,e,t){let s=e[t];typeof s=="boolean"&&(r[t]=s)}function V(r){if(!_(r)||Array.isArray(r))return;let e={};return y(e,r,"total"),y(e,r,"used"),y(e,r,"remaining"),y(e,r,"percentage"),k(e,r,"unit"),D(e)?e:void 0}function se(r){if(!_(r)||Array.isArray(r))return;let e=V(r)??{};return k(e,r,"detailUrl"),D(e)?e:void 0}function re(r){if(!_(r)||Array.isArray(r))return;let e={};return y(e,r,"used"),y(e,r,"cap"),y(e,r,"remaining"),y(e,r,"percentage"),P(e,r,"available"),k(e,r,"unit"),D(e)?e:void 0}function ne(r){if(!_(r)||Array.isArray(r))return null;let e={};k(e,r,"userId"),k(e,r,"userType"),y(e,r,"totalUsagePercentage"),P(e,r,"isHighestTier"),y(e,r,"expiresAt"),k(e,r,"upgradeUrl"),P(e,r,"isQuotaExceeded"),P(e,r,"isPlanQuotaProrated");let t=V(r.userQuota);t&&(e.userQuota=t);let s=se(r.addOnQuota);s&&(e.addOnQuota=s);let o=re(r.orgResourcePackage);return o&&(e.orgResourcePackage=o),e}function oe(r){let e=r instanceof Error?r.message:String(r),t=typeof r=="object"&&r!==null?r.code:void 0,s=typeof t=="string"&&t.length>0?t:void 0,o=/^([a-z][a-z0-9_]*):\s*(.*)$/.exec(e);if(o){let n=s??o[1];return(!s||s===o[1])&&(e=o[2]||e),{error:e,code:n}}return s?{error:e,code:s}:{error:e}}function W(r){let e=/^(\d+)\.(\d+)(?:\.\d+)?(?:[-+].*)?$/.exec(r);return e?{major:Number(e[1]),minor:Number(e[2])}:null}var q=class{sendMcpMessage;isClosed=!1;onclose;onerror;onmessage;constructor(e){this.sendMcpMessage=e}async start(){}async send(e){if(this.isClosed)throw new Error("Transport is closed");this.sendMcpMessage(e)}async close(){this.isClosed||(this.isClosed=!0,this.onclose?.())}get closed(){return this.isClosed}};function ie(r){let{prompt:e,websocket:t,abortController:s,canUseTool:o,hooks:n,mcpServers:i,jsonSchema:a}=r,c=new Map,u=new Map,p=new Map;if(i)for(let[g,h]of Object.entries(i))if(h.type==="sdk"&&"instance"in h){let f=h.instance;c.set(g,f);let m=new q(T=>{K(g,T,p)});u.set(g,m),f.connect(m).catch(()=>{})}else throw new Error(`Browser SDK only supports SDK MCP servers. Server "${g}" has type "${h.type}".`);let d=new w({url:t.url,headers:t.headers,authMessage:t.authMessage,abortController:s}),l=new I(d,!0,o,n,s,c,a,{},void 0,void 0,void 0,void 0,u,p);return l.streamInput(e),l}export{Z as createSdkMcpServer,ie as query,Y as tool};
@@ -1,40 +0,0 @@
1
- import type { Transport } from '../core/transport.js';
2
- import type { StdoutMessage } from '../types/control.js';
3
- export interface WebSocketTransportOptions {
4
- url: string;
5
- headers?: Record<string, string>;
6
- authMessage?: {
7
- type: 'auth';
8
- credential: {
9
- type: 'oauth';
10
- token: string;
11
- };
12
- };
13
- abortController?: AbortController;
14
- }
15
- /**
16
- * WebSocketTransport — Browser transport using native WebSocket.
17
- *
18
- * Messages are sent/received as newline-delimited JSON over WebSocket frames.
19
- * Supports OAuth authentication via an auth message sent on connect.
20
- */
21
- export declare class WebSocketTransport implements Transport {
22
- private options;
23
- private ws;
24
- private ready;
25
- private readyResolve?;
26
- private readyReject?;
27
- private readyPromise;
28
- private messages;
29
- private keepAliveTimer?;
30
- private exitError?;
31
- private initialized;
32
- constructor(options: WebSocketTransportOptions);
33
- initialize(): Promise<void>;
34
- private open;
35
- write(data: string): Promise<void>;
36
- close(): void;
37
- isReady(): boolean;
38
- readMessages(): AsyncGenerator<StdoutMessage, void, unknown>;
39
- endInput(): void;
40
- }
@@ -1,31 +0,0 @@
1
- import type { Transport } from '../core/transport.js';
2
- import type { StdoutMessage } from '../types/control.js';
3
- export interface DirectConnectOptions {
4
- url: string;
5
- abortController?: AbortController;
6
- cwd?: string;
7
- }
8
- /**
9
- * DirectConnectTransport — Connects to a remote qodercli server via WebSocket.
10
- *
11
- * Flow:
12
- * 1. POST /sessions -> creates a session, gets { sessionId, workDir, wsUrl }
13
- * 2. WebSocket to wsUrl -> bidirectional JSONL communication
14
- */
15
- export declare class DirectConnectTransport implements Transport {
16
- private options;
17
- private ws;
18
- private ready;
19
- private messages;
20
- private exitError?;
21
- private partialLine;
22
- private initializePromise;
23
- constructor(options: DirectConnectOptions);
24
- initialize(): Promise<void>;
25
- private doInitialize;
26
- write(data: string): Promise<void>;
27
- close(): void;
28
- isReady(): boolean;
29
- readMessages(): AsyncGenerator<StdoutMessage, void, unknown>;
30
- endInput(): void;
31
- }
@@ -1,14 +0,0 @@
1
- export type DirectConnectUrlResult = {
2
- serverUrl: string;
3
- authToken?: string;
4
- };
5
- /**
6
- * Parse a direct-connect URL.
7
- *
8
- * Supported formats:
9
- * - cc://token@host:port/path -> { serverUrl: "http://host:port/path", authToken: "token" }
10
- * - cc://host:port/path -> { serverUrl: "http://host:port/path" }
11
- * - http://host:port/path -> { serverUrl: "http://host:port/path" }
12
- * - https://host:port/path -> { serverUrl: "https://host:port/path" }
13
- */
14
- export declare function parseDirectConnectUrl(url: string): DirectConnectUrlResult;
@@ -1,2 +0,0 @@
1
- declare const cliPath: string;
2
- export default cliPath;
@@ -1 +0,0 @@
1
- import{fileURLToPath as t}from"url";import{join as i,dirname as o}from"path";var r=t(import.meta.url),m=o(r),e=i(m,"..","cli.js"),l=e;export{l as default};
@@ -1,5 +0,0 @@
1
- /**
2
- * If `embeddedPath` is inside Bun's $bunfs virtual filesystem, extract it to a
3
- * temp directory and return the real path. Otherwise return the path unchanged.
4
- */
5
- export declare function extractFromBunfs(embeddedPath: string): string;
@@ -1,62 +0,0 @@
1
- import type { SDKMessage } from './messages.js';
2
- import type { SDKControlRequest, SDKControlResponse } from './control.js';
3
- import type { CanUseToolOptions, PermissionMode, PermissionResult } from './permissions.js';
4
- export type SessionState = 'idle' | 'running' | 'requires_action';
5
- export type BridgeSessionHandle = {
6
- readonly sessionId: string;
7
- getSequenceNum(): number;
8
- isConnected(): boolean;
9
- write(msg: SDKMessage): void;
10
- sendResult(): void;
11
- sendControlRequest(req: SDKControlRequest): void;
12
- sendControlResponse(res: SDKControlResponse): void;
13
- sendControlCancelRequest(requestId: string): void;
14
- reconnectTransport(opts: {
15
- ingressToken: string;
16
- apiBaseUrl: string;
17
- epoch?: number;
18
- }): Promise<void>;
19
- reportState(state: SessionState): void;
20
- reportMetadata(metadata: Record<string, unknown>): void;
21
- reportDelivery(eventId: string, status: 'processing' | 'processed'): void;
22
- flush(): Promise<void>;
23
- close(): void;
24
- };
25
- export type AttachBridgeSessionOptions = {
26
- sessionId: string;
27
- ingressToken: string;
28
- apiBaseUrl: string;
29
- epoch?: number;
30
- initialSequenceNum?: number;
31
- heartbeatIntervalMs?: number;
32
- outboundOnly?: boolean;
33
- onInboundMessage?: (msg: SDKMessage) => void | Promise<void>;
34
- onPermissionResponse?: (res: SDKControlResponse) => void;
35
- /**
36
- * Called before a bridge permission prompt is resolved remotely. Return a
37
- * PermissionResult to short-circuit the bridge prompt; return undefined to
38
- * let the normal bridge permission flow continue.
39
- */
40
- canUseToolPreFilter?: (toolName: string, input: Record<string, unknown>, ctx: CanUseToolOptions) => Promise<PermissionResult | undefined>;
41
- /**
42
- * Called after a permission result is resolved by the pre-filter or the
43
- * bridge response path.
44
- */
45
- onPermissionResolved?: (toolName: string, result: PermissionResult) => void;
46
- onInterrupt?: () => void;
47
- onSetModel?: (model: string | undefined) => void;
48
- onSetMaxThinkingTokens?: (tokens: number | null) => void;
49
- onSetPermissionMode?: (mode: PermissionMode) => {
50
- ok: true;
51
- } | {
52
- ok: false;
53
- error: string;
54
- };
55
- onClose?: (code?: number) => void;
56
- };
57
- export type RemoteCredentials = {
58
- worker_jwt: string;
59
- api_base_url: string;
60
- expires_in: number;
61
- worker_epoch: number;
62
- };
@@ -1,26 +0,0 @@
1
- import type { SDKUserMessage } from './messages.js';
2
- import type { CanUseTool } from './permissions.js';
3
- import type { HookEvent, HookCallbackMatcher } from './hooks.js';
4
- import type { McpServerConfig } from './mcp.js';
5
- export type OAuthCredential = {
6
- type: 'oauth';
7
- token: string;
8
- };
9
- export type AuthMessage = {
10
- type: 'auth';
11
- credential: OAuthCredential;
12
- };
13
- export type WebSocketOptions = {
14
- url: string;
15
- headers?: Record<string, string>;
16
- authMessage?: AuthMessage;
17
- };
18
- export type BrowserQueryOptions = {
19
- prompt: AsyncIterable<SDKUserMessage>;
20
- websocket: WebSocketOptions;
21
- abortController?: AbortController;
22
- canUseTool?: CanUseTool;
23
- hooks?: Partial<Record<HookEvent, HookCallbackMatcher[]>>;
24
- mcpServers?: Record<string, McpServerConfig>;
25
- jsonSchema?: Record<string, unknown>;
26
- };