@qoder-ai/qoder-agent-sdk 1.0.46 → 1.0.47
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
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var Er=Object.defineProperty;var Pr=(n,e)=>{for(var t in e)Er(n,t,{get:e[t],enumerable:!0})};import{spawn as ui}from"child_process";import{createInterface as ci}from"readline";var Tr=["PreToolUse","PostToolUse","PostToolUseFailure","UserPromptSubmit","SessionStart","SessionEnd","Stop","SubagentStart","SubagentStop","PreCompact","PostCompact","CwdChanged","InstructionsLoaded","FileChanged","PermissionRequest","PermissionDenied","WorktreeCreate","WorktreeRemove"],Mr=["clear","resume","logout","prompt_input_exit","other","bypass_permissions_disabled"],Ze=2e3,Ln=5e3;var et="1.0.46";var we=41,Kn=["Agent","AskUserQuestion","Bash","Edit","Glob","Grep","ImageGen","ImageSearch","NotebookEdit","Read","Skill","TaskCreate","TaskGet","TaskUpdate","TaskList","UpdateGoal","WebFetch","WebSearch","Write"],Un=["TaskCreate","TaskGet","TaskUpdate","TaskList"],Ar="QODER_FEATURE_TASKS";function Bn(n){let e=n[Ar];if(e!=="0"&&e!=="false")return[...Kn];let t=new Set(Un);return Kn.flatMap(s=>s===Un[0]?["TodoWrite"]:t.has(s)?[]:[s])}import{chmod as Wn,mkdtemp as Lr,rm as Jn,writeFile as Br}from"fs/promises";import{existsSync as ot,mkdtempSync as $r,readFileSync as zr,rmSync as Qr,writeFileSync as Gr}from"fs";import{homedir as Hr,tmpdir as Vn}from"os";import{dirname as ss,join as z}from"path";import{fileURLToPath as Wr}from"url";var Ir=/^[A-Za-z0-9_-]{1,64}$/,Dr=new Set(["mcp_list","mcp_get","mcp_call"]);function xt(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(!Ir.test(e.exposedName))throw new Error(`MCP tool "${n}/${e.name}" has invalid exposedName "${e.exposedName}".`);if(Dr.has(e.exposedName))throw new Error(`MCP tool "${n}/${e.name}" cannot use reserved exposedName "${e.exposedName}".`)}}function qt(n,e){let t={};for(let s of e)xt(n,s),(s.exposedName!==void 0||s.alwaysLoad===!0)&&(t[s.name]={...s.exposedName!==void 0?{exposedName:s.exposedName}:{},...s.alwaysLoad===!0?{alwaysLoad:!0}:{}});return Object.keys(t).length>0?t:void 0}function Nt(n,e,t=e.tools??[]){let{tools:s,...o}=e,r=qt(n,t);return{...o,...r?{toolOverrides:r}:{}}}function $n(n){let e={};for(let[t,s]of Object.entries(n)){if(s.type==="sdk")throw new Error(`MCP server "${t}" uses an in-process SDK transport and cannot be changed with setMcpServers().`);let o=s.tools??[],r=o.find(i=>i.permission_policy!==void 0);if(r)throw new Error(`MCP tool "${t}/${r.name}" cannot set permission_policy through setMcpServers(); configure it when creating the query.`);e[t]=Nt(t,s,o)}return e}var Or="global",zn=Or==="cn",xr=zn?"QODERCN_":"QODER_",jt=`${xr}VPC_ENDPOINT`,v=zn?{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 Qn=v.accessTokenEnv,tt=v.serviceAccountEnv;function qr(n){return{type:"accessToken",accessToken:n}}function Nr(n=Qn){return{type:"accessToken",accessToken:{envVar:n}}}function jr(){return{type:"qodercli"}}function Fr(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 Kr(n=tt){return{type:"serviceAccount",serviceAccountKey:{envVar:n}}}function Ur(n){return{type:"jobToken",fetchJobToken:n}}var Gn=["l1StaticCheck","l2LightweightScan","l3DeepScan"];function Hn(n){if(n===null||typeof n!="object"||Array.isArray(n))throw new TypeError("securityScan must be an object.");let e=new Set(Gn),t=Object.keys(n).filter(s=>!e.has(s));if(t.length>0)throw new TypeError(`securityScan contains unknown option${t.length===1?"":"s"}: ${t.join(", ")}.`);for(let s of Gn){let o=n[s];if(o!==void 0&&typeof o!="boolean")throw new TypeError(`securityScan.${s} must be a boolean.`)}return{l1StaticCheck:n.l1StaticCheck??!1,l2LightweightScan:n.l2LightweightScan??!1,l3DeepScan:n.l3DeepScan??!1}}var Yn="QODER_AGENT_SDK_ENTRYPOINT",Xn="QODER_AGENT_SDK_VERSION",Zn="QODER_SDK_AUTH_PAYLOAD_FILE",Jr="sdk-ts",Vr=Wr(import.meta.url),es=ss(Vr),nt=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"}},st=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 X(n){return/\.(js|mjs|tsx?|jsx)$/.test(n)}function Z(){if(process.env.QODERCLI_PATH)return process.env.QODERCLI_PATH;let n=Yr();if(n)return n;let e=Xr();if(ot(e))return e;let t=Zr();return t||v.cliCommands[0]}function Yr(){for(let n of os())for(let e of v.cliCommands){let t=process.platform==="win32"?`${e}.exe`:e,s=z(n,"dist","_bundled",t);if(ot(s))return s}return null}function Xr(){for(let n of os())for(let e of v.cliCommands){let t=process.platform==="win32"?`${e}.exe`:e,s=[z(n,"node_modules",".bin",t),z(n,"..","..",".bin",t)];for(let o of s)if(ot(o))return o}return v.cliCommands[0]}function Zr(){let n=process.env[v.cliHomeEnv]??Hr();for(let e of v.cliCommands){let t=process.platform==="win32"?`${e}.exe`:e,s=z(n,v.configDirName,"local",t);if(ot(s))return s}return null}function os(){let n=[z(es,".."),z(es,"..","..")];return[...new Set(n)]}function ei(){return{allow:[],ask:[],deny:[]}}function ts(n){return n.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}function ti(n,e){if(e.startsWith("mcp__"))return e;let t=ts(n),s=e==="*"?"*":ts(e);if(!t||!s)throw new Error(`Invalid MCP tool policy name for server "${n}" and tool "${e}"`);return`mcp__${t}__${s}`}function ns(n,e){if(e.length===0)return;let t=new Set(n);for(let s of e)t.has(s)||(n.push(s),t.add(s))}function ni(n){let e=n??{},t=e.general&&typeof e.general=="object"&&!Array.isArray(e.general)?e.general:{},s=t.fileCheckpointing&&typeof t.fileCheckpointing=="object"&&!Array.isArray(t.fileCheckpointing)?t.fileCheckpointing:{};return{...e,general:{...t,fileCheckpointing:{...s,enabled:!0}}}}var j=class{options;diagnostics;logPrefix;authPayloadPath=null;generatedSettingsDir;constructor(e,t,s="[RuntimeLaunch]"){this.options=e,this.diagnostics=t,this.logPrefix=s}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{Qr(this.generatedSettingsDir,{recursive:!0,force:!0})}catch{}finally{this.generatedSettingsDir=void 0}}async cleanupLaunchArtifacts(){this.cleanupGeneratedSettings(),await this.cleanupAuthPayload()}async cleanupAuthPayload(){if(!this.authPayloadPath)return;let e=ss(this.authPayloadPath);try{await Jn(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[s,o]of Object.entries(e))o!==void 0&&(t[s]=o);delete t[Yn],delete t[Xn],delete t[Zn];for(let s of this.serviceAccountCredentialEnvVars())ri(t,s);if(t[Yn]=Jr,t[Xn]=et,this.authPayloadPath&&(t[Zn]=this.authPayloadPath),delete t.NODE_OPTIONS,this.options.vpcEndpoint!==void 0){let s=this.options.vpcEndpoint.trim();s?t[jt]=s:delete t[jt]}return t}serviceAccountCredentialEnvVars(){let e=this.options.auth;if(e?.type!=="serviceAccount")return[];let t=[tt];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 r of t.allowedTools)e.push("--allowed-tools",r);if(t.disallowedTools&&t.disallowedTools.length>0)for(let r of t.disallowedTools)e.push("--disallowed-tools",r);let s=t.tools??Bn(t.env??process.env);if(Array.isArray(s)?e.push("--tools",s.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 r of t.extensions)e.push("--extensions",r);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 r of t.allowedMcpServerNames)e.push("--allowed-mcp-server-names",r);t.strictMcpConfig&&e.push("--strict-mcp-config");let o=this.buildSettingsArg();if(o!==void 0&&e.push("--settings",o),t.settingSources!==void 0&&e.push("--setting-sources",t.settingSources.join(",")),e.push("--disable-builtin-skills"),t.additionalDirectories&&t.additionalDirectories.length>0)for(let r of t.additionalDirectories)e.push("--add-dir",r);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 r of t.plugins)r.type==="local"&&e.push("--plugin-dir",r.path);if(t.extraArgs)for(let[r,i]of Object.entries(t.extraArgs))e.push(`--${r}`),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 r=this.readSettingsFile(e);this.applySettingsCompatibility(r),this.applyAdditionalDirectories(r),this.applyMcpPolicyRules(r,t),this.applySecurityScanSetting(r);let i=this.applyFileCheckpointingSetting(r);return Object.keys(i).length>0?this.writeGeneratedSettingsFile(i):void 0}let s={...e??{}};this.applySettingsCompatibility(s),this.applyAdditionalDirectories(s),this.applyMcpPolicyRules(s,t),this.applySecurityScanSetting(s);let o=this.applyFileCheckpointingSetting(s);return Object.keys(o).length>0?JSON.stringify(o):void 0}applyFileCheckpointingSetting(e){return this.options.enableFileCheckpointing?ni(e):e}applySecurityScanSetting(e){let t=this.options.securityScan;t!==void 0&&(e.securityScan=Hn(t))}applySettingsCompatibility(e){let t=e.permissions;if(t?.defaultMode!==void 0){let s=e.general!==null&&typeof e.general=="object"?e.general:{},o=this.toQoderDefaultPermissionMode(t.defaultMode);o!==void 0&&s.defaultPermissionMode===void 0&&(s.defaultPermissionMode=o),e.general=s}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 s=e.permissions!==null&&typeof e.permissions=="object"?e.permissions:{},o=Array.isArray(s.additionalDirectories)?[...s.additionalDirectories]:[];ns(o,t),s.additionalDirectories=o,e.permissions=s}buildCliMcpServers(){let e=this.options.mcpServers;if(!e||Object.keys(e).length===0)return e;let t={};for(let[s,o]of Object.entries(e)){let r=this.options.mcpToolPolicies?.[s]??o.tools??[];t[s]=Nt(s,o,r)}return t}collectMcpPolicyPermissionRules(){let e=ei(),t=new Map;for(let[s,o]of Object.entries(this.options.mcpToolPolicies??{}))o.length>0&&t.set(s,o);for(let[s,o]of Object.entries(this.options.mcpServers??{})){let r=o.tools;Array.isArray(r)&&r.length>0&&t.set(s,[...t.get(s)??[],...r])}for(let[s,o]of t)for(let r of o){let i=ti(s,r.name);switch(r.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 s=e.permissions!==null&&typeof e.permissions=="object"?e.permissions:{};e.permissions=s;for(let o of["allow","ask","deny"]){let r=Array.isArray(s[o])?[...s[o]]:[];ns(r,t[o]),s[o]=r}}readSettingsFile(e){let t=zr(e,"utf8").trim();if(!t)return{};let s=JSON.parse(t);if(s===null||typeof s!="object"||Array.isArray(s))throw new Error("Settings file must contain a JSON object.");return s}writeGeneratedSettingsFile(e){this.generatedSettingsDir=$r(z(Vn(),"qoder-agent-sdk-settings-"));let t=z(this.generatedSettingsDir,"settings.json");return Gr(t,JSON.stringify(e),"utf8"),t}async createAuthPayloadFile(e){let t=Ft(e,this.options.env),s=await Lr(z(Vn(),"qoder-sdk-auth-"));try{await Wn(s,448);let o=z(s,"payload.json");return await Br(o,JSON.stringify(t),{mode:384}),await Wn(o,384),this.diagnostics?.record(`${this.logPrefix} Auth payload created: type=${t.type}, path=${o}`),o}catch(o){throw await Jn(s,{recursive:!0,force:!0}).catch(()=>{}),o}}};function Ft(n,e){switch(n.type){case"accessToken":return{type:"accessToken",accessToken:oi(n,e)};case"qodercli":return{type:"qodercli"};case"jobToken":return{type:"jobToken",jobTokenProvider:"host"};case"serviceAccount":{let t=n.serviceAccountKey!==void 0,s=typeof n.fetchServiceAccountToken=="function";if(t===s)throw new TypeError("Service Account auth requires exactly one credential source: serviceAccountKey or fetchServiceAccountToken");return s?{type:"serviceAccount",serviceAccountTokenProvider:"host"}:{type:"serviceAccount",serviceAccountKey:si(n,e)}}}}function si(n,e){if(!n.serviceAccountKey)throw new Error("Service Account key authentication requires serviceAccountKey");if(typeof n.serviceAccountKey=="string")return n.serviceAccountKey;let t=n.serviceAccountKey.envVar,s=e&&Object.hasOwn(e,t)?e[t]:process.env[t];if(!s)throw new st(t);return s}function oi(n,e){if(typeof n.accessToken=="string")return n.accessToken;let t=n.accessToken.envVar,s=e&&Object.hasOwn(e,t)?e[t]:process.env[t];if(!s)throw new nt(t);return s}function ri(n,e){if(process.platform!=="win32"){delete n[e];return}let t=e.toLowerCase();for(let s of Object.keys(n))s.toLowerCase()===t&&delete n[s]}function rt(n,e){let t={...n};for(let[s,o]of Object.entries(e))o!==void 0&&(t[s]=o);return t}var ii=new Set(["--mcp-config","--proxy","--settings"]);function it(n){let e=[];for(let t=0;t<n.length;t+=1){let s=n[t];e.push(s),ii.has(s)&&t+1<n.length&&(e.push("[redacted]"),t+=1)}return e.join(" ")}import{Transform as ai}from"node:stream";var Q=16*1024*1024,Ne=class extends Error{constructor(t,s){super(`${t} exceeded the ${s}-byte frame limit`);this.direction=t;this.limit=s;this.name="FrameTooLargeError"}code="DAEMON_FRAME_TOO_LARGE"},ee=class extends ai{constructor(t=Q,s="JSONL input"){super();this.maxLineBytes=t;this.direction=s;if(!Number.isSafeInteger(t)||t<=0)throw new Error("maxLineBytes must be a positive safe integer")}bytesSinceNewline=0;_transform(t,s,o){let r=Buffer.isBuffer(t)?t:Buffer.from(t,s),i=0;for(let a=0;a<r.length;a+=1)if(r[a]===10){if(this.bytesSinceNewline+=a-i,this.bytesSinceNewline>this.maxLineBytes){o(new Ne(this.direction,this.maxLineBytes));return}this.bytesSinceNewline=0,i=a+1}if(this.bytesSinceNewline+=r.length-i,this.bytesSinceNewline>this.maxLineBytes){o(new Ne(this.direction,this.maxLineBytes));return}o(void 0,r)}};function ve(n,e=Q,t="JSONL output"){let s=n.endsWith(`
|
|
1
|
+
var Er=Object.defineProperty;var Pr=(n,e)=>{for(var t in e)Er(n,t,{get:e[t],enumerable:!0})};import{spawn as ui}from"child_process";import{createInterface as ci}from"readline";var Tr=["PreToolUse","PostToolUse","PostToolUseFailure","UserPromptSubmit","SessionStart","SessionEnd","Stop","SubagentStart","SubagentStop","PreCompact","PostCompact","CwdChanged","InstructionsLoaded","FileChanged","PermissionRequest","PermissionDenied","WorktreeCreate","WorktreeRemove"],Mr=["clear","resume","logout","prompt_input_exit","other","bypass_permissions_disabled"],Ze=2e3,Ln=5e3;var et="1.0.47";var we=41,Kn=["Agent","AskUserQuestion","Bash","Edit","Glob","Grep","ImageGen","ImageSearch","NotebookEdit","Read","Skill","TaskCreate","TaskGet","TaskUpdate","TaskList","UpdateGoal","WebFetch","WebSearch","Write"],Un=["TaskCreate","TaskGet","TaskUpdate","TaskList"],Ar="QODER_FEATURE_TASKS";function Bn(n){let e=n[Ar];if(e!=="0"&&e!=="false")return[...Kn];let t=new Set(Un);return Kn.flatMap(s=>s===Un[0]?["TodoWrite"]:t.has(s)?[]:[s])}import{chmod as Wn,mkdtemp as Lr,rm as Jn,writeFile as Br}from"fs/promises";import{existsSync as ot,mkdtempSync as $r,readFileSync as zr,rmSync as Qr,writeFileSync as Gr}from"fs";import{homedir as Hr,tmpdir as Vn}from"os";import{dirname as ss,join as z}from"path";import{fileURLToPath as Wr}from"url";var Ir=/^[A-Za-z0-9_-]{1,64}$/,Dr=new Set(["mcp_list","mcp_get","mcp_call"]);function xt(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(!Ir.test(e.exposedName))throw new Error(`MCP tool "${n}/${e.name}" has invalid exposedName "${e.exposedName}".`);if(Dr.has(e.exposedName))throw new Error(`MCP tool "${n}/${e.name}" cannot use reserved exposedName "${e.exposedName}".`)}}function qt(n,e){let t={};for(let s of e)xt(n,s),(s.exposedName!==void 0||s.alwaysLoad===!0)&&(t[s.name]={...s.exposedName!==void 0?{exposedName:s.exposedName}:{},...s.alwaysLoad===!0?{alwaysLoad:!0}:{}});return Object.keys(t).length>0?t:void 0}function Nt(n,e,t=e.tools??[]){let{tools:s,...o}=e,r=qt(n,t);return{...o,...r?{toolOverrides:r}:{}}}function $n(n){let e={};for(let[t,s]of Object.entries(n)){if(s.type==="sdk")throw new Error(`MCP server "${t}" uses an in-process SDK transport and cannot be changed with setMcpServers().`);let o=s.tools??[],r=o.find(i=>i.permission_policy!==void 0);if(r)throw new Error(`MCP tool "${t}/${r.name}" cannot set permission_policy through setMcpServers(); configure it when creating the query.`);e[t]=Nt(t,s,o)}return e}var Or="global",zn=Or==="cn",xr=zn?"QODERCN_":"QODER_",jt=`${xr}VPC_ENDPOINT`,v=zn?{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 Qn=v.accessTokenEnv,tt=v.serviceAccountEnv;function qr(n){return{type:"accessToken",accessToken:n}}function Nr(n=Qn){return{type:"accessToken",accessToken:{envVar:n}}}function jr(){return{type:"qodercli"}}function Fr(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 Kr(n=tt){return{type:"serviceAccount",serviceAccountKey:{envVar:n}}}function Ur(n){return{type:"jobToken",fetchJobToken:n}}var Gn=["l1StaticCheck","l2LightweightScan","l3DeepScan"];function Hn(n){if(n===null||typeof n!="object"||Array.isArray(n))throw new TypeError("securityScan must be an object.");let e=new Set(Gn),t=Object.keys(n).filter(s=>!e.has(s));if(t.length>0)throw new TypeError(`securityScan contains unknown option${t.length===1?"":"s"}: ${t.join(", ")}.`);for(let s of Gn){let o=n[s];if(o!==void 0&&typeof o!="boolean")throw new TypeError(`securityScan.${s} must be a boolean.`)}return{l1StaticCheck:n.l1StaticCheck??!1,l2LightweightScan:n.l2LightweightScan??!1,l3DeepScan:n.l3DeepScan??!1}}var Yn="QODER_AGENT_SDK_ENTRYPOINT",Xn="QODER_AGENT_SDK_VERSION",Zn="QODER_SDK_AUTH_PAYLOAD_FILE",Jr="sdk-ts",Vr=Wr(import.meta.url),es=ss(Vr),nt=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"}},st=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 X(n){return/\.(js|mjs|tsx?|jsx)$/.test(n)}function Z(){if(process.env.QODERCLI_PATH)return process.env.QODERCLI_PATH;let n=Yr();if(n)return n;let e=Xr();if(ot(e))return e;let t=Zr();return t||v.cliCommands[0]}function Yr(){for(let n of os())for(let e of v.cliCommands){let t=process.platform==="win32"?`${e}.exe`:e,s=z(n,"dist","_bundled",t);if(ot(s))return s}return null}function Xr(){for(let n of os())for(let e of v.cliCommands){let t=process.platform==="win32"?`${e}.exe`:e,s=[z(n,"node_modules",".bin",t),z(n,"..","..",".bin",t)];for(let o of s)if(ot(o))return o}return v.cliCommands[0]}function Zr(){let n=process.env[v.cliHomeEnv]??Hr();for(let e of v.cliCommands){let t=process.platform==="win32"?`${e}.exe`:e,s=z(n,v.configDirName,"local",t);if(ot(s))return s}return null}function os(){let n=[z(es,".."),z(es,"..","..")];return[...new Set(n)]}function ei(){return{allow:[],ask:[],deny:[]}}function ts(n){return n.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}function ti(n,e){if(e.startsWith("mcp__"))return e;let t=ts(n),s=e==="*"?"*":ts(e);if(!t||!s)throw new Error(`Invalid MCP tool policy name for server "${n}" and tool "${e}"`);return`mcp__${t}__${s}`}function ns(n,e){if(e.length===0)return;let t=new Set(n);for(let s of e)t.has(s)||(n.push(s),t.add(s))}function ni(n){let e=n??{},t=e.general&&typeof e.general=="object"&&!Array.isArray(e.general)?e.general:{},s=t.fileCheckpointing&&typeof t.fileCheckpointing=="object"&&!Array.isArray(t.fileCheckpointing)?t.fileCheckpointing:{};return{...e,general:{...t,fileCheckpointing:{...s,enabled:!0}}}}var j=class{options;diagnostics;logPrefix;authPayloadPath=null;generatedSettingsDir;constructor(e,t,s="[RuntimeLaunch]"){this.options=e,this.diagnostics=t,this.logPrefix=s}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{Qr(this.generatedSettingsDir,{recursive:!0,force:!0})}catch{}finally{this.generatedSettingsDir=void 0}}async cleanupLaunchArtifacts(){this.cleanupGeneratedSettings(),await this.cleanupAuthPayload()}async cleanupAuthPayload(){if(!this.authPayloadPath)return;let e=ss(this.authPayloadPath);try{await Jn(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[s,o]of Object.entries(e))o!==void 0&&(t[s]=o);delete t[Yn],delete t[Xn],delete t[Zn];for(let s of this.serviceAccountCredentialEnvVars())ri(t,s);if(t[Yn]=Jr,t[Xn]=et,this.authPayloadPath&&(t[Zn]=this.authPayloadPath),delete t.NODE_OPTIONS,this.options.vpcEndpoint!==void 0){let s=this.options.vpcEndpoint.trim();s?t[jt]=s:delete t[jt]}return t}serviceAccountCredentialEnvVars(){let e=this.options.auth;if(e?.type!=="serviceAccount")return[];let t=[tt];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 r of t.allowedTools)e.push("--allowed-tools",r);if(t.disallowedTools&&t.disallowedTools.length>0)for(let r of t.disallowedTools)e.push("--disallowed-tools",r);let s=t.tools??Bn(t.env??process.env);if(Array.isArray(s)?e.push("--tools",s.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 r of t.extensions)e.push("--extensions",r);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 r of t.allowedMcpServerNames)e.push("--allowed-mcp-server-names",r);t.strictMcpConfig&&e.push("--strict-mcp-config");let o=this.buildSettingsArg();if(o!==void 0&&e.push("--settings",o),t.settingSources!==void 0&&e.push("--setting-sources",t.settingSources.join(",")),e.push("--disable-builtin-skills"),t.additionalDirectories&&t.additionalDirectories.length>0)for(let r of t.additionalDirectories)e.push("--add-dir",r);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 r of t.plugins)r.type==="local"&&e.push("--plugin-dir",r.path);if(t.extraArgs)for(let[r,i]of Object.entries(t.extraArgs))e.push(`--${r}`),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 r=this.readSettingsFile(e);this.applySettingsCompatibility(r),this.applyAdditionalDirectories(r),this.applyMcpPolicyRules(r,t),this.applySecurityScanSetting(r);let i=this.applyFileCheckpointingSetting(r);return Object.keys(i).length>0?this.writeGeneratedSettingsFile(i):void 0}let s={...e??{}};this.applySettingsCompatibility(s),this.applyAdditionalDirectories(s),this.applyMcpPolicyRules(s,t),this.applySecurityScanSetting(s);let o=this.applyFileCheckpointingSetting(s);return Object.keys(o).length>0?JSON.stringify(o):void 0}applyFileCheckpointingSetting(e){return this.options.enableFileCheckpointing?ni(e):e}applySecurityScanSetting(e){let t=this.options.securityScan;t!==void 0&&(e.securityScan=Hn(t))}applySettingsCompatibility(e){let t=e.permissions;if(t?.defaultMode!==void 0){let s=e.general!==null&&typeof e.general=="object"?e.general:{},o=this.toQoderDefaultPermissionMode(t.defaultMode);o!==void 0&&s.defaultPermissionMode===void 0&&(s.defaultPermissionMode=o),e.general=s}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 s=e.permissions!==null&&typeof e.permissions=="object"?e.permissions:{},o=Array.isArray(s.additionalDirectories)?[...s.additionalDirectories]:[];ns(o,t),s.additionalDirectories=o,e.permissions=s}buildCliMcpServers(){let e=this.options.mcpServers;if(!e||Object.keys(e).length===0)return e;let t={};for(let[s,o]of Object.entries(e)){let r=this.options.mcpToolPolicies?.[s]??o.tools??[];t[s]=Nt(s,o,r)}return t}collectMcpPolicyPermissionRules(){let e=ei(),t=new Map;for(let[s,o]of Object.entries(this.options.mcpToolPolicies??{}))o.length>0&&t.set(s,o);for(let[s,o]of Object.entries(this.options.mcpServers??{})){let r=o.tools;Array.isArray(r)&&r.length>0&&t.set(s,[...t.get(s)??[],...r])}for(let[s,o]of t)for(let r of o){let i=ti(s,r.name);switch(r.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 s=e.permissions!==null&&typeof e.permissions=="object"?e.permissions:{};e.permissions=s;for(let o of["allow","ask","deny"]){let r=Array.isArray(s[o])?[...s[o]]:[];ns(r,t[o]),s[o]=r}}readSettingsFile(e){let t=zr(e,"utf8").trim();if(!t)return{};let s=JSON.parse(t);if(s===null||typeof s!="object"||Array.isArray(s))throw new Error("Settings file must contain a JSON object.");return s}writeGeneratedSettingsFile(e){this.generatedSettingsDir=$r(z(Vn(),"qoder-agent-sdk-settings-"));let t=z(this.generatedSettingsDir,"settings.json");return Gr(t,JSON.stringify(e),"utf8"),t}async createAuthPayloadFile(e){let t=Ft(e,this.options.env),s=await Lr(z(Vn(),"qoder-sdk-auth-"));try{await Wn(s,448);let o=z(s,"payload.json");return await Br(o,JSON.stringify(t),{mode:384}),await Wn(o,384),this.diagnostics?.record(`${this.logPrefix} Auth payload created: type=${t.type}, path=${o}`),o}catch(o){throw await Jn(s,{recursive:!0,force:!0}).catch(()=>{}),o}}};function Ft(n,e){switch(n.type){case"accessToken":return{type:"accessToken",accessToken:oi(n,e)};case"qodercli":return{type:"qodercli"};case"jobToken":return{type:"jobToken",jobTokenProvider:"host"};case"serviceAccount":{let t=n.serviceAccountKey!==void 0,s=typeof n.fetchServiceAccountToken=="function";if(t===s)throw new TypeError("Service Account auth requires exactly one credential source: serviceAccountKey or fetchServiceAccountToken");return s?{type:"serviceAccount",serviceAccountTokenProvider:"host"}:{type:"serviceAccount",serviceAccountKey:si(n,e)}}}}function si(n,e){if(!n.serviceAccountKey)throw new Error("Service Account key authentication requires serviceAccountKey");if(typeof n.serviceAccountKey=="string")return n.serviceAccountKey;let t=n.serviceAccountKey.envVar,s=e&&Object.hasOwn(e,t)?e[t]:process.env[t];if(!s)throw new st(t);return s}function oi(n,e){if(typeof n.accessToken=="string")return n.accessToken;let t=n.accessToken.envVar,s=e&&Object.hasOwn(e,t)?e[t]:process.env[t];if(!s)throw new nt(t);return s}function ri(n,e){if(process.platform!=="win32"){delete n[e];return}let t=e.toLowerCase();for(let s of Object.keys(n))s.toLowerCase()===t&&delete n[s]}function rt(n,e){let t={...n};for(let[s,o]of Object.entries(e))o!==void 0&&(t[s]=o);return t}var ii=new Set(["--mcp-config","--proxy","--settings"]);function it(n){let e=[];for(let t=0;t<n.length;t+=1){let s=n[t];e.push(s),ii.has(s)&&t+1<n.length&&(e.push("[redacted]"),t+=1)}return e.join(" ")}import{Transform as ai}from"node:stream";var Q=16*1024*1024,Ne=class extends Error{constructor(t,s){super(`${t} exceeded the ${s}-byte frame limit`);this.direction=t;this.limit=s;this.name="FrameTooLargeError"}code="DAEMON_FRAME_TOO_LARGE"},ee=class extends ai{constructor(t=Q,s="JSONL input"){super();this.maxLineBytes=t;this.direction=s;if(!Number.isSafeInteger(t)||t<=0)throw new Error("maxLineBytes must be a positive safe integer")}bytesSinceNewline=0;_transform(t,s,o){let r=Buffer.isBuffer(t)?t:Buffer.from(t,s),i=0;for(let a=0;a<r.length;a+=1)if(r[a]===10){if(this.bytesSinceNewline+=a-i,this.bytesSinceNewline>this.maxLineBytes){o(new Ne(this.direction,this.maxLineBytes));return}this.bytesSinceNewline=0,i=a+1}if(this.bytesSinceNewline+=r.length-i,this.bytesSinceNewline>this.maxLineBytes){o(new Ne(this.direction,this.maxLineBytes));return}o(void 0,r)}};function ve(n,e=Q,t="JSONL output"){let s=n.endsWith(`
|
|
2
2
|
`)?n.slice(0,-1):n;if(Buffer.byteLength(s,"utf8")>e)throw new Ne(t,e)}var rs=8192,D=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}},ke=class n{static default=new n;process=null;customHandle=null;options;ready=!1;closed=!1;shutdownStarted=!1;initializePromise=null;authExpiredFired=!1;pendingInput=[];diagnostics;processExitError;processStopped=!1;closeTimer;killTimer;stderrTail="";launchOptionsBuilder;constructor(e={}){this.options={...e},this.diagnostics=e.diagnostics,this.launchOptionsBuilder=new j(this.options,this.diagnostics,"[ProcessTransport]")}create(e){return new n(rt(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.cleanupLaunchArtifacts();return}let s=e.env,{command:o,commandArgs:r}=this.resolveExecutable(t);if(this.diagnostics?.record(`[ProcessTransport] Spawning: ${o} ${it(r)}`),this.diagnostics?.record(`[ProcessTransport] CWD: ${this.options.cwd??""}`),this.options.spawnQoderCLIProcess){let i=this.options.spawnQoderCLIProcess({command:o,args:r,cwd:this.options.cwd,env:s,signal:this.options.abortController?.signal??new AbortController().signal});this.customHandle=i,this.observeProcess(i)}else this.process=ui(o,r,{cwd:this.options.cwd,env:s,stdio:["pipe","pipe",this.options.stderr??"pipe"]}),this.observeProcess(this.process),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=!this.closed&&!this.shutdownStarted&&!this.processStopped,this.flushPendingInput()}catch(e){throw this.process||this.customHandle?this.shutdownProcess():await this.cleanupLaunchArtifacts(),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(`
|
|
3
3
|
`)?e:e+`
|
|
4
4
|
`;if(ve(t,Q,"SDK process input"),!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=new ee(Q,"SDK process output");e.pipe(t);let s=ci({input:t,crlfDelay:1/0});try{for await(let o of s){if(this.closed)break;let r=o.trim();if(r)try{yield JSON.parse(r)}catch{}}this.closed||await this.waitForProcessExit()}finally{s.close(),e.unpipe(t),t.destroy()}}close(){this.closed||(this.closed=!0,this.shutdownProcess())}shutdownProcess(){if(this.shutdownStarted)return;this.shutdownStarted=!0,this.ready=!1,this.pendingInput=[];let e=this.process??this.customHandle;if(!e)return;if(this.hasProcessStopped()){this.finishProcess();return}if(this.endInput(),this.hasProcessStopped()){this.finishProcess();return}let t=o=>{try{e.kill(o)}catch(r){this.diagnostics?.record(`[ProcessTransport] Failed to send ${o}:`,r)}},s=this.options.closeGraceMs??Ze;this.closeTimer=setTimeout(()=>{this.closeTimer=void 0,!this.hasProcessStopped()&&(t("SIGTERM"),!this.hasProcessStopped()&&(this.killTimer=setTimeout(()=>{this.killTimer=void 0,this.hasProcessStopped()||t("SIGKILL")},Ln),this.killTimer.unref()))},s),this.closeTimer.unref()}hasProcessStopped(){let e=this.process??this.customHandle;return this.processStopped||e!==null&&e.exitCode!==null||this.process!==null&&this.process.signalCode!==null}finishProcess(){this.processStopped||(this.processStopped=!0,this.ready=!1,clearTimeout(this.closeTimer),clearTimeout(this.killTimer),this.closeTimer=void 0,this.killTimer=void 0,this.cleanupLaunchArtifacts().catch(()=>{}))}observeProcess(e){e.on("error",t=>{this.ready=!1,this.closed||(this.processExitError??=this.createSpawnError(t)),this.diagnostics?.record("[ProcessTransport] Process error:",t),this.hasProcessStopped()?this.finishProcess():this.shutdownProcess()}),e.once("exit",(t,s)=>{if(this.finishProcess(),this.diagnostics?.record(`[ProcessTransport] Process exited: code=${t}, signal=${s}`),!this.closed&&!this.processExitError){t===we&&this.fireAuthExpired();let o=this.createProcessExitError(t,s);o&&(this.processExitError=o)}})}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>rs&&(this.stderrTail=this.stderrTail.slice(-rs))}createSpawnError(e){let t=this.options.pathToQoderCLIExecutable??"qodercli",o=e.code==="ENOENT"?`Qoder CLI executable not found: ${t}`:`Failed to spawn Qoder CLI process: ${e.message}`;return new D(o,{stderr:this.getStderrTail(),cause:e})}createProcessExitError(e,t){if(e!==we){if(e!==0&&e!==null)return new D(`Qoder CLI process exited with code ${e}`,{exitCode:e,signal:t,stderr:this.getStderrTail()});if(t)return new D(`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(this.hasProcessStopped()){let t=this.createProcessExitError(e.exitCode,this.process?.signalCode??null);if(t)throw this.processExitError=t,t;return}await new Promise((t,s)=>{let o=(i,a)=>{if(e.off("error",r),this.closed){t();return}let u=this.processExitError??this.createProcessExitError(i,a);u?(this.processExitError=u,s(u)):t()},r=i=>{if(e.off("exit",o),this.closed){t();return}let a=this.processExitError??this.createSpawnError(i);this.processExitError=a,s(a)};e.once("exit",o),e.once("error",r)})}}resolveExecutable(e){let t=this.options.pathToQoderCLIExecutable??Z();if(X(t)){let s=this.options.executable??"node",o=this.options.executableArgs??[];return{command:s,commandArgs:[...o,t,...e]}}return{command:t,commandArgs:e}}async cleanupLaunchArtifacts(){await this.launchOptionsBuilder.cleanupLaunchArtifacts()}fireAuthExpired(){if(!this.authExpiredFired){this.authExpiredFired=!0;try{this.options.onAuthExpired?.()}catch{}}}};function li(){switch("worker"){case"worker":return"worker";case"process":return"process"}return"process"}var ae=li();function is(n){return typeof n=="object"&&n!==null&&typeof n.create=="function"}function at(n,e){return n.create(e)}import{existsSync as qi}from"fs";import{createInterface as Ni}from"readline";import{Worker as ji}from"worker_threads";import{createHash as di}from"node:crypto";import{existsSync as pi}from"node:fs";import{chmod as mi,lstat as fi,mkdir as je,readFile as as,readdir as gi,readlink as hi,rename as yi,rm as ut,stat as Si,symlink as wi,writeFile as us}from"node:fs/promises";import{tmpdir as vi,userInfo as ki}from"node:os";import{basename as cs,dirname as be,join as G,relative as bi}from"node:path";var _i="QODER_WORKER_RUNTIME_ASSET_ROOT",ls=/(^|[\\/])app\.asar([\\/]|$)/,Ut=".qoder-worker-runtime-ready";function ds(n){return ls.test(n)}function Lt(n){return ds(n)?n.replace(ls,(e,t,s)=>`${t}app.asar.unpacked${s}`):null}async function _e(n,e={}){let t=Lt(n);if(!e.forceMaterialize&&t){let u=be(t);if(pi(t))return e.diagnostics?.record(`[WorkerTransport] Using asar-unpacked worker runtime: ${t}`),Kt(t,u,!1,be(n))}if(!(e.forceMaterialize||ds(n))){let u=be(n);return Kt(n,u,!1)}let o=be(n),r=await Ri(o,n,{cacheDir:e.cacheDir,diagnostics:e.diagnostics}),i=bi(o,n)||cs(n),a=G(r,i);return Kt(a,r,!0,o)}function Kt(n,e,t,s){return{runtimePath:n,runtimeRoot:e,materialized:t,sourceRuntimeRoot:s,env:{[_i]:e}}}async function Ri(n,e,t){let s=await Ci(n,e),o=t.cacheDir??Ti(),r=G(o,s),i=G(r,Ut);if(await ms(i)===s)return r;let a=G(o,`.setup-${s}-${process.pid}-${Date.now()}`);await je(o,{recursive:!0,mode:448}),await ut(a,{recursive:!0,force:!0}),await ut(r,{recursive:!0,force:!0}),t.diagnostics?.record(`[WorkerTransport] Materializing worker runtime: ${n} -> ${r}`);try{return await je(a,{recursive:!0,mode:448}),await ps(n,a),await us(G(a,Ut),s,{mode:384}),await Pi(a,r,s),r}catch(u){throw await ut(a,{recursive:!0,force:!0}).catch(()=>{}),u}}async function Ci(n,e){let t=di("sha256");t.update("qoder-worker-runtime-v1\0");let s=await fs(G(n,"runtime-info.json"));if(s)t.update(s);else{t.update(e);let o=await Si(e).catch(()=>null);o&&t.update(`${o.size}\0${o.mtimeMs}`)}return`runtime-${t.digest("hex").slice(0,24)}`}async function ps(n,e){let t=await gi(n,{withFileTypes:!0});await je(e,{recursive:!0,mode:448});for(let s of t){let o=G(n,s.name),r=G(e,s.name);if(s.isDirectory()){await ps(o,r);continue}if(s.isSymbolicLink()){await je(be(r),{recursive:!0,mode:448}),await wi(await hi(o),r);continue}if(!s.isFile())continue;let i=await Ei(o);await je(be(r),{recursive:!0,mode:448}),await us(r,await as(o),{mode:i}),process.platform!=="win32"&&await mi(r,i)}}async function Ei(n){let e=((await fi(n)).mode||420)&511;if(process.platform==="win32")return e||420;let t=cs(n);return t==="rg"||t==="spawn-helper"||/\.(?:node|dylib|exe)$/.test(t)||/\.so(?:\.\d+)*$/.test(t)?493:e||420}async function Pi(n,e,t){try{await yi(n,e)}catch(s){if(await ms(G(e,Ut))===t){await ut(n,{recursive:!0,force:!0});return}throw s}}async function ms(n){let e=await fs(n);return e?e.toString("utf8"):null}async function fs(n){try{return await as(n)}catch{return null}}function Ti(){let n=Mi(ki().username||process.env.USER||process.env.USERNAME||"user");return G(vi(),`qoder-sdk-worker-runtime-${n}`)}function Mi(n){return n.replace(/[^a-zA-Z0-9._-]/g,"_")||"unknown"}var Ai="QODER_WORKER_CWD";function ct(n,e){return{env:{...e.env,[Ai]:e.cwd,...n.env},workerData:{...e.workerData??{},qoderWorkerRuntime:{cwd:e.cwd,runtimeRoot:n.runtimeRoot,materialized:n.materialized}}}}import{existsSync as Bt}from"node:fs";import{dirname as Ii,join as ue}from"node:path";import{fileURLToPath as Di}from"node:url";var Oi=Di(import.meta.url),$t=Ii(Oi);function te(n){if(n)return n;let e=[];for(let t of xi())e.push(ue(t,"dist","_worker","qoder-worker-runtime.obf.mjs"),ue(t,"dist","_worker","qoder-worker-runtime.mjs"),ue(t,"_worker","qoder-worker-runtime.obf.mjs"),ue(t,"_worker","qoder-worker-runtime.mjs"));for(let t of e)if(Bt(t))return t;return e[0]??ue($t,"..","_worker","qoder-worker-runtime.obf.mjs")}function gs(n){let e=te(n);if(Bt(e))return!0;let t=Lt(e);return t!==null&&Bt(t)}function xi(){let n=[ue($t,".."),ue($t,"..","..")];return[...new Set(n)]}var hs=8192,ce=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}},Re=class n{static default=new n;options;constructor(e={}){this.options={...e}}create(e){return new zt(rt(this.options,e))}},zt=class{worker=null;options;ready=!1;closed=!1;initializePromise=null;authExpiredFired=!1;pendingInput=[];diagnostics;workerExitError;stderrTail="";observedExitCode=null;launchOptionsBuilder;closeTimer=null;closePromise;abortSignal;abortListener;constructor(e={}){this.options={...e},this.diagnostics=e.diagnostics,this.launchOptionsBuilder=new j(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.cleanupLaunchArtifacts();return}let t=te(this.options.pathToQoderWorkerRuntime),s;try{s=await _e(t,{diagnostics:this.diagnostics})}catch(a){throw new ce(`Failed to prepare Qoder worker runtime: ${t}`,{cause:a})}let o=s.runtimePath;if(!qi(o))throw new ce(`Qoder worker runtime not found: ${o}`);if(this.closed){await this.cleanupLaunchArtifacts();return}let r=this.options.cwd??process.cwd(),i=ct(s,{cwd:r,env:e.env,workerData:this.options.workerData});if(this.diagnostics?.record(`[WorkerTransport] Starting: ${o}`),this.diagnostics?.record(`[WorkerTransport] CWD: ${r}`),this.diagnostics?.record(`[WorkerTransport] Args: ${it(e.args)}`),this.worker=new ji(o,{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.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.cleanupLaunchArtifacts().catch(()=>{});return}a===we&&this.fireAuthExpired();let u=this.createWorkerExitError(a);u&&(this.workerExitError=u),this.cleanupLaunchArtifacts().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=!this.closed,this.ready&&this.flushPendingInput()}catch(e){throw this.worker?this.close():await this.cleanupLaunchArtifacts(),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(`
|
|
@@ -131,6 +131,7 @@ export type SDKResultSuccess = {
|
|
|
131
131
|
is_error: boolean;
|
|
132
132
|
num_turns: number;
|
|
133
133
|
result: string;
|
|
134
|
+
/** 最后一条模型回复的结束原因;tool_use 不代表 Agent 本轮仍在运行。 */
|
|
134
135
|
stop_reason: string | null;
|
|
135
136
|
total_cost_usd: number;
|
|
136
137
|
/** Session-cumulative Qoder credits. Added by newer CLI versions. */
|
|
@@ -140,6 +141,11 @@ export type SDKResultSuccess = {
|
|
|
140
141
|
permission_denials: SDKPermissionDenial[];
|
|
141
142
|
error_code?: number | string;
|
|
142
143
|
deferred_tool_use?: unknown;
|
|
144
|
+
/**
|
|
145
|
+
* Agent 本轮的执行终止原因,与模型 stop_reason 独立。
|
|
146
|
+
* hook_stopped 表示 Hook 主动结束本轮,即使 stop_reason 为 tool_use 也已停止。
|
|
147
|
+
* 旧版 CLI 可能不返回此字段;SDK 原样透传,不推断或改写模型原因。
|
|
148
|
+
*/
|
|
143
149
|
terminal_reason?: string | null;
|
|
144
150
|
fast_mode_state?: FastModeState;
|
|
145
151
|
origin?: SDKMessageOrigin;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
3
|
"brand": "global",
|
|
4
|
-
"sdkVersion": "1.0.
|
|
4
|
+
"sdkVersion": "1.0.47",
|
|
5
5
|
"qoderCliVersion": "1.1.59",
|
|
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.59/qodercli-worker-runtime-{target}.tgz",
|
|
12
12
|
"artifactNameTemplate": "qodercli-worker-runtime-{target}.tgz",
|
|
13
|
-
"sdkVersion": "1.0.
|
|
13
|
+
"sdkVersion": "1.0.47",
|
|
14
14
|
"qoderCliVersion": "1.1.59"
|
|
15
15
|
}
|
|
16
16
|
}
|