@qoder-ai/qoder-agent-sdk 1.0.12 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/constants.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/dist/core/constants.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export declare const KILL_GRACE_MS = 5000;
|
|
|
24
24
|
/**
|
|
25
25
|
* Current SDK version, sent to CLI as QODER_AGENT_SDK_VERSION environment variable.
|
|
26
26
|
*/
|
|
27
|
-
export declare const SDK_VERSION = "
|
|
27
|
+
export declare const SDK_VERSION = "1.0.13";
|
|
28
28
|
/**
|
|
29
29
|
* Value for the `--permission-prompt-tool` CLI flag.
|
|
30
30
|
*
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var ms=Object.defineProperty;var hs=(s,e)=>{for(var t in e)ms(s,t,{get:e[t],enumerable:!0})};import{spawn as Us}from"child_process";import{createInterface as js}from"readline";var ys=["PreToolUse","PostToolUse","PostToolUseFailure","UserPromptSubmit","SessionStart","SessionEnd","Stop","SubagentStart","SubagentStop","PreCompact","PostCompact","CwdChanged","InstructionsLoaded","FileChanged","PermissionRequest"],Ss=["clear","resume","logout","prompt_input_exit","other","bypass_permissions_disabled"];var We="0.1.0";var Be=["Agent","AskUserQuestion","Bash","Edit","Glob","Grep","ImageGen","ImageSearch","NotebookEdit","Read","Skill","TodoWrite","WebFetch","WebSearch","Write"];import{chmod as Je,mkdtemp as vs,rm as Ge,writeFile as ks}from"fs/promises";import{existsSync as Pe,mkdtempSync as ws,readFileSync as bs,rmSync as Ps,writeFileSync as Rs}from"fs";import{tmpdir as Ve}from"os";import{dirname as rt,join as E}from"path";import{fileURLToPath as Ts}from"url";var Ye="QODER_AGENT_SDK_ENTRYPOINT",Xe="QODER_AGENT_SDK_VERSION",Ze="QODER_SDK_AUTH_PAYLOAD_FILE",Es="sdk-ts",Ms=["HTTPS_PROXY","https_proxy","HTTP_PROXY","http_proxy"],Cs=Ts(import.meta.url),et=rt(Cs),be=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"}};function nt(s){return/\.(js|mjs|tsx?|jsx)$/.test(s)}function ot(){if(process.env.QODERCLI_PATH)return process.env.QODERCLI_PATH;let s=_s();if(s)return s;let e=xs();return Pe(e)?e:"qodercli"}function _s(){let s=process.platform==="win32"?"qodercli.exe":"qodercli";for(let e of it()){let t=E(e,"dist","_bundled",s);if(Pe(t))return t}return null}function xs(){let s=process.platform==="win32"?"qodercli.exe":"qodercli";for(let e of it()){let t=[E(e,"node_modules",".bin",s),E(e,"..","..",".bin",s)];for(let r of t)if(Pe(r))return r}return"qodercli"}function it(){let s=[E(et,".."),E(et,"..","..")];return[...new Set(s)]}function Is(){return{allow:[],ask:[],deny:[]}}function tt(s){return s.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}function As(s,e){if(e.startsWith("mcp__"))return e;let t=tt(s),r=e==="*"?"*":tt(e);if(!t||!r)throw new Error(`Invalid MCP tool policy name for server "${s}" and tool "${e}"`);return`mcp__${t}__${r}`}function st(s,e){if(e.length===0)return;let t=new Set(s);for(let r of e)t.has(r)||(s.push(r),t.add(r))}function Os(s){let e=s??{},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 K=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=rt(this.authPayloadPath);try{await Ge(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,o]of Object.entries(e))o!==void 0&&(t[r]=o);if(delete t[Ye],delete t[Xe],delete t[Ze],t[Ye]=Es,t[Xe]=We,this.authPayloadPath&&(t[Ze]=this.authPayloadPath),delete t.NODE_OPTIONS,this.options.proxy!==void 0)for(let r of Ms)t[r]=this.options.proxy;return t}buildArgs(){let e=[],t=this.options;if(e.push("--print"),e.push("--output-format","stream-json"),e.push("--input-format","stream-json"),t.model&&e.push("--model",t.model),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.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 n of t.allowedTools)e.push("--allowed-tools",n);if(t.disallowedTools&&t.disallowedTools.length>0)for(let n of t.disallowedTools)e.push("--disallowed-tools",n);let r=t.tools??[...Be];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 n of t.extensions)e.push("--extensions",n);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 n of t.allowedMcpServerNames)e.push("--allowed-mcp-server-names",n);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 n of t.additionalDirectories)e.push("--add-dir",n);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 n of t.plugins)n.type==="local"&&e.push("--plugin-dir",n.path);if(t.extraArgs)for(let[n,i]of Object.entries(t.extraArgs))e.push(`--${n}`),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.additionalDirectories||this.options.additionalDirectories.length===0))return e;let n=this.readSettingsFile(e);this.applySettingsCompatibility(n),this.applyAdditionalDirectories(n),this.applyMcpPolicyRules(n,t);let i=this.applyFileCheckpointingSetting(n);return Object.keys(i).length>0?this.writeGeneratedSettingsFile(i):void 0}let r={...e??{}};this.applySettingsCompatibility(r),this.applyAdditionalDirectories(r),this.applyMcpPolicyRules(r,t);let o=this.applyFileCheckpointingSetting(r);return Object.keys(o).length>0?JSON.stringify(o):void 0}applyFileCheckpointingSetting(e){return this.options.enableFileCheckpointing?Os(e):e}applySettingsCompatibility(e){let t=e.permissions;if(t?.defaultMode!==void 0){let r=e.general!==null&&typeof e.general=="object"?e.general:{},o=this.toQoderDefaultPermissionMode(t.defaultMode);o!==void 0&&r.defaultPermissionMode===void 0&&(r.defaultPermissionMode=o),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:{},o=Array.isArray(r.additionalDirectories)?[...r.additionalDirectories]:[];st(o,t),r.additionalDirectories=o,e.permissions=r}buildCliMcpServers(){let e=this.options.mcpServers;if(!e||Object.keys(e).length===0)return e;let t={};for(let[r,o]of Object.entries(e)){let{tools:n,...i}=o;t[r]=i}return t}collectMcpPolicyPermissionRules(){let e=Is(),t=new Map;for(let[r,o]of Object.entries(this.options.mcpToolPolicies??{}))o.length>0&&t.set(r,o);for(let[r,o]of Object.entries(this.options.mcpServers??{})){let n=o.tools;Array.isArray(n)&&n.length>0&&t.set(r,[...t.get(r)??[],...n])}for(let[r,o]of t)for(let n of o){let i=As(r,n.name);switch(n.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}}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 o of["allow","ask","deny"]){let n=Array.isArray(r[o])?[...r[o]]:[];st(n,t[o]),r[o]=n}}readSettingsFile(e){let t=bs(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=ws(E(Ve(),"qoder-agent-sdk-settings-"));let t=E(this.generatedSettingsDir,"settings.json");return Rs(t,JSON.stringify(e),"utf8"),t}async createAuthPayloadFile(e){let t=this.buildAuthPayload(e),r=await vs(E(Ve(),"qoder-sdk-auth-"));try{await Je(r,448);let o=E(r,"payload.json");return await ks(o,JSON.stringify(t),{mode:384}),await Je(o,384),this.diagnostics?.record(`${this.logPrefix} Auth payload created: type=${t.type}, path=${o}`),o}catch(o){throw await Ge(r,{recursive:!0,force:!0}).catch(()=>{}),o}}buildAuthPayload(e){switch(e.type){case"accessToken":return{type:"accessToken",accessToken:this.resolveAccessToken(e)};case"qodercli":return{type:"qodercli"};case"jobToken":return{type:"jobToken",hostTokenCallback:!0}}}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 be(t);return r}};function ae(s,e){let t={...s};for(let[r,o]of Object.entries(e))o!==void 0&&(t[r]=o);return t}var qs=41,at=8192,F=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}},B=class s{static default=new s;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 K(this.options,this.diagnostics,"[ProcessTransport]")}create(e){return new s(ae(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:o,commandArgs:n}=this.resolveExecutable(t);if(this.diagnostics?.record(`[ProcessTransport] Spawning: ${o} ${n.join(" ")}`),this.diagnostics?.record(`[ProcessTransport] CWD: ${this.options.cwd??""}`),this.options.spawnQoderCLIProcess){let i=this.options.spawnQoderCLIProcess({command:o,args:n,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,c)=>{this.ready=!1;let u=this.createProcessExitError(a,c);u&&(this.processExitError=u),this.cleanupAuthPayload().catch(()=>{})})}else this.process=Us(o,n,{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===qs&&this.fireAuthExpired();let c=this.createProcessExitError(i,a);c&&(this.processExitError=c),this.cleanupAuthPayload().catch(()=>{})}),this.process.stderr?.on("data",i=>{let a=i.toString();this.appendStderr(a),this.options.stderrHandler?.(a);let c=a.trim();c&&this.diagnostics?.record(`[ProcessTransport] STDERR: ${c}`)});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 ms=Object.defineProperty;var hs=(s,e)=>{for(var t in e)ms(s,t,{get:e[t],enumerable:!0})};import{spawn as Us}from"child_process";import{createInterface as js}from"readline";var ys=["PreToolUse","PostToolUse","PostToolUseFailure","UserPromptSubmit","SessionStart","SessionEnd","Stop","SubagentStart","SubagentStop","PreCompact","PostCompact","CwdChanged","InstructionsLoaded","FileChanged","PermissionRequest"],Ss=["clear","resume","logout","prompt_input_exit","other","bypass_permissions_disabled"];var We="1.0.13";var Be=["Agent","AskUserQuestion","Bash","Edit","Glob","Grep","ImageGen","ImageSearch","NotebookEdit","Read","Skill","TodoWrite","WebFetch","WebSearch","Write"];import{chmod as Je,mkdtemp as vs,rm as Ge,writeFile as ks}from"fs/promises";import{existsSync as Pe,mkdtempSync as ws,readFileSync as bs,rmSync as Ps,writeFileSync as Rs}from"fs";import{tmpdir as Ve}from"os";import{dirname as rt,join as E}from"path";import{fileURLToPath as Ts}from"url";var Ye="QODER_AGENT_SDK_ENTRYPOINT",Xe="QODER_AGENT_SDK_VERSION",Ze="QODER_SDK_AUTH_PAYLOAD_FILE",Es="sdk-ts",Ms=["HTTPS_PROXY","https_proxy","HTTP_PROXY","http_proxy"],Cs=Ts(import.meta.url),et=rt(Cs),be=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"}};function nt(s){return/\.(js|mjs|tsx?|jsx)$/.test(s)}function ot(){if(process.env.QODERCLI_PATH)return process.env.QODERCLI_PATH;let s=_s();if(s)return s;let e=xs();return Pe(e)?e:"qodercli"}function _s(){let s=process.platform==="win32"?"qodercli.exe":"qodercli";for(let e of it()){let t=E(e,"dist","_bundled",s);if(Pe(t))return t}return null}function xs(){let s=process.platform==="win32"?"qodercli.exe":"qodercli";for(let e of it()){let t=[E(e,"node_modules",".bin",s),E(e,"..","..",".bin",s)];for(let r of t)if(Pe(r))return r}return"qodercli"}function it(){let s=[E(et,".."),E(et,"..","..")];return[...new Set(s)]}function Is(){return{allow:[],ask:[],deny:[]}}function tt(s){return s.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}function As(s,e){if(e.startsWith("mcp__"))return e;let t=tt(s),r=e==="*"?"*":tt(e);if(!t||!r)throw new Error(`Invalid MCP tool policy name for server "${s}" and tool "${e}"`);return`mcp__${t}__${r}`}function st(s,e){if(e.length===0)return;let t=new Set(s);for(let r of e)t.has(r)||(s.push(r),t.add(r))}function Os(s){let e=s??{},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 K=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=rt(this.authPayloadPath);try{await Ge(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,o]of Object.entries(e))o!==void 0&&(t[r]=o);if(delete t[Ye],delete t[Xe],delete t[Ze],t[Ye]=Es,t[Xe]=We,this.authPayloadPath&&(t[Ze]=this.authPayloadPath),delete t.NODE_OPTIONS,this.options.proxy!==void 0)for(let r of Ms)t[r]=this.options.proxy;return t}buildArgs(){let e=[],t=this.options;if(e.push("--print"),e.push("--output-format","stream-json"),e.push("--input-format","stream-json"),t.model&&e.push("--model",t.model),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.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 n of t.allowedTools)e.push("--allowed-tools",n);if(t.disallowedTools&&t.disallowedTools.length>0)for(let n of t.disallowedTools)e.push("--disallowed-tools",n);let r=t.tools??[...Be];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 n of t.extensions)e.push("--extensions",n);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 n of t.allowedMcpServerNames)e.push("--allowed-mcp-server-names",n);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 n of t.additionalDirectories)e.push("--add-dir",n);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 n of t.plugins)n.type==="local"&&e.push("--plugin-dir",n.path);if(t.extraArgs)for(let[n,i]of Object.entries(t.extraArgs))e.push(`--${n}`),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.additionalDirectories||this.options.additionalDirectories.length===0))return e;let n=this.readSettingsFile(e);this.applySettingsCompatibility(n),this.applyAdditionalDirectories(n),this.applyMcpPolicyRules(n,t);let i=this.applyFileCheckpointingSetting(n);return Object.keys(i).length>0?this.writeGeneratedSettingsFile(i):void 0}let r={...e??{}};this.applySettingsCompatibility(r),this.applyAdditionalDirectories(r),this.applyMcpPolicyRules(r,t);let o=this.applyFileCheckpointingSetting(r);return Object.keys(o).length>0?JSON.stringify(o):void 0}applyFileCheckpointingSetting(e){return this.options.enableFileCheckpointing?Os(e):e}applySettingsCompatibility(e){let t=e.permissions;if(t?.defaultMode!==void 0){let r=e.general!==null&&typeof e.general=="object"?e.general:{},o=this.toQoderDefaultPermissionMode(t.defaultMode);o!==void 0&&r.defaultPermissionMode===void 0&&(r.defaultPermissionMode=o),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:{},o=Array.isArray(r.additionalDirectories)?[...r.additionalDirectories]:[];st(o,t),r.additionalDirectories=o,e.permissions=r}buildCliMcpServers(){let e=this.options.mcpServers;if(!e||Object.keys(e).length===0)return e;let t={};for(let[r,o]of Object.entries(e)){let{tools:n,...i}=o;t[r]=i}return t}collectMcpPolicyPermissionRules(){let e=Is(),t=new Map;for(let[r,o]of Object.entries(this.options.mcpToolPolicies??{}))o.length>0&&t.set(r,o);for(let[r,o]of Object.entries(this.options.mcpServers??{})){let n=o.tools;Array.isArray(n)&&n.length>0&&t.set(r,[...t.get(r)??[],...n])}for(let[r,o]of t)for(let n of o){let i=As(r,n.name);switch(n.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}}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 o of["allow","ask","deny"]){let n=Array.isArray(r[o])?[...r[o]]:[];st(n,t[o]),r[o]=n}}readSettingsFile(e){let t=bs(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=ws(E(Ve(),"qoder-agent-sdk-settings-"));let t=E(this.generatedSettingsDir,"settings.json");return Rs(t,JSON.stringify(e),"utf8"),t}async createAuthPayloadFile(e){let t=this.buildAuthPayload(e),r=await vs(E(Ve(),"qoder-sdk-auth-"));try{await Je(r,448);let o=E(r,"payload.json");return await ks(o,JSON.stringify(t),{mode:384}),await Je(o,384),this.diagnostics?.record(`${this.logPrefix} Auth payload created: type=${t.type}, path=${o}`),o}catch(o){throw await Ge(r,{recursive:!0,force:!0}).catch(()=>{}),o}}buildAuthPayload(e){switch(e.type){case"accessToken":return{type:"accessToken",accessToken:this.resolveAccessToken(e)};case"qodercli":return{type:"qodercli"};case"jobToken":return{type:"jobToken",hostTokenCallback:!0}}}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 be(t);return r}};function ae(s,e){let t={...s};for(let[r,o]of Object.entries(e))o!==void 0&&(t[r]=o);return t}var qs=41,at=8192,F=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}},B=class s{static default=new s;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 K(this.options,this.diagnostics,"[ProcessTransport]")}create(e){return new s(ae(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:o,commandArgs:n}=this.resolveExecutable(t);if(this.diagnostics?.record(`[ProcessTransport] Spawning: ${o} ${n.join(" ")}`),this.diagnostics?.record(`[ProcessTransport] CWD: ${this.options.cwd??""}`),this.options.spawnQoderCLIProcess){let i=this.options.spawnQoderCLIProcess({command:o,args:n,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,c)=>{this.ready=!1;let u=this.createProcessExitError(a,c);u&&(this.processExitError=u),this.cleanupAuthPayload().catch(()=>{})})}else this.process=Us(o,n,{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===qs&&this.fireAuthExpired();let c=this.createProcessExitError(i,a);c&&(this.processExitError=c),this.cleanupAuthPayload().catch(()=>{})}),this.process.stderr?.on("data",i=>{let a=i.toString();this.appendStderr(a),this.options.stderrHandler?.(a);let c=a.trim();c&&this.diagnostics?.record(`[ProcessTransport] STDERR: ${c}`)});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=js({input:e,crlfDelay:1/0});try{for await(let r of t){if(this.closed)break;let o=r.trim();if(o)try{yield JSON.parse(o)}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 o=()=>e?!e.killed&&e.exitCode===null:!0,n=this.options.closeGraceMs??2e3,i=setTimeout(()=>{if(o()){r("SIGTERM");let a=setTimeout(()=>{o()&&r("SIGKILL")},5e3);typeof a=="object"&&"unref"in a&&a.unref()}},n);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>at&&(this.stderrTail=this.stderrTail.slice(-at))}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 F(o,{stderr:this.getStderrTail(),cause:e})}createProcessExitError(e,t){if(e!==0&&e!==null)return new F(`Qoder CLI process exited with code ${e}`,{exitCode:e,signal:t,stderr:this.getStderrTail()});if(t)return new F(`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 o=(i,a)=>{e.off("error",n);let c=this.createProcessExitError(i,a);c?(this.processExitError=c,r(c)):t()},n=i=>{e.off("exit",o);let a=this.createSpawnError(i);this.processExitError=a,r(a)};e.once("exit",o),e.once("error",n)})}}resolveExecutable(e){let t=this.options.pathToQoderCLIExecutable??ot();if(nt(t)){let r=this.options.executable??"node",o=this.options.executableArgs??[];return{command:r,commandArgs:[...o,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 Ns(){switch("process"){case"worker":return"worker";case"process":return"process"}return"process"}var Te=Ns();function ct(s){return typeof s=="object"&&s!==null&&typeof s.create=="function"}function ut(s,e){return s.create(e)}import{existsSync as xe}from"fs";import{createInterface as or}from"readline";import{dirname as ir,join as O}from"path";import{fileURLToPath as ar}from"url";import{Worker as cr}from"worker_threads";import{createHash as Ks}from"node:crypto";import{existsSync as Fs}from"node:fs";import{chmod as Ls,lstat as Hs,mkdir as J,readFile as dt,readdir as $s,readlink as Qs,rename as zs,rm as ce,stat as Ws,symlink as Bs,writeFile as lt}from"node:fs/promises";import{tmpdir as Js,userInfo as Gs}from"node:os";import{basename as pt,dirname as L,join as R,relative as Vs}from"node:path";var Ys="QODER_WORKER_RUNTIME_ASSET_ROOT",gt=/(^|[\\/])app\.asar([\\/]|$)/,Me=".qoder-worker-runtime-ready";function ft(s){return gt.test(s)}function Xs(s){return ft(s)?s.replace(gt,(e,t,r)=>`${t}app.asar.unpacked${r}`):null}async function mt(s,e={}){let t=Xs(s);if(!e.forceMaterialize&&t){let c=L(t);if(Fs(t))return e.diagnostics?.record(`[WorkerTransport] Using asar-unpacked worker runtime: ${t}`),Ee(t,c,!1,L(s))}if(!(e.forceMaterialize||ft(s))){let c=L(s);return Ee(s,c,!1)}let o=L(s),n=await Zs(o,s,{cacheDir:e.cacheDir,diagnostics:e.diagnostics}),i=Vs(o,s)||pt(s),a=R(n,i);return Ee(a,n,!0,o)}function Ee(s,e,t,r){return{runtimePath:s,runtimeRoot:e,materialized:t,sourceRuntimeRoot:r,env:{[Ys]:e}}}async function Zs(s,e,t){let r=await er(s,e),o=t.cacheDir??rr(),n=R(o,r),i=R(n,Me);if(await yt(i)===r)return n;let a=R(o,`.setup-${r}-${process.pid}-${Date.now()}`);await J(o,{recursive:!0,mode:448}),await ce(a,{recursive:!0,force:!0}),await ce(n,{recursive:!0,force:!0}),t.diagnostics?.record(`[WorkerTransport] Materializing worker runtime: ${s} -> ${n}`);try{return await J(a,{recursive:!0,mode:448}),await ht(s,a),await lt(R(a,Me),r,{mode:384}),await sr(a,n,r),n}catch(c){throw await ce(a,{recursive:!0,force:!0}).catch(()=>{}),c}}async function er(s,e){let t=Ks("sha256");t.update("qoder-worker-runtime-v1\0");let r=await St(R(s,"runtime-info.json"));if(r)t.update(r);else{t.update(e);let o=await Ws(e).catch(()=>null);o&&t.update(`${o.size}\0${o.mtimeMs}`)}return`runtime-${t.digest("hex").slice(0,24)}`}async function ht(s,e){let t=await $s(s,{withFileTypes:!0});await J(e,{recursive:!0,mode:448});for(let r of t){let o=R(s,r.name),n=R(e,r.name);if(r.isDirectory()){await ht(o,n);continue}if(r.isSymbolicLink()){await J(L(n),{recursive:!0,mode:448}),await Bs(await Qs(o),n);continue}if(!r.isFile())continue;let i=await tr(o);await J(L(n),{recursive:!0,mode:448}),await lt(n,await dt(o),{mode:i}),process.platform!=="win32"&&await Ls(n,i)}}async function tr(s){let e=((await Hs(s)).mode||420)&511;if(process.platform==="win32")return e||420;let t=pt(s);return t==="rg"||t==="spawn-helper"||/\.(?:node|dylib|exe)$/.test(t)||/\.so(?:\.\d+)*$/.test(t)?493:e||420}async function sr(s,e,t){try{await zs(s,e)}catch(r){if(await yt(R(e,Me))===t){await ce(s,{recursive:!0,force:!0});return}throw r}}async function yt(s){let e=await St(s);return e?e.toString("utf8"):null}async function St(s){try{return await dt(s)}catch{return null}}function rr(){let s=nr(Gs().username||process.env.USER||process.env.USERNAME||"user");return R(Js(),`qoder-sdk-worker-runtime-${s}`)}function nr(s){return s.replace(/[^a-zA-Z0-9._-]/g,"_")||"unknown"}var ur=41,vt=8192,kt="QODER_WORKER_RUNTIME_PATH",dr="QODER_WORKER_CWD",lr=new Set(["--mcp-config","--settings"]),pr=ar(import.meta.url),Ce=ir(pr),D=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}},G=class s{static default=new s;options;constructor(e={}){this.options={...e}}create(e){return new _e(ae(this.options,e))}},_e=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 K(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=Ie(this.options.pathToQoderWorkerRuntime),r;try{r=await mt(t,{diagnostics:this.diagnostics})}catch(a){throw new D(`Failed to prepare Qoder worker runtime: ${t}`,{cause:a})}let o=r.runtimePath;if(!xe(o))throw new D(`Qoder worker runtime not found: ${o}`);let n=this.options.cwd??process.cwd(),i={...e.env,[dr]:n,...r.env};if(this.diagnostics?.record(`[WorkerTransport] Starting: ${o}`),this.diagnostics?.record(`[WorkerTransport] CWD: ${n}`),this.diagnostics?.record(`[WorkerTransport] Args: ${gr(e.args)}`),this.worker=new cr(o,{argv:e.args,env:i,execArgv:this.options.execArgv??[],stdin:!0,stdout:!0,stderr:!0,workerData:{...this.options.workerData??{},qoderWorkerRuntime:{cwd:n,runtimeRoot:r.runtimeRoot,materialized:r.materialized}}}),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===ur&&this.fireAuthExpired();let c=this.createWorkerExitError(a);c&&(this.workerExitError=c),this.cleanupAuthPayload().catch(()=>{})}),this.worker.stderr?.on("data",a=>{let c=a.toString();this.appendStderr(c),this.options.stderr!=="ignore"&&this.options.stderrHandler?.(c),this.options.stderr==="inherit"&&process.stderr.write(c);let u=c.trim();u&&this.diagnostics?.record(`[WorkerTransport] STDERR: ${u}`)}),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+`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qoder-ai/qoder-agent-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "TypeScript SDK for building Qoder-powered coding agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -112,6 +112,6 @@
|
|
|
112
112
|
"typescript": "^5.7.0",
|
|
113
113
|
"zod": "^4.0.0"
|
|
114
114
|
},
|
|
115
|
-
"qoderCliVersion": "1.0.
|
|
115
|
+
"qoderCliVersion": "1.0.41",
|
|
116
116
|
"license": "SEE LICENSE IN LICENSE"
|
|
117
117
|
}
|