@qoder-ai/qoder-agent-sdk 1.0.26 → 1.0.27
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/dist/index.js +2 -2
- package/dist/runtime-manifest.json +2 -2
- package/dist/types/auth.d.ts +3 -1
- package/dist/types/control.d.ts +2 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var Wr=Object.defineProperty;var Hr=(n,e)=>{for(var t in e)Wr(n,t,{get:e[t],enumerable:!0})};import{spawn as Ps}from"child_process";import{createInterface as _s}from"readline";var Jr=["PreToolUse","PostToolUse","PostToolUseFailure","UserPromptSubmit","SessionStart","SessionEnd","Stop","SubagentStart","SubagentStop","PreCompact","PostCompact","CwdChanged","InstructionsLoaded","FileChanged","PermissionRequest","PermissionDenied","WorktreeCreate","WorktreeRemove"],Vr=["clear","resume","logout","prompt_input_exit","other","bypass_permissions_disabled"],_e=2e3,Gt=5e3;var Bt="1.0.26";var q=41,$t=["Agent","AskUserQuestion","Bash","Edit","Glob","Grep","ImageGen","ImageSearch","NotebookEdit","Read","Skill","TaskCreate","TaskGet","TaskUpdate","TaskList","UpdateGoal","WebFetch","WebSearch","Write"],Qt=["TaskCreate","TaskGet","TaskUpdate","TaskList"],Yr="QODER_FEATURE_TASKS";function zt(n){let e=n[Yr];if(e!=="0"&&e!=="false")return[...$t];let t=new Set(Qt);return $t.flatMap(r=>r===Qt[0]?["TodoWrite"]:t.has(r)?[]:[r])}import{chmod as Xt,mkdtemp as us,rm as Zt,writeFile as cs}from"fs/promises";import{existsSync as xe,mkdtempSync as ls,readFileSync as ds,rmSync as ps,writeFileSync as ms}from"fs";import{homedir as fs,tmpdir as en}from"os";import{dirname as un,join as O}from"path";import{fileURLToPath as gs}from"url";var Xr=/^[A-Za-z0-9_-]{1,64}$/,Zr=new Set(["mcp_list","mcp_get","mcp_call"]);function rt(n,e){if(e.exposedName!==void 0){if(e.alwaysLoad!==!0)throw new Error(`MCP tool "${n}/${e.name}" requires alwaysLoad: true when exposedName is set.`);if(!Xr.test(e.exposedName))throw new Error(`MCP tool "${n}/${e.name}" has invalid exposedName "${e.exposedName}".`);if(Zr.has(e.exposedName))throw new Error(`MCP tool "${n}/${e.name}" cannot use reserved exposedName "${e.exposedName}".`)}}function st(n,e){let t={};for(let r of e)rt(n,r),(r.exposedName!==void 0||r.alwaysLoad===!0)&&(t[r.name]={...r.exposedName!==void 0?{exposedName:r.exposedName}:{},...r.alwaysLoad===!0?{alwaysLoad:!0}:{}});return Object.keys(t).length>0?t:void 0}function ot(n,e,t=e.tools??[]){let{tools:r,...s}=e,o=st(n,t);return{...s,...o?{toolOverrides:o}:{}}}function Wt(n){let e={};for(let[t,r]of Object.entries(n)){if(r.type==="sdk")throw new Error(`MCP server "${t}" uses an in-process SDK transport and cannot be changed with setMcpServers().`);let s=r.tools??[],o=s.find(i=>i.permission_policy!==void 0);if(o)throw new Error(`MCP tool "${t}/${o.name}" cannot set permission_policy through setMcpServers(); configure it when creating the query.`);e[t]=ot(t,r,s)}return e}var es="global",Ht=es==="cn",ts=Ht?"QODERCN_":"QODER_",it=`${ts}VPC_ENDPOINT`,v=Ht?{productName:"QoderCN",packageName:"@qodercn-ai/qodercn-agent-sdk",cliCommands:["qoderclicn","qodercn"],configDirName:".qoder-cn",projectConfigDirName:".qoder",configDirEnv:"QODERCN_CONFIG_DIR",configDirNameEnv:"QODERCN_CONFIG_DIR_NAME",cliHomeEnv:"QODERCN_CLI_HOME",accessTokenEnv:"QODERCN_PERSONAL_ACCESS_TOKEN",serviceAccountEnv:"QODERCN_SERVICE_ACCOUNT_KEY"}:{productName:"Qoder",packageName:"@qoder-ai/qoder-agent-sdk",cliCommands:["qodercli","qoder"],configDirName:".qoder",projectConfigDirName:".qoder",configDirEnv:"QODER_CONFIG_DIR",configDirNameEnv:"QODER_CONFIG_DIR_NAME",cliHomeEnv:"QODER_CLI_HOME",accessTokenEnv:"QODER_PERSONAL_ACCESS_TOKEN",serviceAccountEnv:"QODER_SERVICE_ACCOUNT_KEY"};var Jt=v.accessTokenEnv,Ce=v.serviceAccountEnv;function ns(n){return{type:"accessToken",accessToken:n}}function rs(n=Jt){return{type:"accessToken",accessToken:{envVar:n}}}function ss(){return{type:"qodercli"}}function os(n){let e=n.serviceAccountKey!==void 0,t=typeof n.fetchServiceAccountToken=="function";if(e===t)throw new TypeError("serviceAccount() requires exactly one credential source: serviceAccountKey or fetchServiceAccountToken");return{type:"serviceAccount",...n}}function is(n=Ce){return{type:"serviceAccount",serviceAccountKey:{envVar:n}}}function as(n){return{type:"jobToken",fetchJobToken:n}}var Vt=["l1StaticCheck","l2LightweightScan","l3DeepScan"];function Yt(n){if(n===null||typeof n!="object"||Array.isArray(n))throw new TypeError("securityScan must be an object.");let e=new Set(Vt),t=Object.keys(n).filter(r=>!e.has(r));if(t.length>0)throw new TypeError(`securityScan contains unknown option${t.length===1?"":"s"}: ${t.join(", ")}.`);for(let r of Vt){let s=n[r];if(s!==void 0&&typeof s!="boolean")throw new TypeError(`securityScan.${r} must be a boolean.`)}return{l1StaticCheck:n.l1StaticCheck??!1,l2LightweightScan:n.l2LightweightScan??!1,l3DeepScan:n.l3DeepScan??!1}}var tn="QODER_AGENT_SDK_ENTRYPOINT",nn="QODER_AGENT_SDK_VERSION",rn="QODER_SDK_AUTH_PAYLOAD_FILE",hs="sdk-ts",ys=gs(import.meta.url),sn=un(ys),Me=class extends Error{code="auth_access_token_env_var_not_configured";constructor(e){super(`The auth access token environment variable "${e}" is not set; set it or pass auth.accessToken directly.`),this.name="AuthAccessTokenEnvVarError"}},Ae=class extends Error{code="auth_service_account_env_var_not_configured";constructor(e){super(`The Service Account key environment variable "${e}" is not set; set it or pass auth.serviceAccountKey directly.`),this.name="AuthServiceAccountEnvVarError"}};function cn(n){return/\.(js|mjs|tsx?|jsx)$/.test(n)}function Z(){if(process.env.QODERCLI_PATH)return process.env.QODERCLI_PATH;let n=Ss();if(n)return n;let e=vs();if(xe(e))return e;let t=ws();return t||v.cliCommands[0]}function Ss(){for(let n of ln())for(let e of v.cliCommands){let t=process.platform==="win32"?`${e}.exe`:e,r=O(n,"dist","_bundled",t);if(xe(r))return r}return null}function vs(){for(let n of ln())for(let e of v.cliCommands){let t=process.platform==="win32"?`${e}.exe`:e,r=[O(n,"node_modules",".bin",t),O(n,"..","..",".bin",t)];for(let s of r)if(xe(s))return s}return v.cliCommands[0]}function ws(){let n=process.env[v.cliHomeEnv]??fs();for(let e of v.cliCommands){let t=process.platform==="win32"?`${e}.exe`:e,r=O(n,v.configDirName,"local",t);if(xe(r))return r}return null}function ln(){let n=[O(sn,".."),O(sn,"..","..")];return[...new Set(n)]}function ks(){return{allow:[],ask:[],deny:[]}}function on(n){return n.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}function bs(n,e){if(e.startsWith("mcp__"))return e;let t=on(n),r=e==="*"?"*":on(e);if(!t||!r)throw new Error(`Invalid MCP tool policy name for server "${n}" and tool "${e}"`);return`mcp__${t}__${r}`}function an(n,e){if(e.length===0)return;let t=new Set(n);for(let r of e)t.has(r)||(n.push(r),t.add(r))}function Rs(n){let e=n??{},t=e.general&&typeof e.general=="object"&&!Array.isArray(e.general)?e.general:{},r=t.fileCheckpointing&&typeof t.fileCheckpointing=="object"&&!Array.isArray(t.fileCheckpointing)?t.fileCheckpointing:{};return{...e,general:{...t,fileCheckpointing:{...r,enabled:!0}}}}var X=class{options;diagnostics;logPrefix;authPayloadPath=null;generatedSettingsDir;constructor(e,t,r="[RuntimeLaunch]"){this.options=e,this.diagnostics=t,this.logPrefix=r}async prepare(){return this.options.auth&&(this.authPayloadPath=await this.createAuthPayloadFile(this.options.auth)),{args:this.buildArgs(),env:this.buildEnv(),authPayloadPath:this.authPayloadPath??void 0}}cleanupGeneratedSettings(){if(this.generatedSettingsDir)try{ps(this.generatedSettingsDir,{recursive:!0,force:!0})}catch{}finally{this.generatedSettingsDir=void 0}}async cleanupAuthPayload(){if(!this.authPayloadPath)return;let e=un(this.authPayloadPath);try{await Zt(e,{recursive:!0,force:!0}),this.diagnostics?.record(`${this.logPrefix} Auth payload cleaned up`)}catch{}this.authPayloadPath=null}buildEnv(){let e=this.options.env??{...process.env},t={};for(let[r,s]of Object.entries(e))s!==void 0&&(t[r]=s);delete t[tn],delete t[nn],delete t[rn];for(let r of this.serviceAccountCredentialEnvVars())Es(t,r);if(t[tn]=hs,t[nn]=Bt,this.authPayloadPath&&(t[rn]=this.authPayloadPath),delete t.NODE_OPTIONS,this.options.vpcEndpoint!==void 0){let r=this.options.vpcEndpoint.trim();r?t[it]=r:delete t[it]}return t}serviceAccountCredentialEnvVars(){let e=this.options.auth;if(e?.type!=="serviceAccount")return[];let t=[Ce];return e.serviceAccountKey&&typeof e.serviceAccountKey!="string"&&t.push(e.serviceAccountKey.envVar),t}buildArgs(){let e=[],t=this.options;if(t.extraArgs&&Object.hasOwn(t.extraArgs,"proxy"))throw new Error("extraArgs.proxy is reserved; use the dedicated proxy option instead.");if(e.push("--print"),e.push("--output-format","stream-json"),e.push("--input-format","stream-json"),t.sessionMirror&&e.push("--session-mirror"),t.persistSession===!1&&e.push("--no-session-persistence"),t.model&&e.push("--model",t.model),t.proxy!==void 0&&e.push("--proxy",t.proxy),t.agent&&e.push("--agent",t.agent),t.debug&&e.push("--debug"),t.resume?e.push("--resume",t.resume):t.continue&&e.push("--continue"),t.resumeSessionAt&&e.push(`--resume-session-at=${t.resumeSessionAt}`),t.resumeDropsTurn!==void 0&&e.push(`--resume-drops-turn=${t.resumeDropsTurn}`),t.sessionId&&e.push("--session-id",t.sessionId),t.permissionMode&&(t.permissionMode==="yolo"?e.push("--yolo"):e.push("--permission-mode",t.permissionMode)),t.allowDangerouslySkipPermissions&&t.permissionMode!=="yolo"&&e.push("--dangerously-skip-permissions"),t.includePartialMessages&&e.push("--include-partial-messages"),t.allowedTools&&t.allowedTools.length>0)for(let o of t.allowedTools)e.push("--allowed-tools",o);if(t.disallowedTools&&t.disallowedTools.length>0)for(let o of t.disallowedTools)e.push("--disallowed-tools",o);let r=t.tools??zt(t.env??process.env);if(Array.isArray(r)?e.push("--tools",r.join(",")):e.push("--tools","default"),t.canUseTool){if(t.permissionPromptToolName)throw new Error("canUseTool callback cannot be used with permissionPromptToolName. Please use one or the other.");e.push("--permission-prompt-tool","stdio")}else t.permissionPromptToolName&&e.push("--permission-prompt-tool",t.permissionPromptToolName);if(t.extensions&&t.extensions.length>0)for(let o of t.extensions)e.push("--extensions",o);if(t.mcpServers&&Object.keys(t.mcpServers).length>0&&e.push("--mcp-config",JSON.stringify({mcpServers:this.buildCliMcpServers()})),t.allowedMcpServerNames&&t.allowedMcpServerNames.length>0)for(let o of t.allowedMcpServerNames)e.push("--allowed-mcp-server-names",o);t.strictMcpConfig&&e.push("--strict-mcp-config");let s=this.buildSettingsArg();if(s!==void 0&&e.push("--settings",s),t.settingSources!==void 0&&e.push("--setting-sources",t.settingSources.join(",")),e.push("--disable-builtin-skills"),t.additionalDirectories&&t.additionalDirectories.length>0)for(let o of t.additionalDirectories)e.push("--add-dir",o);if(t.maxTurns!==void 0&&e.push("--max-turns",String(t.maxTurns)),t.forkSession&&e.push("--fork-session"),t.plugins&&t.plugins.length>0)for(let o of t.plugins)o.type==="local"&&e.push("--plugin-dir",o.path);if(t.extraArgs)for(let[o,i]of Object.entries(t.extraArgs))e.push(`--${o}`),i!==null&&e.push(i);return e}buildSettingsArg(){let e=this.options.settings,t=this.collectMcpPolicyPermissionRules();if(typeof e=="string"){if(e.length===0)return;if(!this.hasMcpPolicyRules(t)&&!this.options.enableFileCheckpointing&&this.options.securityScan===void 0&&(!this.options.additionalDirectories||this.options.additionalDirectories.length===0))return e;let o=this.readSettingsFile(e);this.applySettingsCompatibility(o),this.applyAdditionalDirectories(o),this.applyMcpPolicyRules(o,t),this.applySecurityScanSetting(o);let i=this.applyFileCheckpointingSetting(o);return Object.keys(i).length>0?this.writeGeneratedSettingsFile(i):void 0}let r={...e??{}};this.applySettingsCompatibility(r),this.applyAdditionalDirectories(r),this.applyMcpPolicyRules(r,t),this.applySecurityScanSetting(r);let s=this.applyFileCheckpointingSetting(r);return Object.keys(s).length>0?JSON.stringify(s):void 0}applyFileCheckpointingSetting(e){return this.options.enableFileCheckpointing?Rs(e):e}applySecurityScanSetting(e){let t=this.options.securityScan;t!==void 0&&(e.securityScan=Yt(t))}applySettingsCompatibility(e){let t=e.permissions;if(t?.defaultMode!==void 0){let r=e.general!==null&&typeof e.general=="object"?e.general:{},s=this.toQoderDefaultPermissionMode(t.defaultMode);s!==void 0&&r.defaultPermissionMode===void 0&&(r.defaultPermissionMode=s),e.general=r}t?.disableBypassPermissionsMode==="disable"&&(e.security={...e.security??{},disableYoloMode:!0})}toQoderDefaultPermissionMode(e){switch(e){case"acceptEdits":return"accept_edits";case"bypassPermissions":case"yolo":return"bypass_permissions";case"dontAsk":return"dont_ask";case"default":case"accept_edits":case"bypass_permissions":case"dont_ask":case"plan":case"auto":return e;default:return}}applyAdditionalDirectories(e){let t=this.options.additionalDirectories;if(!t||t.length===0)return;let r=e.permissions!==null&&typeof e.permissions=="object"?e.permissions:{},s=Array.isArray(r.additionalDirectories)?[...r.additionalDirectories]:[];an(s,t),r.additionalDirectories=s,e.permissions=r}buildCliMcpServers(){let e=this.options.mcpServers;if(!e||Object.keys(e).length===0)return e;let t={};for(let[r,s]of Object.entries(e)){let o=this.options.mcpToolPolicies?.[r]??s.tools??[];t[r]=ot(r,s,o)}return t}collectMcpPolicyPermissionRules(){let e=ks(),t=new Map;for(let[r,s]of Object.entries(this.options.mcpToolPolicies??{}))s.length>0&&t.set(r,s);for(let[r,s]of Object.entries(this.options.mcpServers??{})){let o=s.tools;Array.isArray(o)&&o.length>0&&t.set(r,[...t.get(r)??[],...o])}for(let[r,s]of t)for(let o of s){let i=bs(r,o.name);switch(o.permission_policy){case"always_allow":e.allow.push(i);break;case"always_ask":e.ask.push(i);break;case"always_deny":e.deny.push(i);break;case void 0:break}}return e}hasMcpPolicyRules(e){return e.allow.length>0||e.ask.length>0||e.deny.length>0}applyMcpPolicyRules(e,t){if(!this.hasMcpPolicyRules(t))return;let r=e.permissions!==null&&typeof e.permissions=="object"?e.permissions:{};e.permissions=r;for(let s of["allow","ask","deny"]){let o=Array.isArray(r[s])?[...r[s]]:[];an(o,t[s]),r[s]=o}}readSettingsFile(e){let t=ds(e,"utf8").trim();if(!t)return{};let r=JSON.parse(t);if(r===null||typeof r!="object"||Array.isArray(r))throw new Error("Settings file must contain a JSON object.");return r}writeGeneratedSettingsFile(e){this.generatedSettingsDir=ls(O(en(),"qoder-agent-sdk-settings-"));let t=O(this.generatedSettingsDir,"settings.json");return ms(t,JSON.stringify(e),"utf8"),t}async createAuthPayloadFile(e){let t=this.buildAuthPayload(e),r=await us(O(en(),"qoder-sdk-auth-"));try{await Xt(r,448);let s=O(r,"payload.json");return await cs(s,JSON.stringify(t),{mode:384}),await Xt(s,384),this.diagnostics?.record(`${this.logPrefix} Auth payload created: type=${t.type}, path=${s}`),s}catch(s){throw await Zt(r,{recursive:!0,force:!0}).catch(()=>{}),s}}buildAuthPayload(e){switch(e.type){case"accessToken":return{type:"accessToken",accessToken:this.resolveAccessToken(e)};case"qodercli":return{type:"qodercli"};case"jobToken":return{type:"jobToken",jobTokenProvider:"host"};case"serviceAccount":{let t=e.serviceAccountKey!==void 0,r=typeof e.fetchServiceAccountToken=="function";if(t===r)throw new TypeError("Service Account auth requires exactly one credential source: serviceAccountKey or fetchServiceAccountToken");return r?{type:"serviceAccount",serviceAccountTokenProvider:"host"}:{type:"serviceAccount",serviceAccountKey:this.resolveServiceAccountKey(e)}}}}resolveServiceAccountKey(e){if(!e.serviceAccountKey)throw new Error("Service Account key authentication requires serviceAccountKey");if(typeof e.serviceAccountKey=="string")return e.serviceAccountKey;let t=e.serviceAccountKey.envVar,r=this.options.env&&Object.hasOwn(this.options.env,t)?this.options.env[t]:process.env[t];if(!r)throw new Ae(t);return r}resolveAccessToken(e){if(typeof e.accessToken=="string")return e.accessToken;let t=e.accessToken.envVar,r=this.options.env&&Object.hasOwn(this.options.env,t)?this.options.env[t]:process.env[t];if(!r)throw new Me(t);return r}};function Es(n,e){if(process.platform!=="win32"){delete n[e];return}let t=e.toLowerCase();for(let r of Object.keys(n))r.toLowerCase()===t&&delete n[r]}function Ie(n,e){let t={...n};for(let[r,s]of Object.entries(e))s!==void 0&&(t[r]=s);return t}var Ts=new Set(["--mcp-config","--proxy","--settings"]);function Oe(n){let e=[];for(let t=0;t<n.length;t+=1){let r=n[t];e.push(r),Ts.has(r)&&t+1<n.length&&(e.push("[redacted]"),t+=1)}return e.join(" ")}var dn=8192,ee=class extends Error{code="QODER_CLI_PROCESS_ERROR";exitCode;signal;stderr;constructor(e,t){super(e,t?.cause?{cause:t.cause}:void 0),this.name="QoderCliProcessError",this.exitCode=t?.exitCode,this.signal=t?.signal,this.stderr=t?.stderr}},te=class n{static default=new n;process=null;customHandle=null;options;ready=!1;closed=!1;initializePromise=null;authExpiredFired=!1;pendingInput=[];diagnostics;processExitError;stderrTail="";launchOptionsBuilder;constructor(e={}){this.options={...e},this.diagnostics=e.diagnostics,this.launchOptionsBuilder=new X(this.options,this.diagnostics,"[ProcessTransport]")}create(e){return new n(Ie(this.options,e))}async initialize(){if(!this.ready)return this.initializePromise||(this.initializePromise=this._doInitialize()),this.initializePromise}async _doInitialize(){try{let e=await this.launchOptionsBuilder.prepare(),t=e.args;if(this.closed){await this.cleanupAuthPayload();return}let r=e.env,{command:s,commandArgs:o}=this.resolveExecutable(t);if(this.diagnostics?.record(`[ProcessTransport] Spawning: ${s} ${Oe(o)}`),this.diagnostics?.record(`[ProcessTransport] CWD: ${this.options.cwd??""}`),this.options.spawnQoderCLIProcess){let i=this.options.spawnQoderCLIProcess({command:s,args:o,cwd:this.options.cwd,env:r,signal:this.options.abortController?.signal??new AbortController().signal});this.customHandle=i,i.once("error",a=>{this.ready=!1,this.processExitError=this.createSpawnError(a),this.diagnostics?.record("[ProcessTransport] Process error:",a),this.cleanupAuthPayload().catch(()=>{})}),i.once("exit",(a,u)=>{this.ready=!1,a===q&&this.fireAuthExpired();let c=this.createProcessExitError(a,u);c&&(this.processExitError=c),this.cleanupAuthPayload().catch(()=>{})})}else this.process=Ps(s,o,{cwd:this.options.cwd,env:r,stdio:["pipe","pipe",this.options.stderr??"pipe"]}),this.process.on("error",i=>{this.ready=!1,this.processExitError=this.createSpawnError(i),this.diagnostics?.record("[ProcessTransport] Process error:",i),this.cleanupAuthPayload().catch(()=>{})}),this.process.on("exit",(i,a)=>{this.ready=!1,this.diagnostics?.record(`[ProcessTransport] Process exited: code=${i}, signal=${a}`),i===q&&this.fireAuthExpired();let u=this.createProcessExitError(i,a);u&&(this.processExitError=u),this.cleanupAuthPayload().catch(()=>{})}),this.process.stderr?.on("data",i=>{let a=i.toString();this.appendStderr(a),this.options.stderrHandler?.(a);let u=a.trim();u&&this.diagnostics?.record(`[ProcessTransport] STDERR: ${u}`)});this.ready=!0,this.flushPendingInput()}catch(e){throw await this.cleanupAuthPayload(),e}}write(e){if(this.processExitError)throw this.processExitError;if(this.closed)throw new Error("Transport is not ready or has been closed");let t=e.endsWith(`
|
|
1
|
+
var Wr=Object.defineProperty;var Hr=(n,e)=>{for(var t in e)Wr(n,t,{get:e[t],enumerable:!0})};import{spawn as Ps}from"child_process";import{createInterface as _s}from"readline";var Jr=["PreToolUse","PostToolUse","PostToolUseFailure","UserPromptSubmit","SessionStart","SessionEnd","Stop","SubagentStart","SubagentStop","PreCompact","PostCompact","CwdChanged","InstructionsLoaded","FileChanged","PermissionRequest","PermissionDenied","WorktreeCreate","WorktreeRemove"],Vr=["clear","resume","logout","prompt_input_exit","other","bypass_permissions_disabled"],_e=2e3,Gt=5e3;var Bt="1.0.27";var q=41,$t=["Agent","AskUserQuestion","Bash","Edit","Glob","Grep","ImageGen","ImageSearch","NotebookEdit","Read","Skill","TaskCreate","TaskGet","TaskUpdate","TaskList","UpdateGoal","WebFetch","WebSearch","Write"],Qt=["TaskCreate","TaskGet","TaskUpdate","TaskList"],Yr="QODER_FEATURE_TASKS";function zt(n){let e=n[Yr];if(e!=="0"&&e!=="false")return[...$t];let t=new Set(Qt);return $t.flatMap(r=>r===Qt[0]?["TodoWrite"]:t.has(r)?[]:[r])}import{chmod as Xt,mkdtemp as us,rm as Zt,writeFile as cs}from"fs/promises";import{existsSync as xe,mkdtempSync as ls,readFileSync as ds,rmSync as ps,writeFileSync as ms}from"fs";import{homedir as fs,tmpdir as en}from"os";import{dirname as un,join as O}from"path";import{fileURLToPath as gs}from"url";var Xr=/^[A-Za-z0-9_-]{1,64}$/,Zr=new Set(["mcp_list","mcp_get","mcp_call"]);function rt(n,e){if(e.exposedName!==void 0){if(e.alwaysLoad!==!0)throw new Error(`MCP tool "${n}/${e.name}" requires alwaysLoad: true when exposedName is set.`);if(!Xr.test(e.exposedName))throw new Error(`MCP tool "${n}/${e.name}" has invalid exposedName "${e.exposedName}".`);if(Zr.has(e.exposedName))throw new Error(`MCP tool "${n}/${e.name}" cannot use reserved exposedName "${e.exposedName}".`)}}function st(n,e){let t={};for(let r of e)rt(n,r),(r.exposedName!==void 0||r.alwaysLoad===!0)&&(t[r.name]={...r.exposedName!==void 0?{exposedName:r.exposedName}:{},...r.alwaysLoad===!0?{alwaysLoad:!0}:{}});return Object.keys(t).length>0?t:void 0}function ot(n,e,t=e.tools??[]){let{tools:r,...s}=e,o=st(n,t);return{...s,...o?{toolOverrides:o}:{}}}function Wt(n){let e={};for(let[t,r]of Object.entries(n)){if(r.type==="sdk")throw new Error(`MCP server "${t}" uses an in-process SDK transport and cannot be changed with setMcpServers().`);let s=r.tools??[],o=s.find(i=>i.permission_policy!==void 0);if(o)throw new Error(`MCP tool "${t}/${o.name}" cannot set permission_policy through setMcpServers(); configure it when creating the query.`);e[t]=ot(t,r,s)}return e}var es="global",Ht=es==="cn",ts=Ht?"QODERCN_":"QODER_",it=`${ts}VPC_ENDPOINT`,v=Ht?{productName:"QoderCN",packageName:"@qodercn-ai/qodercn-agent-sdk",cliCommands:["qoderclicn","qodercn"],configDirName:".qoder-cn",projectConfigDirName:".qoder",configDirEnv:"QODERCN_CONFIG_DIR",configDirNameEnv:"QODERCN_CONFIG_DIR_NAME",cliHomeEnv:"QODERCN_CLI_HOME",accessTokenEnv:"QODERCN_PERSONAL_ACCESS_TOKEN",serviceAccountEnv:"QODERCN_SERVICE_ACCOUNT_KEY"}:{productName:"Qoder",packageName:"@qoder-ai/qoder-agent-sdk",cliCommands:["qodercli","qoder"],configDirName:".qoder",projectConfigDirName:".qoder",configDirEnv:"QODER_CONFIG_DIR",configDirNameEnv:"QODER_CONFIG_DIR_NAME",cliHomeEnv:"QODER_CLI_HOME",accessTokenEnv:"QODER_PERSONAL_ACCESS_TOKEN",serviceAccountEnv:"QODER_SERVICE_ACCOUNT_KEY"};var Jt=v.accessTokenEnv,Ce=v.serviceAccountEnv;function ns(n){return{type:"accessToken",accessToken:n}}function rs(n=Jt){return{type:"accessToken",accessToken:{envVar:n}}}function ss(){return{type:"qodercli"}}function os(n){let e=n.serviceAccountKey!==void 0,t=typeof n.fetchServiceAccountToken=="function";if(e===t)throw new TypeError("serviceAccount() requires exactly one credential source: serviceAccountKey or fetchServiceAccountToken");return{type:"serviceAccount",...n}}function is(n=Ce){return{type:"serviceAccount",serviceAccountKey:{envVar:n}}}function as(n){return{type:"jobToken",fetchJobToken:n}}var Vt=["l1StaticCheck","l2LightweightScan","l3DeepScan"];function Yt(n){if(n===null||typeof n!="object"||Array.isArray(n))throw new TypeError("securityScan must be an object.");let e=new Set(Vt),t=Object.keys(n).filter(r=>!e.has(r));if(t.length>0)throw new TypeError(`securityScan contains unknown option${t.length===1?"":"s"}: ${t.join(", ")}.`);for(let r of Vt){let s=n[r];if(s!==void 0&&typeof s!="boolean")throw new TypeError(`securityScan.${r} must be a boolean.`)}return{l1StaticCheck:n.l1StaticCheck??!1,l2LightweightScan:n.l2LightweightScan??!1,l3DeepScan:n.l3DeepScan??!1}}var tn="QODER_AGENT_SDK_ENTRYPOINT",nn="QODER_AGENT_SDK_VERSION",rn="QODER_SDK_AUTH_PAYLOAD_FILE",hs="sdk-ts",ys=gs(import.meta.url),sn=un(ys),Me=class extends Error{code="auth_access_token_env_var_not_configured";constructor(e){super(`The auth access token environment variable "${e}" is not set; set it or pass auth.accessToken directly.`),this.name="AuthAccessTokenEnvVarError"}},Ae=class extends Error{code="auth_service_account_env_var_not_configured";constructor(e){super(`The Service Account key environment variable "${e}" is not set; set it or pass auth.serviceAccountKey directly.`),this.name="AuthServiceAccountEnvVarError"}};function cn(n){return/\.(js|mjs|tsx?|jsx)$/.test(n)}function Z(){if(process.env.QODERCLI_PATH)return process.env.QODERCLI_PATH;let n=Ss();if(n)return n;let e=vs();if(xe(e))return e;let t=ws();return t||v.cliCommands[0]}function Ss(){for(let n of ln())for(let e of v.cliCommands){let t=process.platform==="win32"?`${e}.exe`:e,r=O(n,"dist","_bundled",t);if(xe(r))return r}return null}function vs(){for(let n of ln())for(let e of v.cliCommands){let t=process.platform==="win32"?`${e}.exe`:e,r=[O(n,"node_modules",".bin",t),O(n,"..","..",".bin",t)];for(let s of r)if(xe(s))return s}return v.cliCommands[0]}function ws(){let n=process.env[v.cliHomeEnv]??fs();for(let e of v.cliCommands){let t=process.platform==="win32"?`${e}.exe`:e,r=O(n,v.configDirName,"local",t);if(xe(r))return r}return null}function ln(){let n=[O(sn,".."),O(sn,"..","..")];return[...new Set(n)]}function ks(){return{allow:[],ask:[],deny:[]}}function on(n){return n.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}function bs(n,e){if(e.startsWith("mcp__"))return e;let t=on(n),r=e==="*"?"*":on(e);if(!t||!r)throw new Error(`Invalid MCP tool policy name for server "${n}" and tool "${e}"`);return`mcp__${t}__${r}`}function an(n,e){if(e.length===0)return;let t=new Set(n);for(let r of e)t.has(r)||(n.push(r),t.add(r))}function Rs(n){let e=n??{},t=e.general&&typeof e.general=="object"&&!Array.isArray(e.general)?e.general:{},r=t.fileCheckpointing&&typeof t.fileCheckpointing=="object"&&!Array.isArray(t.fileCheckpointing)?t.fileCheckpointing:{};return{...e,general:{...t,fileCheckpointing:{...r,enabled:!0}}}}var X=class{options;diagnostics;logPrefix;authPayloadPath=null;generatedSettingsDir;constructor(e,t,r="[RuntimeLaunch]"){this.options=e,this.diagnostics=t,this.logPrefix=r}async prepare(){return this.options.auth&&(this.authPayloadPath=await this.createAuthPayloadFile(this.options.auth)),{args:this.buildArgs(),env:this.buildEnv(),authPayloadPath:this.authPayloadPath??void 0}}cleanupGeneratedSettings(){if(this.generatedSettingsDir)try{ps(this.generatedSettingsDir,{recursive:!0,force:!0})}catch{}finally{this.generatedSettingsDir=void 0}}async cleanupAuthPayload(){if(!this.authPayloadPath)return;let e=un(this.authPayloadPath);try{await Zt(e,{recursive:!0,force:!0}),this.diagnostics?.record(`${this.logPrefix} Auth payload cleaned up`)}catch{}this.authPayloadPath=null}buildEnv(){let e=this.options.env??{...process.env},t={};for(let[r,s]of Object.entries(e))s!==void 0&&(t[r]=s);delete t[tn],delete t[nn],delete t[rn];for(let r of this.serviceAccountCredentialEnvVars())Es(t,r);if(t[tn]=hs,t[nn]=Bt,this.authPayloadPath&&(t[rn]=this.authPayloadPath),delete t.NODE_OPTIONS,this.options.vpcEndpoint!==void 0){let r=this.options.vpcEndpoint.trim();r?t[it]=r:delete t[it]}return t}serviceAccountCredentialEnvVars(){let e=this.options.auth;if(e?.type!=="serviceAccount")return[];let t=[Ce];return e.serviceAccountKey&&typeof e.serviceAccountKey!="string"&&t.push(e.serviceAccountKey.envVar),t}buildArgs(){let e=[],t=this.options;if(t.extraArgs&&Object.hasOwn(t.extraArgs,"proxy"))throw new Error("extraArgs.proxy is reserved; use the dedicated proxy option instead.");if(e.push("--print"),e.push("--output-format","stream-json"),e.push("--input-format","stream-json"),t.sessionMirror&&e.push("--session-mirror"),t.persistSession===!1&&e.push("--no-session-persistence"),t.model&&e.push("--model",t.model),t.proxy!==void 0&&e.push("--proxy",t.proxy),t.agent&&e.push("--agent",t.agent),t.debug&&e.push("--debug"),t.resume?e.push("--resume",t.resume):t.continue&&e.push("--continue"),t.resumeSessionAt&&e.push(`--resume-session-at=${t.resumeSessionAt}`),t.resumeDropsTurn!==void 0&&e.push(`--resume-drops-turn=${t.resumeDropsTurn}`),t.sessionId&&e.push("--session-id",t.sessionId),t.permissionMode&&(t.permissionMode==="yolo"?e.push("--yolo"):e.push("--permission-mode",t.permissionMode)),t.allowDangerouslySkipPermissions&&t.permissionMode!=="yolo"&&e.push("--dangerously-skip-permissions"),t.includePartialMessages&&e.push("--include-partial-messages"),t.allowedTools&&t.allowedTools.length>0)for(let o of t.allowedTools)e.push("--allowed-tools",o);if(t.disallowedTools&&t.disallowedTools.length>0)for(let o of t.disallowedTools)e.push("--disallowed-tools",o);let r=t.tools??zt(t.env??process.env);if(Array.isArray(r)?e.push("--tools",r.join(",")):e.push("--tools","default"),t.canUseTool){if(t.permissionPromptToolName)throw new Error("canUseTool callback cannot be used with permissionPromptToolName. Please use one or the other.");e.push("--permission-prompt-tool","stdio")}else t.permissionPromptToolName&&e.push("--permission-prompt-tool",t.permissionPromptToolName);if(t.extensions&&t.extensions.length>0)for(let o of t.extensions)e.push("--extensions",o);if(t.mcpServers&&Object.keys(t.mcpServers).length>0&&e.push("--mcp-config",JSON.stringify({mcpServers:this.buildCliMcpServers()})),t.allowedMcpServerNames&&t.allowedMcpServerNames.length>0)for(let o of t.allowedMcpServerNames)e.push("--allowed-mcp-server-names",o);t.strictMcpConfig&&e.push("--strict-mcp-config");let s=this.buildSettingsArg();if(s!==void 0&&e.push("--settings",s),t.settingSources!==void 0&&e.push("--setting-sources",t.settingSources.join(",")),e.push("--disable-builtin-skills"),t.additionalDirectories&&t.additionalDirectories.length>0)for(let o of t.additionalDirectories)e.push("--add-dir",o);if(t.maxTurns!==void 0&&e.push("--max-turns",String(t.maxTurns)),t.forkSession&&e.push("--fork-session"),t.plugins&&t.plugins.length>0)for(let o of t.plugins)o.type==="local"&&e.push("--plugin-dir",o.path);if(t.extraArgs)for(let[o,i]of Object.entries(t.extraArgs))e.push(`--${o}`),i!==null&&e.push(i);return e}buildSettingsArg(){let e=this.options.settings,t=this.collectMcpPolicyPermissionRules();if(typeof e=="string"){if(e.length===0)return;if(!this.hasMcpPolicyRules(t)&&!this.options.enableFileCheckpointing&&this.options.securityScan===void 0&&(!this.options.additionalDirectories||this.options.additionalDirectories.length===0))return e;let o=this.readSettingsFile(e);this.applySettingsCompatibility(o),this.applyAdditionalDirectories(o),this.applyMcpPolicyRules(o,t),this.applySecurityScanSetting(o);let i=this.applyFileCheckpointingSetting(o);return Object.keys(i).length>0?this.writeGeneratedSettingsFile(i):void 0}let r={...e??{}};this.applySettingsCompatibility(r),this.applyAdditionalDirectories(r),this.applyMcpPolicyRules(r,t),this.applySecurityScanSetting(r);let s=this.applyFileCheckpointingSetting(r);return Object.keys(s).length>0?JSON.stringify(s):void 0}applyFileCheckpointingSetting(e){return this.options.enableFileCheckpointing?Rs(e):e}applySecurityScanSetting(e){let t=this.options.securityScan;t!==void 0&&(e.securityScan=Yt(t))}applySettingsCompatibility(e){let t=e.permissions;if(t?.defaultMode!==void 0){let r=e.general!==null&&typeof e.general=="object"?e.general:{},s=this.toQoderDefaultPermissionMode(t.defaultMode);s!==void 0&&r.defaultPermissionMode===void 0&&(r.defaultPermissionMode=s),e.general=r}t?.disableBypassPermissionsMode==="disable"&&(e.security={...e.security??{},disableYoloMode:!0})}toQoderDefaultPermissionMode(e){switch(e){case"acceptEdits":return"accept_edits";case"bypassPermissions":case"yolo":return"bypass_permissions";case"dontAsk":return"dont_ask";case"default":case"accept_edits":case"bypass_permissions":case"dont_ask":case"plan":case"auto":return e;default:return}}applyAdditionalDirectories(e){let t=this.options.additionalDirectories;if(!t||t.length===0)return;let r=e.permissions!==null&&typeof e.permissions=="object"?e.permissions:{},s=Array.isArray(r.additionalDirectories)?[...r.additionalDirectories]:[];an(s,t),r.additionalDirectories=s,e.permissions=r}buildCliMcpServers(){let e=this.options.mcpServers;if(!e||Object.keys(e).length===0)return e;let t={};for(let[r,s]of Object.entries(e)){let o=this.options.mcpToolPolicies?.[r]??s.tools??[];t[r]=ot(r,s,o)}return t}collectMcpPolicyPermissionRules(){let e=ks(),t=new Map;for(let[r,s]of Object.entries(this.options.mcpToolPolicies??{}))s.length>0&&t.set(r,s);for(let[r,s]of Object.entries(this.options.mcpServers??{})){let o=s.tools;Array.isArray(o)&&o.length>0&&t.set(r,[...t.get(r)??[],...o])}for(let[r,s]of t)for(let o of s){let i=bs(r,o.name);switch(o.permission_policy){case"always_allow":e.allow.push(i);break;case"always_ask":e.ask.push(i);break;case"always_deny":e.deny.push(i);break;case void 0:break}}return e}hasMcpPolicyRules(e){return e.allow.length>0||e.ask.length>0||e.deny.length>0}applyMcpPolicyRules(e,t){if(!this.hasMcpPolicyRules(t))return;let r=e.permissions!==null&&typeof e.permissions=="object"?e.permissions:{};e.permissions=r;for(let s of["allow","ask","deny"]){let o=Array.isArray(r[s])?[...r[s]]:[];an(o,t[s]),r[s]=o}}readSettingsFile(e){let t=ds(e,"utf8").trim();if(!t)return{};let r=JSON.parse(t);if(r===null||typeof r!="object"||Array.isArray(r))throw new Error("Settings file must contain a JSON object.");return r}writeGeneratedSettingsFile(e){this.generatedSettingsDir=ls(O(en(),"qoder-agent-sdk-settings-"));let t=O(this.generatedSettingsDir,"settings.json");return ms(t,JSON.stringify(e),"utf8"),t}async createAuthPayloadFile(e){let t=this.buildAuthPayload(e),r=await us(O(en(),"qoder-sdk-auth-"));try{await Xt(r,448);let s=O(r,"payload.json");return await cs(s,JSON.stringify(t),{mode:384}),await Xt(s,384),this.diagnostics?.record(`${this.logPrefix} Auth payload created: type=${t.type}, path=${s}`),s}catch(s){throw await Zt(r,{recursive:!0,force:!0}).catch(()=>{}),s}}buildAuthPayload(e){switch(e.type){case"accessToken":return{type:"accessToken",accessToken:this.resolveAccessToken(e)};case"qodercli":return{type:"qodercli"};case"jobToken":return{type:"jobToken",jobTokenProvider:"host"};case"serviceAccount":{let t=e.serviceAccountKey!==void 0,r=typeof e.fetchServiceAccountToken=="function";if(t===r)throw new TypeError("Service Account auth requires exactly one credential source: serviceAccountKey or fetchServiceAccountToken");return r?{type:"serviceAccount",serviceAccountTokenProvider:"host"}:{type:"serviceAccount",serviceAccountKey:this.resolveServiceAccountKey(e)}}}}resolveServiceAccountKey(e){if(!e.serviceAccountKey)throw new Error("Service Account key authentication requires serviceAccountKey");if(typeof e.serviceAccountKey=="string")return e.serviceAccountKey;let t=e.serviceAccountKey.envVar,r=this.options.env&&Object.hasOwn(this.options.env,t)?this.options.env[t]:process.env[t];if(!r)throw new Ae(t);return r}resolveAccessToken(e){if(typeof e.accessToken=="string")return e.accessToken;let t=e.accessToken.envVar,r=this.options.env&&Object.hasOwn(this.options.env,t)?this.options.env[t]:process.env[t];if(!r)throw new Me(t);return r}};function Es(n,e){if(process.platform!=="win32"){delete n[e];return}let t=e.toLowerCase();for(let r of Object.keys(n))r.toLowerCase()===t&&delete n[r]}function Ie(n,e){let t={...n};for(let[r,s]of Object.entries(e))s!==void 0&&(t[r]=s);return t}var Ts=new Set(["--mcp-config","--proxy","--settings"]);function Oe(n){let e=[];for(let t=0;t<n.length;t+=1){let r=n[t];e.push(r),Ts.has(r)&&t+1<n.length&&(e.push("[redacted]"),t+=1)}return e.join(" ")}var dn=8192,ee=class extends Error{code="QODER_CLI_PROCESS_ERROR";exitCode;signal;stderr;constructor(e,t){super(e,t?.cause?{cause:t.cause}:void 0),this.name="QoderCliProcessError",this.exitCode=t?.exitCode,this.signal=t?.signal,this.stderr=t?.stderr}},te=class n{static default=new n;process=null;customHandle=null;options;ready=!1;closed=!1;initializePromise=null;authExpiredFired=!1;pendingInput=[];diagnostics;processExitError;stderrTail="";launchOptionsBuilder;constructor(e={}){this.options={...e},this.diagnostics=e.diagnostics,this.launchOptionsBuilder=new X(this.options,this.diagnostics,"[ProcessTransport]")}create(e){return new n(Ie(this.options,e))}async initialize(){if(!this.ready)return this.initializePromise||(this.initializePromise=this._doInitialize()),this.initializePromise}async _doInitialize(){try{let e=await this.launchOptionsBuilder.prepare(),t=e.args;if(this.closed){await this.cleanupAuthPayload();return}let r=e.env,{command:s,commandArgs:o}=this.resolveExecutable(t);if(this.diagnostics?.record(`[ProcessTransport] Spawning: ${s} ${Oe(o)}`),this.diagnostics?.record(`[ProcessTransport] CWD: ${this.options.cwd??""}`),this.options.spawnQoderCLIProcess){let i=this.options.spawnQoderCLIProcess({command:s,args:o,cwd:this.options.cwd,env:r,signal:this.options.abortController?.signal??new AbortController().signal});this.customHandle=i,i.once("error",a=>{this.ready=!1,this.processExitError=this.createSpawnError(a),this.diagnostics?.record("[ProcessTransport] Process error:",a),this.cleanupAuthPayload().catch(()=>{})}),i.once("exit",(a,u)=>{this.ready=!1,a===q&&this.fireAuthExpired();let c=this.createProcessExitError(a,u);c&&(this.processExitError=c),this.cleanupAuthPayload().catch(()=>{})})}else this.process=Ps(s,o,{cwd:this.options.cwd,env:r,stdio:["pipe","pipe",this.options.stderr??"pipe"]}),this.process.on("error",i=>{this.ready=!1,this.processExitError=this.createSpawnError(i),this.diagnostics?.record("[ProcessTransport] Process error:",i),this.cleanupAuthPayload().catch(()=>{})}),this.process.on("exit",(i,a)=>{this.ready=!1,this.diagnostics?.record(`[ProcessTransport] Process exited: code=${i}, signal=${a}`),i===q&&this.fireAuthExpired();let u=this.createProcessExitError(i,a);u&&(this.processExitError=u),this.cleanupAuthPayload().catch(()=>{})}),this.process.stderr?.on("data",i=>{let a=i.toString();this.appendStderr(a),this.options.stderrHandler?.(a);let u=a.trim();u&&this.diagnostics?.record(`[ProcessTransport] STDERR: ${u}`)});this.ready=!0,this.flushPendingInput()}catch(e){throw await this.cleanupAuthPayload(),e}}write(e){if(this.processExitError)throw this.processExitError;if(this.closed)throw new Error("Transport is not ready or has been closed");let t=e.endsWith(`
|
|
2
2
|
`)?e:e+`
|
|
3
3
|
`;if(!this.ready){if(this.initializePromise){this.pendingInput.push({type:"write",line:t});return}throw new Error("Transport is not ready or has been closed")}this.writeReadyLine(t)}writeReadyLine(e){if(this.customHandle){let t=this.customHandle.stdin;if(t.destroyed||t.writableEnded)return;typeof t.write=="function"&&t.write(e)}else this.process?.stdin&&!this.process.stdin.destroyed&&!this.process.stdin.writableEnded&&this.process.stdin.write(e)}flushPendingInput(){if(this.pendingInput.length===0)return;let e=this.pendingInput;this.pendingInput=[];for(let t of e)t.type==="write"?this.writeReadyLine(t.line):this.endReadyInput()}isReady(){return this.ready&&!this.closed}endInput(){if(!this.ready&&!this.process&&!this.customHandle){this.initializePromise&&this.pendingInput.push({type:"end"});return}this.endReadyInput()}endReadyInput(){if(this.customHandle){let e=this.customHandle.stdin;if(e.destroyed||e.writableEnded)return;typeof e.end=="function"&&e.end()}else this.process?.stdin&&!this.process.stdin.destroyed&&!this.process.stdin.writableEnded&&this.process.stdin.end()}async*readMessages(){this.initializePromise&&await this.initializePromise;let e=this.getStdout();if(!e)return;let t=_s({input:e,crlfDelay:1/0});try{for await(let r of t){if(this.closed)break;let s=r.trim();if(s)try{yield JSON.parse(s)}catch{}}this.closed||await this.waitForProcessExit()}finally{t.close()}}close(){if(this.closed)return;this.closed=!0,this.ready=!1,this.pendingInput=[],this.cleanupGeneratedSettings();let e=this.process,t=this.customHandle;if(this.cleanupAuthPayload().catch(()=>{}),!e&&!t)return;this.endInput();let r=e?a=>{try{e.kill(a)}catch{}}:t?a=>{try{t.kill(a)}catch{}}:void 0;if(!r)return;let s=()=>e?!e.killed&&e.exitCode===null:!0,o=this.options.closeGraceMs??_e,i=setTimeout(()=>{if(s()){r("SIGTERM");let a=setTimeout(()=>{s()&&r("SIGKILL")},Gt);typeof a=="object"&&"unref"in a&&a.unref()}},o);typeof i=="object"&&"unref"in i&&i.unref(),e?e.once("exit",()=>{clearTimeout(i)}):t?.once&&t.once("exit",()=>{clearTimeout(i)})}cleanupGeneratedSettings(){this.launchOptionsBuilder.cleanupGeneratedSettings()}get pid(){return this.process?.pid??void 0}getStdout(){return this.process?.stdout?this.process.stdout:this.customHandle?.stdout?this.customHandle.stdout:null}appendStderr(e){this.stderrTail+=e,this.stderrTail.length>dn&&(this.stderrTail=this.stderrTail.slice(-dn))}createSpawnError(e){let t=this.options.pathToQoderCLIExecutable??"qodercli",s=e.code==="ENOENT"?`Qoder CLI executable not found: ${t}`:`Failed to spawn Qoder CLI process: ${e.message}`;return new ee(s,{stderr:this.getStderrTail(),cause:e})}createProcessExitError(e,t){if(e!==q){if(e!==0&&e!==null)return new ee(`Qoder CLI process exited with code ${e}`,{exitCode:e,signal:t,stderr:this.getStderrTail()});if(t)return new ee(`Qoder CLI process terminated by signal ${t}`,{exitCode:e,signal:t,stderr:this.getStderrTail()})}}getStderrTail(){return this.stderrTail.trim()||void 0}async waitForProcessExit(){if(this.processExitError)throw this.processExitError;let e=this.process??this.customHandle;if(e){if(e.exitCode!==null||e.killed){let t=this.createProcessExitError(e.exitCode,null);if(t)throw this.processExitError=t,t;return}await new Promise((t,r)=>{let s=(i,a)=>{e.off("error",o);let u=this.createProcessExitError(i,a);u?(this.processExitError=u,r(u)):t()},o=i=>{e.off("exit",s);let a=this.createSpawnError(i);this.processExitError=a,r(a)};e.once("exit",s),e.once("error",o)})}}resolveExecutable(e){let t=this.options.pathToQoderCLIExecutable??Z();if(cn(t)){let r=this.options.executable??"node",s=this.options.executableArgs??[];return{command:r,commandArgs:[...s,t,...e]}}return{command:t,commandArgs:e}}async cleanupAuthPayload(){await this.launchOptionsBuilder.cleanupAuthPayload()}fireAuthExpired(){if(!this.authExpiredFired){this.authExpiredFired=!0;try{this.options.onAuthExpired?.()}catch{}}}};function Cs(){switch("worker"){case"worker":return"worker";case"process":return"process"}return"process"}var he=Cs();function pn(n){return typeof n=="object"&&n!==null&&typeof n.create=="function"}function De(n,e){return n.create(e)}import{existsSync as Zs}from"fs";import{createInterface as eo}from"readline";import{Worker as to}from"worker_threads";import{createHash as Ms}from"node:crypto";import{existsSync as As}from"node:fs";import{chmod as xs,lstat as Is,mkdir as ye,readFile as mn,readdir as Os,readlink as Ds,rename as js,rm as je,stat as Ns,symlink as Ks,writeFile as fn}from"node:fs/promises";import{tmpdir as Fs,userInfo as Us}from"node:os";import{basename as gn,dirname as ne,join as D,relative as qs}from"node:path";var Ls="QODER_WORKER_RUNTIME_ASSET_ROOT",hn=/(^|[\\/])app\.asar([\\/]|$)/,ut=".qoder-worker-runtime-ready";function yn(n){return hn.test(n)}function ct(n){return yn(n)?n.replace(hn,(e,t,r)=>`${t}app.asar.unpacked${r}`):null}async function Ne(n,e={}){let t=ct(n);if(!e.forceMaterialize&&t){let u=ne(t);if(As(t))return e.diagnostics?.record(`[WorkerTransport] Using asar-unpacked worker runtime: ${t}`),at(t,u,!1,ne(n))}if(!(e.forceMaterialize||yn(n))){let u=ne(n);return at(n,u,!1)}let s=ne(n),o=await $s(s,n,{cacheDir:e.cacheDir,diagnostics:e.diagnostics}),i=qs(s,n)||gn(n),a=D(o,i);return at(a,o,!0,s)}function at(n,e,t,r){return{runtimePath:n,runtimeRoot:e,materialized:t,sourceRuntimeRoot:r,env:{[Ls]:e}}}async function $s(n,e,t){let r=await Qs(n,e),s=t.cacheDir??zs(),o=D(s,r),i=D(o,ut);if(await vn(i)===r)return o;let a=D(s,`.setup-${r}-${process.pid}-${Date.now()}`);await ye(s,{recursive:!0,mode:448}),await je(a,{recursive:!0,force:!0}),await je(o,{recursive:!0,force:!0}),t.diagnostics?.record(`[WorkerTransport] Materializing worker runtime: ${n} -> ${o}`);try{return await ye(a,{recursive:!0,mode:448}),await Sn(n,a),await fn(D(a,ut),r,{mode:384}),await Bs(a,o,r),o}catch(u){throw await je(a,{recursive:!0,force:!0}).catch(()=>{}),u}}async function Qs(n,e){let t=Ms("sha256");t.update("qoder-worker-runtime-v1\0");let r=await wn(D(n,"runtime-info.json"));if(r)t.update(r);else{t.update(e);let s=await Ns(e).catch(()=>null);s&&t.update(`${s.size}\0${s.mtimeMs}`)}return`runtime-${t.digest("hex").slice(0,24)}`}async function Sn(n,e){let t=await Os(n,{withFileTypes:!0});await ye(e,{recursive:!0,mode:448});for(let r of t){let s=D(n,r.name),o=D(e,r.name);if(r.isDirectory()){await Sn(s,o);continue}if(r.isSymbolicLink()){await ye(ne(o),{recursive:!0,mode:448}),await Ks(await Ds(s),o);continue}if(!r.isFile())continue;let i=await Gs(s);await ye(ne(o),{recursive:!0,mode:448}),await fn(o,await mn(s),{mode:i}),process.platform!=="win32"&&await xs(o,i)}}async function Gs(n){let e=((await Is(n)).mode||420)&511;if(process.platform==="win32")return e||420;let t=gn(n);return t==="rg"||t==="spawn-helper"||/\.(?:node|dylib|exe)$/.test(t)||/\.so(?:\.\d+)*$/.test(t)?493:e||420}async function Bs(n,e,t){try{await js(n,e)}catch(r){if(await vn(D(e,ut))===t){await je(n,{recursive:!0,force:!0});return}throw r}}async function vn(n){let e=await wn(n);return e?e.toString("utf8"):null}async function wn(n){try{return await mn(n)}catch{return null}}function zs(){let n=Ws(Us().username||process.env.USER||process.env.USERNAME||"user");return D(Fs(),`qoder-sdk-worker-runtime-${n}`)}function Ws(n){return n.replace(/[^a-zA-Z0-9._-]/g,"_")||"unknown"}var Hs="QODER_WORKER_CWD";function Ke(n,e){return{env:{...e.env,[Hs]:e.cwd,...n.env},workerData:{...e.workerData??{},qoderWorkerRuntime:{cwd:e.cwd,runtimeRoot:n.runtimeRoot,materialized:n.materialized}}}}import{existsSync as lt}from"node:fs";import{dirname as Js,join as L}from"node:path";import{fileURLToPath as Vs}from"node:url";var Ys=Vs(import.meta.url),dt=Js(Ys);function re(n){if(n)return n;let e=[];for(let t of Xs())e.push(L(t,"dist","_worker","qoder-worker-runtime.obf.mjs"),L(t,"dist","_worker","qoder-worker-runtime.mjs"),L(t,"_worker","qoder-worker-runtime.obf.mjs"),L(t,"_worker","qoder-worker-runtime.mjs"));for(let t of e)if(lt(t))return t;return e[0]??L(dt,"..","_worker","qoder-worker-runtime.obf.mjs")}function kn(n){let e=re(n);if(lt(e))return!0;let t=ct(e);return t!==null&<(t)}function Xs(){let n=[L(dt,".."),L(dt,"..","..")];return[...new Set(n)]}var bn=8192,$=class extends Error{code="QODER_WORKER_RUNTIME_ERROR";exitCode;stderr;constructor(e,t){super(e,t?.cause?{cause:t.cause}:void 0),this.name="QoderWorkerRuntimeError",this.exitCode=t?.exitCode,this.stderr=t?.stderr}},se=class n{static default=new n;options;constructor(e={}){this.options={...e}}create(e){return new pt(Ie(this.options,e))}},pt=class{worker=null;options;ready=!1;closed=!1;initializePromise=null;authExpiredFired=!1;pendingInput=[];diagnostics;workerExitError;stderrTail="";observedExitCode=null;launchOptionsBuilder;closeTimer=null;abortSignal;abortListener;constructor(e={}){this.options={...e},this.diagnostics=e.diagnostics,this.launchOptionsBuilder=new X(this.options,this.diagnostics,"[WorkerTransport]")}async initialize(){if(!this.ready)return this.initializePromise||(this.initializePromise=this._doInitialize()),this.initializePromise}async _doInitialize(){try{let e=await this.launchOptionsBuilder.prepare();if(this.closed){await this.cleanupAuthPayload();return}let t=re(this.options.pathToQoderWorkerRuntime),r;try{r=await Ne(t,{diagnostics:this.diagnostics})}catch(a){throw new $(`Failed to prepare Qoder worker runtime: ${t}`,{cause:a})}let s=r.runtimePath;if(!Zs(s))throw new $(`Qoder worker runtime not found: ${s}`);let o=this.options.cwd??process.cwd(),i=Ke(r,{cwd:o,env:e.env,workerData:this.options.workerData});if(this.diagnostics?.record(`[WorkerTransport] Starting: ${s}`),this.diagnostics?.record(`[WorkerTransport] CWD: ${o}`),this.diagnostics?.record(`[WorkerTransport] Args: ${Oe(e.args)}`),this.worker=new to(s,{argv:e.args,env:i.env,execArgv:this.options.execArgv??[],stdin:!0,stdout:!0,stderr:!0,workerData:i.workerData}),this.worker.once("error",a=>{this.ready=!1,this.cleanupAbortListener(),this.closed||(this.workerExitError=this.createWorkerError(a)),this.diagnostics?.record("[WorkerTransport] Worker error:",a),this.destroyWorkerStreams(this.worker),this.cleanupAuthPayload().catch(()=>{})}),this.worker.once("exit",a=>{if(this.ready=!1,this.observedExitCode=a,this.cleanupAbortListener(),this.clearCloseTimer(),this.recordWorkerExit(a),this.destroyWorkerStreams(this.worker),this.closed){a!==0&&this.recordSuppressedWorkerExit(a),this.cleanupAuthPayload().catch(()=>{});return}a===q&&this.fireAuthExpired();let u=this.createWorkerExitError(a);u&&(this.workerExitError=u),this.cleanupAuthPayload().catch(()=>{})}),this.worker.stderr?.on("data",a=>{let u=a.toString();this.appendStderr(u),this.options.stderr!=="ignore"&&this.options.stderrHandler?.(u),this.options.stderr==="inherit"&&process.stderr.write(u);let c=u.trim();c&&this.diagnostics?.record(`[WorkerTransport] STDERR: ${c}`)}),this.options.abortController){let a=this.options.abortController.signal;a.aborted?this.close():(this.abortSignal=a,this.abortListener=()=>this.close(),a.addEventListener("abort",this.abortListener,{once:!0}))}this.ready=!0,this.flushPendingInput()}catch(e){throw await this.cleanupAuthPayload(),e}}write(e){if(this.workerExitError)throw this.workerExitError;if(this.closed)throw new Error("Transport is not ready or has been closed");let t=e.endsWith(`
|
|
4
4
|
`)?e:e+`
|
|
@@ -8,7 +8,7 @@ ${e.stack??e.message}`;try{return` ${JSON.stringify(e)}`}catch{return` ${String(
|
|
|
8
8
|
`)}catch(g){this.diagnostics?.record("[QueryRunner] Failed to send control_cancel_request:",g)}},p=()=>{d&&(clearTimeout(d),d=null),t?.signal?.removeEventListener("abort",l)},l=()=>{this.pendingRequests.delete(r)&&(p(),this.diagnostics?.record(`[QueryRunner] control_request cancelled request_id=${r} subtype=${i}`),m(),c(new M))};this.pendingRequests.set(r,{resolve:g=>{p(),this.diagnostics?.record(`[QueryRunner] control_response received request_id=${r} subtype=${i} status=success duration_ms=${Date.now()-a}`),u(g)},reject:g=>{p(),this.diagnostics?.record(`[QueryRunner] control_response received request_id=${r} subtype=${i} status=error duration_ms=${Date.now()-a}`,g),c(g)}}),t?.signal?.addEventListener("abort",l,{once:!0}),o>0&&Number.isFinite(o)&&(d=setTimeout(()=>{this.pendingRequests.has(r)&&(this.pendingRequests.delete(r),p(),this.diagnostics?.record(`[QueryRunner] control_request timed out request_id=${r} subtype=${i} timeout_ms=${o}`),m(),c(new Error(`Control request "${ie(s.request)??"unknown"}" timed out after ${o}ms`)))},o));try{this.diagnostics?.record(`[QueryRunner] control_request sending request_id=${r} subtype=${i} timeout_ms=${o}`),this.transport.write(JSON.stringify(s)+`
|
|
9
9
|
`),this.diagnostics?.record(`[QueryRunner] control_request sent request_id=${r} subtype=${i}`)}catch(g){p(),this.pendingRequests.delete(r),this.diagnostics?.record(`[QueryRunner] control_request send failed request_id=${r} subtype=${i}`,g),c(g)}})}handleControlResponse(e){let t=e.response,r=t.request_id,s=this.pendingRequests.get(r);if(!s){this.diagnostics?.record(`[QueryRunner] unmatched control_response received request_id=${r} status=${t.subtype}`);return}if(this.pendingRequests.delete(r),t.subtype==="success")s.resolve(t.response);else{let o=new Error(t.error);t.code&&(o.code=t.code),s.reject(o),this.processPendingPermissionRequests(t.pending_permission_requests)}}processPendingPermissionRequests(e){if(e)for(let t of e)ie(t.request)==="can_use_tool"&&this.handleControlRequest(t).catch(r=>{this.diagnostics?.record("[QueryRunner] Error handling pending permission request:",r)})}async handleControlRequest(e){let t=e.request_id,r=ie(e.request)??"unknown",s=Date.now(),o=new AbortController;this.pendingInboundRequests.set(t,{abortController:o}),this.diagnostics?.record(`[QueryRunner] inbound control_request received request_id=${t} subtype=${r}`);try{let i=await this.awaitAbortable(this.processControlRequest(e,o.signal),o.signal);if(!o.signal.aborted){let a=xn(t,i);this.transport.write(JSON.stringify(a)+`
|
|
10
10
|
`),this.diagnostics?.record(`[QueryRunner] inbound control_response sent request_id=${t} subtype=${r} status=success duration_ms=${Date.now()-s}`)}}catch(i){if(!o.signal.aborted){let{error:a,code:u}=_o(i),c=In(t,a,u);this.transport.write(JSON.stringify(c)+`
|
|
11
|
-
`),this.diagnostics?.record(`[QueryRunner] inbound control_response sent request_id=${t} subtype=${r} status=error duration_ms=${Date.now()-s}`,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 M}validateProtocolHandshake(e){if(this.protocolHandshakeValidated)return;this.protocolHandshakeValidated=!0;let t=e.protocol_version,r=mt;if(!t){this.diagnostics?.record(`[QueryRunner] CLI did not announce protocol_version. This SDK was built for ${r}. Consider upgrading qodercli for the version handshake.`);return}let s=Ln(t),o=Ln(r);if(!s||!o){this.diagnostics?.record(`[QueryRunner] Could not parse protocol_version "${t}" or built-in "${r}"; skipping handshake.`);return}if(s.major!==o.major)throw new ve(t,r);s.minor<o.minor&&this.diagnostics?.record(`[QueryRunner] CLI protocol_version ${t} is older than this SDK's ${r}. New optional fields may be absent.`)}async awaitAbortable(e,t){if(t.aborted)throw new M;return new Promise((r,s)=>{let o=()=>{s(new M)};t.addEventListener("abort",o,{once:!0}),e.then(i=>{t.removeEventListener("abort",o),r(i)},i=>{t.removeEventListener("abort",o),s(i)})})}async processControlRequest(e,t){this.throwIfAborted(t);let r=e.request,s=ie(r),o=r;switch(s){case"fetch_job_token":{if(!this.fetchJobToken)throw new Error("job_token_unavailable: No fetchJobToken callback configured");let i=o.reason??"initial",a=o.session_id,u=e.request_id,c=await this.awaitAbortable(this.fetchJobToken({requestId:u,reason:i,sessionId:a},{signal:t}),t);if(!c?.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:c.token}}case"fetch_service_account_token":{if(!this.fetchServiceAccountToken)throw new Error("service_account_token_unavailable: No fetchServiceAccountToken callback configured");let i=await this.awaitAbortable(this.fetchServiceAccountToken(),t);if(!i?.token)throw new Error("service_account_token_unavailable: Host did not provide a Service Account token");let a=i.expiresAt;if(a!==void 0&&(!Number.isFinite(a)||a<1e12))throw new Error("service_account_token_unavailable: expiresAt must be a Unix timestamp in milliseconds");return this.diagnostics?.record("[QueryRunner] fetch_service_account_token fulfilled"),{token:i.token,...a!==void 0?{expires_at:a}:{}}}case"can_use_tool":{let i=o.tool_name,a=o.input??{};if(!this.canUseTool)throw new Error("canUseTool callback is not provided.");let u=o.tool_use_id,c=o.permission_suggestions??o.suggestions,d=o.blocked_path,m=o.decision_reason,p=o.title,l=o.display_name,g=o.description,h=o.agent_id,f=await this.awaitAbortable(this.canUseTool(i,a,{signal:t,suggestions:c,blockedPath:d,decisionReason:m,title:p,displayName:l,description:g,toolUseID:u,agentID:h}),t);if(f.behavior==="deny"&&!f.message)throw new Error("Permission deny result must include a message.");return f.behavior==="allow"?{...f,updatedInput:f.updatedInput??a,toolUseID:u}:{...f,toolUseID:u}}case"hook_callback":{let i=o.callback_id;if(!i)throw new Error("Hook callback missing callback_id");return this.invokeRegisteredHookCallback(i,o.input,o.tool_use_id,t)}case"memory_should_generate":{let i=o.callbackId;if(!i)throw new Error("Memory shouldGenerate request missing callbackId");let a=this.memoryCallbacks?.shouldGenerateCallbacks.get(i);if(!a)throw new Error(`Unknown memory shouldGenerate callback: ${i}`);let u=await this.awaitAbortable(a(o.input,{signal:t}),t);if(!u||typeof u.run!="boolean")throw new TypeError("Memory shouldGenerate callback must return { run: boolean }");return{run:u.run,...typeof u.reason=="string"?{reason:u.reason}:{}}}case"skill_evolution_should_review":{let i=o.callbackId;if(!i)throw new Error("Skill evolution shouldReview request missing callbackId");let a=this.skillEvolutionCallbacks?.shouldReviewCallbacks.get(i);if(!a)throw new Error(`Unknown skill evolution shouldReview callback: ${i}`);let u=await this.awaitAbortable(a(o.input,{signal:t}),t);if(!u||typeof u.run!="boolean")throw new TypeError("Skill evolution shouldReview callback must return { run: boolean }");return{run:u.run,...typeof u.reason=="string"?{reason:u.reason}:{}}}case"mcp_message":{let i=o.server_name,a=o.message,u=this.sdkMcpTransports.get(i);if(!u)throw new Error(`Unknown in-process MCP server: ${i}`);return{mcp_response:await this.awaitAbortable(Rn(i,a,u,this.pendingMcpResponses),t)}}case"elicitation":case"elicitation_response":return this.onElicitation?await this.awaitAbortable(this.onElicitation({serverName:o.mcp_server_name??"",message:o.message??o.prompt??"",mode:o.mode,url:o.url,elicitationId:o.elicitation_id,requestedSchema:o.requested_schema,title:o.title,displayName:o.display_name,description:o.description},{signal:t}),t):{action:"cancel"};case"get_model_policy":{if(!this.resolveModel)return{type:"get_model_policy"};let i={purpose:o.purpose,sessionId:o.sessionId,turnIndex:o.turnIndex,agentId:o.agentId,agentType:o.agentType,resolvedModel:o.resolvedModel,availableModels:o.models??[]},a=this.resolveModelTimeoutMs,u=Promise.resolve(this.resolveModel(i)),c,d=new Promise((f,y)=>{c=setTimeout(()=>{y(new Se(a))},a)}),m;try{m=await this.awaitAbortable(Promise.race([u,d]),t)}finally{clearTimeout(c)}let p={type:"get_model_policy",...m?.parameters!==void 0?{parameters:m.parameters}:{}},l=m?.model;if(typeof l=="string")p.model=l;else if(l!==void 0){let{model:f,...y}=l;p.model=f,p.custom_model={...y,style:y.style??"openai"}}let g=m?.taskId?.trim();g&&(p.task_id=g);let h=m?.subTask?.trim();return h&&(p.sub_task=h),p}default:throw new Error(`Unhandled control request subtype: ${s??"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:n.INITIALIZE_TIMEOUT_MS},t={};for(let[s,o]of Object.entries(this.hooks)){if(!o||o.length===0)continue;let i=[];for(let a of o){let u=a.hooks.map(c=>{let d=`hook_${this.nextHookCallbackId++}`;return this.hookCallbacks.set(d,c),d});u.length!==0&&i.push({matcher:a.matcher,hookCallbackIds:u,timeout:a.timeout})}i.length>0&&(t[s]=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.modelRequestPatches!==void 0&&(e.modelRequestPatches=this.initConfig.modelRequestPatches),this.initConfig.agents&&(e.agents=this.initConfig.agents),this.initConfig.skills!==void 0&&(e.skills=this.initConfig.skills),this.initConfig.promptSuggestions!==void 0&&(e.promptSuggestions=this.initConfig.promptSuggestions),this.initConfig.enableFileCheckpointing!==void 0&&(e.enableFileCheckpointing=this.initConfig.enableFileCheckpointing),this.initConfig.memory!==void 0&&(e.memory=this.initConfig.memory),this.initConfig.evolution!==void 0&&(e.evolution=this.initConfig.evolution),this.sdkMcpServers.size>0&&(e.sdkMcpServers=Array.from(this.sdkMcpServers.keys()),Object.keys(this.sdkMcpToolOverrides).length>0&&(e.sdkMcpToolOverrides=this.sdkMcpToolOverrides));let r=await this.request(e,{timeoutMs:n.INITIALIZE_TIMEOUT_MS});if(r&&typeof r=="object"){let s=r;this.initResponse=s,this.cliCapabilities=new Set(s.capabilities??[])}if(!this.initResponse)throw new Error("Failed to receive initialization response");if(this.initConfig.planMode!==void 0){if(!this.cliCapabilities?.has(n.PLAN_MODE_CAPABILITY))throw new Q(n.PLAN_MODE_CAPABILITY);let s={subtype:"set_plan_mode",active:this.initConfig.planMode};await this.request(s)}return this.initResponse}async invokeRegisteredHookCallback(e,t,r,s){let o=this.hookCallbacks.get(e);if(!o)throw new Error(`Unknown hook callback: ${e}`);return await this.awaitAbortable(o(t,r,{signal:s}),s)??{continue:!0}}async initializationResult(){return this.initialize()}async streamInput(e){(async()=>{try{await this.initialize();let t=0;for await(let r of e){if(this.closed)break;t+=1;let o=Object.prototype.hasOwnProperty.call(r,"custom_context")?r.custom_context:this.initConfig.customContext,i=o===void 0?r:{...r,custom_context:o};this.pendingErrorResultExit=!1,o!==void 0&&!this.cliCapabilities?.has(n.CUSTOM_CONTEXT_CAPABILITY)&&!this.customContextCapabilityWarningEmitted&&(this.customContextCapabilityWarningEmitted=!0,this.diagnostics?.record("[QueryRunner] custom_context requested but paired CLI does not advertise custom_context_v1; the field may be ignored")),this.transport.write(JSON.stringify(i)+`
|
|
11
|
+
`),this.diagnostics?.record(`[QueryRunner] inbound control_response sent request_id=${t} subtype=${r} status=error duration_ms=${Date.now()-s}`,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 M}validateProtocolHandshake(e){if(this.protocolHandshakeValidated)return;this.protocolHandshakeValidated=!0;let t=e.protocol_version,r=mt;if(!t){this.diagnostics?.record(`[QueryRunner] CLI did not announce protocol_version. This SDK was built for ${r}. Consider upgrading qodercli for the version handshake.`);return}let s=Ln(t),o=Ln(r);if(!s||!o){this.diagnostics?.record(`[QueryRunner] Could not parse protocol_version "${t}" or built-in "${r}"; skipping handshake.`);return}if(s.major!==o.major)throw new ve(t,r);s.minor<o.minor&&this.diagnostics?.record(`[QueryRunner] CLI protocol_version ${t} is older than this SDK's ${r}. New optional fields may be absent.`)}async awaitAbortable(e,t){if(t.aborted)throw new M;return new Promise((r,s)=>{let o=()=>{s(new M)};t.addEventListener("abort",o,{once:!0}),e.then(i=>{t.removeEventListener("abort",o),r(i)},i=>{t.removeEventListener("abort",o),s(i)})})}async processControlRequest(e,t){this.throwIfAborted(t);let r=e.request,s=ie(r),o=r;switch(s){case"fetch_job_token":{if(!this.fetchJobToken)throw new Error("job_token_unavailable: No fetchJobToken callback configured");let i=o.reason??"initial",a=o.session_id,u=e.request_id,c=await this.awaitAbortable(this.fetchJobToken({requestId:u,reason:i,sessionId:a},{signal:t}),t);if(!c?.token)throw new Error("job_token_unavailable: Host did not provide a Job Token");let d=c.expiresAt;if(d!==void 0&&(!Number.isFinite(d)||d<1e12))throw new Error("job_token_unavailable: expiresAt must be a Unix timestamp in milliseconds");return this.diagnostics?.record(`[QueryRunner] fetch_job_token fulfilled: reason=${i}`),{token:c.token,...d!==void 0?{expires_at:d}:{}}}case"fetch_service_account_token":{if(!this.fetchServiceAccountToken)throw new Error("service_account_token_unavailable: No fetchServiceAccountToken callback configured");let i=await this.awaitAbortable(this.fetchServiceAccountToken(),t);if(!i?.token)throw new Error("service_account_token_unavailable: Host did not provide a Service Account token");let a=i.expiresAt;if(a!==void 0&&(!Number.isFinite(a)||a<1e12))throw new Error("service_account_token_unavailable: expiresAt must be a Unix timestamp in milliseconds");return this.diagnostics?.record("[QueryRunner] fetch_service_account_token fulfilled"),{token:i.token,...a!==void 0?{expires_at:a}:{}}}case"can_use_tool":{let i=o.tool_name,a=o.input??{};if(!this.canUseTool)throw new Error("canUseTool callback is not provided.");let u=o.tool_use_id,c=o.permission_suggestions??o.suggestions,d=o.blocked_path,m=o.decision_reason,p=o.title,l=o.display_name,g=o.description,h=o.agent_id,f=await this.awaitAbortable(this.canUseTool(i,a,{signal:t,suggestions:c,blockedPath:d,decisionReason:m,title:p,displayName:l,description:g,toolUseID:u,agentID:h}),t);if(f.behavior==="deny"&&!f.message)throw new Error("Permission deny result must include a message.");return f.behavior==="allow"?{...f,updatedInput:f.updatedInput??a,toolUseID:u}:{...f,toolUseID:u}}case"hook_callback":{let i=o.callback_id;if(!i)throw new Error("Hook callback missing callback_id");return this.invokeRegisteredHookCallback(i,o.input,o.tool_use_id,t)}case"memory_should_generate":{let i=o.callbackId;if(!i)throw new Error("Memory shouldGenerate request missing callbackId");let a=this.memoryCallbacks?.shouldGenerateCallbacks.get(i);if(!a)throw new Error(`Unknown memory shouldGenerate callback: ${i}`);let u=await this.awaitAbortable(a(o.input,{signal:t}),t);if(!u||typeof u.run!="boolean")throw new TypeError("Memory shouldGenerate callback must return { run: boolean }");return{run:u.run,...typeof u.reason=="string"?{reason:u.reason}:{}}}case"skill_evolution_should_review":{let i=o.callbackId;if(!i)throw new Error("Skill evolution shouldReview request missing callbackId");let a=this.skillEvolutionCallbacks?.shouldReviewCallbacks.get(i);if(!a)throw new Error(`Unknown skill evolution shouldReview callback: ${i}`);let u=await this.awaitAbortable(a(o.input,{signal:t}),t);if(!u||typeof u.run!="boolean")throw new TypeError("Skill evolution shouldReview callback must return { run: boolean }");return{run:u.run,...typeof u.reason=="string"?{reason:u.reason}:{}}}case"mcp_message":{let i=o.server_name,a=o.message,u=this.sdkMcpTransports.get(i);if(!u)throw new Error(`Unknown in-process MCP server: ${i}`);return{mcp_response:await this.awaitAbortable(Rn(i,a,u,this.pendingMcpResponses),t)}}case"elicitation":case"elicitation_response":return this.onElicitation?await this.awaitAbortable(this.onElicitation({serverName:o.mcp_server_name??"",message:o.message??o.prompt??"",mode:o.mode,url:o.url,elicitationId:o.elicitation_id,requestedSchema:o.requested_schema,title:o.title,displayName:o.display_name,description:o.description},{signal:t}),t):{action:"cancel"};case"get_model_policy":{if(!this.resolveModel)return{type:"get_model_policy"};let i={purpose:o.purpose,sessionId:o.sessionId,turnIndex:o.turnIndex,agentId:o.agentId,agentType:o.agentType,resolvedModel:o.resolvedModel,availableModels:o.models??[]},a=this.resolveModelTimeoutMs,u=Promise.resolve(this.resolveModel(i)),c,d=new Promise((f,y)=>{c=setTimeout(()=>{y(new Se(a))},a)}),m;try{m=await this.awaitAbortable(Promise.race([u,d]),t)}finally{clearTimeout(c)}let p={type:"get_model_policy",...m?.parameters!==void 0?{parameters:m.parameters}:{}},l=m?.model;if(typeof l=="string")p.model=l;else if(l!==void 0){let{model:f,...y}=l;p.model=f,p.custom_model={...y,style:y.style??"openai"}}let g=m?.taskId?.trim();g&&(p.task_id=g);let h=m?.subTask?.trim();return h&&(p.sub_task=h),p}default:throw new Error(`Unhandled control request subtype: ${s??"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:n.INITIALIZE_TIMEOUT_MS},t={};for(let[s,o]of Object.entries(this.hooks)){if(!o||o.length===0)continue;let i=[];for(let a of o){let u=a.hooks.map(c=>{let d=`hook_${this.nextHookCallbackId++}`;return this.hookCallbacks.set(d,c),d});u.length!==0&&i.push({matcher:a.matcher,hookCallbackIds:u,timeout:a.timeout})}i.length>0&&(t[s]=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.modelRequestPatches!==void 0&&(e.modelRequestPatches=this.initConfig.modelRequestPatches),this.initConfig.agents&&(e.agents=this.initConfig.agents),this.initConfig.skills!==void 0&&(e.skills=this.initConfig.skills),this.initConfig.promptSuggestions!==void 0&&(e.promptSuggestions=this.initConfig.promptSuggestions),this.initConfig.enableFileCheckpointing!==void 0&&(e.enableFileCheckpointing=this.initConfig.enableFileCheckpointing),this.initConfig.memory!==void 0&&(e.memory=this.initConfig.memory),this.initConfig.evolution!==void 0&&(e.evolution=this.initConfig.evolution),this.sdkMcpServers.size>0&&(e.sdkMcpServers=Array.from(this.sdkMcpServers.keys()),Object.keys(this.sdkMcpToolOverrides).length>0&&(e.sdkMcpToolOverrides=this.sdkMcpToolOverrides));let r=await this.request(e,{timeoutMs:n.INITIALIZE_TIMEOUT_MS});if(r&&typeof r=="object"){let s=r;this.initResponse=s,this.cliCapabilities=new Set(s.capabilities??[])}if(!this.initResponse)throw new Error("Failed to receive initialization response");if(this.initConfig.planMode!==void 0){if(!this.cliCapabilities?.has(n.PLAN_MODE_CAPABILITY))throw new Q(n.PLAN_MODE_CAPABILITY);let s={subtype:"set_plan_mode",active:this.initConfig.planMode};await this.request(s)}return this.initResponse}async invokeRegisteredHookCallback(e,t,r,s){let o=this.hookCallbacks.get(e);if(!o)throw new Error(`Unknown hook callback: ${e}`);return await this.awaitAbortable(o(t,r,{signal:s}),s)??{continue:!0}}async initializationResult(){return this.initialize()}async streamInput(e){(async()=>{try{await this.initialize();let t=0;for await(let r of e){if(this.closed)break;t+=1;let o=Object.prototype.hasOwnProperty.call(r,"custom_context")?r.custom_context:this.initConfig.customContext,i=o===void 0?r:{...r,custom_context:o};this.pendingErrorResultExit=!1,o!==void 0&&!this.cliCapabilities?.has(n.CUSTOM_CONTEXT_CAPABILITY)&&!this.customContextCapabilityWarningEmitted&&(this.customContextCapabilityWarningEmitted=!0,this.diagnostics?.record("[QueryRunner] custom_context requested but paired CLI does not advertise custom_context_v1; the field may be ignored")),this.transport.write(JSON.stringify(i)+`
|
|
12
12
|
`),this.recordOutboundSessionMessage(i)}t>0&&await this.waitForFirstResult(),(!this.isSingleTurn||!this.firstResultReceived)&&await this.flushBeforeEndInput()}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(){let t=(await this.request({type:"interrupt"}))?.still_queued;if(Array.isArray(t))return{still_queued:t.filter(r=>typeof r=="string")}}async cancelAsyncMessage(e){return(await this.request({subtype:"cancel_async_message",message_uuid:e})).cancelled}async stopTask(e){await this.requireCliCapability(n.BACKGROUND_TASKS_CAPABILITY),await this.request({subtype:"stop_task",task_id:e})}async backgroundTasks(e){await this.requireCliCapability(n.BACKGROUND_TASKS_CAPABILITY);let t=await this.request({subtype:"background_tasks",tool_use_id:e});return typeof t?.backgrounded=="boolean"?t.backgrounded:!0}async setGoal(e){await this.requireCliCapability(n.GOAL_CAPABILITY);let t={subtype:"set_goal"};return e.objective!==void 0&&(t.objective=e.objective),e.status!==void 0&&(t.status=e.status),e.creditsBudget!==void 0&&(t.credits_budget=e.creditsBudget),(await this.request(t))?.goal??null}async getGoal(){await this.requireCliCapability(n.GOAL_CAPABILITY);let e={subtype:"get_goal"};return(await this.request(e))?.goal??null}async clearGoal(){await this.requireCliCapability(n.GOAL_CAPABILITY);let e={subtype:"clear_goal"};return(await this.request(e))?.cleared===!0}async setPlanMode(e){await this.requireCliCapability(n.PLAN_MODE_CAPABILITY);let t={subtype:"set_plan_mode",active:e};return(await this.request(t)).plan_mode}async getPlanMode(){await this.requireCliCapability(n.PLAN_MODE_CAPABILITY);let e={subtype:"get_plan_mode"};return(await this.request(e)).plan_mode}async requireCliCapability(e){if(await this.initializationResult(),!this.cliCapabilities?.has(e))throw new Q(e)}async setPermissionMode(e){await this.request({type:"set_permission_mode",mode:e==="yolo"?"bypassPermissions":e})}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 askSideQuestion(e,t){await this.requireCliCapability(n.SIDE_QUESTION_CAPABILITY);let r=await this.request({subtype:"side_question",question:e,...t?.history?.length?{history:t.history.map(s=>({...s}))}:{}},{timeoutMs:0,signal:t?.signal});return r?.response==null?null:{response:r.response,synthetic:r.synthetic??!1,...r.refusal_fallback?{refusalFallback:{originalModel:r.refusal_fallback.original_model,fallbackModel:r.refusal_fallback.fallback_model,content:r.refusal_fallback.content}}:{}}}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&&Object.keys(t.account).length>0)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"}),t=Po(e?.usage),r=To(e?.session);return!t&&!r?null:{...t??{},...r?{session:r}:{}}}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 r={type:"rewind_files",user_message_id:e};t?.dryRun&&(r.dry_run=!0);let o=await this.request(r);if(!t?.dryRun&&o?.canRewind===!1)throw new Error(typeof o.error=="string"&&o.error.length>0?o.error:"Unable to rewind files.");return o}async rewind(e,t){if(!(await this.initializationResult()).capabilities?.includes("session_rewind_v1"))throw new Error("The connected qodercli does not support full session rewind (session_rewind_v1).");let s={type:"rewind",user_message_id:e,scope:t?.scope??"both"};return t?.dryRun&&(s.dry_run=!0),await this.request(s)}async seedReadState(e,t){await this.request({type:"seed_read_state",path:e,mtime:t})}async flushMemory(){return this.memoryFlushPromise||(this.memoryFlushPromise=this.performMemoryFlush().finally(()=>{this.memoryFlushPromise=void 0})),this.memoryFlushPromise}async flushSkillEvolution(){return this.skillEvolutionFlushPromise||(this.skillEvolutionFlushPromise=this.performSkillEvolutionFlush().finally(()=>{this.skillEvolutionFlushPromise=void 0})),this.skillEvolutionFlushPromise}async performSkillEvolutionFlush(){await this.requireSkillEvolutionEnabled(),await this.request({type:"flush_skill_evolution"})}async requireSkillEvolutionEnabled(){let e=await this.initializationResult();if(!this.cliCapabilities?.has("skill_evolution_v1"))throw new Q("skill_evolution_v1");if(e.evolution?.skill?.enabled!==!0||e.evolution.skill.requester!=="sdk")throw new Error("The connected CLI did not enable SDK skill evolution for this query")}async performMemoryFlush(){await this.requireSdkMemoryEnabled(),await this.request({type:"flush_memory"})}async refreshMemory(){await this.requireSdkMemoryEnabled(),await this.request({type:"refresh_memory"})}async requireSdkMemoryEnabled(){let e=await this.initializationResult();if(e.memory?.enabled!==!0||e.memory.requester!=="sdk")throw new Error("The connected CLI did not enable SDK memory for this query")}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){let t=Wt(e);return await this.request({type:"mcp_set_servers",servers:t})??{added:[],removed:[],errors:{}}}async injectMcpToken(e,t){await this.request({type:"mcp_inject_token",serverName:e,token:t})}async mcpAuthenticate(e,t){let r=await this.request({type:"mcp_authenticate",serverName:e,...t!==void 0?{redirectUri:t}:{}}),s=r?.requiresUserAction===!0,o=typeof r?.authUrl=="string"?r.authUrl:void 0;if(s&&o===void 0)throw new Error("mcp_authenticate response set requiresUserAction=true but did not include an authUrl");return s?{authUrl:o,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(){return this.closePromise||(this.closePromise=this.performClose()),this.closePromise}async performClose(){if(this.closed)return;if((this.initConfig.memory!==void 0||this.initConfig.evolution?.skill!==void 0)&&(this.initResponse?.memory?.enabled===!0||this.initResponse?.evolution?.skill?.enabled===!0)&&this.transport.isReady()&&this.abortController?.signal.aborted!==!0)try{await(this.endInputFlushPromise??this.flushBeforeEndInput())}catch(t){this.diagnostics?.record("[QueryRunner] post-turn flush during close failed:",t)}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,r]of this.sdkMcpTransports){try{await r.close()}catch(s){this.diagnostics?.record(`[QueryRunner] error closing SDK MCP transport "${t}":`,s)}Tn(t,e,this.pendingMcpResponses)}this.transport.close();try{await this.readLoopPromise}catch{}await this.transcriptMirrorBatcher?.flush()}async[Symbol.asyncDispose](){await this.close()}};function G(n){return typeof n=="object"&&n!==null}function ft(n){return typeof n=="number"&&Number.isFinite(n)}function gt(n){return Object.keys(n).length>0}function j(n,e,t){let r=e[t];ft(r)&&(n[t]=r)}function ae(n,e,t){let r=e[t];typeof r=="string"&&(n[t]=r)}function $e(n,e,t){let r=e[t];typeof r=="boolean"&&(n[t]=r)}function $n(n){if(!G(n)||Array.isArray(n))return;let e={};return j(e,n,"total"),j(e,n,"used"),j(e,n,"remaining"),j(e,n,"percentage"),ae(e,n,"unit"),gt(e)?e:void 0}function Ro(n){if(!G(n)||Array.isArray(n))return;let e=$n(n)??{};return ae(e,n,"detailUrl"),gt(e)?e:void 0}function Eo(n){if(!G(n)||Array.isArray(n))return;let e={};return j(e,n,"used"),j(e,n,"cap"),j(e,n,"remaining"),j(e,n,"percentage"),$e(e,n,"available"),ae(e,n,"unit"),gt(e)?e:void 0}function To(n){if(!G(n)||Array.isArray(n))return;let e=n.total_credits,t=n.model_usage;if(!ft(e)||e<0||!G(t)||Array.isArray(t))return;let r={};for(let[s,o]of Object.entries(t)){if(!G(o)||Array.isArray(o))continue;let i=o.credits;ft(i)&&i>=0&&(r[s]={credits:i})}return{total_credits:e,model_usage:r}}function Po(n){if(!G(n)||Array.isArray(n))return null;let e={};ae(e,n,"userId"),ae(e,n,"userType"),j(e,n,"totalUsagePercentage"),$e(e,n,"isHighestTier"),j(e,n,"expiresAt"),ae(e,n,"upgradeUrl"),$e(e,n,"isQuotaExceeded"),$e(e,n,"isPlanQuotaProrated");let t=$n(n.userQuota);t&&(e.userQuota=t);let r=Ro(n.addOnQuota);r&&(e.addOnQuota=r);let s=Eo(n.orgResourcePackage);return s&&(e.orgResourcePackage=s),e}function _o(n){let e=n instanceof Error?n.message:String(n),t=typeof n=="object"&&n!==null?n.code:void 0,r=typeof t=="string"&&t.length>0?t:void 0,s=/^([a-z][a-z0-9_]*):\s*(.*)$/.exec(e);if(s){let o=r??s[1];return(!r||r===s[1])&&(e=s[2]||e),{error:e,code:o}}return r?{error:e,code:r}:{error:e}}function Ln(n){let e=/^(\d+)\.(\d+)(?:\.\d+)?(?:[-+].*)?$/.exec(n);return e?{major:Number(e[1]),minor:Number(e[2])}:null}var Ge=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}};import{randomUUID as Qn}from"crypto";var Co="QODER_CLOUD_AGENT_API_BASE",Mo="https://api.qoder.com/api/v1/cloud",N={agentMessage:"agent.message",modelRequestEnd:"span.model_request_end",idle:"session.status_idle",error:"session.error",terminated:"terminated",userMessage:"user.message",userInterrupt:"user.interrupt"},Ao=1024,Gn=1*1024*1024,Bn=4*1024*1024,xo=8*1024,yt=class extends Error{code="auth_access_token_env_var_not_configured";constructor(e){super(`The auth access token environment variable "${e}" is not set; set it or pass auth.accessToken directly.`),this.name="CloudAuthAccessTokenEnvVarError"}},Be=class extends Error{code="cloud_agent_auth_requires_access_token";constructor(){super("options.experimentalCloudAgent requires PAT authentication via accessToken() or accessTokenFromEnv()."),this.name="CloudAgentUnsupportedAuthError"}},St=class extends Error{code="cloud_agent_api_error";status;constructor(e,t){super(`Cloud Agent API request failed with status ${e}: ${t}`),this.name="CloudAgentApiError",this.status=e}},Io=new Set(["abortController","auth","experimentalCloudAgent","debug","debugFile","stderr","env","includePartialMessages","onAuthExpired"]);function Jn(n){if(!n.experimentalCloudAgent)return;let e=Object.keys(n).filter(o=>n[o]!==void 0&&!Io.has(o));if(e.length>0)throw new Error(`options.experimentalCloudAgent cannot be combined with CLI runtime options: ${e.join(", ")}`);if(n.auth?.type!=="accessToken")throw new Be;let{agent:t,session:r}=n.experimentalCloudAgent;if(t&&ue(t)&&ht(t))throw new Error("options.experimentalCloudAgent.agent must specify either id or create, not both.");if(r&&ue(r)&&ht(r))throw new Error("options.experimentalCloudAgent.session must specify either id or create, not both.");if(r&&ue(r)&&t!==void 0)throw new Error("options.experimentalCloudAgent.agent cannot be combined with experimentalCloudAgent.session.id because an existing session already selects its agent.");let s=!!r&&ue(r);if(!s&&t===void 0)throw new Error("options.experimentalCloudAgent.agent is required when experimentalCloudAgent.session.id is not provided.");if(!s){if(!r||!ht(r))throw new Error("options.experimentalCloudAgent.session.create is required when creating a Cloud Agent session.");if(typeof r.create.environment_id!="string"||r.create.environment_id.length===0)throw new Error("options.experimentalCloudAgent.session.create.environment_id is required when creating a Cloud Agent session.")}}function ue(n){return"id"in n&&n.id!==void 0}function ht(n){return"create"in n&&n.create!==void 0}function Vn(n){return new vt(n)}var vt=class{experimentalCloudAgent;inputStream;abortController=new AbortController;accessToken;apiBase;diagnostics;onAuthExpired;sessionReadyPromise;readLoopPromise;sseConnected=Wo();startedAt=Date.now();closed=!1;authExpiredFired=!1;sessionId;assistantTextParts=[];currentTurnId;lastSseEventId;hasCurrentTurn=!1;pendingTurnEvents=[];latestUsage=Hn();latestModelUsage={};totalCostUsd=0;postedMessages=0;activeInputStreams=0;idleSeen=!1;resultEmitted=!1;constructor(e){if(!e.options.experimentalCloudAgent)throw new Error("options.experimentalCloudAgent is required for CloudAgentQuery.");this.experimentalCloudAgent=e.options.experimentalCloudAgent,this.diagnostics=e.diagnostics,this.onAuthExpired=e.options.onAuthExpired,this.accessToken=Oo(e.options.auth,e.options.env),this.apiBase=Do(),this.inputStream=new oe(()=>{this.close().catch(()=>{})});let t=e.options.abortController?.signal;t?.aborted?this.abortController.abort():t?.addEventListener("abort",()=>{this.close().catch(()=>{})},{once:!0}),this.sessionReadyPromise=this.initializeCloudSession(),this.readLoopPromise=this.readCloudEvents().catch(r=>{this.sseConnected.reject(r),this.closed||this.inputStream.error(r)}),this.streamInput(Bo(e.prompt)).catch(r=>{this.closed||this.inputStream.error(r)})}[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 initializationResult(){return(await this.sessionReadyPromise).init}async streamInput(e){this.activeInputStreams+=1,(async()=>{try{await this.sessionReadyPromise,await this.sseConnected.promise;for await(let t of e){if(this.closed)break;let r=Go(t);this.beginPendingTurn();let s=await this.postSessionEvents([{type:N.userMessage,content:r}]);this.postedMessages+=1,this.activateTurn(s.find(o=>o.type===N.userMessage)?.turnId)}}finally{this.activeInputStreams=Math.max(0,this.activeInputStreams-1),this.finishIfIdle()}})().catch(t=>{this.closed||this.inputStream.error(t)})}async interrupt(){await this.sessionReadyPromise,await this.postSessionEvents([{type:N.userInterrupt}])}async cancelAsyncMessage(e){this.unsupported("cancelAsyncMessage")}async stopTask(e){this.unsupported("stopTask")}async backgroundTasks(e){this.unsupported("backgroundTasks")}async setPermissionMode(e){this.unsupported("setPermissionMode")}async setModel(e){this.unsupported("setModel")}async setProxy(e){this.unsupported("setProxy")}async generateSessionTitle(e,t){this.unsupported("generateSessionTitle")}async addDirectories(e){this.unsupported("addDirectories")}async applyFlagSettings(e){this.unsupported("applyFlagSettings")}async supportedCommands(){this.unsupported("supportedCommands")}async getAvailableModels(){this.unsupported("getAvailableModels")}async listByokProviders(){this.unsupported("listByokProviders")}async validateByokModel(e){this.unsupported("validateByokModel")}async supportedAgents(){this.unsupported("supportedAgents")}async mcpServerStatus(){this.unsupported("mcpServerStatus")}async getContextUsage(){this.unsupported("getContextUsage")}async getUsageInfo(){this.unsupported("getUsageInfo")}async reloadPlugins(){this.unsupported("reloadPlugins")}async listPlugins(){this.unsupported("listPlugins")}async accountInfo(){this.unsupported("accountInfo")}async rewindFiles(e,t){this.unsupported("rewindFiles")}async rewind(e,t){this.unsupported("rewind")}async seedReadState(e,t){this.unsupported("seedReadState")}async flushMemory(){this.unsupported("flushMemory")}async flushSkillEvolution(){this.unsupported("flushSkillEvolution")}async refreshMemory(){this.unsupported("refreshMemory")}async mcpAuthenticate(e,t){this.unsupported("mcpAuthenticate")}async mcpSubmitOAuthCallbackUrl(e,t){this.unsupported("mcpSubmitOAuthCallbackUrl")}async close(){this.finish();try{await this.readLoopPromise}catch{}}async[Symbol.asyncDispose](){await this.close()}async initializeCloudSession(){if(this.closed)throw new Error("Cloud Agent query is closed.");let{session:e}=this.experimentalCloudAgent,t;if(e&&ue(e))t=e.id;else{let r=await this.resolveAgentId(),s=e.create,o=await this.requestJson("/sessions",{method:"POST",body:{agent:r,...No(s)}});t=zn(o,"Cloud session")}return this.sessionId=t,this.diagnostics?.record(`[cloud-agent] session ready: ${t}`),{sessionId:t,init:{commands:[],agents:[],output_style:"cloud-agent",available_output_styles:["cloud-agent"],models:[],account:{}}}}async resolveAgentId(){let{agent:e}=this.experimentalCloudAgent;if(!e)throw new Error("options.experimentalCloudAgent.agent is required when experimentalCloudAgent.session.id is not provided.");if(ue(e))return e.id;let t=await this.requestJson("/agents",{method:"POST",body:jo(e.create)});return zn(t,"Cloud agent")}async readCloudEvents(){let{sessionId:e}=await this.sessionReadyPromise,t=0;for(;!this.closed;){let r=this.lastSseEventId;if(await this.readCloudEventStream(e),this.closed||this.resultEmitted)return;if(!this.shouldReconnectSse()||t>=3){this.finishAfterSseClosed();return}this.lastSseEventId!==r&&(t=0),t+=1,await zo(250*t,this.abortController.signal)}}async readCloudEventStream(e){let t=new URL(`${this.apiBase}/sessions/${encodeURIComponent(e)}/events/stream`),r=this.lastSseEventId??this.experimentalCloudAgent.stream?.afterId;r&&t.searchParams.set("after_id",r),this.experimentalCloudAgent.stream?.deltaFlushIntervalMs!==void 0&&t.searchParams.set("delta_flush_interval_ms",String(this.experimentalCloudAgent.stream.deltaFlushIntervalMs));let s=await fetch(t.toString(),{headers:this.authHeaders({accept:"text/event-stream"}),signal:this.abortController.signal});if(!s.ok)throw this.handleAuthFailure(s.status),await Wn(s);if(!s.body)throw new Error("Cloud Agent SSE response did not include a body.");this.sseConnected.resolve(),await this.readSseBody(s.body)}async readSseBody(e){let t=e.getReader(),r=new TextDecoder,s="",o={data:[],dataBytes:0};try{for(;!this.closed;){let{done:i,value:a}=await t.read();if(i){s+=r.decode(),s.length>0&&this.consumeSseLine(s,o);break}s+=r.decode(a,{stream:!0});let u;for(;(u=s.indexOf(`
|
|
13
13
|
`))!==-1;){let c=s.slice(0,u);s=s.slice(u+1);let d=c.endsWith("\r")?c.slice(0,-1):c;if(this.consumeSseLine(d,o),this.closed)break}s.length>Gn&&(this.diagnostics?.record(`[cloud-agent] SSE line exceeded ${Gn} bytes; resetting buffer.`),s="",o.id=void 0,o.event=void 0,o.data.length=0,o.dataBytes=0)}}finally{try{await t.cancel()}catch{}t.releaseLock()}}consumeSseLine(e,t){if(e===""){(t.event||t.data.length>0)&&this.handleSseEvent({id:t.id,event:t.event??"message",data:Uo(t.data.join(`
|
|
14
14
|
`))}),t.id=void 0,t.event=void 0,t.data.length=0,t.dataBytes=0;return}if(e.startsWith(":"))return;let r=e.indexOf(":"),s=r===-1?e:e.slice(0,r),o=r===-1?"":e.slice(r+1);switch(o.startsWith(" ")&&(o=o.slice(1)),s){case"id":t.id=o;break;case"event":t.event=o;break;case"data":if(t.dataBytes+o.length>Bn){this.diagnostics?.record(`[cloud-agent] SSE event data exceeded ${Bn} bytes; dropping event.`),t.id=void 0,t.event=void 0,t.data.length=0,t.dataBytes=0;return}t.data.push(o),t.dataBytes+=o.length;break}}handleSseEvent(e){if(this.closed)return;let t=A(e.data,"type")??e.event,r=A(e.data,"turn_id"),s={type:"cloud_agent_event",event:t,id:e.id,data:e.data,uuid:e.id??Qn(),session_id:this.sessionId??A(e.data,"session_id")??""};if(e.id&&(this.lastSseEventId=e.id),this.inputStream.enqueue(s),!this.isCurrentTurnEvent(r)){this.bufferPendingTurnEvent(e,t,r);return}this.handleCurrentTurnEvent(e,t)}handleCurrentTurnEvent(e,t){switch(t){case N.agentMessage:{let r=Lo(we(e.data,"content"));r&&this.assistantTextParts.push(r);return}case N.modelRequestEnd:this.captureUsage(e.data);return;case N.idle:this.idleSeen=!0,this.finishIfIdle();return;case N.error:this.emitErrorResult(e),this.finish();return;case N.terminated:this.resultEmitted||this.emitSuccessResult(),this.finish();return}}beginPendingTurn(){this.currentTurnId=void 0,this.hasCurrentTurn=!1,this.pendingTurnEvents=[],this.assistantTextParts=[],this.latestUsage=Hn(),this.latestModelUsage={},this.totalCostUsd=0,this.idleSeen=!1}activateTurn(e){this.currentTurnId=e,this.hasCurrentTurn=!0;let t=this.pendingTurnEvents;this.pendingTurnEvents=[];for(let r of t)if(this.isCurrentTurnEvent(r.turnId)&&this.handleCurrentTurnEvent(r.event,r.type),this.closed)break}isCurrentTurnEvent(e){return this.hasCurrentTurn?this.currentTurnId?e===this.currentTurnId:e===void 0:!1}bufferPendingTurnEvent(e,t,r){this.hasCurrentTurn||this.activeInputStreams===0||(this.pendingTurnEvents.length>=Ao&&this.pendingTurnEvents.shift(),this.pendingTurnEvents.push({event:e,type:t,turnId:r}))}finishIfIdle(){this.closed||!this.idleSeen||this.activeInputStreams>0||this.postedMessages===0||(this.emitSuccessResult(),this.finish())}finishAfterSseClosed(){this.finishIfIdle(),!this.closed&&(!this.resultEmitted&&(this.hasCurrentTurn||this.postedMessages>0||this.activeInputStreams>0)&&this.emitErrorResultMessage("Cloud Agent SSE stream closed before the current turn reached a terminal state."),this.finish())}shouldReconnectSse(){return!this.resultEmitted&&(this.hasCurrentTurn||this.postedMessages>0||this.activeInputStreams>0)}emitSuccessResult(){this.resultEmitted||this.closed||(this.resultEmitted=!0,this.inputStream.enqueue({...this.buildResultBase(),subtype:"success",is_error:!1,result:this.assistantTextParts.join("")}))}emitErrorResult(e){this.emitErrorResultMessage(A(e.data,"error")??A(ze(e.data,"error"),"message")??"Cloud Agent session failed.")}emitErrorResultMessage(e){this.resultEmitted||this.closed||(this.resultEmitted=!0,this.inputStream.enqueue({...this.buildResultBase(),subtype:"error_during_execution",is_error:!0,errors:[e]}))}buildResultBase(){let e=Date.now()-this.startedAt;return{type:"result",duration_ms:e,duration_api_ms:e,num_turns:Math.max(1,this.postedMessages),stop_reason:null,total_cost_usd:this.totalCostUsd,usage:this.latestUsage,modelUsage:this.latestModelUsage,permission_denials:[],uuid:Qn(),session_id:this.sessionId??""}}async postSessionEvents(e){let t=this.sessionId??(await this.sessionReadyPromise).sessionId,r=await this.requestJson(`/sessions/${encodeURIComponent(t)}/events`,{method:"POST",body:{events:e}});return Ko(r)}captureUsage(e){let t=ze(e,"usage");if(!t)return;this.latestUsage=$o(this.latestUsage,t);let r=_(e,"total_cost_usd")??_(e,"cost_usd")??_(t,"total_cost_usd")??_(t,"cost_usd");r!==void 0&&(this.totalCostUsd+=r);let s=A(e,"model")??A(t,"model");if(s){let o=this.latestModelUsage[s]?.costUSD??0;this.latestModelUsage[s]=Qo(this.latestUsage,o+(r??0))}}async requestJson(e,t){let r=await fetch(`${this.apiBase}${e}`,{method:t.method,headers:this.authHeaders({accept:"application/json",contentType:t.body?"application/json":void 0}),body:t.body?JSON.stringify(t.body):void 0,signal:this.abortController.signal});if(!r.ok)throw this.handleAuthFailure(r.status),await Wn(r);if(r.status===204)return{};try{return await r.json()}catch{return{}}}authHeaders(e){let t={Authorization:`Bearer ${this.accessToken}`,Accept:e.accept};return e.contentType&&(t["Content-Type"]=e.contentType),t}handleAuthFailure(e){if((e===401||e===403)&&!this.authExpiredFired){this.authExpiredFired=!0;try{this.onAuthExpired?.()}catch(t){this.diagnostics?.record("[cloud-agent] onAuthExpired callback threw:",t)}}}finish(){this.closed||(this.closed=!0,this.abortController.abort(),this.sseConnected.resolve(),this.inputStream.done())}unsupported(e){throw new Error(`Query.${e}() is not supported when options.experimentalCloudAgent is enabled.`)}};function Oo(n,e){if(n?.type!=="accessToken")throw new Be;if(typeof n.accessToken=="string")return n.accessToken;let t=n.accessToken.envVar,r=e&&Object.hasOwn(e,t)?e[t]:process.env[t];if(!r)throw new yt(t);return r}function Do(){return process.env[Co]?.replace(/\/+$/,"")??Mo}function jo(n){return wt({name:n.name,model:n.model,system:n.system,description:n.description,tools:n.tools,mcp_servers:n.mcp_servers,skills:n.skills,metadata:n.metadata})}function No(n){return wt({title:n.title,environment_id:n.environment_id,resources:n.resources?.map(e=>wt({...e})),vault_ids:n.vault_ids,memory_store_ids:n.memory_store_ids})}function wt(n){return Object.fromEntries(Object.entries(n).filter(([,e])=>e!==void 0))}function zn(n,e){let t=A(n,"id");if(!t)throw new Error(`${e} response did not include an id.`);return t}function Ko(n){let e=qo(n,"data");return e?e.flatMap(t=>t===null||typeof t!="object"||Array.isArray(t)?[]:[{id:A(t,"id"),turnId:A(t,"turn_id"),type:A(t,"type")}]):[]}async function Wn(n){let e=await Fo(n,xo);return new St(n.status,e||n.statusText||"unknown error")}async function Fo(n,e){if(!n.body)try{return(await n.text()).slice(0,e)}catch{return""}let t=n.body.getReader(),r=new TextDecoder,s=[],o=0;try{for(;o<e;){let{done:i,value:a}=await t.read();if(i)break;o+=a.byteLength,s.push(r.decode(a,{stream:!0}))}s.push(r.decode())}catch{}finally{try{await t.cancel()}catch{}t.releaseLock()}return s.join("").slice(0,e)}function Uo(n){if(n.length===0)return{};try{return JSON.parse(n)}catch{return n}}function ze(n,e){let t=we(n,e);return t!==null&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function qo(n,e){let t=we(n,e);return Array.isArray(t)?t:void 0}function A(n,e){let t=we(n,e);return typeof t=="string"?t:void 0}function _(n,e){let t=we(n,e);return typeof t=="number"&&Number.isFinite(t)?t:void 0}function we(n,e){if(!(n===null||typeof n!="object"||Array.isArray(n)))return n[e]}function Lo(n){return typeof n=="string"?n:Array.isArray(n)&&n.map(t=>Yn(t)?t.text:"").filter(Boolean).join("")||void 0}function $o(n,e){let t=ze(e,"cache_creation"),r=ze(e,"server_tool_use");return{...n,cache_creation:{ephemeral_1h_input_tokens:_(t,"ephemeral_1h_input_tokens")??n.cache_creation.ephemeral_1h_input_tokens,ephemeral_5m_input_tokens:_(t,"ephemeral_5m_input_tokens")??n.cache_creation.ephemeral_5m_input_tokens},cache_creation_input_tokens:_(e,"cache_creation_input_tokens")??n.cache_creation_input_tokens,cache_read_input_tokens:_(e,"cache_read_input_tokens")??n.cache_read_input_tokens,input_tokens:_(e,"input_tokens")??n.input_tokens,output_tokens:_(e,"output_tokens")??n.output_tokens,server_tool_use:{web_fetch_requests:_(r,"web_fetch_requests")??n.server_tool_use.web_fetch_requests,web_search_requests:_(r,"web_search_requests")??n.server_tool_use.web_search_requests}}}function Qo(n,e){return{inputTokens:n.input_tokens,outputTokens:n.output_tokens,cacheReadInputTokens:n.cache_read_input_tokens,cacheCreationInputTokens:n.cache_creation_input_tokens,webSearchRequests:n.server_tool_use.web_search_requests,costUSD:e,contextWindow:0,maxOutputTokens:0}}function Go(n){let e=n.message.content;return typeof e=="string"?e:Array.isArray(e)?e.map(t=>Yn(t)?t.text:JSON.stringify(t)).join(`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
3
|
"brand": "global",
|
|
4
|
-
"sdkVersion": "1.0.
|
|
4
|
+
"sdkVersion": "1.0.27",
|
|
5
5
|
"qoderCliVersion": "1.1.31",
|
|
6
6
|
"defaultTransport": "worker",
|
|
7
7
|
"workerRuntime": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"source": "qodercli-worker-runtime",
|
|
11
11
|
"urlTemplate": "https://download.qoder.com/qodercli/releases/1.1.31/qodercli-worker-runtime-{target}.tgz",
|
|
12
12
|
"artifactNameTemplate": "qodercli-worker-runtime-{target}.tgz",
|
|
13
|
-
"sdkVersion": "1.0.
|
|
13
|
+
"sdkVersion": "1.0.27",
|
|
14
14
|
"qoderCliVersion": "1.1.31"
|
|
15
15
|
}
|
|
16
16
|
}
|
package/dist/types/auth.d.ts
CHANGED
|
@@ -36,11 +36,13 @@ export type AuthOptions = {
|
|
|
36
36
|
} | ServiceAccountAuthOptions;
|
|
37
37
|
export type JobTokenRequest = {
|
|
38
38
|
requestId: string;
|
|
39
|
-
reason: 'initial' | 'unauthorized';
|
|
39
|
+
reason: 'initial' | 'expiring' | 'unauthorized';
|
|
40
40
|
sessionId?: string;
|
|
41
41
|
};
|
|
42
42
|
export type JobTokenResult = {
|
|
43
43
|
token: string;
|
|
44
|
+
/** Absolute expiration time as a Unix timestamp in milliseconds. */
|
|
45
|
+
expiresAt?: number;
|
|
44
46
|
};
|
|
45
47
|
export type FetchJobToken = (request: JobTokenRequest, options: {
|
|
46
48
|
signal: AbortSignal;
|
package/dist/types/control.d.ts
CHANGED
|
@@ -9,12 +9,13 @@ export type { SDKControlRequest, SDKControlResponse, SDKControlCancelRequest, SD
|
|
|
9
9
|
/** Wire format for fetch_job_token inbound control request from CLI. */
|
|
10
10
|
export type FetchJobTokenWireRequest = {
|
|
11
11
|
subtype: 'fetch_job_token';
|
|
12
|
-
reason: 'initial' | 'unauthorized';
|
|
12
|
+
reason: 'initial' | 'expiring' | 'unauthorized';
|
|
13
13
|
session_id?: string;
|
|
14
14
|
};
|
|
15
15
|
/** Wire format for fetch_job_token success response. */
|
|
16
16
|
export type FetchJobTokenWireResponse = {
|
|
17
17
|
token: string;
|
|
18
|
+
expires_at?: number;
|
|
18
19
|
};
|
|
19
20
|
/** Wire format for Service Account token requests sent by qodercli. */
|
|
20
21
|
export type FetchServiceAccountTokenWireRequest = {
|