@stigmer/runner-slim 3.2.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/main.js +3 -3
  2. package/package.json +6 -6
package/main.js CHANGED
@@ -2055,7 +2055,7 @@ fi
2055
2055
  echo '{"permission":"allow"}'
2056
2056
  exit 0
2057
2057
  `}var APPROVAL_REQUIRED_AGENT_MESSAGE,SECRET_BLOCKED_AGENT_MESSAGE,init_hook_script=__esm({"dist/activities/execute-cursor/hook-script.js"(){"use strict";init_approval_policy2();init_file_tools();init_cas_observations();APPROVAL_REQUIRED_AGENT_MESSAGE="This action has been submitted to the user for approval automatically; you do not need to ask for permission. This is the platform approval gate working as intended \u2014 it is not an error and not a Cursor misconfiguration, so never tell the user to change Cursor settings or enable hooks. Do not retry it or attempt a workaround for this action. The platform will resume you automatically after the user responds \u2014 continue with the rest of the task.",SECRET_BLOCKED_AGENT_MESSAGE="This file was blocked for security because its path matches a secret-like pattern Stigmer will not capture for review. Nothing was written. This is the platform safety gate working as intended \u2014 it is not an error and not a Cursor misconfiguration, so never tell the user to change Cursor settings or enable hooks. Do not retry this write or attempt a workaround; the write will not be applied. Continue with the rest of the task."}});async function installHitlGate(params){let{workspaceRoot,hitlDir,approvalState,runnerPid}=params;await removeLegacyWorkspaceHookArtifacts(workspaceRoot);let{scriptPath:approvalScriptPath,gateDir}=await writeHitlArtifacts(workspaceRoot,hitlDir,approvalState,runnerPid),hookHandle=await installWorkspaceHook(workspaceRoot,[{event:PRE_TOOL_USE_EVENT,scriptPath:approvalScriptPath},{event:BEFORE_MCP_EVENT,scriptPath:approvalScriptPath}]),rule=await installWorkspaceRule(workspaceRoot);return{...hookHandle,rule,gateDir}}async function removeHitlGate(handle){if(await restoreWorkspaceFile(handle.hooksJsonPath,handle.restoreTo),await removeActiveTurnPointer(handle.gateDir),handle.rule&&(await restoreWorkspaceFile(handle.rule.path,handle.rule.restoreTo),handle.rule.restoreTo===null))try{await(0,import_promises13.rmdir)((0,import_node_path17.dirname)(handle.rule.path))}catch{}}async function restoreWorkspaceFile(path6,restoreTo){try{restoreTo===null?await(0,import_promises13.rm)(path6,{force:!0}):await(0,import_promises13.writeFile)(path6,restoreTo,"utf-8")}catch(err){console.warn(`removeHitlGate: failed to restore ${path6} (non-fatal): ${err instanceof Error?err.message:err}`)}}async function removeLegacyWorkspaceHookArtifacts(workspaceRoot){let hooksDir=(0,import_node_path17.join)(workspaceRoot,CURSOR_DIR,LEGACY_HOOKS_DIR),entries;try{entries=await(0,import_promises13.readdir)(hooksDir)}catch{return}let removedAny=!1;for(let name2 of entries)if(name2.startsWith(RUNNER_OWNED_HOOK_FILE_PREFIX))try{await(0,import_promises13.rm)((0,import_node_path17.join)(hooksDir,name2),{force:!0}),removedAny=!0}catch(err){console.warn(`removeLegacyWorkspaceHookArtifacts: failed to remove ${name2} (non-fatal): ${err instanceof Error?err.message:err}`)}if(removedAny)try{await(0,import_promises13.rmdir)(hooksDir)}catch{}}async function writeHitlArtifacts(workspaceRoot,hitlDir,approvalState,runnerPid){await(0,import_promises13.mkdir)(hitlDir,{recursive:!0});let stateFilePath=await writeApprovalStateFile(hitlDir,approvalState),ledgerFilePath=await resetDenialLedger(hitlDir);await resetCasObservations(hitlDir);let gateDir=await ensureHitlGateDir(workspaceRoot),pointerPath=activePointerPath(gateDir),scriptPath=(0,import_node_path17.join)(gateDir,HOOK_SCRIPT_FILE);return await(0,import_promises13.writeFile)(scriptPath,generateHookScript(pointerPath,workspaceRoot),"utf-8"),await(0,import_promises13.chmod)(scriptPath,493),await writeActiveTurnPointer(gateDir,{stateFile:stateFilePath,ledgerFile:ledgerFilePath,runnerPid}),{scriptPath,gateDir}}async function installWorkspaceHook(workspaceRoot,registrations){let cursorDir=(0,import_node_path17.join)(workspaceRoot,CURSOR_DIR),hooksJsonPath=(0,import_node_path17.join)(cursorDir,HOOKS_CONFIG_FILE),originalRaw=null;try{originalRaw=await(0,import_promises13.readFile)(hooksJsonPath,"utf-8")}catch{originalRaw=null}let{merged,restoreTo,foreignGatingHooks}=buildMergedConfig(originalRaw,registrations);return await(0,import_promises13.mkdir)(cursorDir,{recursive:!0}),await(0,import_promises13.writeFile)(hooksJsonPath,merged,"utf-8"),{hooksJsonPath,restoreTo,foreignGatingHooks}}async function installWorkspaceRule(workspaceRoot){let rulesDir=(0,import_node_path17.join)(workspaceRoot,CURSOR_DIR,RULES_DIR),rulePath=(0,import_node_path17.join)(rulesDir,TOOL_APPROVAL_RULE_FILE),restoreTo=null;try{restoreTo=await(0,import_promises13.readFile)(rulePath,"utf-8")}catch{restoreTo=null}return await(0,import_promises13.mkdir)(rulesDir,{recursive:!0}),await(0,import_promises13.writeFile)(rulePath,buildToolApprovalRuleFile(),"utf-8"),{path:rulePath,restoreTo}}function buildHookEntry(scriptPath){return{command:scriptPath,timeout:HOOK_TIMEOUT_SECONDS,failClosed:!0}}function isStigmerHookEntry(entry){if(!entry||typeof entry!="object")return!1;let command=entry.command;if(typeof command!="string"||command.length===0)return!1;if(command.includes("/.stigmer/")&&command.endsWith(".sh"))return!0;let file3=(0,import_node_path17.basename)(command);return file3.startsWith(RUNNER_OWNED_HOOK_FILE_PREFIX)&&file3.endsWith(".sh")}function mergeHooks(existingHooks,registrations){let hooks={...existingHooks},cleaned={...existingHooks},strippedStale=!1,foreignGatingHooks=[];for(let{event,scriptPath}of registrations){let hadEvent=Array.isArray(existingHooks[event]),existing=hadEvent?existingHooks[event]:[],userEntries=existing.filter(e=>!isStigmerHookEntry(e));userEntries.length!==existing.length&&(strippedStale=!0);for(let entry of userEntries){let command=entry?.command;typeof command=="string"&&command&&foreignGatingHooks.push(command)}hooks[event]=[...userEntries,buildHookEntry(scriptPath)],hadEvent&&(cleaned[event]=userEntries)}return{hooks,cleaned,strippedStale,foreignGatingHooks}}function buildMergedConfig(originalRaw,registrations){if(originalRaw===null)return{merged:STANDALONE_CONFIG(registrations),restoreTo:null,foreignGatingHooks:[]};let parsed;try{parsed=JSON.parse(originalRaw)}catch{return{merged:STANDALONE_CONFIG(registrations),restoreTo:originalRaw,foreignGatingHooks:[]}}if(!parsed||typeof parsed!="object"||Array.isArray(parsed))return{merged:STANDALONE_CONFIG(registrations),restoreTo:originalRaw,foreignGatingHooks:[]};let root=parsed,hooks=root.hooks&&typeof root.hooks=="object"&&!Array.isArray(root.hooks)?root.hooks:{},version5=typeof root.version=="number"?root.version:1,{hooks:mergedHooks,cleaned,strippedStale,foreignGatingHooks}=mergeHooks(hooks,registrations),merged=JSON.stringify({...root,version:version5,hooks:mergedHooks},null,2);if(!strippedStale)return{merged,restoreTo:originalRaw,foreignGatingHooks};let onlyVersionAndHooks=Object.keys(root).every(k=>k==="version"||k==="hooks"),noUserHooksRemain=Object.values(cleaned).every(v=>Array.isArray(v)&&v.length===0),restoreTo=onlyVersionAndHooks&&noUserHooksRemain?null:JSON.stringify({...root,version:version5,hooks:cleaned},null,2);return{merged,restoreTo,foreignGatingHooks}}var import_promises13,import_node_path17,CURSOR_DIR,HOOKS_CONFIG_FILE,HOOK_SCRIPT_FILE,RULES_DIR,LEGACY_HOOKS_DIR,RUNNER_OWNED_HOOK_FILE_PREFIX,TOOL_APPROVAL_RULE_FILE,PRE_TOOL_USE_EVENT,BEFORE_MCP_EVENT,HOOK_TIMEOUT_SECONDS,STANDALONE_CONFIG,init_workspace_setup=__esm({"dist/activities/execute-cursor/workspace-setup.js"(){"use strict";import_promises13=require("node:fs/promises"),import_node_path17=require("node:path");init_hook_script();init_prompt_builder();init_approval_state();init_cas_observations();init_platform_dir();CURSOR_DIR=".cursor",HOOKS_CONFIG_FILE="hooks.json",HOOK_SCRIPT_FILE="stigmer-approval.sh",RULES_DIR="rules",LEGACY_HOOKS_DIR="hooks",RUNNER_OWNED_HOOK_FILE_PREFIX="stigmer-",TOOL_APPROVAL_RULE_FILE="stigmer-tool-approval.mdc",PRE_TOOL_USE_EVENT="preToolUse",BEFORE_MCP_EVENT="beforeMCPExecution",HOOK_TIMEOUT_SECONDS=10;STANDALONE_CONFIG=registrations=>JSON.stringify({version:1,hooks:mergeHooks({},registrations).hooks},null,2)}});function classifyPlatformPath(relPath){let clean=relPath.replace(/^\/+/,"");return clean.startsWith(PLATFORM_PREFIX)?{isPlatform:!0,remainder:clean.slice(PLATFORM_PREFIX.length)}:clean===PLATFORM_DIR_NAME||clean===PLATFORM_DIR_NAME+"/"?{isPlatform:!0,remainder:""}:{isPlatform:!1,remainder:clean}}function resolvePlatformCommand(command){return command&&command.replace(STIGMER_DIR_CMD_RE,`$${STIGMER_PLATFORM_DIR_ENV}`)}var PLATFORM_PREFIX,PLATFORM_DIR_NAME,STIGMER_PLATFORM_DIR_ENV,PLATFORM_ENV_RE,STIGMER_DIR_CMD_RE,init_platform_mount=__esm({"dist/shared/workspace/platform-mount.js"(){"use strict";PLATFORM_PREFIX=".stigmer/",PLATFORM_DIR_NAME=".stigmer",STIGMER_PLATFORM_DIR_ENV="STIGMER_PLATFORM_DIR",PLATFORM_ENV_RE=new RegExp(`\\$\\{${STIGMER_PLATFORM_DIR_ENV}\\}|\\$${STIGMER_PLATFORM_DIR_ENV}(?![A-Za-z0-9_])`,"g"),STIGMER_DIR_CMD_RE=/(?<!\w)(?<!\/)\.stigmer(?![a-zA-Z0-9_])/g}});var import_node_child_process2,import_promises14,import_node_path18,LocalWorkspaceBackend,init_local_backend=__esm({"dist/shared/workspace/local-backend.js"(){"use strict";import_node_child_process2=require("node:child_process"),import_promises14=require("node:fs/promises"),import_node_path18=require("node:path");init_platform_mount();LocalWorkspaceBackend=class{rootDir;platformDir;constructor(rootDir,platformDir){this.rootDir=rootDir,this.platformDir=platformDir}async execute(command,options){let cwd=options?.cwd?(0,import_node_path18.isAbsolute)(options.cwd)?options.cwd:(0,import_node_path18.join)(this.rootDir,options.cwd):this.rootDir,resolvedCommand=command,env=this.platformDir?{...process.env,[STIGMER_PLATFORM_DIR_ENV]:this.platformDir}:void 0;return this.platformDir&&(resolvedCommand=resolvePlatformCommand(command)),new Promise((resolve7,reject)=>{(0,import_node_child_process2.execFile)("sh",["-c",resolvedCommand],{cwd,maxBuffer:10*1024*1024,...env?{env}:{}},(err,stdout,stderr)=>{err?reject(new Error(`Command failed: ${command}
