@humain/terminal 0.0.11 → 0.0.13

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.13] - 2026-08-31
4
+
5
+ - Record the contracts tarball integrity from the pinned Linux release image.
6
+
7
+ ## [0.0.12] - 2026-08-31
8
+
9
+ ### Fixed
10
+
11
+ - Verify the Terminal shrinkwrap against the exact contracts tarball while keeping contracts-first tag releases possible.
12
+ - Bound timed-out execution cancellation so a hung provider cannot block agent-exec shutdown indefinitely.
13
+ - Reject malformed or oversized RPC child output immediately instead of leaving requests pending until timeout.
14
+ - Validate Anthropic OAuth token responses before persistence and require the OAuth token prefix at the start of a key.
15
+
16
+ ### Changed
17
+
18
+ - Reuse the contracts package as the canonical artifact-kind, reference, and execution-summary safety boundary.
19
+ - Remove the obsolete single-package npm publish workflow superseded by contracts-first publication.
20
+
3
21
  ## [0.0.11] - 2026-08-31
4
22
 
5
23
  ### Fixed
@@ -3,4 +3,4 @@ import{splitDeferredTools}from"./chunk-GMWCTUPB.js";import{buildCopilotDynamicHe
3
3
  `));let blocks=content.map(block=>block.type==="text"?{type:"text",text:sanitizeSurrogates(block.text)}:{type:"image",source:{type:"base64",media_type:block.mimeType,data:block.data}});return blocks.some(b=>b.type==="text")||blocks.unshift({type:"text",text:"(see attached image)"}),blocks}var FINE_GRAINED_TOOL_STREAMING_BETA="fine-grained-tool-streaming-2025-05-14",INTERLEAVED_THINKING_BETA="interleaved-thinking-2025-05-14",SERVER_SIDE_FALLBACK_BETA="server-side-fallback-2026-07-01";function shouldUseServerSideFallbackBeta(model){return(model.compat?.allowedFallbackModels?.length??0)>0}function getAnthropicCompat(model){return{supportsEagerToolInputStreaming:model.compat?.supportsEagerToolInputStreaming??!0,supportsLongCacheRetention:model.compat?.supportsLongCacheRetention??!0,sendSessionAffinityHeaders:model.compat?.sendSessionAffinityHeaders??!1,supportsCacheControlOnTools:model.compat?.supportsCacheControlOnTools??!0,supportsTemperature:model.compat?.supportsTemperature??!0,allowEmptySignature:model.compat?.allowEmptySignature??!1,supportsStrictTools:model.compat?.supportsStrictTools??!1,supportsToolReferences:model.compat?.supportsToolReferences??defaultSupportsToolReferences(model)}}function defaultSupportsToolReferences(model){if(model.provider!=="anthropic"||model.id.includes("haiku"))return!1;let version=model.id.match(/^claude-(?:opus|sonnet|fable)-(\d+)(?:-(\d+))?(?:-|$)/);if(!version)return!1;let major=Number(version[1]),minor=version[2]&&version[2].length<8?Number(version[2]):0;return major>4||major===4&&minor>=5}function mergeHeaders(...headerSources){let merged={};for(let headers of headerSources)headers&&Object.assign(merged,headers);return merged}function mergeClientHeaders(...headerSources){return mergeHeaders({"User-Agent":getPiUserAgent()},...headerSources)}function hasHeader(headers,name){if(!headers)return!1;let expected=name.toLowerCase();for(let[key,value]of Object.entries(headers))if(key.toLowerCase()===expected&&value!==null&&value.trim().length>0)return!0;return!1}function assertRequestAuth(provider,apiKey,headers){if(!apiKey&&!(hasHeader(headers,"authorization")||hasHeader(headers,"x-api-key")||hasHeader(headers,"cf-aig-authorization")))throw new Error(`No API key for provider: ${provider}`)}var ANTHROPIC_MESSAGE_EVENTS=new Set(["message_start","message_delta","message_stop","content_block_start","content_block_delta","content_block_stop"]);function flushSseEvent(state){if(!state.event&&state.data.length===0)return null;let event={event:state.event,data:state.data.join(`
4
4
  `),raw:[...state.raw]};return state.event=null,state.data=[],state.raw=[],event}function decodeSseLine(line,state){if(line==="")return flushSseEvent(state);if(state.raw.push(line),line.startsWith(":"))return null;let delimiterIndex=line.indexOf(":"),fieldName=delimiterIndex===-1?line:line.slice(0,delimiterIndex),value=delimiterIndex===-1?"":line.slice(delimiterIndex+1);return value.startsWith(" ")&&(value=value.slice(1)),fieldName==="event"?state.event=value:fieldName==="data"&&state.data.push(value),null}function nextLineBreakIndex(text){let carriageReturnIndex=text.indexOf("\r"),newlineIndex=text.indexOf(`
5
5
  `);return carriageReturnIndex===-1?newlineIndex:newlineIndex===-1?carriageReturnIndex:Math.min(carriageReturnIndex,newlineIndex)}function consumeLine(text){let lineBreakIndex=nextLineBreakIndex(text);if(lineBreakIndex===-1)return null;let nextIndex=lineBreakIndex+1;return text[lineBreakIndex]==="\r"&&text[nextIndex]===`
6
- `&&(nextIndex+=1),{line:text.slice(0,lineBreakIndex),rest:text.slice(nextIndex)}}async function*iterateSseMessages(body,signal){let reader=body.getReader(),decoder=new TextDecoder,state={event:null,data:[],raw:[]},buffer="";try{for(;;){if(signal?.aborted)throw new Error("Request was aborted");let{value,done}=await reader.read();if(done)break;buffer+=decoder.decode(value,{stream:!0});let consumed2=consumeLine(buffer);for(;consumed2;){buffer=consumed2.rest;let event=decodeSseLine(consumed2.line,state);event&&(yield event),consumed2=consumeLine(buffer)}}buffer+=decoder.decode();let consumed=consumeLine(buffer);for(;consumed;){buffer=consumed.rest;let event=decodeSseLine(consumed.line,state);event&&(yield event),consumed=consumeLine(buffer)}if(buffer.length>0){let event=decodeSseLine(buffer,state);event&&(yield event)}let trailingEvent=flushSseEvent(state);trailingEvent&&(yield trailingEvent)}finally{reader.releaseLock()}}async function*iterateAnthropicEvents(response,signal){if(!response.body)throw new Error("Attempted to iterate over an Anthropic response with no body");let sawMessageStart=!1,sawMessageEnd=!1;for await(let sse of iterateSseMessages(response.body,signal)){if(sse.event==="error")throw new Error(sse.data);if(ANTHROPIC_MESSAGE_EVENTS.has(sse.event??""))try{let event=parseJsonWithRepair(sse.data);event.type==="message_start"?sawMessageStart=!0:event.type==="message_stop"&&(sawMessageEnd=!0),yield event}catch(error){let message=error instanceof Error?error.message:String(error);throw new Error(`Could not parse Anthropic SSE event ${sse.event}: ${message}; data=${sse.data}; raw=${sse.raw.join("\\n")}`)}}if(sawMessageStart&&!sawMessageEnd)throw new Error("Anthropic stream ended before message_stop")}var stream=(model,context,options)=>{let stream2=new AssistantMessageEventStream;return(async()=>{let output={role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"pending",timestamp:Date.now()};try{let client,isOAuth,usageModel=model;if(options?.client)client=options.client,isOAuth=!1;else{let apiKey=options?.apiKey;assertRequestAuth(model.provider,apiKey,options?.headers);let copilotDynamicHeaders;if(model.provider==="github-copilot"){let hasImages=hasCopilotVisionInput(context.messages);copilotDynamicHeaders=buildCopilotDynamicHeaders({messages:context.messages,hasImages})}let cacheSessionId=resolveCacheRetention(options?.cacheRetention,options?.env)==="none"?void 0:options?.sessionId,created=createClient(model,apiKey,options?.interleavedThinking??!0,shouldUseFineGrainedToolStreamingBeta(model,context),shouldUseServerSideFallbackBeta(model),options?.headers,options?.fetch,copilotDynamicHeaders,cacheSessionId);client=created.client,isOAuth=created.isOAuthToken}let params=buildParams(model,context,isOAuth,options),nextParams=await options?.onPayload?.(params,model);nextParams!==void 0&&(params=nextParams);let requestOptions={...options?.signal?{signal:options.signal}:{},...options?.timeoutMs!==void 0?{timeout:options.timeoutMs}:{},maxRetries:0},response=await retryProviderRequest(()=>client.messages.create({...params,stream:!0},requestOptions).asResponse(),{maxRetries:options?.maxRetries,maxRetryDelayMs:options?.maxRetryDelayMs,signal:options?.signal});await options?.onResponse?.({status:response.status,headers:headersToRecord(response.headers)},model),stream2.push({type:"start",partial:output});let blocks=output.content;for await(let event of iterateAnthropicEvents(response,options?.signal))if(event.type==="message_start"){output.responseId=event.message.id,output.model=event.message.model;let fallbackCost=output.model===model.id?void 0:model.compat?.allowedFallbackModels?.find(fallback=>fallback.provider===model.provider&&fallback.model===output.model)?.cost;usageModel=fallbackCost?{...model,id:output.model,cost:fallbackCost}:model,output.usage.input=event.message.usage.input_tokens||0,output.usage.output=event.message.usage.output_tokens||0,output.usage.cacheRead=event.message.usage.cache_read_input_tokens||0,output.usage.cacheWrite=event.message.usage.cache_creation_input_tokens||0,output.usage.cacheWrite1h=event.message.usage.cache_creation?.ephemeral_1h_input_tokens||0,output.usage.totalTokens=output.usage.input+output.usage.output+output.usage.cacheRead+output.usage.cacheWrite,calculateCost(usageModel,output.usage)}else if(event.type==="content_block_start"){if(event.content_block.type==="text"){let block={type:"text",text:event.content_block.text??"",index:event.index};output.content.push(block),stream2.push({type:"text_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="thinking"){let block={type:"thinking",thinking:event.content_block.thinking??"",thinkingSignature:event.content_block.signature??"",index:event.index};output.content.push(block),stream2.push({type:"thinking_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="redacted_thinking"){let block={type:"thinking",thinking:"[Reasoning redacted]",thinkingSignature:event.content_block.data,redacted:!0,index:event.index};output.content.push(block),stream2.push({type:"thinking_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="tool_use"){let block={type:"toolCall",id:event.content_block.id,name:isOAuth?fromClaudeCodeName(event.content_block.name,context.tools):event.content_block.name,arguments:event.content_block.input??{},partialJson:"",index:event.index};output.content.push(block),stream2.push({type:"toolcall_start",contentIndex:output.content.length-1,partial:output})}}else if(event.type==="content_block_delta"){if(event.delta.type==="text_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="text"&&(block.text+=event.delta.text,stream2.push({type:"text_delta",contentIndex:index,delta:event.delta.text,partial:output}))}else if(event.delta.type==="thinking_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="thinking"&&(block.thinking+=event.delta.thinking,stream2.push({type:"thinking_delta",contentIndex:index,delta:event.delta.thinking,partial:output}))}else if(event.delta.type==="input_json_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="toolCall"&&(block.partialJson+=event.delta.partial_json,block.arguments=parseStreamingJson(block.partialJson),stream2.push({type:"toolcall_delta",contentIndex:index,delta:event.delta.partial_json,partial:output}))}else if(event.delta.type==="signature_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="thinking"&&(block.thinkingSignature=block.thinkingSignature||"",block.thinkingSignature+=event.delta.signature)}}else if(event.type==="content_block_stop"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&(delete block.index,block.type==="text"?stream2.push({type:"text_end",contentIndex:index,content:block.text,partial:output}):block.type==="thinking"?stream2.push({type:"thinking_end",contentIndex:index,content:block.thinking,partial:output}):block.type==="toolCall"&&(block.arguments=parseStreamingJson(block.partialJson),delete block.partialJson,stream2.push({type:"toolcall_end",contentIndex:index,toolCall:block,partial:output})))}else if(event.type==="message_delta"){if(event.delta.stop_reason){output.rawStopReason=event.delta.stop_reason;let stopReasonResult=mapStopReason(event.delta.stop_reason,event.delta.stop_details);output.stopReason=stopReasonResult.stopReason,stopReasonResult.errorMessage&&(output.errorMessage=stopReasonResult.errorMessage)}if(event.usage){event.usage.input_tokens!=null&&(output.usage.input=event.usage.input_tokens),event.usage.output_tokens!=null&&(output.usage.output=event.usage.output_tokens),event.usage.cache_read_input_tokens!=null&&(output.usage.cacheRead=event.usage.cache_read_input_tokens),event.usage.cache_creation_input_tokens!=null&&(output.usage.cacheWrite=event.usage.cache_creation_input_tokens);let thinkingTokens=event.usage.output_tokens_details?.thinking_tokens;thinkingTokens!=null&&(output.usage.reasoning=thinkingTokens)}output.usage.totalTokens=output.usage.input+output.usage.output+output.usage.cacheRead+output.usage.cacheWrite,calculateCost(usageModel,output.usage)}if(options?.signal?.aborted)throw new Error("Request was aborted");if(output.stopReason==="pending")throw new Error("Anthropic stream ended without a stop reason");if(output.stopReason==="aborted"||output.stopReason==="error")throw new Error(output.errorMessage||"An unknown error occurred");stream2.push({type:"done",reason:output.stopReason,message:output}),stream2.end()}catch(error){for(let block of output.content)delete block.index,delete block.partialJson;output.stopReason=options?.signal?.aborted?"aborted":"error",output.errorMessage=error instanceof Error?error.message:JSON.stringify(error),stream2.push({type:"error",reason:output.stopReason,error:output}),stream2.end()}})(),stream2};function mapThinkingLevelToEffort(model,level){let mapped=level?model.thinkingLevelMap?.[level]:void 0;if(typeof mapped=="string")return mapped;switch(level){case"minimal":case"low":return"low";case"medium":return"medium";case"high":return"high";default:return"high"}}var streamSimple=(model,context,options)=>{assertRequestAuth(model.provider,options?.apiKey,options?.headers);let base={...buildBaseOptions(model,context,options,options?.apiKey),toolChoice:options?.toolChoice};if(!options?.reasoning)return stream(model,context,{...base,thinkingEnabled:!1});if(model.compat?.forceAdaptiveThinking===!0){let effort=mapThinkingLevelToEffort(model,options.reasoning);return stream(model,context,{...base,thinkingEnabled:!0,effort})}let adjusted=adjustMaxTokensForThinking(base.maxTokens,model.maxTokens,options.reasoning,options.thinkingBudgets),maxTokens=clampMaxTokensToContext(model,context,adjusted.maxTokens);return stream(model,context,{...base,maxTokens,thinkingEnabled:!0,thinkingBudgetTokens:Math.min(adjusted.thinkingBudget,Math.max(0,maxTokens-1024))})};function isOAuthToken(apiKey){return apiKey.includes("sk-ant-oat")}function createClient(model,apiKey,interleavedThinking,useFineGrainedToolStreamingBeta,useServerSideFallbackBeta,optionsHeaders,fetch,dynamicHeaders,sessionId){let needsInterleavedBeta=interleavedThinking&&model.compat?.forceAdaptiveThinking!==!0,betaFeatures=[];if(useFineGrainedToolStreamingBeta&&betaFeatures.push(FINE_GRAINED_TOOL_STREAMING_BETA),needsInterleavedBeta&&betaFeatures.push(INTERLEAVED_THINKING_BETA),useServerSideFallbackBeta&&betaFeatures.push(SERVER_SIDE_FALLBACK_BETA),model.provider==="github-copilot")return{client:new Anthropic({apiKey:null,authToken:apiKey??null,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders:mergeClientHeaders({accept:"application/json","anthropic-dangerous-direct-browser-access":"true",...betaFeatures.length>0?{"anthropic-beta":betaFeatures.join(",")}:{}},model.headers,dynamicHeaders,optionsHeaders)}),isOAuthToken:!1};if(apiKey&&isOAuthToken(apiKey))return{client:new Anthropic({apiKey:null,authToken:apiKey,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders:mergeClientHeaders({accept:"application/json","anthropic-dangerous-direct-browser-access":"true","anthropic-beta":["claude-code-20250219","oauth-2025-04-20",...betaFeatures].join(","),"user-agent":`claude-cli/${claudeCodeVersion}`,"x-app":"cli"},model.headers,optionsHeaders)}),isOAuthToken:!0};let sessionAffinityHeaders=sessionId&&getAnthropicCompat(model).sendSessionAffinityHeaders?{"x-session-affinity":sessionId}:{},defaultHeaders=mergeClientHeaders({accept:"application/json","anthropic-dangerous-direct-browser-access":"true",...betaFeatures.length>0?{"anthropic-beta":betaFeatures.join(",")}:{}},sessionAffinityHeaders,model.headers,optionsHeaders);return{client:new Anthropic({apiKey:apiKey??null,authToken:null,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders}),isOAuthToken:!1}}function buildParams(model,context,isOAuthToken2,options){let{cacheControl}=getCacheControl(model,options?.cacheRetention,options?.env),compat=getAnthropicCompat(model),transformedMessages=transformMessages(context.messages,model,normalizeToolCallId),normalizeToolName=isOAuthToken2?toClaudeCodeName:name=>name,toolPlacement=splitDeferredTools({...context,messages:transformedMessages},compat.supportsToolReferences,normalizeToolName),immediateTools=toolPlacement.immediate,deferredTools=[...toolPlacement.deferred.values()];immediateTools.length===0&&deferredTools.length>0&&(immediateTools=deferredTools,deferredTools=[]);let deferredToolNames=new Set(deferredTools.map(tool=>normalizeToolName(tool.name))),params={model:model.id,messages:convertMessages(transformedMessages,isOAuthToken2,cacheControl,compat.allowEmptySignature,deferredToolNames,normalizeToolName),max_tokens:options?.maxTokens??model.maxTokens,stream:!0};if(isOAuthToken2?(params.system=[{type:"text",text:"You are Claude Code, Anthropic's official CLI for Claude.",...cacheControl?{cache_control:cacheControl}:{}}],context.systemPrompt&&params.system.push({type:"text",text:sanitizeSurrogates(context.systemPrompt),...cacheControl?{cache_control:cacheControl}:{}})):context.systemPrompt&&(params.system=[{type:"text",text:sanitizeSurrogates(context.systemPrompt),...cacheControl?{cache_control:cacheControl}:{}}]),options?.temperature!==void 0&&!options?.thinkingEnabled&&compat.supportsTemperature&&(params.temperature=options.temperature),(immediateTools.length>0||deferredTools.length>0)&&(params.tools=[...convertTools(immediateTools,isOAuthToken2,compat.supportsEagerToolInputStreaming,compat.supportsStrictTools,compat.supportsCacheControlOnTools?cacheControl:void 0),...convertTools(deferredTools,isOAuthToken2,compat.supportsEagerToolInputStreaming,compat.supportsStrictTools,void 0,!0)]),model.reasoning)if(options?.thinkingEnabled){let display=options.thinkingDisplay??"summarized";model.compat?.forceAdaptiveThinking===!0?(params.thinking={type:"adaptive",display},options.effort&&(params.output_config=options.effort==="xhigh"?{effort:options.effort}:{effort:options.effort})):params.thinking={type:"enabled",budget_tokens:options.thinkingBudgetTokens||1024,display}}else options?.thinkingEnabled===!1&&model.thinkingLevelMap?.off!==null&&(params.thinking={type:"disabled"});if(options?.metadata){let userId=options.metadata.user_id;typeof userId=="string"&&(params.metadata={user_id:userId})}options?.toolChoice&&(typeof options.toolChoice=="string"?params.tool_choice={type:options.toolChoice}:params.tool_choice=options.toolChoice);let allowedFallbackModels=model.compat?.allowedFallbackModels;return allowedFallbackModels&&allowedFallbackModels.length>0&&(params.fallbacks=allowedFallbackModels.map(fallback=>({model:fallback.model}))),params}function normalizeToolCallId(id){return id.replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,64)}function convertToolResult(msg,isOAuthToken2,deferredToolNames,loadedToolNames,normalizeToolName){let references=[];for(let name of msg.addedToolNames??[]){let normalizedName=normalizeToolName(name);!deferredToolNames.has(normalizedName)||loadedToolNames.has(normalizedName)||(loadedToolNames.add(normalizedName),references.push({type:"tool_reference",tool_name:isOAuthToken2?toClaudeCodeName(name):name}))}let convertedContent=convertContentBlocks(msg.content);return{toolResult:{type:"tool_result",tool_use_id:msg.toolCallId,content:references.length>0?references:convertedContent,is_error:msg.isError},siblingContent:references.length===0?[]:typeof convertedContent=="string"?[{type:"text",text:convertedContent}]:convertedContent}}function convertMessages(transformedMessages,isOAuthToken2,cacheControl,allowEmptySignature=!1,deferredToolNames=new Set,normalizeToolName=name=>name){let params=[],loadedToolNames=new Set;for(let i=0;i<transformedMessages.length;i++){let msg=transformedMessages[i];if(msg.role==="user")if(typeof msg.content=="string")msg.content.trim().length>0&&params.push({role:"user",content:sanitizeSurrogates(msg.content)});else{let filteredBlocks=msg.content.map(item=>item.type==="text"?{type:"text",text:sanitizeSurrogates(item.text)}:{type:"image",source:{type:"base64",media_type:item.mimeType,data:item.data}}).filter(b=>b.type==="text"?b.text.trim().length>0:!0);if(filteredBlocks.length===0)continue;params.push({role:"user",content:filteredBlocks})}else if(msg.role==="assistant"){let blocks=[];for(let block of msg.content)if(block.type==="text"){if(block.text.trim().length===0)continue;blocks.push({type:"text",text:sanitizeSurrogates(block.text)})}else if(block.type==="thinking"){if(block.redacted){blocks.push({type:"redacted_thinking",data:block.thinkingSignature});continue}let thinkingSignature=block.thinkingSignature,hasThinkingSignature=!!thinkingSignature&&thinkingSignature.trim().length>0;if(block.thinking.trim().length===0&&!hasThinkingSignature)continue;hasThinkingSignature?blocks.push({type:"thinking",thinking:sanitizeSurrogates(block.thinking),signature:thinkingSignature}):blocks.push(allowEmptySignature?{type:"thinking",thinking:sanitizeSurrogates(block.thinking),signature:""}:{type:"text",text:sanitizeSurrogates(block.thinking)})}else block.type==="toolCall"&&blocks.push({type:"tool_use",id:block.id,name:isOAuthToken2?toClaudeCodeName(block.name):block.name,input:block.arguments??{}});if(blocks.length===0)continue;params.push({role:"assistant",content:blocks})}else if(msg.role==="toolResult"){let toolResults=[],siblingContent=[],j=i;for(;j<transformedMessages.length&&transformedMessages[j].role==="toolResult";){let converted=convertToolResult(transformedMessages[j],isOAuthToken2,deferredToolNames,loadedToolNames,normalizeToolName);toolResults.push(converted.toolResult),siblingContent.push(...converted.siblingContent),j++}i=j-1,params.push({role:"user",content:[...toolResults,...siblingContent]})}}if(cacheControl&&params.length>0){let lastMessage=params[params.length-1];if(lastMessage.role==="user")if(Array.isArray(lastMessage.content)){let lastBlock=lastMessage.content[lastMessage.content.length-1];lastBlock&&(lastBlock.type==="text"||lastBlock.type==="image"||lastBlock.type==="tool_result")&&(lastBlock.cache_control=cacheControl)}else typeof lastMessage.content=="string"&&(lastMessage.content=[{type:"text",text:lastMessage.content,cache_control:cacheControl}])}return params}function shouldUseFineGrainedToolStreamingBeta(model,context){return!!context.tools?.length&&!getAnthropicCompat(model).supportsEagerToolInputStreaming}function convertTools(tools,isOAuthToken2,supportsEagerToolInputStreaming,supportsStrictTools,cacheControl,deferLoading=!1){return tools?tools.map((tool,index)=>{let strict=resolveJsonSchemaStrictSampling(tool,supportsStrictTools),parameters=getJsonSchemaToolParameters(tool,strict),schema=parameters,legacyInputSchema={type:"object",properties:schema.properties??{},required:schema.required??[]},inputSchema=strict===!0?{...parameters,...legacyInputSchema}:legacyInputSchema;return{name:isOAuthToken2?toClaudeCodeName(tool.name):tool.name,description:tool.description,...supportsEagerToolInputStreaming?{eager_input_streaming:!0}:{},...strict===!0?{strict:!0}:{},input_schema:inputSchema,...deferLoading?{defer_loading:!0}:{},...cacheControl&&index===tools.length-1?{cache_control:cacheControl}:{}}}):[]}function mapStopReason(reason,stopDetails){switch(reason){case"end_turn":return{stopReason:"stop"};case"max_tokens":return{stopReason:"length"};case"tool_use":return{stopReason:"toolUse"};case"refusal":return{stopReason:"error",errorMessage:stopDetails?.explanation||"The model refused to complete the request"};case"pause_turn":return{stopReason:"stop"};case"stop_sequence":return{stopReason:"stop"};case"sensitive":return{stopReason:"error",errorMessage:"Provider stopped with: sensitive"};default:throw new Error(`Unhandled stop reason: ${reason}`)}}export{stream,streamSimple};
6
+ `&&(nextIndex+=1),{line:text.slice(0,lineBreakIndex),rest:text.slice(nextIndex)}}async function*iterateSseMessages(body,signal){let reader=body.getReader(),decoder=new TextDecoder,state={event:null,data:[],raw:[]},buffer="";try{for(;;){if(signal?.aborted)throw new Error("Request was aborted");let{value,done}=await reader.read();if(done)break;buffer+=decoder.decode(value,{stream:!0});let consumed2=consumeLine(buffer);for(;consumed2;){buffer=consumed2.rest;let event=decodeSseLine(consumed2.line,state);event&&(yield event),consumed2=consumeLine(buffer)}}buffer+=decoder.decode();let consumed=consumeLine(buffer);for(;consumed;){buffer=consumed.rest;let event=decodeSseLine(consumed.line,state);event&&(yield event),consumed=consumeLine(buffer)}if(buffer.length>0){let event=decodeSseLine(buffer,state);event&&(yield event)}let trailingEvent=flushSseEvent(state);trailingEvent&&(yield trailingEvent)}finally{reader.releaseLock()}}async function*iterateAnthropicEvents(response,signal){if(!response.body)throw new Error("Attempted to iterate over an Anthropic response with no body");let sawMessageStart=!1,sawMessageEnd=!1;for await(let sse of iterateSseMessages(response.body,signal)){if(sse.event==="error")throw new Error(sse.data);if(ANTHROPIC_MESSAGE_EVENTS.has(sse.event??""))try{let event=parseJsonWithRepair(sse.data);event.type==="message_start"?sawMessageStart=!0:event.type==="message_stop"&&(sawMessageEnd=!0),yield event}catch(error){let message=error instanceof Error?error.message:String(error);throw new Error(`Could not parse Anthropic SSE event ${sse.event}: ${message}; data=${sse.data}; raw=${sse.raw.join("\\n")}`)}}if(sawMessageStart&&!sawMessageEnd)throw new Error("Anthropic stream ended before message_stop")}var stream=(model,context,options)=>{let stream2=new AssistantMessageEventStream;return(async()=>{let output={role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"pending",timestamp:Date.now()};try{let client,isOAuth,usageModel=model;if(options?.client)client=options.client,isOAuth=!1;else{let apiKey=options?.apiKey;assertRequestAuth(model.provider,apiKey,options?.headers);let copilotDynamicHeaders;if(model.provider==="github-copilot"){let hasImages=hasCopilotVisionInput(context.messages);copilotDynamicHeaders=buildCopilotDynamicHeaders({messages:context.messages,hasImages})}let cacheSessionId=resolveCacheRetention(options?.cacheRetention,options?.env)==="none"?void 0:options?.sessionId,created=createClient(model,apiKey,options?.interleavedThinking??!0,shouldUseFineGrainedToolStreamingBeta(model,context),shouldUseServerSideFallbackBeta(model),options?.headers,options?.fetch,copilotDynamicHeaders,cacheSessionId);client=created.client,isOAuth=created.isOAuthToken}let params=buildParams(model,context,isOAuth,options),nextParams=await options?.onPayload?.(params,model);nextParams!==void 0&&(params=nextParams);let requestOptions={...options?.signal?{signal:options.signal}:{},...options?.timeoutMs!==void 0?{timeout:options.timeoutMs}:{},maxRetries:0},response=await retryProviderRequest(()=>client.messages.create({...params,stream:!0},requestOptions).asResponse(),{maxRetries:options?.maxRetries,maxRetryDelayMs:options?.maxRetryDelayMs,signal:options?.signal});await options?.onResponse?.({status:response.status,headers:headersToRecord(response.headers)},model),stream2.push({type:"start",partial:output});let blocks=output.content;for await(let event of iterateAnthropicEvents(response,options?.signal))if(event.type==="message_start"){output.responseId=event.message.id,output.model=event.message.model;let fallbackCost=output.model===model.id?void 0:model.compat?.allowedFallbackModels?.find(fallback=>fallback.provider===model.provider&&fallback.model===output.model)?.cost;usageModel=fallbackCost?{...model,id:output.model,cost:fallbackCost}:model,output.usage.input=event.message.usage.input_tokens||0,output.usage.output=event.message.usage.output_tokens||0,output.usage.cacheRead=event.message.usage.cache_read_input_tokens||0,output.usage.cacheWrite=event.message.usage.cache_creation_input_tokens||0,output.usage.cacheWrite1h=event.message.usage.cache_creation?.ephemeral_1h_input_tokens||0,output.usage.totalTokens=output.usage.input+output.usage.output+output.usage.cacheRead+output.usage.cacheWrite,calculateCost(usageModel,output.usage)}else if(event.type==="content_block_start"){if(event.content_block.type==="text"){let block={type:"text",text:event.content_block.text??"",index:event.index};output.content.push(block),stream2.push({type:"text_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="thinking"){let block={type:"thinking",thinking:event.content_block.thinking??"",thinkingSignature:event.content_block.signature??"",index:event.index};output.content.push(block),stream2.push({type:"thinking_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="redacted_thinking"){let block={type:"thinking",thinking:"[Reasoning redacted]",thinkingSignature:event.content_block.data,redacted:!0,index:event.index};output.content.push(block),stream2.push({type:"thinking_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="tool_use"){let block={type:"toolCall",id:event.content_block.id,name:isOAuth?fromClaudeCodeName(event.content_block.name,context.tools):event.content_block.name,arguments:event.content_block.input??{},partialJson:"",index:event.index};output.content.push(block),stream2.push({type:"toolcall_start",contentIndex:output.content.length-1,partial:output})}}else if(event.type==="content_block_delta"){if(event.delta.type==="text_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="text"&&(block.text+=event.delta.text,stream2.push({type:"text_delta",contentIndex:index,delta:event.delta.text,partial:output}))}else if(event.delta.type==="thinking_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="thinking"&&(block.thinking+=event.delta.thinking,stream2.push({type:"thinking_delta",contentIndex:index,delta:event.delta.thinking,partial:output}))}else if(event.delta.type==="input_json_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="toolCall"&&(block.partialJson+=event.delta.partial_json,block.arguments=parseStreamingJson(block.partialJson),stream2.push({type:"toolcall_delta",contentIndex:index,delta:event.delta.partial_json,partial:output}))}else if(event.delta.type==="signature_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="thinking"&&(block.thinkingSignature=block.thinkingSignature||"",block.thinkingSignature+=event.delta.signature)}}else if(event.type==="content_block_stop"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&(delete block.index,block.type==="text"?stream2.push({type:"text_end",contentIndex:index,content:block.text,partial:output}):block.type==="thinking"?stream2.push({type:"thinking_end",contentIndex:index,content:block.thinking,partial:output}):block.type==="toolCall"&&(block.arguments=parseStreamingJson(block.partialJson),delete block.partialJson,stream2.push({type:"toolcall_end",contentIndex:index,toolCall:block,partial:output})))}else if(event.type==="message_delta"){if(event.delta.stop_reason){output.rawStopReason=event.delta.stop_reason;let stopReasonResult=mapStopReason(event.delta.stop_reason,event.delta.stop_details);output.stopReason=stopReasonResult.stopReason,stopReasonResult.errorMessage&&(output.errorMessage=stopReasonResult.errorMessage)}if(event.usage){event.usage.input_tokens!=null&&(output.usage.input=event.usage.input_tokens),event.usage.output_tokens!=null&&(output.usage.output=event.usage.output_tokens),event.usage.cache_read_input_tokens!=null&&(output.usage.cacheRead=event.usage.cache_read_input_tokens),event.usage.cache_creation_input_tokens!=null&&(output.usage.cacheWrite=event.usage.cache_creation_input_tokens);let thinkingTokens=event.usage.output_tokens_details?.thinking_tokens;thinkingTokens!=null&&(output.usage.reasoning=thinkingTokens)}output.usage.totalTokens=output.usage.input+output.usage.output+output.usage.cacheRead+output.usage.cacheWrite,calculateCost(usageModel,output.usage)}if(options?.signal?.aborted)throw new Error("Request was aborted");if(output.stopReason==="pending")throw new Error("Anthropic stream ended without a stop reason");if(output.stopReason==="aborted"||output.stopReason==="error")throw new Error(output.errorMessage||"An unknown error occurred");stream2.push({type:"done",reason:output.stopReason,message:output}),stream2.end()}catch(error){for(let block of output.content)delete block.index,delete block.partialJson;output.stopReason=options?.signal?.aborted?"aborted":"error",output.errorMessage=error instanceof Error?error.message:JSON.stringify(error),stream2.push({type:"error",reason:output.stopReason,error:output}),stream2.end()}})(),stream2};function mapThinkingLevelToEffort(model,level){let mapped=level?model.thinkingLevelMap?.[level]:void 0;if(typeof mapped=="string")return mapped;switch(level){case"minimal":case"low":return"low";case"medium":return"medium";case"high":return"high";default:return"high"}}var streamSimple=(model,context,options)=>{assertRequestAuth(model.provider,options?.apiKey,options?.headers);let base={...buildBaseOptions(model,context,options,options?.apiKey),toolChoice:options?.toolChoice};if(!options?.reasoning)return stream(model,context,{...base,thinkingEnabled:!1});if(model.compat?.forceAdaptiveThinking===!0){let effort=mapThinkingLevelToEffort(model,options.reasoning);return stream(model,context,{...base,thinkingEnabled:!0,effort})}let adjusted=adjustMaxTokensForThinking(base.maxTokens,model.maxTokens,options.reasoning,options.thinkingBudgets),maxTokens=clampMaxTokensToContext(model,context,adjusted.maxTokens);return stream(model,context,{...base,maxTokens,thinkingEnabled:!0,thinkingBudgetTokens:Math.min(adjusted.thinkingBudget,Math.max(0,maxTokens-1024))})};function isOAuthToken(apiKey){return apiKey.startsWith("sk-ant-oat")}function createClient(model,apiKey,interleavedThinking,useFineGrainedToolStreamingBeta,useServerSideFallbackBeta,optionsHeaders,fetch,dynamicHeaders,sessionId){let needsInterleavedBeta=interleavedThinking&&model.compat?.forceAdaptiveThinking!==!0,betaFeatures=[];if(useFineGrainedToolStreamingBeta&&betaFeatures.push(FINE_GRAINED_TOOL_STREAMING_BETA),needsInterleavedBeta&&betaFeatures.push(INTERLEAVED_THINKING_BETA),useServerSideFallbackBeta&&betaFeatures.push(SERVER_SIDE_FALLBACK_BETA),model.provider==="github-copilot")return{client:new Anthropic({apiKey:null,authToken:apiKey??null,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders:mergeClientHeaders({accept:"application/json","anthropic-dangerous-direct-browser-access":"true",...betaFeatures.length>0?{"anthropic-beta":betaFeatures.join(",")}:{}},model.headers,dynamicHeaders,optionsHeaders)}),isOAuthToken:!1};if(apiKey&&isOAuthToken(apiKey))return{client:new Anthropic({apiKey:null,authToken:apiKey,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders:mergeClientHeaders({accept:"application/json","anthropic-dangerous-direct-browser-access":"true","anthropic-beta":["claude-code-20250219","oauth-2025-04-20",...betaFeatures].join(","),"user-agent":`claude-cli/${claudeCodeVersion}`,"x-app":"cli"},model.headers,optionsHeaders)}),isOAuthToken:!0};let sessionAffinityHeaders=sessionId&&getAnthropicCompat(model).sendSessionAffinityHeaders?{"x-session-affinity":sessionId}:{},defaultHeaders=mergeClientHeaders({accept:"application/json","anthropic-dangerous-direct-browser-access":"true",...betaFeatures.length>0?{"anthropic-beta":betaFeatures.join(",")}:{}},sessionAffinityHeaders,model.headers,optionsHeaders);return{client:new Anthropic({apiKey:apiKey??null,authToken:null,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders}),isOAuthToken:!1}}function buildParams(model,context,isOAuthToken2,options){let{cacheControl}=getCacheControl(model,options?.cacheRetention,options?.env),compat=getAnthropicCompat(model),transformedMessages=transformMessages(context.messages,model,normalizeToolCallId),normalizeToolName=isOAuthToken2?toClaudeCodeName:name=>name,toolPlacement=splitDeferredTools({...context,messages:transformedMessages},compat.supportsToolReferences,normalizeToolName),immediateTools=toolPlacement.immediate,deferredTools=[...toolPlacement.deferred.values()];immediateTools.length===0&&deferredTools.length>0&&(immediateTools=deferredTools,deferredTools=[]);let deferredToolNames=new Set(deferredTools.map(tool=>normalizeToolName(tool.name))),params={model:model.id,messages:convertMessages(transformedMessages,isOAuthToken2,cacheControl,compat.allowEmptySignature,deferredToolNames,normalizeToolName),max_tokens:options?.maxTokens??model.maxTokens,stream:!0};if(isOAuthToken2?(params.system=[{type:"text",text:"You are Claude Code, Anthropic's official CLI for Claude.",...cacheControl?{cache_control:cacheControl}:{}}],context.systemPrompt&&params.system.push({type:"text",text:sanitizeSurrogates(context.systemPrompt),...cacheControl?{cache_control:cacheControl}:{}})):context.systemPrompt&&(params.system=[{type:"text",text:sanitizeSurrogates(context.systemPrompt),...cacheControl?{cache_control:cacheControl}:{}}]),options?.temperature!==void 0&&!options?.thinkingEnabled&&compat.supportsTemperature&&(params.temperature=options.temperature),(immediateTools.length>0||deferredTools.length>0)&&(params.tools=[...convertTools(immediateTools,isOAuthToken2,compat.supportsEagerToolInputStreaming,compat.supportsStrictTools,compat.supportsCacheControlOnTools?cacheControl:void 0),...convertTools(deferredTools,isOAuthToken2,compat.supportsEagerToolInputStreaming,compat.supportsStrictTools,void 0,!0)]),model.reasoning)if(options?.thinkingEnabled){let display=options.thinkingDisplay??"summarized";model.compat?.forceAdaptiveThinking===!0?(params.thinking={type:"adaptive",display},options.effort&&(params.output_config=options.effort==="xhigh"?{effort:options.effort}:{effort:options.effort})):params.thinking={type:"enabled",budget_tokens:options.thinkingBudgetTokens||1024,display}}else options?.thinkingEnabled===!1&&model.thinkingLevelMap?.off!==null&&(params.thinking={type:"disabled"});if(options?.metadata){let userId=options.metadata.user_id;typeof userId=="string"&&(params.metadata={user_id:userId})}options?.toolChoice&&(typeof options.toolChoice=="string"?params.tool_choice={type:options.toolChoice}:params.tool_choice=options.toolChoice);let allowedFallbackModels=model.compat?.allowedFallbackModels;return allowedFallbackModels&&allowedFallbackModels.length>0&&(params.fallbacks=allowedFallbackModels.map(fallback=>({model:fallback.model}))),params}function normalizeToolCallId(id){return id.replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,64)}function convertToolResult(msg,isOAuthToken2,deferredToolNames,loadedToolNames,normalizeToolName){let references=[];for(let name of msg.addedToolNames??[]){let normalizedName=normalizeToolName(name);!deferredToolNames.has(normalizedName)||loadedToolNames.has(normalizedName)||(loadedToolNames.add(normalizedName),references.push({type:"tool_reference",tool_name:isOAuthToken2?toClaudeCodeName(name):name}))}let convertedContent=convertContentBlocks(msg.content);return{toolResult:{type:"tool_result",tool_use_id:msg.toolCallId,content:references.length>0?references:convertedContent,is_error:msg.isError},siblingContent:references.length===0?[]:typeof convertedContent=="string"?[{type:"text",text:convertedContent}]:convertedContent}}function convertMessages(transformedMessages,isOAuthToken2,cacheControl,allowEmptySignature=!1,deferredToolNames=new Set,normalizeToolName=name=>name){let params=[],loadedToolNames=new Set;for(let i=0;i<transformedMessages.length;i++){let msg=transformedMessages[i];if(msg.role==="user")if(typeof msg.content=="string")msg.content.trim().length>0&&params.push({role:"user",content:sanitizeSurrogates(msg.content)});else{let filteredBlocks=msg.content.map(item=>item.type==="text"?{type:"text",text:sanitizeSurrogates(item.text)}:{type:"image",source:{type:"base64",media_type:item.mimeType,data:item.data}}).filter(b=>b.type==="text"?b.text.trim().length>0:!0);if(filteredBlocks.length===0)continue;params.push({role:"user",content:filteredBlocks})}else if(msg.role==="assistant"){let blocks=[];for(let block of msg.content)if(block.type==="text"){if(block.text.trim().length===0)continue;blocks.push({type:"text",text:sanitizeSurrogates(block.text)})}else if(block.type==="thinking"){if(block.redacted){blocks.push({type:"redacted_thinking",data:block.thinkingSignature});continue}let thinkingSignature=block.thinkingSignature,hasThinkingSignature=!!thinkingSignature&&thinkingSignature.trim().length>0;if(block.thinking.trim().length===0&&!hasThinkingSignature)continue;hasThinkingSignature?blocks.push({type:"thinking",thinking:sanitizeSurrogates(block.thinking),signature:thinkingSignature}):blocks.push(allowEmptySignature?{type:"thinking",thinking:sanitizeSurrogates(block.thinking),signature:""}:{type:"text",text:sanitizeSurrogates(block.thinking)})}else block.type==="toolCall"&&blocks.push({type:"tool_use",id:block.id,name:isOAuthToken2?toClaudeCodeName(block.name):block.name,input:block.arguments??{}});if(blocks.length===0)continue;params.push({role:"assistant",content:blocks})}else if(msg.role==="toolResult"){let toolResults=[],siblingContent=[],j=i;for(;j<transformedMessages.length&&transformedMessages[j].role==="toolResult";){let converted=convertToolResult(transformedMessages[j],isOAuthToken2,deferredToolNames,loadedToolNames,normalizeToolName);toolResults.push(converted.toolResult),siblingContent.push(...converted.siblingContent),j++}i=j-1,params.push({role:"user",content:[...toolResults,...siblingContent]})}}if(cacheControl&&params.length>0){let lastMessage=params[params.length-1];if(lastMessage.role==="user")if(Array.isArray(lastMessage.content)){let lastBlock=lastMessage.content[lastMessage.content.length-1];lastBlock&&(lastBlock.type==="text"||lastBlock.type==="image"||lastBlock.type==="tool_result")&&(lastBlock.cache_control=cacheControl)}else typeof lastMessage.content=="string"&&(lastMessage.content=[{type:"text",text:lastMessage.content,cache_control:cacheControl}])}return params}function shouldUseFineGrainedToolStreamingBeta(model,context){return!!context.tools?.length&&!getAnthropicCompat(model).supportsEagerToolInputStreaming}function convertTools(tools,isOAuthToken2,supportsEagerToolInputStreaming,supportsStrictTools,cacheControl,deferLoading=!1){return tools?tools.map((tool,index)=>{let strict=resolveJsonSchemaStrictSampling(tool,supportsStrictTools),parameters=getJsonSchemaToolParameters(tool,strict),schema=parameters,legacyInputSchema={type:"object",properties:schema.properties??{},required:schema.required??[]},inputSchema=strict===!0?{...parameters,...legacyInputSchema}:legacyInputSchema;return{name:isOAuthToken2?toClaudeCodeName(tool.name):tool.name,description:tool.description,...supportsEagerToolInputStreaming?{eager_input_streaming:!0}:{},...strict===!0?{strict:!0}:{},input_schema:inputSchema,...deferLoading?{defer_loading:!0}:{},...cacheControl&&index===tools.length-1?{cache_control:cacheControl}:{}}}):[]}function mapStopReason(reason,stopDetails){switch(reason){case"end_turn":return{stopReason:"stop"};case"max_tokens":return{stopReason:"length"};case"tool_use":return{stopReason:"toolUse"};case"refusal":return{stopReason:"error",errorMessage:stopDetails?.explanation||"The model refused to complete the request"};case"pause_turn":return{stopReason:"stop"};case"stop_sequence":return{stopReason:"stop"};case"sensitive":return{stopReason:"error",errorMessage:"Provider stopped with: sensitive"};default:throw new Error(`Unhandled stop reason: ${reason}`)}}export{stream,streamSimple};
@@ -72,4 +72,4 @@ var __require=(x=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(x,{get:(
72
72
  ${details?`<div class="details">${details}</div>`:""}
73
73
  </main>
74
74
  </body>
75
- </html>`}function oauthSuccessHtml(message){return renderPage({title:"Authentication successful",heading:"Authentication successful",message})}function oauthErrorHtml(message,details){return renderPage({title:"Authentication failed",heading:"Authentication failed",message,details})}function base64urlEncode(bytes){let binary="";for(let byte of bytes)binary+=String.fromCharCode(byte);return btoa(binary).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async function generatePKCE(){let verifierBytes=new Uint8Array(32);crypto.getRandomValues(verifierBytes);let verifier=base64urlEncode(verifierBytes),data=new TextEncoder().encode(verifier),hashBuffer=await crypto.subtle.digest("SHA-256",data),challenge=base64urlEncode(new Uint8Array(hashBuffer));return{verifier,challenge}}var nodeApis=null,nodeApisPromise=null,decode=s=>atob(s),CLIENT_ID=decode("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl"),AUTHORIZE_URL="https://claude.ai/oauth/authorize",TOKEN_URL="https://platform.claude.com/v1/oauth/token",CALLBACK_HOST=getProviderEnvValue("PI_OAUTH_CALLBACK_HOST")||"127.0.0.1",CALLBACK_PORT=53692,CALLBACK_PATH="/callback",REDIRECT_URI=`http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`,SCOPES="org:create_api_key user:profile user:inference user:sessions:claude_code user:mcp_servers user:file_upload";async function getNodeApis(){if(nodeApis)return nodeApis;if(!nodeApisPromise){if(typeof process>"u"||!process.versions?.node&&!process.versions?.bun)throw new Error("Anthropic OAuth is only available in Node.js environments");nodeApisPromise=import("node:http").then(httpModule=>({createServer:httpModule.createServer}))}return nodeApis=await nodeApisPromise,nodeApis}function parseAuthorizationInput(input){let value=input.trim();if(!value)return{};try{let url=new URL(value);return{code:url.searchParams.get("code")??void 0,state:url.searchParams.get("state")??void 0}}catch{}if(value.includes("#")){let[code,state]=value.split("#",2);return{code,state}}if(value.includes("code=")){let params=new URLSearchParams(value);return{code:params.get("code")??void 0,state:params.get("state")??void 0}}return{code:value}}function formatErrorDetails(error){if(error instanceof Error){let details=[`${error.name}: ${error.message}`],errorWithCode=error;return errorWithCode.code&&details.push(`code=${errorWithCode.code}`),typeof errorWithCode.errno<"u"&&details.push(`errno=${String(errorWithCode.errno)}`),typeof error.cause<"u"&&details.push(`cause=${formatErrorDetails(error.cause)}`),error.stack&&details.push(`stack=${error.stack}`),details.join("; ")}return String(error)}async function startCallbackServer(expectedState){let{createServer}=await getNodeApis();return new Promise((resolve,reject)=>{let settleWait,waitForCodePromise=new Promise(resolveWait=>{let settled=!1;settleWait=value=>{settled||(settled=!0,resolveWait(value))}}),server=createServer((req,res)=>{try{let url=new URL(req.url||"","http://localhost");if(url.pathname!==CALLBACK_PATH){res.writeHead(404,{"Content-Type":"text/html; charset=utf-8"}),res.end(oauthErrorHtml("Callback route not found."));return}let code=url.searchParams.get("code"),state=url.searchParams.get("state"),error=url.searchParams.get("error");if(error){res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(oauthErrorHtml("Anthropic authentication did not complete.",`Error: ${error}`));return}if(!code||!state){res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(oauthErrorHtml("Missing code or state parameter."));return}if(state!==expectedState){res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(oauthErrorHtml("State mismatch."));return}res.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),res.end(oauthSuccessHtml("Anthropic authentication completed. You can close this window.")),settleWait?.({code,state})}catch{res.writeHead(500,{"Content-Type":"text/plain; charset=utf-8"}),res.end("Internal error")}});server.on("error",err=>{reject(err)}),server.listen(CALLBACK_PORT,CALLBACK_HOST,()=>{resolve({server,redirectUri:REDIRECT_URI,cancelWait:()=>{settleWait?.(null)},waitForCode:()=>waitForCodePromise})})})}async function postJson(url,body,signal){let response=await fetch(url,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(body),signal:AbortSignal.any([signal,AbortSignal.timeout(3e4)])}),responseBody=await response.text();if(!response.ok)throw new Error(`HTTP request failed. status=${response.status}; url=${url}; body=${responseBody}`);return responseBody}async function exchangeAuthorizationCode(code,state,verifier,redirectUri,signal){let responseBody;try{responseBody=await postJson(TOKEN_URL,{grant_type:"authorization_code",client_id:CLIENT_ID,code,state,redirect_uri:redirectUri,code_verifier:verifier},signal)}catch(error){throw new Error(`Token exchange request failed. url=${TOKEN_URL}; redirect_uri=${redirectUri}; response_type=authorization_code; details=${formatErrorDetails(error)}`)}let tokenData;try{tokenData=JSON.parse(responseBody)}catch(error){throw new Error(`Token exchange returned invalid JSON. url=${TOKEN_URL}; body=${responseBody}; details=${formatErrorDetails(error)}`)}return{type:"oauth",refresh:tokenData.refresh_token,access:tokenData.access_token,expires:Date.now()+tokenData.expires_in*1e3-300*1e3}}async function loginAnthropic(interaction){let{verifier,challenge}=await generatePKCE(),server=await startCallbackServer(verifier),manualAbort=new AbortController,onAbort=()=>server.cancelWait();interaction.signal.addEventListener("abort",onAbort,{once:!0}),interaction.signal.aborted&&onAbort();let code,state,manualInput,manualError;try{let authParams=new URLSearchParams({code:"true",client_id:CLIENT_ID,response_type:"code",redirect_uri:REDIRECT_URI,scope:SCOPES,code_challenge:challenge,code_challenge_method:"S256",state:verifier});interaction.notify({type:"auth_url",url:`${AUTHORIZE_URL}?${authParams.toString()}`,instructions:"Complete login in your browser. If the browser is on another machine, paste the final redirect URL here."});let manualPromise=interaction.prompt({type:"manual_code",message:"Complete login in your browser, or paste the authorization code / redirect URL here:",placeholder:REDIRECT_URI,signal:manualAbort.signal}).then(input=>{manualInput=input,server.cancelWait()}).catch(error=>{manualError=error instanceof Error?error:new Error(String(error)),server.cancelWait()}),result=await server.waitForCode();if(manualError)throw manualError;if(result?.code)code=result.code,state=result.state;else if(manualInput){let parsed=parseAuthorizationInput(manualInput);if(parsed.state&&parsed.state!==verifier)throw new Error("OAuth state mismatch");code=parsed.code,state=parsed.state??verifier}if(!code){if(await manualPromise,manualError)throw manualError;if(manualInput){let parsed=parseAuthorizationInput(manualInput);if(parsed.state&&parsed.state!==verifier)throw new Error("OAuth state mismatch");code=parsed.code,state=parsed.state??verifier}}if(!code)throw new Error("Missing authorization code");if(!state)throw new Error("Missing OAuth state");return interaction.notify({type:"progress",message:"Exchanging authorization code for tokens..."}),exchangeAuthorizationCode(code,state,verifier,REDIRECT_URI,interaction.signal)}finally{interaction.signal.removeEventListener("abort",onAbort),manualAbort.abort(),server.server.close()}}async function refreshAnthropicToken(refreshToken,signal){let responseBody;try{responseBody=await postJson(TOKEN_URL,{grant_type:"refresh_token",client_id:CLIENT_ID,refresh_token:refreshToken},signal)}catch(error){throw new Error(`Anthropic token refresh request failed. url=${TOKEN_URL}; details=${formatErrorDetails(error)}`)}let data;try{data=JSON.parse(responseBody)}catch(error){throw new Error(`Anthropic token refresh returned invalid JSON. url=${TOKEN_URL}; body=${responseBody}; details=${formatErrorDetails(error)}`)}return{type:"oauth",refresh:data.refresh_token,access:data.access_token,expires:Date.now()+data.expires_in*1e3-300*1e3}}var anthropicOAuth={name:"Anthropic (Claude Pro/Max)",isSubscription:!0,login:loginAnthropic,refresh:(credential,signal)=>refreshAnthropicToken(credential.refresh,signal),async toAuth(credential){return{apiKey:credential.access}}};export{anthropicOAuth};
75
+ </html>`}function oauthSuccessHtml(message){return renderPage({title:"Authentication successful",heading:"Authentication successful",message})}function oauthErrorHtml(message,details){return renderPage({title:"Authentication failed",heading:"Authentication failed",message,details})}function base64urlEncode(bytes){let binary="";for(let byte of bytes)binary+=String.fromCharCode(byte);return btoa(binary).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async function generatePKCE(){let verifierBytes=new Uint8Array(32);crypto.getRandomValues(verifierBytes);let verifier=base64urlEncode(verifierBytes),data=new TextEncoder().encode(verifier),hashBuffer=await crypto.subtle.digest("SHA-256",data),challenge=base64urlEncode(new Uint8Array(hashBuffer));return{verifier,challenge}}var nodeApis=null,nodeApisPromise=null,decode=s=>atob(s),CLIENT_ID=decode("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl"),AUTHORIZE_URL="https://claude.ai/oauth/authorize",TOKEN_URL="https://platform.claude.com/v1/oauth/token",CALLBACK_HOST=getProviderEnvValue("PI_OAUTH_CALLBACK_HOST")||"127.0.0.1",CALLBACK_PORT=53692,CALLBACK_PATH="/callback",REDIRECT_URI=`http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`,SCOPES="org:create_api_key user:profile user:inference user:sessions:claude_code user:mcp_servers user:file_upload";async function getNodeApis(){if(nodeApis)return nodeApis;if(!nodeApisPromise){if(typeof process>"u"||!process.versions?.node&&!process.versions?.bun)throw new Error("Anthropic OAuth is only available in Node.js environments");nodeApisPromise=import("node:http").then(httpModule=>({createServer:httpModule.createServer}))}return nodeApis=await nodeApisPromise,nodeApis}function parseAuthorizationInput(input){let value=input.trim();if(!value)return{};try{let url=new URL(value);return{code:url.searchParams.get("code")??void 0,state:url.searchParams.get("state")??void 0}}catch{}if(value.includes("#")){let[code,state]=value.split("#",2);return{code,state}}if(value.includes("code=")){let params=new URLSearchParams(value);return{code:params.get("code")??void 0,state:params.get("state")??void 0}}return{code:value}}function formatErrorDetails(error){if(error instanceof Error){let details=[`${error.name}: ${error.message}`],errorWithCode=error;return errorWithCode.code&&details.push(`code=${errorWithCode.code}`),typeof errorWithCode.errno<"u"&&details.push(`errno=${String(errorWithCode.errno)}`),typeof error.cause<"u"&&details.push(`cause=${formatErrorDetails(error.cause)}`),error.stack&&details.push(`stack=${error.stack}`),details.join("; ")}return String(error)}async function startCallbackServer(expectedState){let{createServer}=await getNodeApis();return new Promise((resolve,reject)=>{let settleWait,waitForCodePromise=new Promise(resolveWait=>{let settled=!1;settleWait=value=>{settled||(settled=!0,resolveWait(value))}}),server=createServer((req,res)=>{try{let url=new URL(req.url||"","http://localhost");if(url.pathname!==CALLBACK_PATH){res.writeHead(404,{"Content-Type":"text/html; charset=utf-8"}),res.end(oauthErrorHtml("Callback route not found."));return}let code=url.searchParams.get("code"),state=url.searchParams.get("state"),error=url.searchParams.get("error");if(error){res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(oauthErrorHtml("Anthropic authentication did not complete.",`Error: ${error}`));return}if(!code||!state){res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(oauthErrorHtml("Missing code or state parameter."));return}if(state!==expectedState){res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(oauthErrorHtml("State mismatch."));return}res.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),res.end(oauthSuccessHtml("Anthropic authentication completed. You can close this window.")),settleWait?.({code,state})}catch{res.writeHead(500,{"Content-Type":"text/plain; charset=utf-8"}),res.end("Internal error")}});server.on("error",err=>{reject(err)}),server.listen(CALLBACK_PORT,CALLBACK_HOST,()=>{resolve({server,redirectUri:REDIRECT_URI,cancelWait:()=>{settleWait?.(null)},waitForCode:()=>waitForCodePromise})})})}async function postJson(url,body,signal){let response=await fetch(url,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(body),signal:AbortSignal.any([signal,AbortSignal.timeout(3e4)])}),responseBody=await response.text();if(!response.ok)throw new Error(`HTTP request failed. status=${response.status}; url=${url}; body=${responseBody}`);return responseBody}function parseTokenResponse(responseBody,requestName){let data;try{data=JSON.parse(responseBody)}catch(error){throw new Error(`${requestName} returned invalid JSON. details=${formatErrorDetails(error)}`)}let token=data;if(typeof token!="object"||token===null||typeof token.access_token!="string"||!token.access_token.trim()||typeof token.refresh_token!="string"||!token.refresh_token.trim()||typeof token.expires_in!="number"||!Number.isFinite(token.expires_in)||token.expires_in<=0)throw new Error(`${requestName} returned an invalid token response`);return token}async function exchangeAuthorizationCode(code,state,verifier,redirectUri,signal){let responseBody;try{responseBody=await postJson(TOKEN_URL,{grant_type:"authorization_code",client_id:CLIENT_ID,code,state,redirect_uri:redirectUri,code_verifier:verifier},signal)}catch(error){throw new Error(`Token exchange request failed. url=${TOKEN_URL}; redirect_uri=${redirectUri}; response_type=authorization_code; details=${formatErrorDetails(error)}`)}let tokenData=parseTokenResponse(responseBody,"Token exchange");return{type:"oauth",refresh:tokenData.refresh_token,access:tokenData.access_token,expires:Date.now()+tokenData.expires_in*1e3-300*1e3}}async function loginAnthropic(interaction){let{verifier,challenge}=await generatePKCE(),server=await startCallbackServer(verifier),manualAbort=new AbortController,onAbort=()=>server.cancelWait();interaction.signal.addEventListener("abort",onAbort,{once:!0}),interaction.signal.aborted&&onAbort();let code,state,manualInput,manualError;try{let authParams=new URLSearchParams({code:"true",client_id:CLIENT_ID,response_type:"code",redirect_uri:REDIRECT_URI,scope:SCOPES,code_challenge:challenge,code_challenge_method:"S256",state:verifier});interaction.notify({type:"auth_url",url:`${AUTHORIZE_URL}?${authParams.toString()}`,instructions:"Complete login in your browser. If the browser is on another machine, paste the final redirect URL here."});let manualPromise=interaction.prompt({type:"manual_code",message:"Complete login in your browser, or paste the authorization code / redirect URL here:",placeholder:REDIRECT_URI,signal:manualAbort.signal}).then(input=>{manualInput=input,server.cancelWait()}).catch(error=>{manualError=error instanceof Error?error:new Error(String(error)),server.cancelWait()}),result=await server.waitForCode();if(manualError)throw manualError;if(result?.code)code=result.code,state=result.state;else if(manualInput){let parsed=parseAuthorizationInput(manualInput);if(parsed.state&&parsed.state!==verifier)throw new Error("OAuth state mismatch");code=parsed.code,state=parsed.state??verifier}if(!code){if(await manualPromise,manualError)throw manualError;if(manualInput){let parsed=parseAuthorizationInput(manualInput);if(parsed.state&&parsed.state!==verifier)throw new Error("OAuth state mismatch");code=parsed.code,state=parsed.state??verifier}}if(!code)throw new Error("Missing authorization code");if(!state)throw new Error("Missing OAuth state");return interaction.notify({type:"progress",message:"Exchanging authorization code for tokens..."}),exchangeAuthorizationCode(code,state,verifier,REDIRECT_URI,interaction.signal)}finally{interaction.signal.removeEventListener("abort",onAbort),manualAbort.abort(),server.server.close()}}async function refreshAnthropicToken(refreshToken,signal){let responseBody;try{responseBody=await postJson(TOKEN_URL,{grant_type:"refresh_token",client_id:CLIENT_ID,refresh_token:refreshToken},signal)}catch(error){throw new Error(`Anthropic token refresh request failed. url=${TOKEN_URL}; details=${formatErrorDetails(error)}`)}let data=parseTokenResponse(responseBody,"Anthropic token refresh");return{type:"oauth",refresh:data.refresh_token,access:data.access_token,expires:Date.now()+data.expires_in*1e3-300*1e3}}var anthropicOAuth={name:"Anthropic (Claude Pro/Max)",isSubscription:!0,login:loginAnthropic,refresh:(credential,signal)=>refreshAnthropicToken(credential.refresh,signal),async toAuth(credential){return{apiKey:credential.access}}};export{anthropicOAuth};