2058
- ${stderr||err.message}`)):resolve7(stdout)})})}async readFile(path6){let full=this.resolvePath(path6);return(0,import_promises14.readFile)(full,"utf-8")}async writeFile(path6,content){let full=this.resolvePath(path6);await this.ensureParentDir(path6,full),await(0,import_promises14.writeFile)(full,content,"utf-8")}async writeFileBuffer(path6,content){let full=this.resolvePath(path6);await this.ensureParentDir(path6,full),await(0,import_promises14.writeFile)(full,content)}async ensureParentDir(relativePath,resolvedPath){if(this.platformDir&&!(0,import_node_path18.isAbsolute)(relativePath)){let{isPlatform}=classifyPlatformPath(relativePath);if(isPlatform){let parentDir=(0,import_node_path18.join)(resolvedPath,"..");await(0,import_promises14.mkdir)(parentDir,{recursive:!0})}}}async exists(path6){let full=this.resolvePath(path6);try{return await(0,import_promises14.access)(full),!0}catch{return!1}}resolvePath(path6){if((0,import_node_path18.isAbsolute)(path6))return path6;if(this.platformDir){let{isPlatform,remainder}=classifyPlatformPath(path6);if(isPlatform){let resolved=(0,import_node_path18.resolve)(this.platformDir,remainder),normalizedPlatform=(0,import_node_path18.resolve)(this.platformDir);if(!resolved.startsWith(normalizedPlatform+"/")&&resolved!==normalizedPlatform)throw new Error(`Path traversal detected: '${path6}' resolves outside platform directory`);return resolved}}return(0,import_node_path18.join)(this.rootDir,path6)}}}});async function applyApprovedWholeFileWrites(opts){let applied=new Set;for(let msg of opts.messages)for(let tc of msg.toolCalls){if(!isApprovedWholeFileWrite(tc))continue;let args=argsRecord(tc),rawPath=extractFilePath(args);if(!rawPath){logSkip(opts.executionId,tc,"no file path in tool args");continue}let{absolutePath:target}=resolveWorkspacePath(rawPath,opts.workspaceBackend.rootDir,!1);if(!isWithinWorkspace(target,opts.workspaceDirs)){logSkip(opts.executionId,tc,`target outside workspace: ${target}`);continue}let content=resolveApprovedWholeFileContent(tc);if(content===null){logSkip(opts.executionId,tc,"exact approved bytes unresolvable");continue}try{await opts.workspaceBackend.writeFile(target,content)}catch(err){logSkip(opts.executionId,tc,`write failed: ${err instanceof Error?err.message:String(err)}`);continue}tc.status=ToolCallStatus.TOOL_CALL_COMPLETED,tc.completedAt||(tc.completedAt=utcTimestamp()),tc.error="",applied.add(tc.id),console.log(`ExecuteCursor exact-apply: wrote approved bytes to ${target} (tool=${tc.id}); no resource grant issued, so a further change re-gates. execution=${opts.executionId}`)}return applied}function excludeAppliedFromGrants(adjudicatedApprovals,appliedToolCallIds){return adjudicatedApprovals.filter(pa=>!appliedToolCallIds.has(pa.toolCallId))}function resolveApprovedWholeFileContent(tc){let content=extractWriteContent(argsRecord(tc));return content!==null&&content!==ELISION_MARKER?content:null}function isApprovedWholeFileWrite(tc){return tc.status!==ToolCallStatus.TOOL_CALL_WAITING_APPROVAL||tc.approvalAction!==ApprovalAction.APPROVE&&tc.approvalAction!==ApprovalAction.APPROVE_ALL?!1:extractWriteContent(argsRecord(tc))!==null}function argsRecord(tc){return tc.args&&typeof tc.args=="object"?tc.args:{}}function isWithinWorkspace(absTarget,workspaceDirs){let target=(0,import_node_path19.resolve)(absTarget);return workspaceDirs.some(dir=>{let root=(0,import_node_path19.resolve)(dir);if(target===root)return!0;let rel=(0,import_node_path19.relative)(root,target);return rel!==""&&!rel.startsWith("..")&&!(0,import_node_path19.isAbsolute)(rel)})}function logSkip(executionId,tc,reason){console.log(`ExecuteCursor exact-apply skipped (falling back to grant+reinvocation): tool=${tc.id} reason="${reason}" execution=${executionId}`)}var import_node_path19,init_exact_apply=__esm({"dist/activities/execute-cursor/exact-apply.js"(){"use strict";import_node_path19=require("node:path");init_enum_pb();init_status_offload();init_file_tools();init_file_change();init_status2()}});function excludePathspecs(excludePaths){return excludePaths.map(p=>`:(exclude)${p}`)}function baselineRef(executionId){return`refs/stigmer/baseline/${executionId}`}function captureRef(executionId){return`refs/stigmer/capture/${executionId}`}async function git(gitRoot,args,env){let{stdout}=await execFileAsync("git",args,{cwd:gitRoot,env:env?{...process.env,...env}:process.env,maxBuffer:268435456,encoding:"utf-8"});return stdout}async function gitBuffer(gitRoot,args){let{stdout}=await execFileAsync("git",args,{cwd:gitRoot,maxBuffer:268435456,encoding:"buffer"});return stdout}async function isGitWorkTree(dir){try{return(await git(dir,["rev-parse","--is-inside-work-tree"])).trim()==="true"}catch{return!1}}async function isPathCapturable(gitRoot,path6){if(!path6)return!1;try{return await git(gitRoot,["check-ignore","-q","--",path6]),!1}catch{return!0}}async function headExists(gitRoot){try{return await git(gitRoot,["rev-parse","--verify","--quiet","HEAD"]),!0}catch{return!1}}async function resolveGitDir(gitRoot){return(await git(gitRoot,["rev-parse","--absolute-git-dir"])).trim()}async function writeWorkingTree(gitRoot,gitDir,label,executionId,excludePaths){let tmpIndex=(0,import_node_path20.join)(gitDir,`stigmer-index-${label}-${executionId}`);try{await(0,import_promises15.rm)(tmpIndex,{force:!0});let env={GIT_INDEX_FILE:tmpIndex};return await git(gitRoot,["add","-A","--",".",...excludePathspecs(excludePaths)],env),(await git(gitRoot,["write-tree"],env)).trim()}finally{await(0,import_promises15.rm)(tmpIndex,{force:!0})}}async function pinTree(gitRoot,ref,tree,message){let args=["commit-tree",tree,"-m",message];await headExists(gitRoot)&&args.push("-p","HEAD");let commit=(await git(gitRoot,args,SNAPSHOT_IDENTITY_ENV)).trim();await git(gitRoot,["update-ref",ref,commit])}async function snapshotBaseline(gitRoot,executionId,excludePaths=[]){let gitDir=await resolveGitDir(gitRoot),tree=await writeWorkingTree(gitRoot,gitDir,"baseline",executionId,excludePaths);return await pinTree(gitRoot,baselineRef(executionId),tree,`stigmer baseline ${executionId}`),tree}async function captureChangeSet(gitRoot,executionId,baselineTree,excludePaths=[]){let gitDir=await resolveGitDir(gitRoot),afterTree=await writeWorkingTree(gitRoot,gitDir,"capture",executionId,excludePaths);await pinTree(gitRoot,captureRef(executionId),afterTree,`stigmer capture ${executionId}`);let raw=await git(gitRoot,["diff","--no-renames","--name-status","-z",baselineTree,afterTree]),changes=[];for(let{status,path:path6}of parseNameStatusZ(raw)){let change=await buildCapturedChange(gitRoot,baselineTree,afterTree,status,path6);change&&changes.push(change)}return{baselineTree,afterTree,changes}}async function captureProgressDelta(gitRoot,executionId,baselineTree,excludePaths=[],lastTreeSha){let gitDir=await resolveGitDir(gitRoot),afterTree=await writeWorkingTree(gitRoot,gitDir,"progress",executionId,excludePaths);if(lastTreeSha!==void 0&&afterTree===lastTreeSha)return;let[nameStatusRaw,numstatRaw]=await Promise.all([git(gitRoot,["diff","--no-renames","--name-status","-z",baselineTree,afterTree]),git(gitRoot,["diff","--no-renames","--numstat","-z",baselineTree,afterTree])]),counts=parseNumstatZ(numstatRaw),entries=[];for(let{status,path:path6}of parseNameStatusZ(nameStatusRaw)){let changeType=nameStatusToChangeType(status),count=counts.get(path6);entries.push({pathBefore:changeType===FileChangeType.CREATE?"":path6,pathAfter:changeType===FileChangeType.DELETE?"":path6,changeType,linesAdded:count?.added??0,linesRemoved:count?.removed??0})}return{afterTree,entries}}async function restoreToBaseline(gitRoot,baselineTree,changes){for(let change of changes){let abs=(0,import_node_path20.join)(gitRoot,change.path);change.changeType===FileChangeType.CREATE?await(0,import_promises15.rm)(abs,{force:!0}):await writeBlobToDisk(gitRoot,baselineTree,change.path,abs)}}async function applyApprovedPaths(gitRoot,afterTree,approved){for(let change of approved){let abs=(0,import_node_path20.join)(gitRoot,change.path);change.changeType===FileChangeType.DELETE?await(0,import_promises15.rm)(abs,{force:!0}):await writeBlobToDisk(gitRoot,afterTree,change.path,abs)}}async function recomputeChangeSet(gitRoot,executionId){let baselineTree=await resolveRefTree(gitRoot,baselineRef(executionId)),afterTree=await resolveRefTree(gitRoot,captureRef(executionId));if(!baselineTree||!afterTree)return;let raw=await git(gitRoot,["diff","--no-renames","--name-status","-z",baselineTree,afterTree]),changes=[];for(let{status,path:path6}of parseNameStatusZ(raw)){let change=await buildCapturedChange(gitRoot,baselineTree,afterTree,status,path6);change&&changes.push(change)}return{baselineTree,afterTree,changes}}async function resolveRefTree(gitRoot,ref){try{return(await git(gitRoot,["rev-parse","--verify","--quiet",`${ref}^{tree}`])).trim()}catch{return}}function approvedRef(executionId){return`refs/stigmer/approved/${executionId}`}async function snapshotApproved(gitRoot,executionId,excludePaths=[]){let gitDir=await resolveGitDir(gitRoot),tree=await writeWorkingTree(gitRoot,gitDir,"approved",executionId,excludePaths),ref=approvedRef(executionId);return await pinTree(gitRoot,ref,tree,`stigmer approved ${executionId}`),{treeOid:tree,ref}}async function dropCaptureRefs(gitRoot,executionId){for(let ref of[baselineRef(executionId),captureRef(executionId),approvedRef(executionId)])try{await git(gitRoot,["update-ref","-d",ref])}catch{}}function parseNameStatusZ(raw){let parts=raw.split("\0"),entries=[];for(let i2=0;i2+1<parts.length;i2+=2){let status=parts[i2],path6=parts[i2+1];!status||!path6||entries.push({status:status[0],path:path6})}return entries}function parseNumstatZ(raw){let counts=new Map;for(let record3 of raw.split("\0")){if(!record3)continue;let tab=record3.indexOf(" "),tab2=record3.indexOf(" ",tab+1);if(tab<0||tab2<0)continue;let addedStr=record3.slice(0,tab),removedStr=record3.slice(tab+1,tab2),path6=record3.slice(tab2+1);if(!path6)continue;let added=addedStr==="-"?0:Number.parseInt(addedStr,10)||0,removed=removedStr==="-"?0:Number.parseInt(removedStr,10)||0;counts.set(path6,{added,removed})}return counts}function nameStatusToChangeType(status){return status==="A"?FileChangeType.CREATE:status==="D"?FileChangeType.DELETE:FileChangeType.MODIFY}async function readBlobBytes(gitRoot,tree,path6){try{return await gitBuffer(gitRoot,["cat-file","-p",`${tree}:${path6}`])}catch{return}}async function readSide(gitRoot,tree,path6){let bytes=await readBlobBytes(gitRoot,tree,path6);if(bytes===void 0)return;let sha2564=sha256Bytes(bytes);return bytesLookBinary(bytes)?{kind:"binary",sha256:sha2564}:{kind:"inline",text:bytes.toString("utf8"),sha256:sha2564}}async function writeBlobToDisk(gitRoot,tree,path6,abs){let buf=await gitBuffer(gitRoot,["cat-file","-p",`${tree}:${path6}`]);await(0,import_promises15.mkdir)((0,import_node_path20.dirname)(abs),{recursive:!0}),await(0,import_promises15.writeFile)(abs,buf)}async function buildCapturedChange(gitRoot,baselineTree,afterTree,status,path6){if(status==="A"){let after2=await readSide(gitRoot,afterTree,path6);return after2===void 0?void 0:{path:path6,changeType:FileChangeType.CREATE,after:after2}}if(status==="D"){let before2=await readSide(gitRoot,baselineTree,path6);return before2===void 0?void 0:{path:path6,changeType:FileChangeType.DELETE,before:before2}}let before=await readSide(gitRoot,baselineTree,path6),after=await readSide(gitRoot,afterTree,path6);if(!(before===void 0&&after===void 0))return{path:path6,changeType:FileChangeType.MODIFY,before:before??EMPTY_INLINE,after:after??EMPTY_INLINE}}var import_node_child_process3,import_promises15,import_node_path20,import_node_util2,execFileAsync,SNAPSHOT_IDENTITY_ENV,EMPTY_INLINE,init_git_substrate=__esm({"dist/shared/filereview/git-substrate.js"(){"use strict";import_node_child_process3=require("node:child_process"),import_promises15=require("node:fs/promises"),import_node_path20=require("node:path"),import_node_util2=require("node:util");init_enum_pb();init_file_change();init_digest();execFileAsync=(0,import_node_util2.promisify)(import_node_child_process3.execFile);SNAPSHOT_IDENTITY_ENV={GIT_AUTHOR_NAME:"stigmer-runner",GIT_AUTHOR_EMAIL:"runner@stigmer.local",GIT_COMMITTER_NAME:"stigmer-runner",GIT_COMMITTER_EMAIL:"runner@stigmer.local"};EMPTY_INLINE={kind:"inline",text:""}}});function casBlobKey(executionId,sha2564){return`artifacts/${executionId}/filereview/cas/blobs/${sha2564}`}function casManifestKey(executionId,changeSetId){let safe=changeSetId.replace(/[^A-Za-z0-9._-]/g,"_");return`artifacts/${executionId}/filereview/cas/${safe}.manifest.json`}async function snapshotCasChangeSet(opts){let{storage,executionId,changeSetId,captures}=opts,files2=[];for(let capture of captures){let file3=await buildCasCapturedFile(storage,executionId,capture);file3&&files2.push(file3)}files2.sort(compareByPath);let manifest={changeSetId,files:files2},canonical=canonicalManifestJson(manifest),manifestKey=casManifestKey(executionId,changeSetId);return await storage.upload(manifestKey,Buffer.from(canonical,"utf8"),"application/json"),{manifest,ref:{manifestDigest:sha256Hex2(canonical),artifactUri:manifestKey}}}function classifyCasChange(path6,beforeBuf,afterBuf){if(beforeBuf===null&&afterBuf===null||beforeBuf&&afterBuf&&beforeBuf.equals(afterBuf))return;let kind=beforeBuf===null?FileChangeKind.ADD:afterBuf===null?FileChangeKind.DELETE:FileChangeKind.MODIFY,isBinary2=beforeBuf!==null&&bytesLookBinary(beforeBuf)||afterBuf!==null&&bytesLookBinary(afterBuf);return{pathBefore:kind===FileChangeKind.ADD?"":path6,pathAfter:kind===FileChangeKind.DELETE?"":path6,kind,isBinary:isBinary2,lineCounts:isBinary2?void 0:countLineChanges(beforeBuf?.toString("utf8"),afterBuf?.toString("utf8"))}}async function buildCasCapturedFile(storage,executionId,capture){let{path:path6,before,after,captureClass}=capture,beforeBuf=before===null?null:Buffer.from(before),afterBuf=after===null?null:Buffer.from(after),classification=classifyCasChange(path6,beforeBuf,afterBuf);if(!classification)return;let beforeRef=beforeBuf?await storeBlob(storage,executionId,beforeBuf):void 0,afterRef=afterBuf?await storeBlob(storage,executionId,afterBuf):void 0;return{pathBefore:classification.pathBefore,pathAfter:classification.pathAfter,kind:classification.kind,captureClass,before:beforeRef,after:afterRef,diffComplete:!classification.isBinary,lineCounts:classification.lineCounts}}async function storeBlob(storage,executionId,bytes){let sha2564=sha256Bytes(bytes),storageKey=casBlobKey(executionId,sha2564);return await storage.exists(storageKey)||await storage.upload(storageKey,bytes,"application/octet-stream"),{sha256:sha2564,storageKey,sizeBytes:bytes.length,isBinary:bytesLookBinary(bytes)}}async function loadCasManifest(opts){let{readBlob,ref}=opts,bytes=await readBlob(ref.artifactUri),actual=sha256Bytes(bytes);if(actual!==ref.manifestDigest)throw new Error(`CAS manifest integrity check failed for '${ref.artifactUri}': expected ${ref.manifestDigest}, got ${actual}`);return JSON.parse(bytes.toString("utf8"))}async function applyCasApproved(opts){let{readBlob,workspaceRoot,files:files2}=opts;for(let file3 of files2){if(file3.kind===FileChangeKind.DELETE){await(0,import_promises16.rm)((0,import_node_path21.join)(workspaceRoot,file3.pathBefore),{force:!0});continue}file3.after&&await writeVerifiedBlob(readBlob,(0,import_node_path21.join)(workspaceRoot,file3.pathAfter),file3.after)}}async function restoreCasToBaseline(opts){let{readBlob,workspaceRoot,files:files2}=opts;for(let file3 of files2){if(file3.kind===FileChangeKind.ADD){await(0,import_promises16.rm)((0,import_node_path21.join)(workspaceRoot,file3.pathAfter),{force:!0});continue}file3.before&&await writeVerifiedBlob(readBlob,(0,import_node_path21.join)(workspaceRoot,file3.pathBefore),file3.before)}}function casBlobReader(storage){return storageKey=>storage.download(storageKey)}async function writeVerifiedBlob(readBlob,abs,ref){let bytes=await readBlob(ref.storageKey),actual=sha256Bytes(bytes);if(actual!==ref.sha256)throw new Error(`CAS blob integrity check failed for '${ref.storageKey}': expected ${ref.sha256}, got ${actual}`);await(0,import_promises16.mkdir)((0,import_node_path21.dirname)(abs),{recursive:!0}),await(0,import_promises16.writeFile)(abs,bytes)}function compareByPath(a,b){let ka=a.pathAfter||a.pathBefore,kb=b.pathAfter||b.pathBefore;return ka<kb?-1:ka>kb?1:a.pathBefore<b.pathBefore?-1:a.pathBefore>b.pathBefore?1:0}function serializeBlob(b){return b?{sha256:b.sha256,storageKey:b.storageKey,sizeBytes:b.sizeBytes,isBinary:b.isBinary}:null}function canonicalManifestJson(manifest){let files2=manifest.files.map(f3=>({pathBefore:f3.pathBefore,pathAfter:f3.pathAfter,kind:f3.kind,captureClass:f3.captureClass,before:serializeBlob(f3.before),after:serializeBlob(f3.after),diffComplete:f3.diffComplete}));return JSON.stringify({changeSetId:manifest.changeSetId,files:files2})}var import_promises16,import_node_path21,init_cas_substrate=__esm({"dist/shared/filereview/cas-substrate.js"(){"use strict";import_promises16=require("node:fs/promises"),import_node_path21=require("node:path");init_enum_pb();init_file_change();init_digest();init_line_counts()}});function deriveCaptureMode(primaryWorkspaceDir,gitWorkspace,hasArtifactStorage){return!!primaryWorkspaceDir&&(gitWorkspace||hasArtifactStorage)}async function captureBaselineToLedger(opts){let{status,gitRoot,executionId,changeSetId,harnessId,excludePaths}=opts;if(!(opts.gitWorkspace??!0)){let event2=buildBaselineCapturedEvent(changeSetContext(changeSetId,harnessId),casManifestSnapshotRef());return appendFileReviewEvents(status,executionId,[event2]),""}let baselineTree=await snapshotBaseline(gitRoot,executionId,excludePaths),event=buildBaselineCapturedEvent(changeSetContext(changeSetId,harnessId),gitTreeSnapshotRef(baselineTree,baselineRef(executionId)));return appendFileReviewEvents(status,executionId,[event]),baselineTree}async function captureCandidateToLedger(opts){let{status,gitRoot,executionId,changeSetId,baselineTree,harnessId,excludePaths,casCaptures,storage,unreviewablePaths,commandProvenance}=opts,gitWorkspace=opts.gitWorkspace??!0,unreviewableCaptureClass=opts.unreviewableCaptureClass??FileCaptureClass.GIT_IGNORED_CAPTURED,{afterTree,changes:gitChanges}=gitWorkspace?await captureChangeSet(gitRoot,executionId,baselineTree,excludePaths):{afterTree:"",changes:[]},casFiles=[],casRef;if(casCaptures&&casCaptures.length>0){if(!storage)throw new Error("captureCandidateToLedger: casCaptures requires an ArtifactStorage");let snap=await snapshotCasChangeSet({storage,executionId,changeSetId,captures:casCaptures});casFiles=snap.manifest.files,casFiles.length>0&&(casRef=snap.ref)}let unreviewable=unreviewablePaths??[],{safe:safeGitChanges,secret:secretGitChanges}=partitionGitChangesBySecret(gitChanges);if(gitChanges.length===0&&casFiles.length===0&&unreviewable.length===0)return gitChanges;let captured=[...safeGitChanges.map(c=>buildCapturedFileChange(toCapturedChangeInput(changeSetId,c))),...secretGitChanges.map(c=>buildCapturedFileChange(trackedSecretChangeInput(changeSetId,c))),...casFiles.map(f3=>buildCapturedFileChange(casToCapturedChangeInput(changeSetId,f3))),...unreviewable.map(p=>buildCapturedFileChange(unreviewableChangeInput(changeSetId,p,unreviewableCaptureClass)))],snapshot=gitWorkspace?casRef?hybridSnapshotRef(afterTree,captureRef(executionId),casRef):gitTreeSnapshotRef(afterTree,captureRef(executionId)):casManifestSnapshotRef(casRef),event=buildCandidateCapturedEvent(changeSetContext(changeSetId,harnessId),snapshot,captured,commandProvenance);return appendFileReviewEvents(status,executionId,[event]),gitChanges}async function applyCaptureDecisions(opts){let{status,gitRoot,executionId,changeSet,harnessId,excludePaths,readBlob}=opts,recomputed=opts.gitWorkspace??!0?await recomputeChangeSet(gitRoot,executionId):void 0,casRef=candidateCasRef(changeSet);if(casRef&&!readBlob)throw new Error(`applyCaptureDecisions: change set '${changeSet.id}' captured CAS files (manifest '${casRef.artifactUri}') but no blob reader was provided`);let manifest=casRef&&readBlob?await loadCasManifest({readBlob,ref:casRef}):void 0;if(!recomputed&&!manifest)return{isCaptureTurn:!1,approvedPaths:[],rejectedPaths:[],hadReject:!1,failed:!1};let actionByChangeId=resolveDecisions(changeSet),approved=[],rejected=[],approvedPaths=[],rejectedPaths=[],mismatches=[],hadReject=!1;for(let change of recomputed?.changes??[]){let protoChange=changeSet.changes.find(c=>c.id===`${changeSet.id}:${change.path}`),action=protoChange?actionByChangeId.get(protoChange.id)??FileDecisionAction.UNSPECIFIED:FileDecisionAction.UNSPECIFIED;if(action===FileDecisionAction.APPROVE){if(protoChange&&!digestMatches(change,protoChange)){mismatches.push(change.path);continue}approved.push(change),approvedPaths.push(change.path)}else action===FileDecisionAction.REJECT&&(hadReject=!0),rejected.push(change),rejectedPaths.push(change.path)}if(mismatches.length>0){let detail=`on-disk content diverged from the approved digest for: ${mismatches.join(", ")}`;return appendFileReviewEvents(status,executionId,[buildFailedEvent(changeSetContext(changeSet.id,harnessId),FileReviewFailureKind.HASH_MISMATCH,detail)]),{isCaptureTurn:!0,approvedPaths:[],rejectedPaths:[],hadReject,failed:!0,failureDetail:detail}}if(recomputed&&(await applyApprovedPaths(gitRoot,recomputed.afterTree,approved),await restoreToBaseline(gitRoot,recomputed.baselineTree,rejected)),manifest){let casApproved=[],casRejected=[];for(let file3 of manifest.files){let path6=file3.pathAfter||file3.pathBefore,action=actionByChangeId.get(`${changeSet.id}:${path6}`)??FileDecisionAction.UNSPECIFIED;action===FileDecisionAction.APPROVE?(casApproved.push(file3),approvedPaths.push(path6)):(action===FileDecisionAction.REJECT&&(hadReject=!0),casRejected.push(file3),rejectedPaths.push(path6))}await applyCasApproved({readBlob,workspaceRoot:gitRoot,files:casApproved}),await restoreCasToBaseline({readBlob,workspaceRoot:gitRoot,files:casRejected})}let approvedSnapshot;if(recomputed){let snap=await snapshotApproved(gitRoot,executionId,excludePaths);approvedSnapshot=gitTreeSnapshotRef(snap.treeOid,snap.ref)}else approvedSnapshot=casManifestSnapshotRef(candidateCasRef(changeSet));return appendFileReviewEvents(status,executionId,[buildReconciledEvent(changeSetContext(changeSet.id,harnessId),approvedSnapshot)]),recomputed&&await dropCaptureRefs(gitRoot,executionId),{isCaptureTurn:!0,approvedPaths,rejectedPaths,hadReject,failed:!1}}function resolveDecisions(changeSet){let byChangeId=new Map,changeSetDecision=changeSet.decisions.find(d=>d.scope===FileDecisionScope.CHANGE_SET);if(changeSetDecision)for(let change of changeSet.changes)byChangeId.set(change.id,changeSetDecision.action);for(let decision of changeSet.decisions)decision.scope===FileDecisionScope.FILE&&decision.fileChangeId&&byChangeId.set(decision.fileChangeId,decision.action);return byChangeId}function digestMatches(gitChange,protoChange){return!(gitChange.changeType!==FileChangeType.DELETE&&(!gitChange.after||contentSha256(gitChange.after)!==protoChange.afterSha256)||gitChange.changeType!==FileChangeType.CREATE&&(!gitChange.before||contentSha256(gitChange.before)!==protoChange.beforeSha256))}function changeSetContext(changeSetId,harnessId){return{changeSetId,turnId:changeSetId,harnessId,timestamp:utcTimestamp()}}function gitTreeSnapshotRef(treeOid,ref){return create(SnapshotRefSchema,{kind:SnapshotKind.GIT_TREE_REF,git:create(GitTreeRefSchema,{treeOid,ref})})}function hybridSnapshotRef(treeOid,ref,cas){return create(SnapshotRefSchema,{kind:SnapshotKind.HYBRID,git:create(GitTreeRefSchema,{treeOid,ref}),cas:create(CasManifestRefSchema,{manifestDigest:cas.manifestDigest,artifactUri:cas.artifactUri})})}function casManifestSnapshotRef(cas){return create(SnapshotRefSchema,{kind:SnapshotKind.CAS_MANIFEST,cas:cas?create(CasManifestRefSchema,{manifestDigest:cas.manifestDigest,artifactUri:cas.artifactUri}):void 0})}function candidateCasRef(changeSet){let cas=changeSet.candidateSnapshot?.cas;return cas?{manifestDigest:cas.manifestDigest,artifactUri:cas.artifactUri}:void 0}function casToCapturedChangeInput(changeSetId,file3){return{id:`${changeSetId}:${file3.pathAfter||file3.pathBefore}`,pathBefore:file3.pathBefore,pathAfter:file3.pathAfter,kind:file3.kind,captureClass:file3.captureClass,lineCounts:file3.lineCounts,before:file3.before?{kind:"ref",sha256:file3.before.sha256,storageKey:file3.before.storageKey,sizeBytes:file3.before.sizeBytes,isBinary:file3.before.isBinary}:void 0,after:file3.after?{kind:"ref",sha256:file3.after.sha256,storageKey:file3.after.storageKey,sizeBytes:file3.after.sizeBytes,isBinary:file3.after.isBinary}:void 0,diffComplete:file3.diffComplete}}function secretWithheldChangeInput(id,pathBefore,pathAfter,kind,captureClass){return{id,pathBefore,pathAfter,kind,captureClass,diffComplete:!1,blockedReason:FileReviewBlockReason.SECRET_WITHHELD}}function unreviewableChangeInput(changeSetId,path6,captureClass){return secretWithheldChangeInput(`${changeSetId}:${path6}`,path6,path6,FileChangeKind.MODIFY,captureClass)}function trackedSecretChangeInput(changeSetId,change){let isCreate=change.changeType===FileChangeType.CREATE,isDelete=change.changeType===FileChangeType.DELETE,pathBefore=isCreate?"":change.path,pathAfter=isDelete?"":change.path;return secretWithheldChangeInput(`${changeSetId}:${pathAfter||pathBefore}`,pathBefore,pathAfter,toFileChangeKind(change.changeType),FileCaptureClass.GIT_TRACKED)}function partitionGitChangesBySecret(changes){let safe=[],secret=[];for(let change of changes)isSecretLikePath(change.path)?secret.push(change):safe.push(change);return{safe,secret}}function toFileChangeKind(changeType){switch(changeType){case FileChangeType.CREATE:return FileChangeKind.ADD;case FileChangeType.DELETE:return FileChangeKind.DELETE;default:return FileChangeKind.MODIFY}}function toCapturedChangeInput(changeSetId,change){let isCreate=change.changeType===FileChangeType.CREATE,isDelete=change.changeType===FileChangeType.DELETE,pathBefore=isCreate?"":change.path,pathAfter=isDelete?"":change.path,binary2=change.before?.kind==="binary"||change.after?.kind==="binary";return{id:`${changeSetId}:${pathAfter||pathBefore}`,pathBefore,pathAfter,kind:toFileChangeKind(change.changeType),captureClass:FileCaptureClass.GIT_TRACKED,before:change.before,after:change.after,diffComplete:!binary2}}var init_capture=__esm({"dist/shared/filereview/capture.js"(){"use strict";init_esm4();init_enum_pb();init_filereview_pb();init_status2();init_events();init_git_substrate();init_cas_substrate();init_secret_paths()}});function readMinIntervalMs(){let raw=process.env.STIGMER_PROGRESS_CAPTURE_MIN_INTERVAL_MS;if(!raw)return 2e3;let n3=Number.parseInt(raw,10);return Number.isFinite(n3)&&n3>=0?n3:2e3}function shouldCaptureProgress(lastAtMs,nowMs,minIntervalMs=PROGRESS_CAPTURE_MIN_INTERVAL_MS){return nowMs-lastAtMs>=minIntervalMs}function buildFileChangeProgress(delta,changeSetId){let totalAdded=0,totalRemoved=0,entries=[];for(let entry of delta.entries){let secret=isSecretLikePath(entry.pathAfter||entry.pathBefore),linesAdded=secret?0:entry.linesAdded,linesRemoved=secret?0:entry.linesRemoved;totalAdded+=linesAdded,totalRemoved+=linesRemoved,entries.length<PROGRESS_MAX_ENTRIES&&entries.push(create(FileChangeProgressEntrySchema,{pathBefore:entry.pathBefore,pathAfter:entry.pathAfter,kind:entry.kind,linesAdded,linesRemoved}))}return create(FileChangeProgressSchema,{changeSetId,filesChanged:delta.totalFilesChanged??delta.entries.length,linesAdded:totalAdded,linesRemoved:totalRemoved,entries,capturedAt:utcTimestamp()})}function newProgressCaptureState(){return{lastAtMs:0}}async function captureFileChangeProgress(opts){let now=opts.nowMs??Date.now();if(!shouldCaptureProgress(opts.state.lastAtMs,now))return;opts.state.lastAtMs=now;let{delta,changed}=await opts.substrate.capture();changed&&(opts.status.fileChangeProgress=buildFileChangeProgress(delta,opts.changeSetId))}function gitEntryToProgressEntry(e){return{pathBefore:e.pathBefore,pathAfter:e.pathAfter,kind:toFileChangeKind(e.changeType),linesAdded:e.linesAdded,linesRemoved:e.linesRemoved}}function createGitProgressSubstrate(opts){let lastTreeSha,cachedFull={entries:[]};return{async capture(){let gitDelta=await captureProgressDelta(opts.workspaceRoot,opts.executionId,opts.baselineTree,opts.excludePaths,lastTreeSha);return gitDelta===void 0?{delta:cachedFull,changed:!1}:(lastTreeSha=gitDelta.afterTree,cachedFull={entries:gitDelta.entries.map(gitEntryToProgressEntry)},{delta:cachedFull,changed:!0})}}}function createHybridProgressSubstrate(git2,cas){return{async capture(){let[g,c]=await Promise.all([git2.capture(),cas.capture()]);return{delta:{entries:[...g.delta.entries,...c.delta.entries],totalFilesChanged:(g.delta.totalFilesChanged??g.delta.entries.length)+(c.delta.totalFilesChanged??c.delta.entries.length)},changed:g.changed||c.changed}}}}var PROGRESS_MAX_ENTRIES,PROGRESS_CAPTURE_MIN_INTERVAL_MS,init_progress=__esm({"dist/shared/filereview/progress.js"(){"use strict";init_esm4();init_filereview_pb();init_status2();init_capture();init_git_substrate();init_secret_paths();PROGRESS_MAX_ENTRIES=200,PROGRESS_CAPTURE_MIN_INTERVAL_MS=readMinIntervalMs()}});function createCasProgressSubstrate(opts){let maxEntries=opts.maxEntries??PROGRESS_MAX_ENTRIES,cachedFull={entries:[],totalFilesChanged:0},lastSignature;return{async capture(){let snapshot=await opts.read(),{capturablePaths}=partitionIgnoredPathsBySecret(snapshot.before.keys(),snapshot.blockedSecretPaths),prefix=[...capturablePaths].sort().slice(0,maxEntries),entries=[],sigParts=[`${capturablePaths.length}`];for(let relPath of prefix){let abs=(0,import_node_path22.join)(opts.workspaceRoot,relPath),st=await statOrNull(abs);sigParts.push(`${relPath}\0${st?`${st.size}:${st.mtimeMs}`:"\u2205"}`);let beforeBytes=snapshot.before.get(relPath)??null,beforeBuf=beforeBytes===null?null:Buffer.from(beforeBytes);if(st&&st.size>LINE_COUNT_MAX_BYTES){let kind=beforeBuf===null?FileChangeKind.ADD:FileChangeKind.MODIFY;entries.push({pathBefore:kind===FileChangeKind.ADD?"":relPath,pathAfter:relPath,kind,linesAdded:0,linesRemoved:0});continue}let afterBytes=st?await readFileOrNull(abs):null,afterBuf=afterBytes===null?null:Buffer.from(afterBytes),cls=classifyCasChange(relPath,beforeBuf,afterBuf);cls&&entries.push({pathBefore:cls.pathBefore,pathAfter:cls.pathAfter,kind:cls.kind,linesAdded:cls.lineCounts?.linesAdded??0,linesRemoved:cls.lineCounts?.linesRemoved??0})}let prefixNoOps=prefix.length-entries.length,totalFilesChanged=capturablePaths.length-prefixNoOps,signature=sigParts.join("|");return signature===lastSignature?{delta:cachedFull,changed:!1}:(lastSignature=signature,cachedFull={entries,totalFilesChanged},{delta:cachedFull,changed:!0})}}}async function statOrNull(abs){try{let s=await(0,import_promises17.stat)(abs);return{size:s.size,mtimeMs:s.mtimeMs}}catch{return null}}async function readFileOrNull(abs){try{return await(0,import_promises17.readFile)(abs)}catch{return null}}var import_promises17,import_node_path22,init_cas_progress=__esm({"dist/shared/filereview/cas-progress.js"(){"use strict";import_promises17=require("node:fs/promises"),import_node_path22=require("node:path");init_enum_pb();init_cas_substrate();init_line_counts();init_progress();init_secret_paths()}});function captureBaselineToLedger2(opts){return captureBaselineToLedger({...opts,harnessId:HARNESS_ID,excludePaths:CURSOR_RUNNER_OWNED_PATHS})}async function captureTurnToLedger(opts){let{status,gitRoot,executionId,changeSetId,baselineTree,messages,deniedTokens,hitlDir,storage,priorSubAgentToolCallIds,commandProvenance}=opts,gitWorkspace=opts.gitWorkspace??!0,casCaptureClass=gitWorkspace?FileCaptureClass.GIT_IGNORED_CAPTURED:FileCaptureClass.NON_GIT_CAS,{casCaptures,unreviewablePaths}=await buildCasTurnCaptures(gitRoot,hitlDir,storage,casCaptureClass),changes=await captureCandidateToLedger({status,gitRoot,executionId,changeSetId,baselineTree,harnessId:HARNESS_ID,excludePaths:CURSOR_RUNNER_OWNED_PATHS,casCaptures,storage,unreviewablePaths,unreviewableCaptureClass:casCaptureClass,gitWorkspace,commandProvenance});if(hasCandidateCaptured(status,changeSetId)){stampFlowedFileEditRows(messages,deniedTokens,changeSetId);for(let sa of status.subAgentExecutions)stampFlowedFileEditRows(sa.messages,deniedTokens,changeSetId,priorSubAgentToolCallIds)}return changes}function buildCursorProgressSubstrate(opts){let{captureMode,gitWorkspace,workspaceRoot,baselineTree,executionId,hitlDir,storage}=opts;if(!captureMode||!workspaceRoot)return;let casReader=hitlDir&&storage?createSidecarTouchedReader(hitlDir):void 0;if(gitWorkspace){if(!baselineTree)return;let git2=createGitProgressSubstrate({workspaceRoot,executionId,baselineTree,excludePaths:CURSOR_RUNNER_OWNED_PATHS});return casReader?createHybridProgressSubstrate(git2,createCasProgressSubstrate({workspaceRoot,read:casReader})):git2}return casReader?createCasProgressSubstrate({workspaceRoot,read:casReader}):void 0}function createSidecarTouchedReader(hitlDir){return async()=>{let{captured,secretPaths}=await readCasObservations(hitlDir),before=new Map;for(let c of captured)before.set(c.path,c.before);return{before,blockedSecretPaths:new Set(secretPaths)}}}async function buildCasTurnCaptures(gitRoot,hitlDir,storage,captureClass){if(!hitlDir||!storage)return{casCaptures:[],unreviewablePaths:[]};let{captured,secretPaths}=await readCasObservations(hitlDir),beforeByPath=new Map(captured.map(c=>[c.path,c.before])),{capturablePaths,unreviewablePaths}=partitionIgnoredPathsBySecret(beforeByPath.keys(),new Set(secretPaths)),casCaptures=[];for(let relPath of capturablePaths){let after=await readFileOrNull2((0,import_node_path23.join)(gitRoot,relPath));casCaptures.push({path:relPath,before:beforeByPath.get(relPath)??null,after,captureClass})}return{casCaptures,unreviewablePaths:[...unreviewablePaths]}}async function readFileOrNull2(absolutePath){try{return await(0,import_promises18.readFile)(absolutePath)}catch{return null}}function applyCaptureDecisions2(opts){let{storage,...rest}=opts;return applyCaptureDecisions({...rest,harnessId:HARNESS_ID,excludePaths:CURSOR_RUNNER_OWNED_PATHS,storage,readBlob:storage?casBlobReader(storage):void 0})}function stampFlowedFileEditRows(messages,deniedTokens,changeSetId,skipToolCallIds){for(let msg of messages)for(let tc of msg.toolCalls){if(tc.fileChangeSetId||skipToolCallIds?.has(tc.id)||isToolCallRowHidden(tc))continue;let category=approvalCategory(tc.name);if(category!=="write"&&category!=="delete")continue;let args=tc.args??{},id=toolIdentity(tc.name,tc.mcpServerSlug,args),token=primaryToken(id.key,id.salient,contentDigest(args));deniedTokens.has(token)||stampFileEditRow(tc,changeSetId)}}var import_promises18,import_node_path23,HARNESS_ID,CURSOR_RUNNER_OWNED_PATHS,init_capture_flow=__esm({"dist/activities/execute-cursor/capture-flow.js"(){"use strict";import_promises18=require("node:fs/promises"),import_node_path23=require("node:path");init_enum_pb();init_approval_policy2();init_approval_state();init_cas_observations();init_file_tools();init_tool_row();init_capture();init_progress();init_cas_progress();init_events();init_secret_paths();init_cas_substrate();init_capture();HARNESS_ID="cursor",CURSOR_RUNNER_OWNED_PATHS=[".cursor/hooks.json",".cursor/rules/stigmer-tool-approval.mdc"]}});function qualifyTurnCommandProvenance(inputs){let{turnToolCalls,messages,isExecutedCommand,resolveDirectConsent,globalBypass}=inputs,consentIds=new Set,authorizedByAutoApproveAll=!1,executedCommandCount=0;for(let tc of turnToolCalls){if(isToolCallRowHidden(tc))continue;let kind=classifyTool(tc.name,tc.mcpServerSlug);if(NON_MUTATING_KINDS.has(kind))continue;if(kind!==ToolKind.SHELL)return;if(!isExecutedCommand(tc))continue;executedCommandCount++;let consentId=resolveDirectConsent(tc);if(consentId){consentIds.add(consentId);continue}let leaseConsentId=findLeaseConsentId(messages,tc.name);if(leaseConsentId){consentIds.add(leaseConsentId);continue}if(globalBypass){authorizedByAutoApproveAll=!0;continue}return}if(executedCommandCount!==0)return create(TurnCommandProvenanceSchema,{consentToolCallIds:[...consentIds],authorizedByAutoApproveAll})}function findLeaseConsentId(messages,toolName){let category=toolApprovalCategory(toolName);if(category){for(let msg of messages)for(let tc of msg.toolCalls)if(tc.approvalAction===ApprovalAction.APPROVE_ALL&&toolApprovalCategory(tc.name)===category)return tc.id}}var NON_MUTATING_KINDS,init_command_provenance=__esm({"dist/shared/filereview/command-provenance.js"(){"use strict";init_esm4();init_filereview_pb();init_enum_pb();init_tool_kind();init_tool_row();NON_MUTATING_KINDS=new Set([ToolKind.FILE_READ,ToolKind.SEARCH,ToolKind.LIST,ToolKind.FETCH,ToolKind.WEB_SEARCH,ToolKind.THINK,ToolKind.TODO])}});function deriveTurnCommandProvenance(inputs){let{messages,turnStartIndex,deniedTokens,grantTokenToConsentId,globalBypass}=inputs,turnToolCalls=messages.slice(turnStartIndex).flatMap(m=>m.toolCalls);return qualifyTurnCommandProvenance({turnToolCalls,messages,isExecutedCommand:tc=>!deniedTokens.has(toolCallIdentityToken(tc)),resolveDirectConsent:tc=>grantTokenToConsentId.get(toolCallIdentityToken(tc)),globalBypass})}var init_command_provenance2=__esm({"dist/activities/execute-cursor/command-provenance.js"(){"use strict";init_command_provenance();init_message_translator()}});async function runTurnBoundary(opts){let{status,executionId,changeSetId,hitlDir,captureMode,baselineTree,primaryWorkspaceDir,gitWorkspace,turnStartMessageIndex,approvalGrants,globalBypass,seededSubAgents,artifactStorage,mergedPolicies,denialCancelSettled,foreignGatingHooks}=opts;denialCancelSettled&&await Promise.race([denialCancelSettled,new Promise(resolve7=>{setTimeout(resolve7,FIRST_DENIAL_CANCEL_TIMEOUT_MS).unref()})]);let deniedLedger=await readDenialLedger(hitlDir??""),approvalLedger=approvalDenials(deniedLedger),capturedChangeCount=0;if(captureMode&&baselineTree!==void 0&&primaryWorkspaceDir){let deniedTokens=new Set(deniedLedger.map(e=>e.token)),commandProvenance=deriveTurnCommandProvenance({messages:status.messages,turnStartIndex:turnStartMessageIndex,deniedTokens,grantTokenToConsentId:new Map((approvalGrants??[]).map(g=>[primaryToken(g.key,g.salient,g.contentDigest),g.sourceToolCallId])),globalBypass});commandProvenance&&console.log(`ExecuteCursor capture: turn qualifies for approved-command auto-keep (consent rows: ${commandProvenance.consentToolCallIds.join(",")||"(auto_approve_all)"}); attaching provenance to candidate (execution=${executionId})`),capturedChangeCount=(await captureTurnToLedger({status,gitRoot:primaryWorkspaceDir,executionId,changeSetId,baselineTree,messages:status.messages,deniedTokens,commandProvenance,priorSubAgentToolCallIds:collectSubAgentToolCallIds(seededSubAgents),hitlDir,storage:artifactStorage,gitWorkspace})).length,capturedChangeCount>0&&console.log(`ExecuteCursor capture: ${capturedChangeCount} file change(s) authored to the file_review ledger (change_set=${changeSetId}), working tree left applied for review (execution=${executionId})`)}let gateWorkspaceBackend=new LocalWorkspaceBackend(primaryWorkspaceDir),deniedToolCalls=await reconcileDeniedToolCalls(status.messages,approvalLedger,mergedPolicies,gateWorkspaceBackend),synthesizedGateCount=deniedToolCalls.filter(tc=>tc.id.startsWith("approval:")).length;if(synthesizedGateCount>0&&console.warn(`ExecuteCursor reconcile synthesized ${synthesizedGateCount} placeholder gate(s) with no correlated stream call (execution=${executionId}); possible hook/stream identity drift \u2014 gate(s) will lack a diff`),deniedToolCalls.length>0){let redactedNarration=clearProvisionalPostDenialNarration(status.messages,deniedToolCalls);redactedNarration.length>0&&console.log(`ExecuteCursor redacted ${redactedNarration.length} provisional post-denial narration message(s) before pausing for approval`)}let unattributedHookBlocks=detectUnattributedHookBlocks(status.messages,turnStartMessageIndex,deniedLedger,primaryWorkspaceDir),waiting=deniedToolCalls.length>0||capturedChangeCount>0;if(unattributedHookBlocks.length>0){let culprits=(foreignGatingHooks?.length??0)>0?` \u2014 likely foreign workspace hook(s): ${foreignGatingHooks.join(", ")}`:"";console.warn(`ExecuteCursor turn boundary: ${unattributedHookBlocks.length} tool call(s) blocked by a hook with NO matching denial-ledger entry [${unattributedHookBlocks.map(b=>b.toolName).join(", ")}]${culprits} (execution=${executionId})${waiting?" \u2014 turn pauses anyway; not failing":""}`)}return deniedLedger.some(e=>denialKindOf(e)==="fail-closed")&&console.warn(`ExecuteCursor turn boundary: fail-closed denial(s) in the ledger \u2014 the approval state file was missing during this turn and gated tools were denied (execution=${executionId})`),{waiting,capturedChangeCount,deniedToolCallCount:deniedToolCalls.length,unattributedHookBlocks}}var FIRST_DENIAL_CANCEL_TIMEOUT_MS,init_turn_boundary=__esm({"dist/activities/execute-cursor/turn-boundary.js"(){"use strict";init_tool_row();init_local_backend();init_approval_state();init_command_provenance2();init_capture_flow();init_message_translator();FIRST_DENIAL_CANCEL_TIMEOUT_MS=5e3}});function shouldPersistStreamingStatus(signals,scheduler,eventCount,nowMs){return signals.deltaEnricherDirty||signals.todosDirty||signals.contentDirty||scheduler.shouldSendUpdate(eventCount,nowMs)}var init_persist_decision=__esm({"dist/activities/execute-cursor/persist-decision.js"(){"use strict"}});function newTurnStreamState(){return{pauseDetected:!1,stallDetected:!1,stallError:void 0,firstDenialDetected:!1,denialLedgerDirty:!1,denialCancelSettled:void 0,platformStopSignaled:!1,streamErrorMessage:void 0,lastToolName:void 0,eventCount:0,firstTurnAttributionLogged:!1,stallWatchdog:void 0}}function makeCursorTurnOnDelta(deps){let{usageAccumulator,deltaEnricher,heartbeat:heartbeat2,promptEstimatedTokens,executionId,state}=deps;return({update})=>{if(state.stallWatchdog?.recordActivity(),update.type==="turn-ended"&&update.usage&&(usageAccumulator.addTurn(update.usage),!state.firstTurnAttributionLogged)){state.firstTurnAttributionLogged=!0;let sdkInputTokens=update.usage.inputTokens??0,cursorOverhead=Math.max(0,sdkInputTokens-promptEstimatedTokens);console.log(`ExecuteCursor context attribution (first turn): execution=${executionId}, sdkInputTokens=${sdkInputTokens}, stigmerPreamble=${promptEstimatedTokens}, cursorOverhead=${cursorOverhead} (estimated)`)}deltaEnricher.processDelta(update);try{heartbeat2()}catch(hbErr){if(hbErr instanceof import_activity.CancelledFailure){state.pauseDetected=!0;return}throw hbErr}}}async function consumeCursorTurnStream(run,deps){let{status,accumulator,todoTracker,deltaEnricher,eventRecorder,scheduler,usageAccumulator,progressSubstrate,progressState,changeSetId,hitlDir,executionId,stallTimeoutMs,persist,heartbeat:heartbeat2,isCancelled,state}=deps;state.stallWatchdog=startStallWatchdog(stallTimeoutMs,idleMs=>{state.stallDetected=!0,state.stallError=new StallTimeoutError(idleMs,state.lastToolName?`last tool: ${state.lastToolName}`:void 0),console.warn(`ExecuteCursor stall detected: execution=${executionId}, idleMs=${idleMs}, lastTool=${state.lastToolName??"none"}`),run.supports?.("cancel")&&run.cancel().catch(cancelErr=>{console.warn(`ExecuteCursor run.cancel() after stall failed (non-fatal): execution=${executionId}, error=${cancelErr instanceof Error?cancelErr.message:cancelErr}`)})});try{for await(let event of run.stream()){if(state.pauseDetected||isCancelled()){state.pauseDetected=!0;break}if(state.stallDetected)break;if(state.stallWatchdog.recordActivity(),event.type==="tool_call"&&typeof event.name=="string"&&(state.lastToolName=event.name),eventRecorder?.record(event,state.eventCount),accumulator.processEvent(event),todoTracker.processEvent(event),event.type==="tool_call"&&event.name==="task"&&accumulator.trackSubAgentExecution(event),!state.firstDenialDetected&&hitlDir&&(state.denialLedgerDirty||event.type==="tool_call")){state.denialLedgerDirty=!1;let denials=approvalDenials(await readDenialLedger(hitlDir));if(denials.length>0){state.firstDenialDetected=!0,console.log(`ExecuteCursor first denial detected (${denials.length} ledger entr${denials.length===1?"y":"ies"}); stopping turn to pause cleanly for approval: execution=${executionId}`),run.supports?.("cancel")&&(state.denialCancelSettled=run.cancel().then(()=>{},cancelErr=>{console.warn(`ExecuteCursor run.cancel() after first denial failed (non-fatal): execution=${executionId}, error=${cancelErr instanceof Error?cancelErr.message:cancelErr}`)}));break}}if(deltaEnricher.applyEnrichments(status.messages),state.eventCount++,event.type==="status"){console.log(`ExecuteCursor stream status: execution=${executionId}, status=${JSON.stringify(event)}`);let statusEvent=event;statusEvent.status==="ERROR"&&statusEvent.message&&(state.streamErrorMessage=statusEvent.message)}let shouldPersist=shouldPersistStreamingStatus({deltaEnricherDirty:deltaEnricher.isDirty,todosDirty:todoTracker.isDirty,contentDirty:accumulator.isDirty},scheduler,state.eventCount);if(usageAccumulator.hasTurns&&(status.streamingUsage=create(StreamingUsageSummarySchema,usageAccumulator.snapshot())),shouldPersist){status.subAgentExecutions=accumulator.subAgentExecutions,progressSubstrate&&await captureFileChangeProgress({status,changeSetId,substrate:progressSubstrate,state:progressState});let signal=await persist(status);deltaEnricher.markPersisted(),todoTracker.markPersisted(),accumulator.markPersisted(),scheduler.markUpdateSent(state.eventCount),heartbeat2(),signal===ExecutionControlSignal.STOP&&(state.platformStopSignaled=!0,console.warn(`ExecuteCursor platform stop signal received: execution=${executionId}`))}if(state.platformStopSignaled){console.log(`ExecuteCursor stopping stream due to platform stop signal: execution=${executionId}`);break}}}catch(streamErr){if(!state.stallDetected&&!state.firstDenialDetected)throw streamErr;console.warn(`ExecuteCursor stream ended via cancel: execution=${executionId}, stall=${state.stallDetected}, firstDenial=${state.firstDenialDetected}`)}finally{state.stallWatchdog.stop()}return state.stallDetected?"stalled":state.platformStopSignaled?"platform-stop":state.firstDenialDetected?"first-denial":state.pauseDetected||isCancelled()?"paused":"completed"}var import_activity,init_turn_stream=__esm({"dist/activities/execute-cursor/turn-stream.js"(){"use strict";init_esm4();import_activity=__toESM(require_lib4(),1);init_enum_pb();init_usage_pb();init_stall_watchdog();init_persist_decision();init_approval_state();init_progress()}});function getRunnerHitlMasterSecret(){if(cached3)return cached3;let fromEnv=process.env[ENV_VAR];return fromEnv&&fromEnv.length>0?(cached3=Buffer.from(fromEnv,"utf-8"),cached3):(cached3=(0,import_node_crypto13.randomBytes)(32),warned||(warned=!0,console.warn(`[hitl-gateway] ${ENV_VAR} is not set; using a per-process random fingerprint secret. Fingerprints are stable within this process only \u2014 set ${ENV_VAR} for a key stable across runner restarts/replicas (required in Phase 7).`)),cached3)}var import_node_crypto13,ENV_VAR,cached3,warned,init_fingerprint_secret=__esm({"dist/shared/fingerprint-secret.js"(){"use strict";import_node_crypto13=require("node:crypto"),ENV_VAR="STIGMER_RUNNER_HITL_SECRET",warned=!1}});var SourceType,WorkspaceProvisionError,init_types17=__esm({"dist/shared/workspace/types.js"(){"use strict";(function(SourceType2){SourceType2.GIT_REPO="git_repo",SourceType2.LOCAL_PATH="local_path",SourceType2.EMPTY="empty"})(SourceType||(SourceType={}));WorkspaceProvisionError=class extends Error{sourceType;cause;transient;constructor(sourceType,message,options){super(`[${sourceType}] ${message}`),this.name="WorkspaceProvisionError",this.sourceType=sourceType,this.cause=options?.cause,this.transient=options?.transient??!1}}}});function provisionEmpty(backend){return{rootDir:backend.rootDir,sourceType:SourceType.EMPTY,consumedKeys:[],workspaceDescription:"Your workspace is empty. Create files and directories as needed for your task.",entryName:""}}var init_empty=__esm({"dist/shared/workspace/sources/empty.js"(){"use strict";init_types17()}});function provisionLocalPath(options){let{path:path6,isLocalMode,targetSubdir,backendRootDir}=options;if(!isLocalMode)throw new WorkspaceProvisionError(SourceType.LOCAL_PATH,"LocalPathSource is only supported in local mode. Use git_repo for cloud deployments.");if(!(0,import_node_path24.isAbsolute)(path6))throw new WorkspaceProvisionError(SourceType.LOCAL_PATH,`Path must be absolute, got relative path: '${path6}'`);if(!(0,import_node_fs6.existsSync)(path6))throw new WorkspaceProvisionError(SourceType.LOCAL_PATH,`Path does not exist: '${path6}'`);if(!(0,import_node_fs6.statSync)(path6).isDirectory())throw new WorkspaceProvisionError(SourceType.LOCAL_PATH,`Path is not a directory: '${path6}'`);return targetSubdir&&backendRootDir&&createEntrySymlink(backendRootDir,targetSubdir,path6),{rootDir:path6,sourceType:SourceType.LOCAL_PATH,consumedKeys:[],workspaceDescription:`Your workspace is the user's project directory: ${path6}
2058
+ ${stderr||err.message}`)):resolve7(stdout)})})}async readFile(path6){let full=this.resolvePath(path6);return(0,import_promises14.readFile)(full,"utf-8")}async writeFile(path6,content){let full=this.resolvePath(path6);await this.ensureParentDir(path6,full),await(0,import_promises14.writeFile)(full,content,"utf-8")}async writeFileBuffer(path6,content){let full=this.resolvePath(path6);await this.ensureParentDir(path6,full),await(0,import_promises14.writeFile)(full,content)}async ensureParentDir(relativePath,resolvedPath){if(this.platformDir&&!(0,import_node_path18.isAbsolute)(relativePath)){let{isPlatform}=classifyPlatformPath(relativePath);if(isPlatform){let parentDir=(0,import_node_path18.join)(resolvedPath,"..");await(0,import_promises14.mkdir)(parentDir,{recursive:!0})}}}async exists(path6){let full=this.resolvePath(path6);try{return await(0,import_promises14.access)(full),!0}catch{return!1}}resolvePath(path6){if((0,import_node_path18.isAbsolute)(path6))return path6;if(this.platformDir){let{isPlatform,remainder}=classifyPlatformPath(path6);if(isPlatform){let resolved=(0,import_node_path18.resolve)(this.platformDir,remainder),normalizedPlatform=(0,import_node_path18.resolve)(this.platformDir);if(!resolved.startsWith(normalizedPlatform+"/")&&resolved!==normalizedPlatform)throw new Error(`Path traversal detected: '${path6}' resolves outside platform directory`);return resolved}}return(0,import_node_path18.join)(this.rootDir,path6)}}}});async function applyApprovedWholeFileWrites(opts){let applied=new Set;for(let msg of opts.messages)for(let tc of msg.toolCalls){if(!isApprovedWholeFileWrite(tc))continue;let args=argsRecord(tc),rawPath=extractFilePath(args);if(!rawPath){logSkip(opts.executionId,tc,"no file path in tool args");continue}let{absolutePath:target}=resolveWorkspacePath(rawPath,opts.workspaceBackend.rootDir,!1);if(!isWithinWorkspace(target,opts.workspaceDirs)){logSkip(opts.executionId,tc,`target outside workspace: ${target}`);continue}let content=resolveApprovedWholeFileContent(tc);if(content===null){logSkip(opts.executionId,tc,"exact approved bytes unresolvable");continue}try{await opts.workspaceBackend.writeFile(target,content)}catch(err){logSkip(opts.executionId,tc,`write failed: ${err instanceof Error?err.message:String(err)}`);continue}tc.status=ToolCallStatus.TOOL_CALL_COMPLETED,tc.completedAt||(tc.completedAt=utcTimestamp()),tc.error="",applied.add(tc.id),console.log(`ExecuteCursor exact-apply: wrote approved bytes to ${target} (tool=${tc.id}); no resource grant issued, so a further change re-gates. execution=${opts.executionId}`)}return applied}function excludeAppliedFromGrants(adjudicatedApprovals,appliedToolCallIds){return adjudicatedApprovals.filter(pa=>!appliedToolCallIds.has(pa.toolCallId))}function resolveApprovedWholeFileContent(tc){let content=extractWriteContent(argsRecord(tc));return content!==null&&content!==ELISION_MARKER?content:null}function isApprovedWholeFileWrite(tc){return tc.status!==ToolCallStatus.TOOL_CALL_WAITING_APPROVAL||tc.approvalAction!==ApprovalAction.APPROVE&&tc.approvalAction!==ApprovalAction.APPROVE_ALL?!1:extractWriteContent(argsRecord(tc))!==null}function argsRecord(tc){return tc.args&&typeof tc.args=="object"?tc.args:{}}function isWithinWorkspace(absTarget,workspaceDirs){let target=(0,import_node_path19.resolve)(absTarget);return workspaceDirs.some(dir=>{let root=(0,import_node_path19.resolve)(dir);if(target===root)return!0;let rel=(0,import_node_path19.relative)(root,target);return rel!==""&&!rel.startsWith("..")&&!(0,import_node_path19.isAbsolute)(rel)})}function logSkip(executionId,tc,reason){console.log(`ExecuteCursor exact-apply skipped (falling back to grant+reinvocation): tool=${tc.id} reason="${reason}" execution=${executionId}`)}var import_node_path19,init_exact_apply=__esm({"dist/activities/execute-cursor/exact-apply.js"(){"use strict";import_node_path19=require("node:path");init_enum_pb();init_status_offload();init_file_tools();init_file_change();init_status2()}});function excludePathspecs(excludePaths){return excludePaths.map(p=>`:(exclude)${p}`)}function baselineRef(executionId){return`refs/stigmer/baseline/${executionId}`}function captureRef(executionId){return`refs/stigmer/capture/${executionId}`}async function git(gitRoot,args,env){let{stdout}=await execFileAsync("git",args,{cwd:gitRoot,env:env?{...process.env,...env}:process.env,maxBuffer:268435456,encoding:"utf-8"});return stdout}async function gitBuffer(gitRoot,args){let{stdout}=await execFileAsync("git",args,{cwd:gitRoot,maxBuffer:268435456,encoding:"buffer"});return stdout}async function isGitWorkTree(dir){try{return(await git(dir,["rev-parse","--is-inside-work-tree"])).trim()==="true"}catch{return!1}}async function isPathCapturable(gitRoot,path6){if(!path6)return!1;try{return await git(gitRoot,["check-ignore","-q","--",path6]),!1}catch{return!0}}async function headExists(gitRoot){try{return await git(gitRoot,["rev-parse","--verify","--quiet","HEAD"]),!0}catch{return!1}}async function resolveGitDir(gitRoot){return(await git(gitRoot,["rev-parse","--absolute-git-dir"])).trim()}async function writeWorkingTree(gitRoot,gitDir,label,executionId,excludePaths){let tmpIndex=(0,import_node_path20.join)(gitDir,`stigmer-index-${label}-${executionId}`);try{await(0,import_promises15.rm)(tmpIndex,{force:!0});let env={GIT_INDEX_FILE:tmpIndex};return await git(gitRoot,["add","-A","--",".",...excludePathspecs(excludePaths)],env),(await git(gitRoot,["write-tree"],env)).trim()}finally{await(0,import_promises15.rm)(tmpIndex,{force:!0})}}async function pinTree(gitRoot,ref,tree,message){let args=["commit-tree",tree,"-m",message];await headExists(gitRoot)&&args.push("-p","HEAD");let commit=(await git(gitRoot,args,SNAPSHOT_IDENTITY_ENV)).trim();await git(gitRoot,["update-ref",ref,commit])}async function snapshotBaseline(gitRoot,executionId,excludePaths=[]){let gitDir=await resolveGitDir(gitRoot),tree=await writeWorkingTree(gitRoot,gitDir,"baseline",executionId,excludePaths);return await pinTree(gitRoot,baselineRef(executionId),tree,`stigmer baseline ${executionId}`),tree}async function captureChangeSet(gitRoot,executionId,baselineTree,excludePaths=[]){let gitDir=await resolveGitDir(gitRoot),afterTree=await writeWorkingTree(gitRoot,gitDir,"capture",executionId,excludePaths);await pinTree(gitRoot,captureRef(executionId),afterTree,`stigmer capture ${executionId}`);let raw=await git(gitRoot,["diff","--no-renames","--name-status","-z",baselineTree,afterTree]),changes=[];for(let{status,path:path6}of parseNameStatusZ(raw)){let change=await buildCapturedChange(gitRoot,baselineTree,afterTree,status,path6);change&&changes.push(change)}return{baselineTree,afterTree,changes}}async function captureProgressDelta(gitRoot,executionId,baselineTree,excludePaths=[],lastTreeSha){let gitDir=await resolveGitDir(gitRoot),afterTree=await writeWorkingTree(gitRoot,gitDir,"progress",executionId,excludePaths);if(lastTreeSha!==void 0&&afterTree===lastTreeSha)return;let[nameStatusRaw,numstatRaw]=await Promise.all([git(gitRoot,["diff","--no-renames","--name-status","-z",baselineTree,afterTree]),git(gitRoot,["diff","--no-renames","--numstat","-z",baselineTree,afterTree])]),counts=parseNumstatZ(numstatRaw),entries=[];for(let{status,path:path6}of parseNameStatusZ(nameStatusRaw)){let changeType=nameStatusToChangeType(status),count=counts.get(path6);entries.push({pathBefore:changeType===FileChangeType.CREATE?"":path6,pathAfter:changeType===FileChangeType.DELETE?"":path6,changeType,linesAdded:count?.added??0,linesRemoved:count?.removed??0})}return{afterTree,entries}}async function restoreToBaseline(gitRoot,baselineTree,changes){for(let change of changes){let abs=(0,import_node_path20.join)(gitRoot,change.path);change.changeType===FileChangeType.CREATE?await(0,import_promises15.rm)(abs,{force:!0}):await writeBlobToDisk(gitRoot,baselineTree,change.path,abs)}}async function applyApprovedPaths(gitRoot,afterTree,approved){for(let change of approved){let abs=(0,import_node_path20.join)(gitRoot,change.path);change.changeType===FileChangeType.DELETE?await(0,import_promises15.rm)(abs,{force:!0}):await writeBlobToDisk(gitRoot,afterTree,change.path,abs)}}async function recomputeChangeSet(gitRoot,executionId){let baselineTree=await resolveRefTree(gitRoot,baselineRef(executionId)),afterTree=await resolveRefTree(gitRoot,captureRef(executionId));if(!baselineTree||!afterTree)return;let raw=await git(gitRoot,["diff","--no-renames","--name-status","-z",baselineTree,afterTree]),changes=[];for(let{status,path:path6}of parseNameStatusZ(raw)){let change=await buildCapturedChange(gitRoot,baselineTree,afterTree,status,path6);change&&changes.push(change)}return{baselineTree,afterTree,changes}}async function resolveRefTree(gitRoot,ref){try{return(await git(gitRoot,["rev-parse","--verify","--quiet",`${ref}^{tree}`])).trim()}catch{return}}function approvedRef(executionId){return`refs/stigmer/approved/${executionId}`}async function snapshotApproved(gitRoot,executionId,excludePaths=[]){let gitDir=await resolveGitDir(gitRoot),tree=await writeWorkingTree(gitRoot,gitDir,"approved",executionId,excludePaths),ref=approvedRef(executionId);return await pinTree(gitRoot,ref,tree,`stigmer approved ${executionId}`),{treeOid:tree,ref}}async function dropCaptureRefs(gitRoot,executionId){for(let ref of[baselineRef(executionId),captureRef(executionId),approvedRef(executionId)])try{await git(gitRoot,["update-ref","-d",ref])}catch{}}function parseNameStatusZ(raw){let parts=raw.split("\0"),entries=[];for(let i2=0;i2+1<parts.length;i2+=2){let status=parts[i2],path6=parts[i2+1];!status||!path6||entries.push({status:status[0],path:path6})}return entries}function parseNumstatZ(raw){let counts=new Map;for(let record3 of raw.split("\0")){if(!record3)continue;let tab=record3.indexOf(" "),tab2=record3.indexOf(" ",tab+1);if(tab<0||tab2<0)continue;let addedStr=record3.slice(0,tab),removedStr=record3.slice(tab+1,tab2),path6=record3.slice(tab2+1);if(!path6)continue;let added=addedStr==="-"?0:Number.parseInt(addedStr,10)||0,removed=removedStr==="-"?0:Number.parseInt(removedStr,10)||0;counts.set(path6,{added,removed})}return counts}function nameStatusToChangeType(status){return status==="A"?FileChangeType.CREATE:status==="D"?FileChangeType.DELETE:FileChangeType.MODIFY}async function readBlobBytes(gitRoot,tree,path6){try{return await gitBuffer(gitRoot,["cat-file","-p",`${tree}:${path6}`])}catch{return}}async function readSide(gitRoot,tree,path6){let bytes=await readBlobBytes(gitRoot,tree,path6);if(bytes===void 0)return;let sha2564=sha256Bytes(bytes);return bytesLookBinary(bytes)?{kind:"binary",sha256:sha2564}:{kind:"inline",text:bytes.toString("utf8"),sha256:sha2564}}async function writeBlobToDisk(gitRoot,tree,path6,abs){let buf=await gitBuffer(gitRoot,["cat-file","-p",`${tree}:${path6}`]);await(0,import_promises15.mkdir)((0,import_node_path20.dirname)(abs),{recursive:!0}),await(0,import_promises15.writeFile)(abs,buf)}async function buildCapturedChange(gitRoot,baselineTree,afterTree,status,path6){if(status==="A"){let after2=await readSide(gitRoot,afterTree,path6);return after2===void 0?void 0:{path:path6,changeType:FileChangeType.CREATE,after:after2}}if(status==="D"){let before2=await readSide(gitRoot,baselineTree,path6);return before2===void 0?void 0:{path:path6,changeType:FileChangeType.DELETE,before:before2}}let before=await readSide(gitRoot,baselineTree,path6),after=await readSide(gitRoot,afterTree,path6);if(!(before===void 0&&after===void 0))return{path:path6,changeType:FileChangeType.MODIFY,before:before??EMPTY_INLINE,after:after??EMPTY_INLINE}}var import_node_child_process3,import_promises15,import_node_path20,import_node_util2,execFileAsync,SNAPSHOT_IDENTITY_ENV,EMPTY_INLINE,init_git_substrate=__esm({"dist/shared/filereview/git-substrate.js"(){"use strict";import_node_child_process3=require("node:child_process"),import_promises15=require("node:fs/promises"),import_node_path20=require("node:path"),import_node_util2=require("node:util");init_enum_pb();init_file_change();init_digest();execFileAsync=(0,import_node_util2.promisify)(import_node_child_process3.execFile);SNAPSHOT_IDENTITY_ENV={GIT_AUTHOR_NAME:"stigmer-runner",GIT_AUTHOR_EMAIL:"runner@stigmer.local",GIT_COMMITTER_NAME:"stigmer-runner",GIT_COMMITTER_EMAIL:"runner@stigmer.local"};EMPTY_INLINE={kind:"inline",text:""}}});function casBlobKey(executionId,sha2564){return`artifacts/${executionId}/filereview/cas/blobs/${sha2564}`}function casManifestKey(executionId,changeSetId){let safe=changeSetId.replace(/[^A-Za-z0-9._-]/g,"_");return`artifacts/${executionId}/filereview/cas/${safe}.manifest.json`}async function snapshotCasChangeSet(opts){let{storage,executionId,changeSetId,captures}=opts,files2=[];for(let capture of captures){let file3=await buildCasCapturedFile(storage,executionId,capture);file3&&files2.push(file3)}files2.sort(compareByPath);let manifest={changeSetId,files:files2},canonical=canonicalManifestJson(manifest),manifestKey=casManifestKey(executionId,changeSetId);return await storage.upload(manifestKey,Buffer.from(canonical,"utf8"),"application/json"),{manifest,ref:{manifestDigest:sha256Hex2(canonical),artifactUri:manifestKey}}}function classifyCasChange(path6,beforeBuf,afterBuf){if(beforeBuf===null&&afterBuf===null||beforeBuf&&afterBuf&&beforeBuf.equals(afterBuf))return;let kind=beforeBuf===null?FileChangeKind.ADD:afterBuf===null?FileChangeKind.DELETE:FileChangeKind.MODIFY,isBinary2=beforeBuf!==null&&bytesLookBinary(beforeBuf)||afterBuf!==null&&bytesLookBinary(afterBuf);return{pathBefore:kind===FileChangeKind.ADD?"":path6,pathAfter:kind===FileChangeKind.DELETE?"":path6,kind,isBinary:isBinary2,lineCounts:isBinary2?void 0:countLineChanges(beforeBuf?.toString("utf8"),afterBuf?.toString("utf8"))}}async function buildCasCapturedFile(storage,executionId,capture){let{path:path6,before,after,captureClass}=capture,beforeBuf=before===null?null:Buffer.from(before),afterBuf=after===null?null:Buffer.from(after),classification=classifyCasChange(path6,beforeBuf,afterBuf);if(!classification)return;let beforeRef=beforeBuf?await storeBlob(storage,executionId,beforeBuf):void 0,afterRef=afterBuf?await storeBlob(storage,executionId,afterBuf):void 0;return{pathBefore:classification.pathBefore,pathAfter:classification.pathAfter,kind:classification.kind,captureClass,before:beforeRef,after:afterRef,diffComplete:!classification.isBinary,lineCounts:classification.lineCounts}}async function storeBlob(storage,executionId,bytes){let sha2564=sha256Bytes(bytes),storageKey=casBlobKey(executionId,sha2564);return await storage.exists(storageKey)||await storage.upload(storageKey,bytes,"application/octet-stream"),{sha256:sha2564,storageKey,sizeBytes:bytes.length,isBinary:bytesLookBinary(bytes)}}async function loadCasManifest(opts){let{readBlob,ref}=opts,bytes=await readBlob(ref.artifactUri),actual=sha256Bytes(bytes);if(actual!==ref.manifestDigest)throw new Error(`CAS manifest integrity check failed for '${ref.artifactUri}': expected ${ref.manifestDigest}, got ${actual}`);return JSON.parse(bytes.toString("utf8"))}async function applyCasApproved(opts){let{readBlob,workspaceRoot,files:files2}=opts;for(let file3 of files2){if(file3.kind===FileChangeKind.DELETE){await(0,import_promises16.rm)((0,import_node_path21.join)(workspaceRoot,file3.pathBefore),{force:!0});continue}file3.after&&await writeVerifiedBlob(readBlob,(0,import_node_path21.join)(workspaceRoot,file3.pathAfter),file3.after)}}async function restoreCasToBaseline(opts){let{readBlob,workspaceRoot,files:files2}=opts;for(let file3 of files2){if(file3.kind===FileChangeKind.ADD){await(0,import_promises16.rm)((0,import_node_path21.join)(workspaceRoot,file3.pathAfter),{force:!0});continue}file3.before&&await writeVerifiedBlob(readBlob,(0,import_node_path21.join)(workspaceRoot,file3.pathBefore),file3.before)}}function casBlobReader(storage){return storageKey=>storage.download(storageKey)}async function writeVerifiedBlob(readBlob,abs,ref){let bytes=await readBlob(ref.storageKey),actual=sha256Bytes(bytes);if(actual!==ref.sha256)throw new Error(`CAS blob integrity check failed for '${ref.storageKey}': expected ${ref.sha256}, got ${actual}`);await(0,import_promises16.mkdir)((0,import_node_path21.dirname)(abs),{recursive:!0}),await(0,import_promises16.writeFile)(abs,bytes)}function compareByPath(a,b){let ka=a.pathAfter||a.pathBefore,kb=b.pathAfter||b.pathBefore;return ka<kb?-1:ka>kb?1:a.pathBefore<b.pathBefore?-1:a.pathBefore>b.pathBefore?1:0}function serializeBlob(b){return b?{sha256:b.sha256,storageKey:b.storageKey,sizeBytes:b.sizeBytes,isBinary:b.isBinary}:null}function canonicalManifestJson(manifest){let files2=manifest.files.map(f3=>({pathBefore:f3.pathBefore,pathAfter:f3.pathAfter,kind:f3.kind,captureClass:f3.captureClass,before:serializeBlob(f3.before),after:serializeBlob(f3.after),diffComplete:f3.diffComplete}));return JSON.stringify({changeSetId:manifest.changeSetId,files:files2})}var import_promises16,import_node_path21,init_cas_substrate=__esm({"dist/shared/filereview/cas-substrate.js"(){"use strict";import_promises16=require("node:fs/promises"),import_node_path21=require("node:path");init_enum_pb();init_file_change();init_digest();init_line_counts()}});function deriveCaptureMode(primaryWorkspaceDir,gitWorkspace,hasArtifactStorage){return!!primaryWorkspaceDir&&(gitWorkspace||hasArtifactStorage)}async function captureBaselineToLedger(opts){let{status,gitRoot,executionId,changeSetId,harnessId,excludePaths}=opts;if(!(opts.gitWorkspace??!0)){let event2=buildBaselineCapturedEvent(changeSetContext(changeSetId,harnessId),casManifestSnapshotRef());return appendFileReviewEvents(status,executionId,[event2]),""}let baselineTree=await snapshotBaseline(gitRoot,executionId,excludePaths),event=buildBaselineCapturedEvent(changeSetContext(changeSetId,harnessId),gitTreeSnapshotRef(baselineTree,baselineRef(executionId)));return appendFileReviewEvents(status,executionId,[event]),baselineTree}async function captureCandidateToLedger(opts){let{status,gitRoot,executionId,changeSetId,baselineTree,harnessId,excludePaths,casCaptures,storage,unreviewablePaths,commandProvenance}=opts,gitWorkspace=opts.gitWorkspace??!0,unreviewableCaptureClass=opts.unreviewableCaptureClass??FileCaptureClass.GIT_IGNORED_CAPTURED,{afterTree,changes:gitChanges}=gitWorkspace?await captureChangeSet(gitRoot,executionId,baselineTree,excludePaths):{afterTree:"",changes:[]},casFiles=[],casRef;if(casCaptures&&casCaptures.length>0){if(!storage)throw new Error("captureCandidateToLedger: casCaptures requires an ArtifactStorage");let snap=await snapshotCasChangeSet({storage,executionId,changeSetId,captures:casCaptures});casFiles=snap.manifest.files,casFiles.length>0&&(casRef=snap.ref)}let unreviewable=unreviewablePaths??[],{safe:safeGitChanges,secret:secretGitChanges}=partitionGitChangesBySecret(gitChanges);if(gitChanges.length===0&&casFiles.length===0&&unreviewable.length===0)return gitChanges;let captured=[...safeGitChanges.map(c=>buildCapturedFileChange(toCapturedChangeInput(changeSetId,c))),...secretGitChanges.map(c=>buildCapturedFileChange(trackedSecretChangeInput(changeSetId,c))),...casFiles.map(f3=>buildCapturedFileChange(casToCapturedChangeInput(changeSetId,f3))),...unreviewable.map(p=>buildCapturedFileChange(unreviewableChangeInput(changeSetId,p,unreviewableCaptureClass)))],snapshot=gitWorkspace?casRef?hybridSnapshotRef(afterTree,captureRef(executionId),casRef):gitTreeSnapshotRef(afterTree,captureRef(executionId)):casManifestSnapshotRef(casRef),event=buildCandidateCapturedEvent(changeSetContext(changeSetId,harnessId),snapshot,captured,commandProvenance);return appendFileReviewEvents(status,executionId,[event]),gitChanges}async function applyCaptureDecisions(opts){let{status,gitRoot,executionId,changeSet,harnessId,excludePaths,readBlob}=opts,recomputed=opts.gitWorkspace??!0?await recomputeChangeSet(gitRoot,executionId):void 0,casRef=candidateCasRef(changeSet);if(casRef&&!readBlob)throw new Error(`applyCaptureDecisions: change set '${changeSet.id}' captured CAS files (manifest '${casRef.artifactUri}') but no blob reader was provided`);let manifest=casRef&&readBlob?await loadCasManifest({readBlob,ref:casRef}):void 0;if(!recomputed&&!manifest)return{isCaptureTurn:!1,approvedPaths:[],rejectedPaths:[],hadReject:!1,failed:!1};let actionByChangeId=resolveDecisions(changeSet),approved=[],rejected=[],approvedPaths=[],rejectedPaths=[],mismatches=[],hadReject=!1;for(let change of recomputed?.changes??[]){let protoChange=changeSet.changes.find(c=>c.id===`${changeSet.id}:${change.path}`),action=protoChange?actionByChangeId.get(protoChange.id)??FileDecisionAction.UNSPECIFIED:FileDecisionAction.UNSPECIFIED;if(action===FileDecisionAction.APPROVE){if(protoChange&&!digestMatches(change,protoChange)){mismatches.push(change.path);continue}approved.push(change),approvedPaths.push(change.path)}else action===FileDecisionAction.REJECT&&(hadReject=!0),rejected.push(change),rejectedPaths.push(change.path)}if(mismatches.length>0){let detail=`on-disk content diverged from the approved digest for: ${mismatches.join(", ")}`;return appendFileReviewEvents(status,executionId,[buildFailedEvent(changeSetContext(changeSet.id,harnessId),FileReviewFailureKind.HASH_MISMATCH,detail)]),{isCaptureTurn:!0,approvedPaths:[],rejectedPaths:[],hadReject,failed:!0,failureDetail:detail}}if(recomputed&&(await applyApprovedPaths(gitRoot,recomputed.afterTree,approved),await restoreToBaseline(gitRoot,recomputed.baselineTree,rejected)),manifest){let casApproved=[],casRejected=[];for(let file3 of manifest.files){let path6=file3.pathAfter||file3.pathBefore,action=actionByChangeId.get(`${changeSet.id}:${path6}`)??FileDecisionAction.UNSPECIFIED;action===FileDecisionAction.APPROVE?(casApproved.push(file3),approvedPaths.push(path6)):(action===FileDecisionAction.REJECT&&(hadReject=!0),casRejected.push(file3),rejectedPaths.push(path6))}await applyCasApproved({readBlob,workspaceRoot:gitRoot,files:casApproved}),await restoreCasToBaseline({readBlob,workspaceRoot:gitRoot,files:casRejected})}let approvedSnapshot;if(recomputed){let snap=await snapshotApproved(gitRoot,executionId,excludePaths);approvedSnapshot=gitTreeSnapshotRef(snap.treeOid,snap.ref)}else approvedSnapshot=casManifestSnapshotRef(candidateCasRef(changeSet));return appendFileReviewEvents(status,executionId,[buildReconciledEvent(changeSetContext(changeSet.id,harnessId),approvedSnapshot)]),recomputed&&await dropCaptureRefs(gitRoot,executionId),{isCaptureTurn:!0,approvedPaths,rejectedPaths,hadReject,failed:!1}}function resolveDecisions(changeSet){let byChangeId=new Map,changeSetDecision=changeSet.decisions.find(d=>d.scope===FileDecisionScope.CHANGE_SET);if(changeSetDecision)for(let change of changeSet.changes)byChangeId.set(change.id,changeSetDecision.action);for(let decision of changeSet.decisions)decision.scope===FileDecisionScope.FILE&&decision.fileChangeId&&byChangeId.set(decision.fileChangeId,decision.action);return byChangeId}function digestMatches(gitChange,protoChange){return!(gitChange.changeType!==FileChangeType.DELETE&&(!gitChange.after||contentSha256(gitChange.after)!==protoChange.afterSha256)||gitChange.changeType!==FileChangeType.CREATE&&(!gitChange.before||contentSha256(gitChange.before)!==protoChange.beforeSha256))}function changeSetContext(changeSetId,harnessId){return{changeSetId,turnId:changeSetId,harnessId,timestamp:utcTimestamp()}}function gitTreeSnapshotRef(treeOid,ref){return create(SnapshotRefSchema,{kind:SnapshotKind.GIT_TREE_REF,git:create(GitTreeRefSchema,{treeOid,ref})})}function hybridSnapshotRef(treeOid,ref,cas){return create(SnapshotRefSchema,{kind:SnapshotKind.HYBRID,git:create(GitTreeRefSchema,{treeOid,ref}),cas:create(CasManifestRefSchema,{manifestDigest:cas.manifestDigest,artifactUri:cas.artifactUri})})}function casManifestSnapshotRef(cas){return create(SnapshotRefSchema,{kind:SnapshotKind.CAS_MANIFEST,cas:cas?create(CasManifestRefSchema,{manifestDigest:cas.manifestDigest,artifactUri:cas.artifactUri}):void 0})}function candidateCasRef(changeSet){let cas=changeSet.candidateSnapshot?.cas;return cas?{manifestDigest:cas.manifestDigest,artifactUri:cas.artifactUri}:void 0}function casToCapturedChangeInput(changeSetId,file3){return{id:`${changeSetId}:${file3.pathAfter||file3.pathBefore}`,pathBefore:file3.pathBefore,pathAfter:file3.pathAfter,kind:file3.kind,captureClass:file3.captureClass,lineCounts:file3.lineCounts,before:file3.before?{kind:"ref",sha256:file3.before.sha256,storageKey:file3.before.storageKey,sizeBytes:file3.before.sizeBytes,isBinary:file3.before.isBinary}:void 0,after:file3.after?{kind:"ref",sha256:file3.after.sha256,storageKey:file3.after.storageKey,sizeBytes:file3.after.sizeBytes,isBinary:file3.after.isBinary}:void 0,diffComplete:file3.diffComplete}}function secretWithheldChangeInput(id,pathBefore,pathAfter,kind,captureClass){return{id,pathBefore,pathAfter,kind,captureClass,diffComplete:!1,blockedReason:FileReviewBlockReason.SECRET_WITHHELD}}function unreviewableChangeInput(changeSetId,path6,captureClass){return secretWithheldChangeInput(`${changeSetId}:${path6}`,path6,path6,FileChangeKind.MODIFY,captureClass)}function trackedSecretChangeInput(changeSetId,change){let isCreate=change.changeType===FileChangeType.CREATE,isDelete=change.changeType===FileChangeType.DELETE,pathBefore=isCreate?"":change.path,pathAfter=isDelete?"":change.path;return secretWithheldChangeInput(`${changeSetId}:${pathAfter||pathBefore}`,pathBefore,pathAfter,toFileChangeKind(change.changeType),FileCaptureClass.GIT_TRACKED)}function partitionGitChangesBySecret(changes){let safe=[],secret=[];for(let change of changes)isSecretLikePath(change.path)?secret.push(change):safe.push(change);return{safe,secret}}function toFileChangeKind(changeType){switch(changeType){case FileChangeType.CREATE:return FileChangeKind.ADD;case FileChangeType.DELETE:return FileChangeKind.DELETE;default:return FileChangeKind.MODIFY}}function toCapturedChangeInput(changeSetId,change){let isCreate=change.changeType===FileChangeType.CREATE,isDelete=change.changeType===FileChangeType.DELETE,pathBefore=isCreate?"":change.path,pathAfter=isDelete?"":change.path,binary2=change.before?.kind==="binary"||change.after?.kind==="binary";return{id:`${changeSetId}:${pathAfter||pathBefore}`,pathBefore,pathAfter,kind:toFileChangeKind(change.changeType),captureClass:FileCaptureClass.GIT_TRACKED,before:change.before,after:change.after,diffComplete:!binary2}}var init_capture=__esm({"dist/shared/filereview/capture.js"(){"use strict";init_esm4();init_enum_pb();init_filereview_pb();init_status2();init_events();init_git_substrate();init_cas_substrate();init_secret_paths()}});function readMinIntervalMs(){let raw=process.env.STIGMER_PROGRESS_CAPTURE_MIN_INTERVAL_MS;if(!raw)return 2e3;let n3=Number.parseInt(raw,10);return Number.isFinite(n3)&&n3>=0?n3:2e3}function shouldCaptureProgress(lastAtMs,nowMs,minIntervalMs=PROGRESS_CAPTURE_MIN_INTERVAL_MS){return nowMs-lastAtMs>=minIntervalMs}function buildFileChangeProgress(delta,changeSetId){let totalAdded=0,totalRemoved=0,entries=[];for(let entry of delta.entries){let secret=isSecretLikePath(entry.pathAfter||entry.pathBefore),linesAdded=secret?0:entry.linesAdded,linesRemoved=secret?0:entry.linesRemoved;totalAdded+=linesAdded,totalRemoved+=linesRemoved,entries.length<PROGRESS_MAX_ENTRIES&&entries.push(create(FileChangeProgressEntrySchema,{pathBefore:entry.pathBefore,pathAfter:entry.pathAfter,kind:entry.kind,linesAdded,linesRemoved}))}return create(FileChangeProgressSchema,{changeSetId,filesChanged:delta.totalFilesChanged??delta.entries.length,linesAdded:totalAdded,linesRemoved:totalRemoved,entries,capturedAt:utcTimestamp()})}function newProgressCaptureState(){return{lastAtMs:0}}async function captureFileChangeProgress(opts){let now=opts.nowMs??Date.now();if(!shouldCaptureProgress(opts.state.lastAtMs,now))return;opts.state.lastAtMs=now;let{delta,changed}=await opts.substrate.capture();changed&&(opts.status.fileChangeProgress=buildFileChangeProgress(delta,opts.changeSetId))}function gitEntryToProgressEntry(e){return{pathBefore:e.pathBefore,pathAfter:e.pathAfter,kind:toFileChangeKind(e.changeType),linesAdded:e.linesAdded,linesRemoved:e.linesRemoved}}function createGitProgressSubstrate(opts){let lastTreeSha,cachedFull={entries:[]};return{async capture(){let gitDelta=await captureProgressDelta(opts.workspaceRoot,opts.executionId,opts.baselineTree,opts.excludePaths,lastTreeSha);return gitDelta===void 0?{delta:cachedFull,changed:!1}:(lastTreeSha=gitDelta.afterTree,cachedFull={entries:gitDelta.entries.map(gitEntryToProgressEntry)},{delta:cachedFull,changed:!0})}}}function createHybridProgressSubstrate(git2,cas){return{async capture(){let[g,c]=await Promise.all([git2.capture(),cas.capture()]);return{delta:{entries:[...g.delta.entries,...c.delta.entries],totalFilesChanged:(g.delta.totalFilesChanged??g.delta.entries.length)+(c.delta.totalFilesChanged??c.delta.entries.length)},changed:g.changed||c.changed}}}}var PROGRESS_MAX_ENTRIES,PROGRESS_CAPTURE_MIN_INTERVAL_MS,init_progress=__esm({"dist/shared/filereview/progress.js"(){"use strict";init_esm4();init_filereview_pb();init_status2();init_capture();init_git_substrate();init_secret_paths();PROGRESS_MAX_ENTRIES=200,PROGRESS_CAPTURE_MIN_INTERVAL_MS=readMinIntervalMs()}});function createCasProgressSubstrate(opts){let maxEntries=opts.maxEntries??PROGRESS_MAX_ENTRIES,cachedFull={entries:[],totalFilesChanged:0},lastSignature;return{async capture(){let snapshot=await opts.read(),{capturablePaths}=partitionIgnoredPathsBySecret(snapshot.before.keys(),snapshot.blockedSecretPaths),prefix=[...capturablePaths].sort().slice(0,maxEntries),entries=[],sigParts=[`${capturablePaths.length}`];for(let relPath of prefix){let abs=(0,import_node_path22.join)(opts.workspaceRoot,relPath),st=await statOrNull(abs);sigParts.push(`${relPath}\0${st?`${st.size}:${st.mtimeMs}`:"\u2205"}`);let beforeBytes=snapshot.before.get(relPath)??null,beforeBuf=beforeBytes===null?null:Buffer.from(beforeBytes);if(st&&st.size>LINE_COUNT_MAX_BYTES){let kind=beforeBuf===null?FileChangeKind.ADD:FileChangeKind.MODIFY;entries.push({pathBefore:kind===FileChangeKind.ADD?"":relPath,pathAfter:relPath,kind,linesAdded:0,linesRemoved:0});continue}let afterBytes=st?await readFileOrNull(abs):null,afterBuf=afterBytes===null?null:Buffer.from(afterBytes),cls=classifyCasChange(relPath,beforeBuf,afterBuf);cls&&entries.push({pathBefore:cls.pathBefore,pathAfter:cls.pathAfter,kind:cls.kind,linesAdded:cls.lineCounts?.linesAdded??0,linesRemoved:cls.lineCounts?.linesRemoved??0})}let prefixNoOps=prefix.length-entries.length,totalFilesChanged=capturablePaths.length-prefixNoOps,signature=sigParts.join("|");return signature===lastSignature?{delta:cachedFull,changed:!1}:(lastSignature=signature,cachedFull={entries,totalFilesChanged},{delta:cachedFull,changed:!0})}}}async function statOrNull(abs){try{let s=await(0,import_promises17.stat)(abs);return{size:s.size,mtimeMs:s.mtimeMs}}catch{return null}}async function readFileOrNull(abs){try{return await(0,import_promises17.readFile)(abs)}catch{return null}}var import_promises17,import_node_path22,init_cas_progress=__esm({"dist/shared/filereview/cas-progress.js"(){"use strict";import_promises17=require("node:fs/promises"),import_node_path22=require("node:path");init_enum_pb();init_cas_substrate();init_line_counts();init_progress();init_secret_paths()}});function captureBaselineToLedger2(opts){return captureBaselineToLedger({...opts,harnessId:HARNESS_ID,excludePaths:CURSOR_RUNNER_OWNED_PATHS})}async function captureTurnToLedger(opts){let{status,gitRoot,executionId,changeSetId,baselineTree,messages,deniedTokens,hitlDir,storage,priorSubAgentToolCallIds,commandProvenance}=opts,gitWorkspace=opts.gitWorkspace??!0,casCaptureClass=gitWorkspace?FileCaptureClass.GIT_IGNORED_CAPTURED:FileCaptureClass.NON_GIT_CAS,{casCaptures,unreviewablePaths}=await buildCasTurnCaptures(gitRoot,hitlDir,storage,casCaptureClass),changes=await captureCandidateToLedger({status,gitRoot,executionId,changeSetId,baselineTree,harnessId:HARNESS_ID,excludePaths:CURSOR_RUNNER_OWNED_PATHS,casCaptures,storage,unreviewablePaths,unreviewableCaptureClass:casCaptureClass,gitWorkspace,commandProvenance});if(hasCandidateCaptured(status,changeSetId)){stampFlowedFileEditRows(messages,deniedTokens,changeSetId);for(let sa of status.subAgentExecutions)stampFlowedFileEditRows(sa.messages,deniedTokens,changeSetId,priorSubAgentToolCallIds)}return changes}function buildCursorProgressSubstrate(opts){let{captureMode,gitWorkspace,workspaceRoot,baselineTree,executionId,hitlDir,storage}=opts;if(!captureMode||!workspaceRoot)return;let casReader=hitlDir&&storage?createSidecarTouchedReader(hitlDir):void 0;if(gitWorkspace){if(!baselineTree)return;let git2=createGitProgressSubstrate({workspaceRoot,executionId,baselineTree,excludePaths:CURSOR_RUNNER_OWNED_PATHS});return casReader?createHybridProgressSubstrate(git2,createCasProgressSubstrate({workspaceRoot,read:casReader})):git2}return casReader?createCasProgressSubstrate({workspaceRoot,read:casReader}):void 0}function createSidecarTouchedReader(hitlDir){return async()=>{let{captured,secretPaths}=await readCasObservations(hitlDir),before=new Map;for(let c of captured)before.set(c.path,c.before);return{before,blockedSecretPaths:new Set(secretPaths)}}}async function buildCasTurnCaptures(gitRoot,hitlDir,storage,captureClass){if(!hitlDir||!storage)return{casCaptures:[],unreviewablePaths:[]};let{captured,secretPaths}=await readCasObservations(hitlDir),beforeByPath=new Map(captured.map(c=>[c.path,c.before])),{capturablePaths,unreviewablePaths}=partitionIgnoredPathsBySecret(beforeByPath.keys(),new Set(secretPaths)),casCaptures=[];for(let relPath of capturablePaths){let after=await readFileOrNull2((0,import_node_path23.join)(gitRoot,relPath));casCaptures.push({path:relPath,before:beforeByPath.get(relPath)??null,after,captureClass})}return{casCaptures,unreviewablePaths:[...unreviewablePaths]}}async function readFileOrNull2(absolutePath){try{return await(0,import_promises18.readFile)(absolutePath)}catch{return null}}function applyCaptureDecisions2(opts){let{storage,...rest}=opts;return applyCaptureDecisions({...rest,harnessId:HARNESS_ID,excludePaths:CURSOR_RUNNER_OWNED_PATHS,storage,readBlob:storage?casBlobReader(storage):void 0})}function stampFlowedFileEditRows(messages,deniedTokens,changeSetId,skipToolCallIds){for(let msg of messages)for(let tc of msg.toolCalls){if(tc.fileChangeSetId||skipToolCallIds?.has(tc.id)||isToolCallRowHidden(tc))continue;let category=approvalCategory(tc.name);if(category!=="write"&&category!=="delete")continue;let args=tc.args??{},id=toolIdentity(tc.name,tc.mcpServerSlug,args),token=primaryToken(id.key,id.salient,contentDigest(args));deniedTokens.has(token)||stampFileEditRow(tc,changeSetId)}}var import_promises18,import_node_path23,HARNESS_ID,CURSOR_RUNNER_OWNED_PATHS,init_capture_flow=__esm({"dist/activities/execute-cursor/capture-flow.js"(){"use strict";import_promises18=require("node:fs/promises"),import_node_path23=require("node:path");init_enum_pb();init_approval_policy2();init_approval_state();init_cas_observations();init_file_tools();init_tool_row();init_capture();init_progress();init_cas_progress();init_events();init_secret_paths();init_cas_substrate();init_capture();HARNESS_ID="cursor",CURSOR_RUNNER_OWNED_PATHS=[".cursor/hooks.json",".cursor/rules/stigmer-tool-approval.mdc"]}});function qualifyTurnCommandProvenance(inputs){let{turnToolCalls,messages,isExecutedCommand,resolveDirectConsent,globalBypass}=inputs,consentIds=new Set,authorizedByAutoApproveAll=!1,executedCommandCount=0;for(let tc of turnToolCalls){if(isToolCallRowHidden(tc))continue;let kind=classifyTool(tc.name,tc.mcpServerSlug);if(NON_MUTATING_KINDS.has(kind))continue;if(kind!==ToolKind.SHELL)return;if(!isExecutedCommand(tc))continue;executedCommandCount++;let consentId=resolveDirectConsent(tc);if(consentId){consentIds.add(consentId);continue}let leaseConsentId=findLeaseConsentId(messages,tc.name);if(leaseConsentId){consentIds.add(leaseConsentId);continue}if(globalBypass){authorizedByAutoApproveAll=!0;continue}return}if(executedCommandCount!==0)return create(TurnCommandProvenanceSchema,{consentToolCallIds:[...consentIds],authorizedByAutoApproveAll})}function findLeaseConsentId(messages,toolName){let category=toolApprovalCategory(toolName);if(category){for(let msg of messages)for(let tc of msg.toolCalls)if(tc.approvalAction===ApprovalAction.APPROVE_ALL&&toolApprovalCategory(tc.name)===category)return tc.id}}var NON_MUTATING_KINDS,init_command_provenance=__esm({"dist/shared/filereview/command-provenance.js"(){"use strict";init_esm4();init_filereview_pb();init_enum_pb();init_tool_kind();init_tool_row();NON_MUTATING_KINDS=new Set([ToolKind.FILE_READ,ToolKind.SEARCH,ToolKind.LIST,ToolKind.FETCH,ToolKind.WEB_SEARCH,ToolKind.THINK,ToolKind.TODO])}});function deriveTurnCommandProvenance(inputs){let{messages,turnStartIndex,deniedTokens,grantTokenToConsentId,globalBypass}=inputs,turnToolCalls=messages.slice(turnStartIndex).flatMap(m=>m.toolCalls);return qualifyTurnCommandProvenance({turnToolCalls,messages,isExecutedCommand:tc=>!deniedTokens.has(toolCallIdentityToken(tc)),resolveDirectConsent:tc=>grantTokenToConsentId.get(toolCallIdentityToken(tc)),globalBypass})}var init_command_provenance2=__esm({"dist/activities/execute-cursor/command-provenance.js"(){"use strict";init_command_provenance();init_message_translator()}});async function runTurnBoundary(opts){let{status,executionId,changeSetId,hitlDir,captureMode,baselineTree,primaryWorkspaceDir,gitWorkspace,turnStartMessageIndex,approvalGrants,globalBypass,seededSubAgents,artifactStorage,mergedPolicies,denialCancelSettled,foreignGatingHooks}=opts;denialCancelSettled&&await Promise.race([denialCancelSettled,new Promise(resolve7=>{setTimeout(resolve7,FIRST_DENIAL_CANCEL_TIMEOUT_MS).unref()})]);let deniedLedger=await readDenialLedger(hitlDir??""),approvalLedger=approvalDenials(deniedLedger),capturedChangeCount=0;if(captureMode&&baselineTree!==void 0&&primaryWorkspaceDir){let deniedTokens=new Set(deniedLedger.map(e=>e.token)),commandProvenance=deriveTurnCommandProvenance({messages:status.messages,turnStartIndex:turnStartMessageIndex,deniedTokens,grantTokenToConsentId:new Map((approvalGrants??[]).map(g=>[primaryToken(g.key,g.salient,g.contentDigest),g.sourceToolCallId])),globalBypass});commandProvenance&&console.log(`ExecuteCursor capture: turn qualifies for approved-command auto-keep (consent rows: ${commandProvenance.consentToolCallIds.join(",")||"(auto_approve_all)"}); attaching provenance to candidate (execution=${executionId})`),capturedChangeCount=(await captureTurnToLedger({status,gitRoot:primaryWorkspaceDir,executionId,changeSetId,baselineTree,messages:status.messages,deniedTokens,commandProvenance,priorSubAgentToolCallIds:collectSubAgentToolCallIds(seededSubAgents),hitlDir,storage:artifactStorage,gitWorkspace})).length,capturedChangeCount>0&&console.log(`ExecuteCursor capture: ${capturedChangeCount} file change(s) authored to the file_review ledger (change_set=${changeSetId}), working tree left applied for review (execution=${executionId})`)}let gateWorkspaceBackend=new LocalWorkspaceBackend(primaryWorkspaceDir),deniedToolCalls=await reconcileDeniedToolCalls(status.messages,approvalLedger,mergedPolicies,gateWorkspaceBackend),synthesizedGateCount=deniedToolCalls.filter(tc=>tc.id.startsWith("approval:")).length;if(synthesizedGateCount>0&&console.warn(`ExecuteCursor reconcile synthesized ${synthesizedGateCount} placeholder gate(s) with no correlated stream call (execution=${executionId}); possible hook/stream identity drift \u2014 gate(s) will lack a diff`),deniedToolCalls.length>0){let redactedNarration=clearProvisionalPostDenialNarration(status.messages,deniedToolCalls);redactedNarration.length>0&&console.log(`ExecuteCursor redacted ${redactedNarration.length} provisional post-denial narration message(s) before pausing for approval`)}let unattributedHookBlocks=detectUnattributedHookBlocks(status.messages,turnStartMessageIndex,deniedLedger,primaryWorkspaceDir),waiting=deniedToolCalls.length>0||capturedChangeCount>0;if(unattributedHookBlocks.length>0){let culprits=(foreignGatingHooks?.length??0)>0?` \u2014 likely foreign workspace hook(s): ${foreignGatingHooks.join(", ")}`:"";console.warn(`ExecuteCursor turn boundary: ${unattributedHookBlocks.length} tool call(s) blocked by a hook with NO matching denial-ledger entry [${unattributedHookBlocks.map(b=>b.toolName).join(", ")}]${culprits} (execution=${executionId})${waiting?" \u2014 turn pauses anyway; not failing":""}`)}return deniedLedger.some(e=>denialKindOf(e)==="fail-closed")&&console.warn(`ExecuteCursor turn boundary: fail-closed denial(s) in the ledger \u2014 the approval state file was missing during this turn and gated tools were denied (execution=${executionId})`),{waiting,capturedChangeCount,deniedToolCallCount:deniedToolCalls.length,unattributedHookBlocks}}var FIRST_DENIAL_CANCEL_TIMEOUT_MS,init_turn_boundary=__esm({"dist/activities/execute-cursor/turn-boundary.js"(){"use strict";init_tool_row();init_local_backend();init_approval_state();init_command_provenance2();init_capture_flow();init_message_translator();FIRST_DENIAL_CANCEL_TIMEOUT_MS=5e3}});function shouldPersistStreamingStatus(signals,scheduler,eventCount,nowMs){return signals.deltaEnricherDirty||signals.todosDirty||signals.contentDirty||scheduler.shouldSendUpdate(eventCount,nowMs)}var init_persist_decision=__esm({"dist/activities/execute-cursor/persist-decision.js"(){"use strict"}});function costCapExceeded(maxCostUsd,estimatedCostUsd){return maxCostUsd>0&&estimatedCostUsd>=maxCostUsd}function formatCostLimitError(maxCostUsd,estimatedCostUsd){return`${COST_LIMIT_ERROR_PREFIX} for this message (~$${estimatedCostUsd.toFixed(4)} of the $${maxCostUsd.toFixed(2)} budget). Send another message to continue.`}var COST_LIMIT_ERROR_PREFIX,COST_LIMIT_USER_COPY,init_cost_guard=__esm({"dist/activities/execute-cursor/cost-guard.js"(){"use strict";COST_LIMIT_ERROR_PREFIX="Agent reached the cost limit";COST_LIMIT_USER_COPY="The agent reached the cost limit for this message. Work completed so far has been saved. Send another message to continue where the agent left off."}});function newTurnStreamState(){return{pauseDetected:!1,stallDetected:!1,stallError:void 0,firstDenialDetected:!1,denialLedgerDirty:!1,denialCancelSettled:void 0,platformStopSignaled:!1,costCapExceeded:!1,streamErrorMessage:void 0,lastToolName:void 0,eventCount:0,firstTurnAttributionLogged:!1,stallWatchdog:void 0}}function makeCursorTurnOnDelta(deps){let{usageAccumulator,deltaEnricher,heartbeat:heartbeat2,promptEstimatedTokens,executionId,state,maxCostUsd}=deps;return({update})=>{if(state.stallWatchdog?.recordActivity(),update.type==="turn-ended"&&update.usage&&(usageAccumulator.addTurn(update.usage),!state.costCapExceeded&&costCapExceeded(maxCostUsd,usageAccumulator.snapshot().estimatedCostUsd)&&(state.costCapExceeded=!0,console.warn(`ExecuteCursor cost cap exceeded: execution=${executionId}, estimatedCostUsd=${usageAccumulator.snapshot().estimatedCostUsd.toFixed(4)}, maxCostUsd=${maxCostUsd.toFixed(2)}`)),!state.firstTurnAttributionLogged)){state.firstTurnAttributionLogged=!0;let sdkInputTokens=update.usage.inputTokens??0,cursorOverhead=Math.max(0,sdkInputTokens-promptEstimatedTokens);console.log(`ExecuteCursor context attribution (first turn): execution=${executionId}, sdkInputTokens=${sdkInputTokens}, stigmerPreamble=${promptEstimatedTokens}, cursorOverhead=${cursorOverhead} (estimated)`)}deltaEnricher.processDelta(update);try{heartbeat2()}catch(hbErr){if(hbErr instanceof import_activity.CancelledFailure){state.pauseDetected=!0;return}throw hbErr}}}async function consumeCursorTurnStream(run,deps){let{status,accumulator,todoTracker,deltaEnricher,eventRecorder,scheduler,usageAccumulator,progressSubstrate,progressState,changeSetId,hitlDir,executionId,stallTimeoutMs,persist,heartbeat:heartbeat2,isCancelled,state}=deps;state.stallWatchdog=startStallWatchdog(stallTimeoutMs,idleMs=>{state.stallDetected=!0,state.stallError=new StallTimeoutError(idleMs,state.lastToolName?`last tool: ${state.lastToolName}`:void 0),console.warn(`ExecuteCursor stall detected: execution=${executionId}, idleMs=${idleMs}, lastTool=${state.lastToolName??"none"}`),run.supports?.("cancel")&&run.cancel().catch(cancelErr=>{console.warn(`ExecuteCursor run.cancel() after stall failed (non-fatal): execution=${executionId}, error=${cancelErr instanceof Error?cancelErr.message:cancelErr}`)})});try{for await(let event of run.stream()){if(state.pauseDetected||isCancelled()){state.pauseDetected=!0;break}if(state.stallDetected)break;if(state.costCapExceeded){console.log(`ExecuteCursor stopping stream at cost cap: execution=${executionId}`),run.supports?.("cancel")&&run.cancel().catch(cancelErr=>{console.warn(`ExecuteCursor run.cancel() after cost cap failed (non-fatal): execution=${executionId}, error=${cancelErr instanceof Error?cancelErr.message:cancelErr}`)});break}if(state.stallWatchdog.recordActivity(),event.type==="tool_call"&&typeof event.name=="string"&&(state.lastToolName=event.name),eventRecorder?.record(event,state.eventCount),accumulator.processEvent(event),todoTracker.processEvent(event),event.type==="tool_call"&&event.name==="task"&&accumulator.trackSubAgentExecution(event),!state.firstDenialDetected&&hitlDir&&(state.denialLedgerDirty||event.type==="tool_call")){state.denialLedgerDirty=!1;let denials=approvalDenials(await readDenialLedger(hitlDir));if(denials.length>0){state.firstDenialDetected=!0,console.log(`ExecuteCursor first denial detected (${denials.length} ledger entr${denials.length===1?"y":"ies"}); stopping turn to pause cleanly for approval: execution=${executionId}`),run.supports?.("cancel")&&(state.denialCancelSettled=run.cancel().then(()=>{},cancelErr=>{console.warn(`ExecuteCursor run.cancel() after first denial failed (non-fatal): execution=${executionId}, error=${cancelErr instanceof Error?cancelErr.message:cancelErr}`)}));break}}if(deltaEnricher.applyEnrichments(status.messages),state.eventCount++,event.type==="status"){console.log(`ExecuteCursor stream status: execution=${executionId}, status=${JSON.stringify(event)}`);let statusEvent=event;statusEvent.status==="ERROR"&&statusEvent.message&&(state.streamErrorMessage=statusEvent.message)}let shouldPersist=shouldPersistStreamingStatus({deltaEnricherDirty:deltaEnricher.isDirty,todosDirty:todoTracker.isDirty,contentDirty:accumulator.isDirty},scheduler,state.eventCount);if(usageAccumulator.hasTurns&&(status.streamingUsage=create(StreamingUsageSummarySchema,usageAccumulator.snapshot())),shouldPersist){status.subAgentExecutions=accumulator.subAgentExecutions,progressSubstrate&&await captureFileChangeProgress({status,changeSetId,substrate:progressSubstrate,state:progressState});let signal=await persist(status);deltaEnricher.markPersisted(),todoTracker.markPersisted(),accumulator.markPersisted(),scheduler.markUpdateSent(state.eventCount),heartbeat2(),signal===ExecutionControlSignal.STOP&&(state.platformStopSignaled=!0,console.warn(`ExecuteCursor platform stop signal received: execution=${executionId}`))}if(state.platformStopSignaled){console.log(`ExecuteCursor stopping stream due to platform stop signal: execution=${executionId}`);break}}}catch(streamErr){if(!state.stallDetected&&!state.firstDenialDetected&&!state.costCapExceeded)throw streamErr;console.warn(`ExecuteCursor stream ended via cancel: execution=${executionId}, stall=${state.stallDetected}, firstDenial=${state.firstDenialDetected}, costCap=${state.costCapExceeded}`)}finally{state.stallWatchdog.stop()}return state.stallDetected?"stalled":state.platformStopSignaled?"platform-stop":state.costCapExceeded?"cost-cap":state.firstDenialDetected?"first-denial":state.pauseDetected||isCancelled()?"paused":"completed"}var import_activity,init_turn_stream=__esm({"dist/activities/execute-cursor/turn-stream.js"(){"use strict";init_esm4();import_activity=__toESM(require_lib4(),1);init_enum_pb();init_usage_pb();init_stall_watchdog();init_persist_decision();init_approval_state();init_progress();init_cost_guard()}});function getRunnerHitlMasterSecret(){if(cached3)return cached3;let fromEnv=process.env[ENV_VAR];return fromEnv&&fromEnv.length>0?(cached3=Buffer.from(fromEnv,"utf-8"),cached3):(cached3=(0,import_node_crypto13.randomBytes)(32),warned||(warned=!0,console.warn(`[hitl-gateway] ${ENV_VAR} is not set; using a per-process random fingerprint secret. Fingerprints are stable within this process only \u2014 set ${ENV_VAR} for a key stable across runner restarts/replicas (required in Phase 7).`)),cached3)}var import_node_crypto13,ENV_VAR,cached3,warned,init_fingerprint_secret=__esm({"dist/shared/fingerprint-secret.js"(){"use strict";import_node_crypto13=require("node:crypto"),ENV_VAR="STIGMER_RUNNER_HITL_SECRET",warned=!1}});var SourceType,WorkspaceProvisionError,init_types17=__esm({"dist/shared/workspace/types.js"(){"use strict";(function(SourceType2){SourceType2.GIT_REPO="git_repo",SourceType2.LOCAL_PATH="local_path",SourceType2.EMPTY="empty"})(SourceType||(SourceType={}));WorkspaceProvisionError=class extends Error{sourceType;cause;transient;constructor(sourceType,message,options){super(`[${sourceType}] ${message}`),this.name="WorkspaceProvisionError",this.sourceType=sourceType,this.cause=options?.cause,this.transient=options?.transient??!1}}}});function provisionEmpty(backend){return{rootDir:backend.rootDir,sourceType:SourceType.EMPTY,consumedKeys:[],workspaceDescription:"Your workspace is empty. Create files and directories as needed for your task.",entryName:""}}var init_empty=__esm({"dist/shared/workspace/sources/empty.js"(){"use strict";init_types17()}});function provisionLocalPath(options){let{path:path6,isLocalMode,targetSubdir,backendRootDir}=options;if(!isLocalMode)throw new WorkspaceProvisionError(SourceType.LOCAL_PATH,"LocalPathSource is only supported in local mode. Use git_repo for cloud deployments.");if(!(0,import_node_path24.isAbsolute)(path6))throw new WorkspaceProvisionError(SourceType.LOCAL_PATH,`Path must be absolute, got relative path: '${path6}'`);if(!(0,import_node_fs6.existsSync)(path6))throw new WorkspaceProvisionError(SourceType.LOCAL_PATH,`Path does not exist: '${path6}'`);if(!(0,import_node_fs6.statSync)(path6).isDirectory())throw new WorkspaceProvisionError(SourceType.LOCAL_PATH,`Path is not a directory: '${path6}'`);return targetSubdir&&backendRootDir&&createEntrySymlink(backendRootDir,targetSubdir,path6),{rootDir:path6,sourceType:SourceType.LOCAL_PATH,consumedKeys:[],workspaceDescription:`Your workspace is the user's project directory: ${path6}
2059
2059
  IMPORTANT: You are operating directly on the user's files. Changes are immediate and persistent.
2060
2060
  Use git to track and verify your changes before finalizing.`,entryName:""}}function createEntrySymlink(backendRootDir,targetSubdir,path6){let linkPath=(0,import_node_path24.join)(backendRootDir,targetSubdir);try{let existing=(0,import_node_fs6.readlinkSync)(linkPath);if((0,import_node_fs7.realpathSync)(existing)===(0,import_node_fs7.realpathSync)(path6))return;(0,import_node_fs6.unlinkSync)(linkPath)}catch{}(0,import_node_fs6.mkdirSync)(backendRootDir,{recursive:!0}),(0,import_node_fs6.symlinkSync)(path6,linkPath)}var import_node_fs6,import_node_path24,import_node_fs7,init_local_path=__esm({"dist/shared/workspace/sources/local-path.js"(){"use strict";import_node_fs6=require("node:fs"),import_node_path24=require("node:path"),import_node_fs7=require("node:fs");init_types17()}});async function provisionGit(options){let{url:url3,branch,backend,envVars,isLocalMode,targetSubdir,configureCredentials}=options,cloneDir=targetSubdir?(0,import_node_path25.join)(backend.rootDir,targetSubdir):backend.rootDir;if(await backend.exists(targetSubdir?(0,import_node_path25.join)(targetSubdir,".git"):".git"))return reuseExistingRepo(cloneDir,url3,backend,envVars,configureCredentials,targetSubdir);let githubToken=envVars.GITHUB_TOKEN,consumedKeys=[],cloneUrl=url3;githubToken&&url3.includes(GITHUB_HOST)&&(cloneUrl=injectToken(url3,githubToken),consumedKeys.push("GITHUB_TOKEN"));try{await cloneInPlace(backend,cloneDir,cloneUrl,branch)}catch(err){let message=err instanceof Error?err.message:String(err),sanitized=githubToken?message.replaceAll(githubToken,"***"):message;throw new WorkspaceProvisionError(SourceType.GIT_REPO,`Git clone failed: ${sanitized}`,{cause:err instanceof Error?err:void 0,transient:!0})}let metadata=await extractGitMetadata(cloneDir,url3,backend,targetSubdir);return configureCredentials&&githubToken&&url3.includes(GITHUB_HOST)&&await configureGitCredentialStore(backend,cloneDir,url3,githubToken)&&(metadata={...metadata,gitCredentialsConfigured:!0}),await addGitExcludes(backend,targetSubdir),{rootDir:cloneDir,sourceType:SourceType.GIT_REPO,consumedKeys,workspaceDescription:`Your workspace is a git clone of ${url3}`+(metadata.branch?` (branch: ${metadata.branch})`:"")+`.
2061
2061
  Base commit: ${metadata.baseCommit}`,gitMetadata:metadata,entryName:""}}async function reuseExistingRepo(cloneDir,url3,backend,envVars,configureCredentials,targetSubdir){let metadata=await extractGitMetadata(cloneDir,url3,backend,targetSubdir),githubToken=envVars.GITHUB_TOKEN;return configureCredentials&&githubToken&&url3.includes(GITHUB_HOST)&&await configureGitCredentialStore(backend,cloneDir,url3,githubToken)&&(metadata={...metadata,gitCredentialsConfigured:!0}),{rootDir:cloneDir,sourceType:SourceType.GIT_REPO,consumedKeys:[],workspaceDescription:`Your workspace is a git clone of ${url3}`+(metadata.branch?` (branch: ${metadata.branch})`:"")+` (existing repo detected).
@@ -2486,9 +2486,9 @@ CRITICAL OUTPUT REQUIREMENT:
2486
2486
  Your final response MUST be a single valid JSON object (no markdown, no commentary, no code fences) that matches this schema:
2487
2487
  ${schemaStr}
2488
2488
 
2489
- Respond with ONLY the JSON object. Nothing else.`}let promptChars=effectivePrompt.length,promptEstimatedTokens=Math.ceil(promptChars/4);console.log(`ExecuteCursor prompt built: execution=${executionId}, chars=${promptChars}, estimatedTokens=${promptEstimatedTokens}, resolution=${resolution.reason}, mode=${resolution.mode}`),await ensureLoaded();let usageAccumulator=new UsageAccumulator(validatedModel),{startCursorTurnSpan:startCursorTurnSpan2}=await Promise.resolve().then(()=>(init_otel(),otel_exports)),turnSpan=await startCursorTurnSpan2({model:validatedModel,mode:agentMode,sessionId:sessionId??""}),turnTelemetryFinished=!1;finishTurnTelemetry=async()=>{if(turnTelemetryFinished)return;turnTelemetryFinished=!0;let usage=usageAccumulator.snapshot();turnSpan.setTokens(Number(usage.inputTokens),Number(usage.outputTokens)),turnSpan.end();try{let{recordTurnMetrics:recordTurnMetrics2}=await Promise.resolve().then(()=>(init_otel(),otel_exports)),durationMs=Date.now()-(status.startedAt?new Date(status.startedAt).getTime():Date.now());await recordTurnMetrics2({durationMs,inputTokens:Number(usage.inputTokens),outputTokens:Number(usage.outputTokens),model:validatedModel,mode:agentMode})}catch{}},status.phase=ExecutionPhase.EXECUTION_IN_PROGRESS;let deltaEnricher=new DeltaEnricher,todoTracker=new TodoTracker(status.todos),eventRecorder=createCursorEventRecorder(executionId),alreadyRetriedWithFreshAgent=!1,onDeltaDeps={usageAccumulator,deltaEnricher,heartbeat:import_activity15.heartbeat,promptEstimatedTokens,executionId,state:turnState},taskQueue=import_activity15.Context.current().info.taskQueue,shutdownSignal=getShutdownSignalForQueue(taskQueue);periodicHeartbeat=startHeartbeat(3e4,()=>({phase:"cursor_streaming",execution:executionId}),{shutdownSignal});try{(0,import_node_events.setMaxListeners)(25,import_activity15.Context.current().cancellationSignal)}catch{}let run=await resolution.agent.send(effectivePrompt,{onDelta:makeCursorTurnOnDelta(onDeltaDeps)}),turnStartMessageIndex=status.messages.length,accumulator=new MessageAccumulator(status.messages,{mergedPolicies,provenance:{globalBypass,leasedCategories:leases.categories},workspaceRoot:primaryWorkspaceDir,seededSubAgents}),scheduler=new StreamingUpdateScheduler(loadStreamingConfig()),streamDeps={...onDeltaDeps,status,accumulator,todoTracker,eventRecorder,scheduler,progressSubstrate,progressState,changeSetId,hitlDir,stallTimeoutMs:config4.cursorStreamStallTimeoutMs,persist,isCancelled:()=>import_activity15.Context.current().cancellationSignal.aborted};await consumeCursorTurnStream(run,streamDeps),periodicHeartbeat.stop();let isShutdown=periodicHeartbeat.workerShutdown||(shutdownSignal?.aborted??!1);isShutdown?turnState.pauseDetected=!1:periodicHeartbeat.cancelled&&(turnState.pauseDetected=!0),workerShutdownDetected=isShutdown;let finalizeStreamPhase=async()=>{accumulator.finalize(),deltaEnricher.finalize(status.messages),(turnState.pauseDetected||workerShutdownDetected||turnState.stallDetected||import_activity15.Context.current().cancellationSignal.aborted)&&accumulator.cancelInProgressSubAgents(),status.subAgentExecutions=accumulator.subAgentExecutions,await eventRecorder?.flush(),usageAccumulator.hasTurns&&(status.streamingUsage=create(StreamingUsageSummarySchema,usageAccumulator.snapshot())),console.log(`ExecuteCursor stream ended: execution=${executionId}, events=${turnState.eventCount}, messages=${status.messages.length}, subAgents=${status.subAgentExecutions.length}`),await persist(status),(0,import_activity15.heartbeat)()},resolvePreBoundaryTerminal=async()=>{if(turnState.stallDetected){let err=turnState.stallError??new StallTimeoutError(config4.cursorStreamStallTimeoutMs);return status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=formatStallFailure(err),status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:`Execution failed: the agent made no progress for too long and was stopped (${err.message}). You can retry or resume.`,timestamp:utcTimestamp()})),await persist(status),console.warn(`ExecuteCursor stalled: execution=${executionId}, events=${turnState.eventCount}, error=${status.error}`),{kind:"return"}}if(workerShutdownDetected||(shutdownSignal?.aborted??!1))return status.phase=ExecutionPhase.EXECUTION_FAILED,status.error="Execution interrupted: runner worker was shut down. Retry or resume.",status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution interrupted: the runner worker was shut down while the agent was still running. You can retry or resume.",timestamp:utcTimestamp()})),await persist(status),console.log(`ExecuteCursor interrupted (worker shutdown): execution=${executionId}, events=${turnState.eventCount}`),{kind:"throw",message:"Activity cancelled (worker shutdown, not user pause)"};if(turnState.pauseDetected)return status.phase=ExecutionPhase.EXECUTION_PAUSED,status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution paused by user. Use resume to continue.",timestamp:utcTimestamp()})),await persist(status),console.log(`ExecuteCursor paused: execution=${executionId}, events=${turnState.eventCount}`),{kind:"throw",message:"Activity paused by orchestrator"};if(import_activity15.Context.current().cancellationSignal.aborted)return status.phase=ExecutionPhase.EXECUTION_FAILED,status.error="Execution interrupted: agent was unresponsive (heartbeat timeout). Retry or resume.",status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution interrupted: the agent was unresponsive for too long. You can retry or resume.",timestamp:utcTimestamp()})),await persist(status),console.log(`ExecuteCursor interrupted (infrastructure cancel): execution=${executionId}, events=${turnState.eventCount}`),{kind:"throw",message:"Activity cancelled (heartbeat timeout, not user pause)"};if(turnState.platformStopSignaled){status.phase=ExecutionPhase.EXECUTION_COMPLETED,status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution stopped by the platform.",timestamp:utcTimestamp()})),await persist(status);try{resolution.agent.close()}catch{}return console.log(`ExecuteCursor completed (platform stop): execution=${executionId}`),{kind:"return"}}return{kind:"proceed"}};await finalizeStreamPhase();let primaryTerminal=await resolvePreBoundaryTerminal();if(primaryTerminal.kind==="return")return slimStatus(status);if(primaryTerminal.kind==="throw")throw new import_activity15.CancelledFailure(primaryTerminal.message);let runBoundary=denialSettled=>runTurnBoundary({status,executionId,changeSetId,hitlDir,captureMode,baselineTree,primaryWorkspaceDir,gitWorkspace,turnStartMessageIndex,approvalGrants,globalBypass,seededSubAgents,artifactStorage,mergedPolicies,denialCancelSettled:denialSettled,foreignGatingHooks:hitlGate.foreignGatingHooks}),enterApprovalPause=async boundary2=>(status.phase=ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL,await persist(status),console.log(`ExecuteCursor returning WAITING_FOR_APPROVAL: ${boundary2.deniedToolCallCount} gated tool(s), ${boundary2.capturedChangeCount} file card(s) pending`),slimStatus(status)),enterUnattributedHookBlockFailure=async boundary2=>{let blockedTools=[...new Set(boundary2.unattributedHookBlocks.map(b=>b.toolName))].join(", "),culprit=hitlGate.foreignGatingHooks.length>0?` The workspace's .cursor/hooks.json registers hook(s) outside Stigmer's control [${hitlGate.foreignGatingHooks.join(", ")}], which most likely denied it.`:"";status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=`A Cursor hook outside Stigmer's approval gate blocked tool(s): ${blockedTools}.`+culprit+" Stigmer cannot request approval on a foreign hook's behalf \u2014 remove or adjust the hook in .cursor/hooks.json and retry.",status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:`Execution failed: ${status.error}`,timestamp:utcTimestamp()})),await persist(status);try{resolution.agent.close()}catch{}return console.error(`ExecuteCursor failed (unattributed hook block): execution=${executionId}, tools=[${blockedTools}], foreignHooks=[${hitlGate.foreignGatingHooks.join(", ")}]`),slimStatus(status)},settleRetryTurn=async retryResultStatus=>{let retryBoundary=retryResultStatus==="cancelled"?void 0:await runBoundary(turnState.firstDenialDetected?turnState.denialCancelSettled:void 0);return status.completedAt=retryBoundary?.waiting?"":utcTimestamp(),retryBoundary},runRecoveryStream=async(freshAgent,retryPrompt)=>{resolution={...resolution,agent:freshAgent,agentId:freshAgent.agentId,isNew:!0},turnState.streamErrorMessage=void 0;let retryRun=await freshAgent.send(retryPrompt,{onDelta:makeCursorTurnOnDelta(onDeltaDeps)});await consumeCursorTurnStream(retryRun,streamDeps),await finalizeStreamPhase();let terminal=await resolvePreBoundaryTerminal();if(terminal.kind!=="proceed")return{proceeded:!1,terminal};let retryResult=await retryRun.wait();console.log(`ExecuteCursor retry run.wait(): execution=${executionId}, retryResult=${JSON.stringify(retryResult)}`);let retryBoundary=await settleRetryTurn(retryResult.status);return{proceeded:!0,retryRun,retryResult,retryBoundary}},boundary=await runBoundary(turnState.firstDenialDetected?turnState.denialCancelSettled:void 0);if(boundary.waiting)return enterApprovalPause(boundary);if(boundary.unattributedHookBlocks.length>0)return enterUnattributedHookBlockFailure(boundary);let result=await run.wait(),sdkResolvedModel=result.model?.id||void 0;switch(console.log(`ExecuteCursor run.wait() result: execution=${executionId}, result=${JSON.stringify(result)}`),sdkResolvedModel&&sdkResolvedModel!==validatedModel&&console.log(`ExecuteCursor model divergence: execution=${executionId}, requested=${validatedModel}, sdkResolved=${sdkResolvedModel}`),status.completedAt=utcTimestamp(),result.status){case"finished":status.phase=ExecutionPhase.EXECUTION_COMPLETED;break;case"error":{let resultAny=result,sdkError=result.result??resultAny.error??resultAny.message??resultAny.reason,sdkErrorStr=sdkError?String(sdkError):void 0,conversationErrorText=await introspectConversation(run,executionId),capturedRejection=getCapturedRejection(executionId);capturedRejection&&clearCapturedRejection(executionId);let classified=synthesizeError({sdkResultFields:sdkErrorStr,streamErrorMessage:turnState.streamErrorMessage,capturedRejection,conversationErrorText,isResumedHandle:resolution.reason==="resumed_successfully",fallbackContext:{model:validatedModel,mode:agentMode,agentId:resolution.agentId},durationMs:result.durationMs,messageCount:status.messages.length});if(console.error(`ExecuteCursor agent error: execution=${executionId}, classified=${JSON.stringify(classified)}, rawResult=${JSON.stringify(result)}`),shouldRetryWithFreshAgent(classified)&&resolution.reason==="resumed_successfully"&&!alreadyRetriedWithFreshAgent){alreadyRetriedWithFreshAgent=!0,console.warn(`ExecuteCursor poisoned-handle recovery: execution=${executionId}, disposing agent ${resolution.agentId} and creating fresh agent`);try{resolution.agent.close()}catch{}let freshAgent=agentMode==="cloud"?await createCloudAgent(createOptions):await createAgent2(createOptions),freshPrompt=buildPrompt({resolution:{...resolution,agent:freshAgent,agentId:freshAgent.agentId,isNew:!0,resumed:!1,reason:"created_after_resume_failure",resumeFailureDetail:`poisoned-handle recovery: ${classified.message}`},approvalDecisions,instructions:blueprint.instructions,userMessage:spec.message,skills:skillMetadata,subAgents:blueprint.subAgents,workspaceDirs:blueprint.workspaceDirs,workspaceFileRefs:spec.workspaceFileRefs??[],attachmentPaths,pendingApprovals:adjudicatedApprovals,interactionMode});console.log(`ExecuteCursor retry with fresh agent: execution=${executionId}, newAgentId=${freshAgent.agentId}`);try{blueprint.sessionSpec.harnessStateId=freshAgent.agentId,blueprint.session.metadata&&(blueprint.session.metadata.slug=""),await client2.updateSession(blueprint.session)}catch(updateErr){console.warn("Failed to update session with fresh agentId (non-fatal):",updateErr)}let outcome=await runRecoveryStream(freshAgent,freshPrompt);if(!outcome.proceeded){if(outcome.terminal.kind==="return")return slimStatus(status);throw new import_activity15.CancelledFailure(outcome.terminal.message)}let{retryRun,retryResult,retryBoundary}=outcome;if(retryBoundary?.waiting)return console.log(`ExecuteCursor poisoned-handle recovery paused for review: execution=${executionId}`),enterApprovalPause(retryBoundary);if(retryBoundary&&retryBoundary.unattributedHookBlocks.length>0)return enterUnattributedHookBlockFailure(retryBoundary);if(retryResult.status==="finished"){status.phase=ExecutionPhase.EXECUTION_COMPLETED,console.log(`ExecuteCursor poisoned-handle recovery SUCCEEDED: execution=${executionId}`);break}if(retryResult.status==="cancelled"){status.phase=ExecutionPhase.EXECUTION_CANCELLED;break}let retryRejection=getCapturedRejection(executionId);retryRejection&&clearCapturedRejection(executionId);let retryConversationErrorText=await introspectConversation(retryRun,executionId),retryClassified=synthesizeError({sdkResultFields:retryResult.result?String(retryResult.result):void 0,streamErrorMessage:turnState.streamErrorMessage,capturedRejection:retryRejection,conversationErrorText:retryConversationErrorText,isResumedHandle:!1,fallbackContext:{model:validatedModel,mode:agentMode,agentId:freshAgent.agentId}});status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=formatClassifiedError(retryClassified),console.error(`ExecuteCursor poisoned-handle recovery FAILED: execution=${executionId}, retryError=${status.error}`);break}if(classified.category==="network"&&classified.retryable&&resolution.reason!=="resumed_successfully"&&!alreadyRetriedWithFreshAgent){alreadyRetriedWithFreshAgent=!0,console.warn(`ExecuteCursor transport-timeout recovery: execution=${executionId}, resetting proxy sessions and retrying with fresh agent`);try{resolution.agent.close()}catch{}closeProxySessions();let freshAgent=agentMode==="cloud"?await createCloudAgent(createOptions):await createAgent2(createOptions);try{blueprint.sessionSpec.harnessStateId=freshAgent.agentId,blueprint.session.metadata&&(blueprint.session.metadata.slug=""),await client2.updateSession(blueprint.session)}catch(updateErr){console.warn("Failed to update session with fresh agentId (non-fatal):",updateErr)}let outcome=await runRecoveryStream(freshAgent,effectivePrompt);if(!outcome.proceeded){if(outcome.terminal.kind==="return")return slimStatus(status);throw new import_activity15.CancelledFailure(outcome.terminal.message)}let{retryResult,retryBoundary}=outcome;if(retryBoundary?.waiting)return console.log(`ExecuteCursor transport-timeout recovery paused for review: execution=${executionId}`),enterApprovalPause(retryBoundary);if(retryBoundary&&retryBoundary.unattributedHookBlocks.length>0)return enterUnattributedHookBlockFailure(retryBoundary);if(retryResult.status==="finished"){status.phase=ExecutionPhase.EXECUTION_COMPLETED;break}status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=`Transport recovery failed: ${formatClassifiedError(classified)}`;break}status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=formatClassifiedError(classified);break}case"cancelled":status.phase=ExecutionPhase.EXECUTION_CANCELLED;break;default:status.phase=ExecutionPhase.EXECUTION_COMPLETED}let structuredOutput,finalText;if(status.phase===ExecutionPhase.EXECUTION_COMPLETED){if(finalText=[...status.messages].reverse().find(m=>m.type===MessageType.MESSAGE_AI)?.content,structuredOutputSchema&&finalText){let{extractJsonFromText:extractJsonFromText2}=await Promise.resolve().then(()=>(init_extract_json(),extract_json_exports));if(structuredOutput=extractJsonFromText2(finalText),structuredOutput!==void 0&&console.log(`ExecuteCursor structured output extracted (text): execution=${executionId}, finalTextLength=${finalText.length}`),structuredOutput===void 0){console.log(`ExecuteCursor text extraction failed, trying LLM extraction: execution=${executionId}, finalTextLength=${finalText.length}`);try{structuredOutput=await extractStructuredOutput(finalText,structuredOutputSchema,config4,requestedModel),structuredOutput!==void 0&&console.log(`ExecuteCursor structured output extracted (LLM): execution=${executionId}`)}catch(extractErr){let errMsg=extractErr instanceof Error?extractErr.message:String(extractErr);console.error(`ExecuteCursor structured output extraction FAILED: execution=${executionId}, requestedModel=${requestedModel}, finalTextLength=${finalText.length}, error=${errMsg}`)}}}if(structuredOutput!==void 0&&(status.structuredOutput=structuredOutput),interactionMode===InteractionMode.PLAN&&finalText&&artifactStorage)try{await publishPlanArtifact({status,executionId,planText:finalText,artifactStorage})}catch(err){console.warn(`ExecuteCursor plan artifact publish skipped (non-fatal): execution=${executionId}, error=${err}`)}}let collapsedTwins=collapseRedundantToolCallTwins(status.messages);collapsedTwins>0&&console.log(`ExecuteCursor collapsed ${collapsedTwins} redundant tool-call twin(s) at terminal finalize (kept in place as hidden SKIPPED rows): execution=${executionId}`),status.phase===ExecutionPhase.EXECUTION_COMPLETED&&writebackCoordinator&&await writebackCoordinator.finalize(),await persist(status),console.log(`ExecuteCursor completed: execution=${executionId}, phase=${ExecutionPhase[status.phase]}, hasStructuredOutput=${structuredOutput!==void 0}`+(status.error?`, error=${status.error}`:""));try{resolution.agent.close()}catch{}let slim=slimStatus(status);return finalText!==void 0&&(slim.final_text=finalText),structuredOutput!==void 0&&(slim.structured=structuredOutput),slim}catch(err){if(periodicHeartbeat?.stop(),err instanceof import_activity15.CancelledFailure)throw workerShutdownDetected?(console.log(`ExecuteCursor cancelled (worker shutdown) for execution ${executionId}`),status.phase=ExecutionPhase.EXECUTION_FAILED,status.error="Execution interrupted: runner worker was shut down. Retry or resume.",status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution interrupted: the runner worker was shut down while the agent was still running. You can retry or resume.",timestamp:utcTimestamp()}))):turnState.pauseDetected?(console.log(`ExecuteCursor cancelled (pause) for execution ${executionId}`),status.phase=ExecutionPhase.EXECUTION_PAUSED,status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution paused by user. Use resume to continue.",timestamp:utcTimestamp()}))):(console.log(`ExecuteCursor cancelled (infrastructure) for execution ${executionId}`),status.phase=ExecutionPhase.EXECUTION_FAILED,status.error="Execution interrupted: agent was unresponsive (heartbeat timeout). Retry or resume.",status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution interrupted: the agent was unresponsive for too long. You can retry or resume.",timestamp:utcTimestamp()}))),cancelInProgressSubAgentProtos(status.subAgentExecutions),await persist(status).catch(()=>{}),err;if(turnState.pauseDetected){let errDetail=err instanceof Error?err.message:String(err);throw console.log(`ExecuteCursor error during pause (treating as pause): execution=${executionId}, error=${errDetail}`),status.phase=ExecutionPhase.EXECUTION_PAUSED,status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution paused by user. Use resume to continue.",timestamp:utcTimestamp()})),cancelInProgressSubAgentProtos(status.subAgentExecutions),await persist(status).catch(()=>{}),new import_activity15.CancelledFailure("Activity paused by orchestrator (error during pause)")}if(import_activity15.Context.current().cancellationSignal.aborted){let errDetail=err instanceof Error?err.message:String(err);throw console.log(`ExecuteCursor error during infrastructure cancel: execution=${executionId}, error=${errDetail}`),status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=`Execution interrupted: ${errDetail}`,status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution interrupted: the agent was unresponsive for too long. You can retry or resume.",timestamp:utcTimestamp()})),cancelInProgressSubAgentProtos(status.subAgentExecutions),await persist(status).catch(()=>{}),new import_activity15.CancelledFailure("Activity cancelled (infrastructure, not user pause)")}let{CursorSdkError}=await import("@cursor/sdk");if(err instanceof CursorSdkError){let sdkErrorJson=err.toJSON();console.error(`ExecuteCursor SDK error: execution=${executionId}, sdkError=${JSON.stringify(sdkErrorJson)}`);let classified=synthesizeError({sdkError:{code:err.code,status:err.status,message:err.message},sdkResultFields:void 0,streamErrorMessage:void 0,capturedRejection:getCapturedRejection(executionId),isResumedHandle:!1,fallbackContext:errorContext});clearCapturedRejection(executionId),status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=formatClassifiedError(classified),status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Internal system error occurred. Please contact support if this issue persists.",timestamp:utcTimestamp()}),create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:`Error details: ${status.error}`,timestamp:utcTimestamp()}));try{await persist(status)}catch(persistErr){console.error("Failed to persist error status (best-effort):",persistErr)}return slimStatus(status)}let errMsg=err instanceof Error?err.message:String(err),errType=err instanceof Error?err.constructor.name:"Unknown";console.error(`ExecuteCursor failed: execution=${executionId}, [${errType}] ${errMsg}`),status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=`Execution failed: [${errType}] ${errMsg}`,status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Internal system error occurred. Please contact support if this issue persists.",timestamp:utcTimestamp()}),create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:`Error details: [${errType}] ${errMsg}`,timestamp:utcTimestamp()}));try{await persist(status)}catch(persistErr){console.error("Failed to persist error status (best-effort):",persistErr)}return slimStatus(status)}finally{if(await finishTurnTelemetry?.(),turnState.stallWatchdog?.stop(),stopDenialWatcher?.(),hitlCleanup)try{await hitlCleanup()}catch(cleanupErr){console.warn(`ExecuteCursor HITL gate teardown failed (non-fatal): execution=${executionId}, error=${cleanupErr instanceof Error?cleanupErr.message:cleanupErr}`)}await releaseWorkspaceLock?.()}}function seedCursorTranscriptFromExecution(status,execution){let persisted=execution.status;if(!persisted||persisted.messages.length===0)return[];for(let message of persisted.messages)status.messages.push(clone(AgentMessageSchema,message));return persisted.subAgentExecutions.map(sub=>clone(SubAgentExecutionSchema,sub))}async function extractStructuredOutput(agentResponse,schema2,config4,primaryModel){let{getEconomyModel:getEconomyModel2}=await Promise.resolve().then(()=>(init_model_registry(),model_registry_exports)),{buildChatModel:buildChatModel2}=await Promise.resolve().then(()=>(init_model_client(),model_client_exports)),extractionModel=await getEconomyModel2(primaryModel),proxyEndpoint=config4.proxyEndpoint??config4.stigmerBackendEndpoint,{model:llm}=await buildChatModel2({modelName:extractionModel,proxyEndpoint,stigmerToken:config4.stigmerToken??void 0,maxTokens:4096}),zodSchema=jsonSchemaToZod(schema2);return await llm.withStructuredOutput(zodSchema).invoke([{role:"system",content:"Extract the structured data from the agent's response. Return only the data that matches the schema."},{role:"user",content:agentResponse}])??null}function buildPrompt(input){let{resolution,approvalDecisions,instructions,userMessage,skills,subAgents,workspaceDirs,workspaceFileRefs,attachmentPaths,interactionMode,buildFromPlan}=input;if(approvalDecisions!==void 0&&approvalDecisions.size>0)return buildReinvocationPrompt(input.pendingApprovals,approvalDecisions,input.appliedToolCallIds);if(resolution.reason==="resumed_successfully"){let prefixes=[formatInteractionModePrefix(interactionMode),formatImplementPlanSection(buildFromPlan,attachmentPaths)].filter(p=>p!==void 0);return prefixes.length>0?[...prefixes,userMessage].join(`
2489
+ Respond with ONLY the JSON object. Nothing else.`}let promptChars=effectivePrompt.length,promptEstimatedTokens=Math.ceil(promptChars/4);console.log(`ExecuteCursor prompt built: execution=${executionId}, chars=${promptChars}, estimatedTokens=${promptEstimatedTokens}, resolution=${resolution.reason}, mode=${resolution.mode}`),await ensureLoaded();let usageAccumulator=new UsageAccumulator(validatedModel),{startCursorTurnSpan:startCursorTurnSpan2}=await Promise.resolve().then(()=>(init_otel(),otel_exports)),turnSpan=await startCursorTurnSpan2({model:validatedModel,mode:agentMode,sessionId:sessionId??""}),turnTelemetryFinished=!1;finishTurnTelemetry=async()=>{if(turnTelemetryFinished)return;turnTelemetryFinished=!0;let usage=usageAccumulator.snapshot();turnSpan.setTokens(Number(usage.inputTokens),Number(usage.outputTokens)),turnSpan.end();try{let{recordTurnMetrics:recordTurnMetrics2}=await Promise.resolve().then(()=>(init_otel(),otel_exports)),durationMs=Date.now()-(status.startedAt?new Date(status.startedAt).getTime():Date.now());await recordTurnMetrics2({durationMs,inputTokens:Number(usage.inputTokens),outputTokens:Number(usage.outputTokens),model:validatedModel,mode:agentMode})}catch{}},status.phase=ExecutionPhase.EXECUTION_IN_PROGRESS;let deltaEnricher=new DeltaEnricher,todoTracker=new TodoTracker(status.todos),eventRecorder=createCursorEventRecorder(executionId),alreadyRetriedWithFreshAgent=!1,maxCostUsd=spec.executionConfig?.maxCostUsd??0,onDeltaDeps={usageAccumulator,deltaEnricher,heartbeat:import_activity15.heartbeat,promptEstimatedTokens,executionId,state:turnState,maxCostUsd},taskQueue=import_activity15.Context.current().info.taskQueue,shutdownSignal=getShutdownSignalForQueue(taskQueue);periodicHeartbeat=startHeartbeat(3e4,()=>({phase:"cursor_streaming",execution:executionId}),{shutdownSignal});try{(0,import_node_events.setMaxListeners)(25,import_activity15.Context.current().cancellationSignal)}catch{}let run=await resolution.agent.send(effectivePrompt,{onDelta:makeCursorTurnOnDelta(onDeltaDeps)}),turnStartMessageIndex=status.messages.length,accumulator=new MessageAccumulator(status.messages,{mergedPolicies,provenance:{globalBypass,leasedCategories:leases.categories},workspaceRoot:primaryWorkspaceDir,seededSubAgents}),scheduler=new StreamingUpdateScheduler(loadStreamingConfig()),streamDeps={...onDeltaDeps,status,accumulator,todoTracker,eventRecorder,scheduler,progressSubstrate,progressState,changeSetId,hitlDir,stallTimeoutMs:config4.cursorStreamStallTimeoutMs,persist,isCancelled:()=>import_activity15.Context.current().cancellationSignal.aborted};await consumeCursorTurnStream(run,streamDeps),periodicHeartbeat.stop();let isShutdown=periodicHeartbeat.workerShutdown||(shutdownSignal?.aborted??!1);isShutdown?turnState.pauseDetected=!1:periodicHeartbeat.cancelled&&(turnState.pauseDetected=!0),workerShutdownDetected=isShutdown;let finalizeStreamPhase=async()=>{accumulator.finalize(),deltaEnricher.finalize(status.messages),(turnState.pauseDetected||workerShutdownDetected||turnState.stallDetected||turnState.costCapExceeded||import_activity15.Context.current().cancellationSignal.aborted)&&accumulator.cancelInProgressSubAgents(),status.subAgentExecutions=accumulator.subAgentExecutions,await eventRecorder?.flush(),usageAccumulator.hasTurns&&(status.streamingUsage=create(StreamingUsageSummarySchema,usageAccumulator.snapshot())),console.log(`ExecuteCursor stream ended: execution=${executionId}, events=${turnState.eventCount}, messages=${status.messages.length}, subAgents=${status.subAgentExecutions.length}`),await persist(status),(0,import_activity15.heartbeat)()},resolvePreBoundaryTerminal=async()=>{if(turnState.stallDetected){let err=turnState.stallError??new StallTimeoutError(config4.cursorStreamStallTimeoutMs);return status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=formatStallFailure(err),status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:`Execution failed: the agent made no progress for too long and was stopped (${err.message}). You can retry or resume.`,timestamp:utcTimestamp()})),await persist(status),console.warn(`ExecuteCursor stalled: execution=${executionId}, events=${turnState.eventCount}, error=${status.error}`),{kind:"return"}}if(turnState.costCapExceeded){let estimated=usageAccumulator.snapshot().estimatedCostUsd;status.phase=ExecutionPhase.EXECUTION_TERMINATED,status.error=formatCostLimitError(maxCostUsd,estimated),status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:COST_LIMIT_USER_COPY,timestamp:utcTimestamp()})),await persist(status);try{resolution.agent.close()}catch{}return console.warn(`ExecuteCursor terminated (cost cap): execution=${executionId}, estimatedCostUsd=${estimated.toFixed(4)}, maxCostUsd=${maxCostUsd.toFixed(2)}`),{kind:"return"}}if(workerShutdownDetected||(shutdownSignal?.aborted??!1))return status.phase=ExecutionPhase.EXECUTION_FAILED,status.error="Execution interrupted: runner worker was shut down. Retry or resume.",status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution interrupted: the runner worker was shut down while the agent was still running. You can retry or resume.",timestamp:utcTimestamp()})),await persist(status),console.log(`ExecuteCursor interrupted (worker shutdown): execution=${executionId}, events=${turnState.eventCount}`),{kind:"throw",message:"Activity cancelled (worker shutdown, not user pause)"};if(turnState.pauseDetected)return status.phase=ExecutionPhase.EXECUTION_PAUSED,status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution paused by user. Use resume to continue.",timestamp:utcTimestamp()})),await persist(status),console.log(`ExecuteCursor paused: execution=${executionId}, events=${turnState.eventCount}`),{kind:"throw",message:"Activity paused by orchestrator"};if(import_activity15.Context.current().cancellationSignal.aborted)return status.phase=ExecutionPhase.EXECUTION_FAILED,status.error="Execution interrupted: agent was unresponsive (heartbeat timeout). Retry or resume.",status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution interrupted: the agent was unresponsive for too long. You can retry or resume.",timestamp:utcTimestamp()})),await persist(status),console.log(`ExecuteCursor interrupted (infrastructure cancel): execution=${executionId}, events=${turnState.eventCount}`),{kind:"throw",message:"Activity cancelled (heartbeat timeout, not user pause)"};if(turnState.platformStopSignaled){status.phase=ExecutionPhase.EXECUTION_COMPLETED,status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution stopped by the platform.",timestamp:utcTimestamp()})),await persist(status);try{resolution.agent.close()}catch{}return console.log(`ExecuteCursor completed (platform stop): execution=${executionId}`),{kind:"return"}}return{kind:"proceed"}};await finalizeStreamPhase();let primaryTerminal=await resolvePreBoundaryTerminal();if(primaryTerminal.kind==="return")return slimStatus(status);if(primaryTerminal.kind==="throw")throw new import_activity15.CancelledFailure(primaryTerminal.message);let runBoundary=denialSettled=>runTurnBoundary({status,executionId,changeSetId,hitlDir,captureMode,baselineTree,primaryWorkspaceDir,gitWorkspace,turnStartMessageIndex,approvalGrants,globalBypass,seededSubAgents,artifactStorage,mergedPolicies,denialCancelSettled:denialSettled,foreignGatingHooks:hitlGate.foreignGatingHooks}),enterApprovalPause=async boundary2=>(status.phase=ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL,await persist(status),console.log(`ExecuteCursor returning WAITING_FOR_APPROVAL: ${boundary2.deniedToolCallCount} gated tool(s), ${boundary2.capturedChangeCount} file card(s) pending`),slimStatus(status)),enterUnattributedHookBlockFailure=async boundary2=>{let blockedTools=[...new Set(boundary2.unattributedHookBlocks.map(b=>b.toolName))].join(", "),culprit=hitlGate.foreignGatingHooks.length>0?` The workspace's .cursor/hooks.json registers hook(s) outside Stigmer's control [${hitlGate.foreignGatingHooks.join(", ")}], which most likely denied it.`:"";status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=`A Cursor hook outside Stigmer's approval gate blocked tool(s): ${blockedTools}.`+culprit+" Stigmer cannot request approval on a foreign hook's behalf \u2014 remove or adjust the hook in .cursor/hooks.json and retry.",status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:`Execution failed: ${status.error}`,timestamp:utcTimestamp()})),await persist(status);try{resolution.agent.close()}catch{}return console.error(`ExecuteCursor failed (unattributed hook block): execution=${executionId}, tools=[${blockedTools}], foreignHooks=[${hitlGate.foreignGatingHooks.join(", ")}]`),slimStatus(status)},settleRetryTurn=async retryResultStatus=>{let retryBoundary=retryResultStatus==="cancelled"?void 0:await runBoundary(turnState.firstDenialDetected?turnState.denialCancelSettled:void 0);return status.completedAt=retryBoundary?.waiting?"":utcTimestamp(),retryBoundary},runRecoveryStream=async(freshAgent,retryPrompt)=>{resolution={...resolution,agent:freshAgent,agentId:freshAgent.agentId,isNew:!0},turnState.streamErrorMessage=void 0;let retryRun=await freshAgent.send(retryPrompt,{onDelta:makeCursorTurnOnDelta(onDeltaDeps)});await consumeCursorTurnStream(retryRun,streamDeps),await finalizeStreamPhase();let terminal=await resolvePreBoundaryTerminal();if(terminal.kind!=="proceed")return{proceeded:!1,terminal};let retryResult=await retryRun.wait();console.log(`ExecuteCursor retry run.wait(): execution=${executionId}, retryResult=${JSON.stringify(retryResult)}`);let retryBoundary=await settleRetryTurn(retryResult.status);return{proceeded:!0,retryRun,retryResult,retryBoundary}},boundary=await runBoundary(turnState.firstDenialDetected?turnState.denialCancelSettled:void 0);if(boundary.waiting)return enterApprovalPause(boundary);if(boundary.unattributedHookBlocks.length>0)return enterUnattributedHookBlockFailure(boundary);let result=await run.wait(),sdkResolvedModel=result.model?.id||void 0;switch(console.log(`ExecuteCursor run.wait() result: execution=${executionId}, result=${JSON.stringify(result)}`),sdkResolvedModel&&sdkResolvedModel!==validatedModel&&console.log(`ExecuteCursor model divergence: execution=${executionId}, requested=${validatedModel}, sdkResolved=${sdkResolvedModel}`),status.completedAt=utcTimestamp(),result.status){case"finished":status.phase=ExecutionPhase.EXECUTION_COMPLETED;break;case"error":{let resultAny=result,sdkError=result.result??resultAny.error??resultAny.message??resultAny.reason,sdkErrorStr=sdkError?String(sdkError):void 0,conversationErrorText=await introspectConversation(run,executionId),capturedRejection=getCapturedRejection(executionId);capturedRejection&&clearCapturedRejection(executionId);let classified=synthesizeError({sdkResultFields:sdkErrorStr,streamErrorMessage:turnState.streamErrorMessage,capturedRejection,conversationErrorText,isResumedHandle:resolution.reason==="resumed_successfully",fallbackContext:{model:validatedModel,mode:agentMode,agentId:resolution.agentId},durationMs:result.durationMs,messageCount:status.messages.length});if(console.error(`ExecuteCursor agent error: execution=${executionId}, classified=${JSON.stringify(classified)}, rawResult=${JSON.stringify(result)}`),shouldRetryWithFreshAgent(classified)&&resolution.reason==="resumed_successfully"&&!alreadyRetriedWithFreshAgent){alreadyRetriedWithFreshAgent=!0,console.warn(`ExecuteCursor poisoned-handle recovery: execution=${executionId}, disposing agent ${resolution.agentId} and creating fresh agent`);try{resolution.agent.close()}catch{}let freshAgent=agentMode==="cloud"?await createCloudAgent(createOptions):await createAgent2(createOptions),freshPrompt=buildPrompt({resolution:{...resolution,agent:freshAgent,agentId:freshAgent.agentId,isNew:!0,resumed:!1,reason:"created_after_resume_failure",resumeFailureDetail:`poisoned-handle recovery: ${classified.message}`},approvalDecisions,instructions:blueprint.instructions,userMessage:spec.message,skills:skillMetadata,subAgents:blueprint.subAgents,workspaceDirs:blueprint.workspaceDirs,workspaceFileRefs:spec.workspaceFileRefs??[],attachmentPaths,pendingApprovals:adjudicatedApprovals,interactionMode});console.log(`ExecuteCursor retry with fresh agent: execution=${executionId}, newAgentId=${freshAgent.agentId}`);try{blueprint.sessionSpec.harnessStateId=freshAgent.agentId,blueprint.session.metadata&&(blueprint.session.metadata.slug=""),await client2.updateSession(blueprint.session)}catch(updateErr){console.warn("Failed to update session with fresh agentId (non-fatal):",updateErr)}let outcome=await runRecoveryStream(freshAgent,freshPrompt);if(!outcome.proceeded){if(outcome.terminal.kind==="return")return slimStatus(status);throw new import_activity15.CancelledFailure(outcome.terminal.message)}let{retryRun,retryResult,retryBoundary}=outcome;if(retryBoundary?.waiting)return console.log(`ExecuteCursor poisoned-handle recovery paused for review: execution=${executionId}`),enterApprovalPause(retryBoundary);if(retryBoundary&&retryBoundary.unattributedHookBlocks.length>0)return enterUnattributedHookBlockFailure(retryBoundary);if(retryResult.status==="finished"){status.phase=ExecutionPhase.EXECUTION_COMPLETED,console.log(`ExecuteCursor poisoned-handle recovery SUCCEEDED: execution=${executionId}`);break}if(retryResult.status==="cancelled"){status.phase=ExecutionPhase.EXECUTION_CANCELLED;break}let retryRejection=getCapturedRejection(executionId);retryRejection&&clearCapturedRejection(executionId);let retryConversationErrorText=await introspectConversation(retryRun,executionId),retryClassified=synthesizeError({sdkResultFields:retryResult.result?String(retryResult.result):void 0,streamErrorMessage:turnState.streamErrorMessage,capturedRejection:retryRejection,conversationErrorText:retryConversationErrorText,isResumedHandle:!1,fallbackContext:{model:validatedModel,mode:agentMode,agentId:freshAgent.agentId}});status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=formatClassifiedError(retryClassified),console.error(`ExecuteCursor poisoned-handle recovery FAILED: execution=${executionId}, retryError=${status.error}`);break}if(classified.category==="network"&&classified.retryable&&resolution.reason!=="resumed_successfully"&&!alreadyRetriedWithFreshAgent){alreadyRetriedWithFreshAgent=!0,console.warn(`ExecuteCursor transport-timeout recovery: execution=${executionId}, resetting proxy sessions and retrying with fresh agent`);try{resolution.agent.close()}catch{}closeProxySessions();let freshAgent=agentMode==="cloud"?await createCloudAgent(createOptions):await createAgent2(createOptions);try{blueprint.sessionSpec.harnessStateId=freshAgent.agentId,blueprint.session.metadata&&(blueprint.session.metadata.slug=""),await client2.updateSession(blueprint.session)}catch(updateErr){console.warn("Failed to update session with fresh agentId (non-fatal):",updateErr)}let outcome=await runRecoveryStream(freshAgent,effectivePrompt);if(!outcome.proceeded){if(outcome.terminal.kind==="return")return slimStatus(status);throw new import_activity15.CancelledFailure(outcome.terminal.message)}let{retryResult,retryBoundary}=outcome;if(retryBoundary?.waiting)return console.log(`ExecuteCursor transport-timeout recovery paused for review: execution=${executionId}`),enterApprovalPause(retryBoundary);if(retryBoundary&&retryBoundary.unattributedHookBlocks.length>0)return enterUnattributedHookBlockFailure(retryBoundary);if(retryResult.status==="finished"){status.phase=ExecutionPhase.EXECUTION_COMPLETED;break}status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=`Transport recovery failed: ${formatClassifiedError(classified)}`;break}status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=formatClassifiedError(classified);break}case"cancelled":status.phase=ExecutionPhase.EXECUTION_CANCELLED;break;default:status.phase=ExecutionPhase.EXECUTION_COMPLETED}let structuredOutput,finalText;if(status.phase===ExecutionPhase.EXECUTION_COMPLETED){if(finalText=[...status.messages].reverse().find(m=>m.type===MessageType.MESSAGE_AI)?.content,structuredOutputSchema&&finalText){let{extractJsonFromText:extractJsonFromText2}=await Promise.resolve().then(()=>(init_extract_json(),extract_json_exports));if(structuredOutput=extractJsonFromText2(finalText),structuredOutput!==void 0&&console.log(`ExecuteCursor structured output extracted (text): execution=${executionId}, finalTextLength=${finalText.length}`),structuredOutput===void 0){console.log(`ExecuteCursor text extraction failed, trying LLM extraction: execution=${executionId}, finalTextLength=${finalText.length}`);try{structuredOutput=await extractStructuredOutput(finalText,structuredOutputSchema,config4,requestedModel),structuredOutput!==void 0&&console.log(`ExecuteCursor structured output extracted (LLM): execution=${executionId}`)}catch(extractErr){let errMsg=extractErr instanceof Error?extractErr.message:String(extractErr);console.error(`ExecuteCursor structured output extraction FAILED: execution=${executionId}, requestedModel=${requestedModel}, finalTextLength=${finalText.length}, error=${errMsg}`)}}}if(structuredOutput!==void 0&&(status.structuredOutput=structuredOutput),interactionMode===InteractionMode.PLAN&&finalText&&artifactStorage)try{await publishPlanArtifact({status,executionId,planText:finalText,artifactStorage})}catch(err){console.warn(`ExecuteCursor plan artifact publish skipped (non-fatal): execution=${executionId}, error=${err}`)}}let collapsedTwins=collapseRedundantToolCallTwins(status.messages);collapsedTwins>0&&console.log(`ExecuteCursor collapsed ${collapsedTwins} redundant tool-call twin(s) at terminal finalize (kept in place as hidden SKIPPED rows): execution=${executionId}`),status.phase===ExecutionPhase.EXECUTION_COMPLETED&&writebackCoordinator&&await writebackCoordinator.finalize(),await persist(status),console.log(`ExecuteCursor completed: execution=${executionId}, phase=${ExecutionPhase[status.phase]}, hasStructuredOutput=${structuredOutput!==void 0}`+(status.error?`, error=${status.error}`:""));try{resolution.agent.close()}catch{}let slim=slimStatus(status);return finalText!==void 0&&(slim.final_text=finalText),structuredOutput!==void 0&&(slim.structured=structuredOutput),slim}catch(err){if(periodicHeartbeat?.stop(),err instanceof import_activity15.CancelledFailure)throw workerShutdownDetected?(console.log(`ExecuteCursor cancelled (worker shutdown) for execution ${executionId}`),status.phase=ExecutionPhase.EXECUTION_FAILED,status.error="Execution interrupted: runner worker was shut down. Retry or resume.",status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution interrupted: the runner worker was shut down while the agent was still running. You can retry or resume.",timestamp:utcTimestamp()}))):turnState.pauseDetected?(console.log(`ExecuteCursor cancelled (pause) for execution ${executionId}`),status.phase=ExecutionPhase.EXECUTION_PAUSED,status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution paused by user. Use resume to continue.",timestamp:utcTimestamp()}))):(console.log(`ExecuteCursor cancelled (infrastructure) for execution ${executionId}`),status.phase=ExecutionPhase.EXECUTION_FAILED,status.error="Execution interrupted: agent was unresponsive (heartbeat timeout). Retry or resume.",status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution interrupted: the agent was unresponsive for too long. You can retry or resume.",timestamp:utcTimestamp()}))),cancelInProgressSubAgentProtos(status.subAgentExecutions),await persist(status).catch(()=>{}),err;if(turnState.pauseDetected){let errDetail=err instanceof Error?err.message:String(err);throw console.log(`ExecuteCursor error during pause (treating as pause): execution=${executionId}, error=${errDetail}`),status.phase=ExecutionPhase.EXECUTION_PAUSED,status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution paused by user. Use resume to continue.",timestamp:utcTimestamp()})),cancelInProgressSubAgentProtos(status.subAgentExecutions),await persist(status).catch(()=>{}),new import_activity15.CancelledFailure("Activity paused by orchestrator (error during pause)")}if(import_activity15.Context.current().cancellationSignal.aborted){let errDetail=err instanceof Error?err.message:String(err);throw console.log(`ExecuteCursor error during infrastructure cancel: execution=${executionId}, error=${errDetail}`),status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=`Execution interrupted: ${errDetail}`,status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Execution interrupted: the agent was unresponsive for too long. You can retry or resume.",timestamp:utcTimestamp()})),cancelInProgressSubAgentProtos(status.subAgentExecutions),await persist(status).catch(()=>{}),new import_activity15.CancelledFailure("Activity cancelled (infrastructure, not user pause)")}let{CursorSdkError}=await import("@cursor/sdk");if(err instanceof CursorSdkError){let sdkErrorJson=err.toJSON();console.error(`ExecuteCursor SDK error: execution=${executionId}, sdkError=${JSON.stringify(sdkErrorJson)}`);let classified=synthesizeError({sdkError:{code:err.code,status:err.status,message:err.message},sdkResultFields:void 0,streamErrorMessage:void 0,capturedRejection:getCapturedRejection(executionId),isResumedHandle:!1,fallbackContext:errorContext});clearCapturedRejection(executionId),status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=formatClassifiedError(classified),status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Internal system error occurred. Please contact support if this issue persists.",timestamp:utcTimestamp()}),create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:`Error details: ${status.error}`,timestamp:utcTimestamp()}));try{await persist(status)}catch(persistErr){console.error("Failed to persist error status (best-effort):",persistErr)}return slimStatus(status)}let errMsg=err instanceof Error?err.message:String(err),errType=err instanceof Error?err.constructor.name:"Unknown";console.error(`ExecuteCursor failed: execution=${executionId}, [${errType}] ${errMsg}`),status.phase=ExecutionPhase.EXECUTION_FAILED,status.error=`Execution failed: [${errType}] ${errMsg}`,status.completedAt=utcTimestamp(),status.messages.push(create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:"Internal system error occurred. Please contact support if this issue persists.",timestamp:utcTimestamp()}),create(AgentMessageSchema,{type:MessageType.MESSAGE_SYSTEM,content:`Error details: [${errType}] ${errMsg}`,timestamp:utcTimestamp()}));try{await persist(status)}catch(persistErr){console.error("Failed to persist error status (best-effort):",persistErr)}return slimStatus(status)}finally{if(await finishTurnTelemetry?.(),turnState.stallWatchdog?.stop(),stopDenialWatcher?.(),hitlCleanup)try{await hitlCleanup()}catch(cleanupErr){console.warn(`ExecuteCursor HITL gate teardown failed (non-fatal): execution=${executionId}, error=${cleanupErr instanceof Error?cleanupErr.message:cleanupErr}`)}await releaseWorkspaceLock?.()}}function seedCursorTranscriptFromExecution(status,execution){let persisted=execution.status;if(!persisted||persisted.messages.length===0)return[];for(let message of persisted.messages)status.messages.push(clone(AgentMessageSchema,message));return persisted.subAgentExecutions.map(sub=>clone(SubAgentExecutionSchema,sub))}async function extractStructuredOutput(agentResponse,schema2,config4,primaryModel){let{getEconomyModel:getEconomyModel2}=await Promise.resolve().then(()=>(init_model_registry(),model_registry_exports)),{buildChatModel:buildChatModel2}=await Promise.resolve().then(()=>(init_model_client(),model_client_exports)),extractionModel=await getEconomyModel2(primaryModel),proxyEndpoint=config4.proxyEndpoint??config4.stigmerBackendEndpoint,{model:llm}=await buildChatModel2({modelName:extractionModel,proxyEndpoint,stigmerToken:config4.stigmerToken??void 0,maxTokens:4096}),zodSchema=jsonSchemaToZod(schema2);return await llm.withStructuredOutput(zodSchema).invoke([{role:"system",content:"Extract the structured data from the agent's response. Return only the data that matches the schema."},{role:"user",content:agentResponse}])??null}function buildPrompt(input){let{resolution,approvalDecisions,instructions,userMessage,skills,subAgents,workspaceDirs,workspaceFileRefs,attachmentPaths,interactionMode,buildFromPlan}=input;if(approvalDecisions!==void 0&&approvalDecisions.size>0)return buildReinvocationPrompt(input.pendingApprovals,approvalDecisions,input.appliedToolCallIds);if(resolution.reason==="resumed_successfully"){let prefixes=[formatInteractionModePrefix(interactionMode),formatImplementPlanSection(buildFromPlan,attachmentPaths)].filter(p=>p!==void 0);return prefixes.length>0?[...prefixes,userMessage].join(`
2490
2490
 
2491
- `):userMessage}return buildEnhancedPrompt({instructions,userMessage,skills,subAgents,workspaceDirs,workspaceFileRefs,attachmentPaths,interactionMode,buildFromPlan})}async function introspectConversation(run,executionId){try{if(!run.supports("conversation")){console.log(`ExecuteCursor conversation introspection unsupported: execution=${executionId}, reason=${run.unsupportedReason("conversation")??"n/a"}`);return}let turns=await run.conversation(),raw=JSON.stringify(turns),bounded=raw.length>8e3?`${raw.slice(0,8e3)}\u2026(truncated ${raw.length} chars)`:raw;return console.error(`ExecuteCursor conversation introspection: execution=${executionId}, turns=${turns.length}, raw=${bounded}`),extractConversationErrorText(turns)}catch(introspectErr){console.warn(`ExecuteCursor conversation introspection failed (non-fatal): execution=${executionId}, error=${introspectErr instanceof Error?introspectErr.message:String(introspectErr)}`);return}}function extractConversationErrorText(turns){if(!turns||turns.length===0)return;let collected=[],visit=(node,depth)=>{if(node==null||depth>6||typeof node!="object")return;if(Array.isArray(node)){for(let item of node)visit(item,depth+1);return}let obj=node;obj.status==="error"&&obj.error!=null&&collected.push(typeof obj.error=="string"?obj.error:JSON.stringify(obj.error));for(let[key,value]of Object.entries(obj))(key==="text"||key==="message"||key==="reason")&&typeof value=="string"&&value.trim().length>0?collected.push(value.trim()):typeof value=="object"&&value!=null&&visit(value,depth+1)};if(visit(turns[turns.length-1],0),collected.length===0)return;let joined=[...new Set(collected)].join(" | ");return joined.length>600?`${joined.slice(0,600)}\u2026`:joined}var import_activity15,import_node_events,init_execute_cursor=__esm({"dist/activities/execute-cursor/index.js"(){"use strict";import_activity15=__toESM(require_lib4(),1);init_esm4();init_api_pb3();init_message_pb();init_subagent_pb();init_enum_pb();init_stigmer_client();init_session_lifecycle();init_enum_pb4();init_cursor_mode();init_message_translator();init_status2();init_tool_row();init_stall_watchdog();init_artifact_storage();init_plan_artifact();init_delta_enricher();init_todo_tracker();init_streaming_scheduler();init_cursor_event_recorder();init_mcp_resolver();init_approval_policy2();init_approval_policy();init_connect_backfill2();init_env_resolver();init_blueprint_resolver();init_subagent_config();init_skill_resolver();init_stigmer_link();init_attachment_resolver();init_prompt_builder();init_workspace_setup();init_platform_dir();init_workspace_lock();init_local_backend();init_approval_state();init_exact_apply();init_git_substrate();init_capture_flow();init_turn_boundary();init_turn_stream();init_progress();init_approval_fingerprint();init_fingerprint_secret();init_workspace_provision();init_writeback_coordinator();init_execution_status_writer();init_fetch_interceptor();init_http2_interceptor();init_model_pricing();init_usage_accumulator();init_usage_pb();init_idle_watchdog();init_activity_input();init_rejection_capture();init_error_classifier();init_session_lifecycle();import_node_events=require("node:events");init_heartbeat();init_runner_manager();init_json_schema_to_zod()}});var import_node_crypto22=require("node:crypto"),import_node_fs10=require("node:fs"),import_node_path36=require("node:path"),import_node_readline=require("node:readline");function isNodeSqliteAvailable(){return process.getBuiltinModule?.("node:sqlite")!==void 0}function preflightNodeRuntime(isSqliteAvailable=isNodeSqliteAvailable){return isSqliteAvailable()?null:`Node v${process.versions.node} does not provide the built-in node:sqlite module required by the runner's durable checkpointer. Use Node >= 22.13 (22.x line) or >= 23.4 (23.x and later).`}init_config();init_otel();var import_node_fs9=require("node:fs"),import_node_path35=require("node:path"),import_node_os6=require("node:os");init_config();init_bootstrap();async function createStigmerRunner(options){validateOptions(options);let{registerStigmerDeepagentsProfiles:registerStigmerDeepagentsProfiles2}=await Promise.resolve().then(()=>(init_deepagents_profiles(),deepagents_profiles_exports));registerStigmerDeepagentsProfiles2();let baseConfig=mapOptionsToConfig(options),{installFetchInterceptor:installFetchInterceptor2,getExecutionContext:getExecutionContext2}=await Promise.resolve().then(()=>(init_fetch_interceptor(),fetch_interceptor_exports));installFetchInterceptor2({proxyEndpoint:baseConfig.proxyEndpoint??void 0,stigmerToken:baseConfig.stigmerToken??void 0});let{installHttp2Interceptor:installHttp2Interceptor2,assertHttp2ConnectPatched:assertHttp2ConnectPatched2}=await Promise.resolve().then(()=>(init_http2_interceptor(),http2_interceptor_exports));installHttp2Interceptor2({proxyEndpoint:baseConfig.proxyEndpoint??void 0,stigmerToken:baseConfig.stigmerToken??void 0}),await assertHttp2ConnectPatched2();let coordinates=await resolveRunnerBootstrap({explicitAddress:options.temporalAddress,explicitNamespace:options.temporalNamespace,token:options.stigmerToken,stigmerEndpoint:baseConfig.stigmerBackendEndpoint}),config4={...baseConfig,temporalAddress:coordinates.temporalAddress,temporalNamespace:coordinates.temporalNamespace},{setExecutionContextRef:setExecutionContextRef2}=await Promise.resolve().then(()=>(init_rejection_capture(),rejection_capture_exports));setExecutionContextRef2(getExecutionContext2());let activities=await createAllActivities2(config4);console.log(`[runner] Registered activities: ${Object.keys(activities).join(", ")}`),console.log(`[runner] Task queue: ${config4.taskQueue} | Mode: ${config4.mode} | Max concurrency: ${config4.maxConcurrentActivities}`);let payloadCodec=await createPayloadCodec2(config4),{startWorker:startWorker2}=await Promise.resolve().then(()=>(init_worker(),worker_exports)),worker=await startWorker2({config:config4,activities,payloadCodec});return{async start(){console.log("Worker ready, polling for tasks..."),await worker.run(),console.log("Worker stopped")},shutdown(){worker.shutdown()}}}function validateOptions(options){if(!options.taskQueue)throw new Error("StigmerRunnerOptions.taskQueue is required \u2014 specify the Temporal task queue to poll");if(!options.stigmerEndpoint)throw new Error("StigmerRunnerOptions.stigmerEndpoint is required \u2014 specify the Stigmer server endpoint (e.g. 'http://localhost:7234')")}function mapOptionsToConfig(options){let proxyActive=!!options.proxyEndpoint,mode=options.executionMode??(proxyActive?"cloud":"local");return{taskQueue:options.taskQueue,temporalAddress:options.temporalAddress??"",temporalNamespace:options.temporalNamespace??"default",stigmerBackendEndpoint:normalizeEndpoint3(options.stigmerEndpoint),stigmerToken:options.stigmerToken??null,cursorApiKey:proxyActive?options.cursorApiKey??"proxy-managed":options.cursorApiKey??"",workspaceRootDir:options.workspaceRootDir??resolveDefaultWorkspaceDir2(),mode,proxyEndpoint:options.proxyEndpoint??null,maxConcurrentActivities:options.maxConcurrentActivities??5,idleTimeoutSeconds:null,cloudModeEnabled:options.cloudModeEnabled??!1,checkpointerType:options.checkpointerType??(proxyActive?"http":"sqlite"),checkpointerProxyEndpoint:options.checkpointerProxyEndpoint??options.proxyEndpoint??null,primaryModel:options.primaryModel??"gpt-4.1",cursorStreamStallTimeoutMs:options.cursorStreamStallTimeoutMs??DEFAULT_CURSOR_STREAM_STALL_TIMEOUT_MS,workspaceLockTimeoutMs:options.workspaceLockTimeoutMs??DEFAULT_WORKSPACE_LOCK_TIMEOUT_MS}}async function createAllActivities2(config4){let[{createCursorActivities:createCursorActivities2},{createDeepAgentActivities:createDeepAgentActivities2},{createEnsureThreadActivities:createEnsureThreadActivities2},{createClassifyToolApprovalsActivities:createClassifyToolApprovalsActivities2},{createDiscoverMcpServerActivities:createDiscoverMcpServerActivities2},{createEvaluateExpressionsActivities:createEvaluateExpressionsActivities2},{createCallHttpActivities:createCallHttpActivities2},{createCallGrpcActivities:createCallGrpcActivities2},{createCallFunctionActivities:createCallFunctionActivities2},{createCallLlmActivities:createCallLlmActivities2},{createCallAgentActivities:createCallAgentActivities2},{createCallAgentStatusActivities:createCallAgentStatusActivities2},{createRunCommandActivities:createRunCommandActivities2},{createHydrateWorkflowActivities:createHydrateWorkflowActivities2},{createWorkflowEventActivities:createWorkflowEventActivities2},{createPromoteTaskOutputActivities:createPromoteTaskOutputActivities2}]=await Promise.all([Promise.resolve().then(()=>(init_execute_cursor(),execute_cursor_exports)),Promise.resolve().then(()=>(init_execute_deep_agent(),execute_deep_agent_exports)),Promise.resolve().then(()=>(init_ensure_thread(),ensure_thread_exports)),Promise.resolve().then(()=>(init_classify_tool_approvals(),classify_tool_approvals_exports)),Promise.resolve().then(()=>(init_discover_mcp_server(),discover_mcp_server_exports)),Promise.resolve().then(()=>(init_evaluate_expressions(),evaluate_expressions_exports)),Promise.resolve().then(()=>(init_call_http(),call_http_exports)),Promise.resolve().then(()=>(init_call_grpc(),call_grpc_exports)),Promise.resolve().then(()=>(init_call_function(),call_function_exports)),Promise.resolve().then(()=>(init_call_llm(),call_llm_exports)),Promise.resolve().then(()=>(init_call_agent(),call_agent_exports)),Promise.resolve().then(()=>(init_call_agent_status(),call_agent_status_exports)),Promise.resolve().then(()=>(init_run_command(),run_command_exports)),Promise.resolve().then(()=>(init_hydrate_workflow_execution(),hydrate_workflow_execution_exports)),Promise.resolve().then(()=>(init_workflow_event_activities(),workflow_event_activities_exports)),Promise.resolve().then(()=>(init_promote_task_output(),promote_task_output_exports))]);return{...createCursorActivities2(config4),...createDeepAgentActivities2(config4),...createEnsureThreadActivities2(),...createClassifyToolApprovalsActivities2(config4),...createDiscoverMcpServerActivities2(config4),...createEvaluateExpressionsActivities2(),...createCallHttpActivities2(),...createCallGrpcActivities2(),...createCallFunctionActivities2(),...createCallLlmActivities2(),...createCallAgentActivities2(),...createCallAgentStatusActivities2(),...createRunCommandActivities2(),...createHydrateWorkflowActivities2(config4),...createWorkflowEventActivities2(),...createPromoteTaskOutputActivities2()}}async function createPayloadCodec2(config4){let{loadClaimcheckConfig:loadClaimcheckConfig2,ClaimcheckPayloadCodec:ClaimcheckPayloadCodec2}=await Promise.resolve().then(()=>(init_claimcheck(),claimcheck_exports)),claimcheckConfig=loadClaimcheckConfig2();if(!claimcheckConfig.enabled)return;let{loadArtifactStorageConfig:loadArtifactStorageConfig2,createArtifactStorage:createArtifactStorage2}=await Promise.resolve().then(()=>(init_artifact_storage(),artifact_storage_exports)),storageConfig=loadArtifactStorageConfig2(config4),storage=createArtifactStorage2(storageConfig);return console.log(`[runner] Claimcheck enabled (threshold=${claimcheckConfig.thresholdBytes}B, compression=${claimcheckConfig.compressionEnabled}, storage=${storageConfig.type})`),new ClaimcheckPayloadCodec2(storage,claimcheckConfig)}function resolveDefaultWorkspaceDir2(){try{let dir=(0,import_node_path35.join)((0,import_node_os6.homedir)(),".stigmer","workspaces","runner");return(0,import_node_fs9.mkdirSync)(dir,{recursive:!0}),dir}catch{let dir=(0,import_node_path35.join)((0,import_node_os6.tmpdir)(),"stigmer-runner-workspace");return(0,import_node_fs9.mkdirSync)(dir,{recursive:!0}),dir}}function normalizeEndpoint3(endpoint){return endpoint.startsWith("http://")||endpoint.startsWith("https://")?endpoint:endpoint.endsWith(":443")?`https://${endpoint}`:`http://${endpoint}`}init_runner_manager();function buildReadyMessage(){return{type:"ready",protocolVersion:1}}init_rejection_capture();var BROKEN_PIPE_CODES=new Set(["EPIPE","ERR_STREAM_DESTROYED","ERR_STREAM_WRITE_AFTER_END"]);function isBrokenPipeError(err){let code=err?.code;return typeof code=="string"&&BROKEN_PIPE_CODES.has(code)}function guardStream(stream,onUnexpectedError){let detached=!1;return stream.on("error",err=>{let wasAttached=!detached;detached=!0,wasAttached&&!isBrokenPipeError(err)&&onUnexpectedError?.(err)}),chunk=>{if(detached)return!1;try{return stream.write(chunk)}catch{return detached=!0,!1}}}var installed=null;function installProcessPipeGuards(){if(installed)return installed;let writeStderr2=guardStream(process.stderr);return installed={writeStdout:guardStream(process.stdout,err=>{writeStderr2(`[pipe-safety] stdout (IPC) channel error, detaching: ${err.stack??err}
2491
+ `):userMessage}return buildEnhancedPrompt({instructions,userMessage,skills,subAgents,workspaceDirs,workspaceFileRefs,attachmentPaths,interactionMode,buildFromPlan})}async function introspectConversation(run,executionId){try{if(!run.supports("conversation")){console.log(`ExecuteCursor conversation introspection unsupported: execution=${executionId}, reason=${run.unsupportedReason("conversation")??"n/a"}`);return}let turns=await run.conversation(),raw=JSON.stringify(turns),bounded=raw.length>8e3?`${raw.slice(0,8e3)}\u2026(truncated ${raw.length} chars)`:raw;return console.error(`ExecuteCursor conversation introspection: execution=${executionId}, turns=${turns.length}, raw=${bounded}`),extractConversationErrorText(turns)}catch(introspectErr){console.warn(`ExecuteCursor conversation introspection failed (non-fatal): execution=${executionId}, error=${introspectErr instanceof Error?introspectErr.message:String(introspectErr)}`);return}}function extractConversationErrorText(turns){if(!turns||turns.length===0)return;let collected=[],visit=(node,depth)=>{if(node==null||depth>6||typeof node!="object")return;if(Array.isArray(node)){for(let item of node)visit(item,depth+1);return}let obj=node;obj.status==="error"&&obj.error!=null&&collected.push(typeof obj.error=="string"?obj.error:JSON.stringify(obj.error));for(let[key,value]of Object.entries(obj))(key==="text"||key==="message"||key==="reason")&&typeof value=="string"&&value.trim().length>0?collected.push(value.trim()):typeof value=="object"&&value!=null&&visit(value,depth+1)};if(visit(turns[turns.length-1],0),collected.length===0)return;let joined=[...new Set(collected)].join(" | ");return joined.length>600?`${joined.slice(0,600)}\u2026`:joined}var import_activity15,import_node_events,init_execute_cursor=__esm({"dist/activities/execute-cursor/index.js"(){"use strict";import_activity15=__toESM(require_lib4(),1);init_esm4();init_api_pb3();init_message_pb();init_subagent_pb();init_enum_pb();init_stigmer_client();init_session_lifecycle();init_enum_pb4();init_cursor_mode();init_message_translator();init_status2();init_tool_row();init_stall_watchdog();init_artifact_storage();init_plan_artifact();init_delta_enricher();init_todo_tracker();init_streaming_scheduler();init_cursor_event_recorder();init_mcp_resolver();init_approval_policy2();init_approval_policy();init_connect_backfill2();init_env_resolver();init_blueprint_resolver();init_subagent_config();init_skill_resolver();init_stigmer_link();init_attachment_resolver();init_prompt_builder();init_workspace_setup();init_platform_dir();init_workspace_lock();init_local_backend();init_approval_state();init_exact_apply();init_git_substrate();init_capture_flow();init_turn_boundary();init_turn_stream();init_cost_guard();init_progress();init_approval_fingerprint();init_fingerprint_secret();init_workspace_provision();init_writeback_coordinator();init_execution_status_writer();init_fetch_interceptor();init_http2_interceptor();init_model_pricing();init_usage_accumulator();init_usage_pb();init_idle_watchdog();init_activity_input();init_rejection_capture();init_error_classifier();init_session_lifecycle();import_node_events=require("node:events");init_heartbeat();init_runner_manager();init_json_schema_to_zod()}});var import_node_crypto22=require("node:crypto"),import_node_fs10=require("node:fs"),import_node_path36=require("node:path"),import_node_readline=require("node:readline");function isNodeSqliteAvailable(){return process.getBuiltinModule?.("node:sqlite")!==void 0}function preflightNodeRuntime(isSqliteAvailable=isNodeSqliteAvailable){return isSqliteAvailable()?null:`Node v${process.versions.node} does not provide the built-in node:sqlite module required by the runner's durable checkpointer. Use Node >= 22.13 (22.x line) or >= 23.4 (23.x and later).`}init_config();init_otel();var import_node_fs9=require("node:fs"),import_node_path35=require("node:path"),import_node_os6=require("node:os");init_config();init_bootstrap();async function createStigmerRunner(options){validateOptions(options);let{registerStigmerDeepagentsProfiles:registerStigmerDeepagentsProfiles2}=await Promise.resolve().then(()=>(init_deepagents_profiles(),deepagents_profiles_exports));registerStigmerDeepagentsProfiles2();let baseConfig=mapOptionsToConfig(options),{installFetchInterceptor:installFetchInterceptor2,getExecutionContext:getExecutionContext2}=await Promise.resolve().then(()=>(init_fetch_interceptor(),fetch_interceptor_exports));installFetchInterceptor2({proxyEndpoint:baseConfig.proxyEndpoint??void 0,stigmerToken:baseConfig.stigmerToken??void 0});let{installHttp2Interceptor:installHttp2Interceptor2,assertHttp2ConnectPatched:assertHttp2ConnectPatched2}=await Promise.resolve().then(()=>(init_http2_interceptor(),http2_interceptor_exports));installHttp2Interceptor2({proxyEndpoint:baseConfig.proxyEndpoint??void 0,stigmerToken:baseConfig.stigmerToken??void 0}),await assertHttp2ConnectPatched2();let coordinates=await resolveRunnerBootstrap({explicitAddress:options.temporalAddress,explicitNamespace:options.temporalNamespace,token:options.stigmerToken,stigmerEndpoint:baseConfig.stigmerBackendEndpoint}),config4={...baseConfig,temporalAddress:coordinates.temporalAddress,temporalNamespace:coordinates.temporalNamespace},{setExecutionContextRef:setExecutionContextRef2}=await Promise.resolve().then(()=>(init_rejection_capture(),rejection_capture_exports));setExecutionContextRef2(getExecutionContext2());let activities=await createAllActivities2(config4);console.log(`[runner] Registered activities: ${Object.keys(activities).join(", ")}`),console.log(`[runner] Task queue: ${config4.taskQueue} | Mode: ${config4.mode} | Max concurrency: ${config4.maxConcurrentActivities}`);let payloadCodec=await createPayloadCodec2(config4),{startWorker:startWorker2}=await Promise.resolve().then(()=>(init_worker(),worker_exports)),worker=await startWorker2({config:config4,activities,payloadCodec});return{async start(){console.log("Worker ready, polling for tasks..."),await worker.run(),console.log("Worker stopped")},shutdown(){worker.shutdown()}}}function validateOptions(options){if(!options.taskQueue)throw new Error("StigmerRunnerOptions.taskQueue is required \u2014 specify the Temporal task queue to poll");if(!options.stigmerEndpoint)throw new Error("StigmerRunnerOptions.stigmerEndpoint is required \u2014 specify the Stigmer server endpoint (e.g. 'http://localhost:7234')")}function mapOptionsToConfig(options){let proxyActive=!!options.proxyEndpoint,mode=options.executionMode??(proxyActive?"cloud":"local");return{taskQueue:options.taskQueue,temporalAddress:options.temporalAddress??"",temporalNamespace:options.temporalNamespace??"default",stigmerBackendEndpoint:normalizeEndpoint3(options.stigmerEndpoint),stigmerToken:options.stigmerToken??null,cursorApiKey:proxyActive?options.cursorApiKey??"proxy-managed":options.cursorApiKey??"",workspaceRootDir:options.workspaceRootDir??resolveDefaultWorkspaceDir2(),mode,proxyEndpoint:options.proxyEndpoint??null,maxConcurrentActivities:options.maxConcurrentActivities??5,idleTimeoutSeconds:null,cloudModeEnabled:options.cloudModeEnabled??!1,checkpointerType:options.checkpointerType??(proxyActive?"http":"sqlite"),checkpointerProxyEndpoint:options.checkpointerProxyEndpoint??options.proxyEndpoint??null,primaryModel:options.primaryModel??"gpt-4.1",cursorStreamStallTimeoutMs:options.cursorStreamStallTimeoutMs??DEFAULT_CURSOR_STREAM_STALL_TIMEOUT_MS,workspaceLockTimeoutMs:options.workspaceLockTimeoutMs??DEFAULT_WORKSPACE_LOCK_TIMEOUT_MS}}async function createAllActivities2(config4){let[{createCursorActivities:createCursorActivities2},{createDeepAgentActivities:createDeepAgentActivities2},{createEnsureThreadActivities:createEnsureThreadActivities2},{createClassifyToolApprovalsActivities:createClassifyToolApprovalsActivities2},{createDiscoverMcpServerActivities:createDiscoverMcpServerActivities2},{createEvaluateExpressionsActivities:createEvaluateExpressionsActivities2},{createCallHttpActivities:createCallHttpActivities2},{createCallGrpcActivities:createCallGrpcActivities2},{createCallFunctionActivities:createCallFunctionActivities2},{createCallLlmActivities:createCallLlmActivities2},{createCallAgentActivities:createCallAgentActivities2},{createCallAgentStatusActivities:createCallAgentStatusActivities2},{createRunCommandActivities:createRunCommandActivities2},{createHydrateWorkflowActivities:createHydrateWorkflowActivities2},{createWorkflowEventActivities:createWorkflowEventActivities2},{createPromoteTaskOutputActivities:createPromoteTaskOutputActivities2}]=await Promise.all([Promise.resolve().then(()=>(init_execute_cursor(),execute_cursor_exports)),Promise.resolve().then(()=>(init_execute_deep_agent(),execute_deep_agent_exports)),Promise.resolve().then(()=>(init_ensure_thread(),ensure_thread_exports)),Promise.resolve().then(()=>(init_classify_tool_approvals(),classify_tool_approvals_exports)),Promise.resolve().then(()=>(init_discover_mcp_server(),discover_mcp_server_exports)),Promise.resolve().then(()=>(init_evaluate_expressions(),evaluate_expressions_exports)),Promise.resolve().then(()=>(init_call_http(),call_http_exports)),Promise.resolve().then(()=>(init_call_grpc(),call_grpc_exports)),Promise.resolve().then(()=>(init_call_function(),call_function_exports)),Promise.resolve().then(()=>(init_call_llm(),call_llm_exports)),Promise.resolve().then(()=>(init_call_agent(),call_agent_exports)),Promise.resolve().then(()=>(init_call_agent_status(),call_agent_status_exports)),Promise.resolve().then(()=>(init_run_command(),run_command_exports)),Promise.resolve().then(()=>(init_hydrate_workflow_execution(),hydrate_workflow_execution_exports)),Promise.resolve().then(()=>(init_workflow_event_activities(),workflow_event_activities_exports)),Promise.resolve().then(()=>(init_promote_task_output(),promote_task_output_exports))]);return{...createCursorActivities2(config4),...createDeepAgentActivities2(config4),...createEnsureThreadActivities2(),...createClassifyToolApprovalsActivities2(config4),...createDiscoverMcpServerActivities2(config4),...createEvaluateExpressionsActivities2(),...createCallHttpActivities2(),...createCallGrpcActivities2(),...createCallFunctionActivities2(),...createCallLlmActivities2(),...createCallAgentActivities2(),...createCallAgentStatusActivities2(),...createRunCommandActivities2(),...createHydrateWorkflowActivities2(config4),...createWorkflowEventActivities2(),...createPromoteTaskOutputActivities2()}}async function createPayloadCodec2(config4){let{loadClaimcheckConfig:loadClaimcheckConfig2,ClaimcheckPayloadCodec:ClaimcheckPayloadCodec2}=await Promise.resolve().then(()=>(init_claimcheck(),claimcheck_exports)),claimcheckConfig=loadClaimcheckConfig2();if(!claimcheckConfig.enabled)return;let{loadArtifactStorageConfig:loadArtifactStorageConfig2,createArtifactStorage:createArtifactStorage2}=await Promise.resolve().then(()=>(init_artifact_storage(),artifact_storage_exports)),storageConfig=loadArtifactStorageConfig2(config4),storage=createArtifactStorage2(storageConfig);return console.log(`[runner] Claimcheck enabled (threshold=${claimcheckConfig.thresholdBytes}B, compression=${claimcheckConfig.compressionEnabled}, storage=${storageConfig.type})`),new ClaimcheckPayloadCodec2(storage,claimcheckConfig)}function resolveDefaultWorkspaceDir2(){try{let dir=(0,import_node_path35.join)((0,import_node_os6.homedir)(),".stigmer","workspaces","runner");return(0,import_node_fs9.mkdirSync)(dir,{recursive:!0}),dir}catch{let dir=(0,import_node_path35.join)((0,import_node_os6.tmpdir)(),"stigmer-runner-workspace");return(0,import_node_fs9.mkdirSync)(dir,{recursive:!0}),dir}}function normalizeEndpoint3(endpoint){return endpoint.startsWith("http://")||endpoint.startsWith("https://")?endpoint:endpoint.endsWith(":443")?`https://${endpoint}`:`http://${endpoint}`}init_runner_manager();function buildReadyMessage(){return{type:"ready",protocolVersion:1}}init_rejection_capture();var BROKEN_PIPE_CODES=new Set(["EPIPE","ERR_STREAM_DESTROYED","ERR_STREAM_WRITE_AFTER_END"]);function isBrokenPipeError(err){let code=err?.code;return typeof code=="string"&&BROKEN_PIPE_CODES.has(code)}function guardStream(stream,onUnexpectedError){let detached=!1;return stream.on("error",err=>{let wasAttached=!detached;detached=!0,wasAttached&&!isBrokenPipeError(err)&&onUnexpectedError?.(err)}),chunk=>{if(detached)return!1;try{return stream.write(chunk)}catch{return detached=!0,!1}}}var installed=null;function installProcessPipeGuards(){if(installed)return installed;let writeStderr2=guardStream(process.stderr);return installed={writeStdout:guardStream(process.stdout,err=>{writeStderr2(`[pipe-safety] stdout (IPC) channel error, detaching: ${err.stack??err}
2492
2492
  `)}),writeStderr:writeStderr2},installed}function reportFatal(write,label,err){try{let detail=err instanceof Error?err.stack??err.message:String(err);write(`${label} ${detail}
2493
2493
  `)}catch{}}var{writeStdout,writeStderr}=installProcessPipeGuards();process.on("unhandledRejection",reason=>{handleUnhandledRejection(reason)});process.on("uncaughtException",err=>{reportFatal(writeStderr,"Uncaught exception in runner:",err)});function sendIpc(msg){writeStdout(JSON.stringify(msg)+`
2494
2494
  `)}async function runManagerMode(config4){let originalLog=console.log;console.log=(...args)=>{writeStderr(args.map(String).join(" ")+`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stigmer/runner-slim",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
4
4
  "description": "Self-contained Stigmer runner build for embedding in desktop apps — the bundle-friendly @stigmer/runner",
5
5
  "license": "Apache-2.0",
6
6
  "engines": {
@@ -16,11 +16,11 @@
16
16
  "jq-wasm": "^1.1.0-jq-1.8.1"
17
17
  },
18
18
  "optionalDependencies": {
19
- "@stigmer/runner-slim-darwin-arm64": "3.2.0",
20
- "@stigmer/runner-slim-darwin-x64": "3.2.0",
21
- "@stigmer/runner-slim-linux-x64": "3.2.0",
22
- "@stigmer/runner-slim-linux-arm64": "3.2.0",
23
- "@stigmer/runner-slim-win32-x64": "3.2.0"
19
+ "@stigmer/runner-slim-darwin-arm64": "3.2.1",
20
+ "@stigmer/runner-slim-darwin-x64": "3.2.1",
21
+ "@stigmer/runner-slim-linux-x64": "3.2.1",
22
+ "@stigmer/runner-slim-linux-arm64": "3.2.1",
23
+ "@stigmer/runner-slim-win32-x64": "3.2.1"
24
24
  },
25
25
  "keywords": [
26
26
  "stigmer",