@devflow-tools/claude-code-plugin 0.19.20 → 0.19.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/dist/command-registry.json +7 -7
- package/dist/hooks/hook-daemon.js +17 -17
- package/dist/hooks/pre-tool-use.js +5 -5
- package/dist/hooks/session-end.js +3 -3
- package/dist/hooks/stop.js +2 -2
- package/dist/runtime-manifest.json +6 -6
- package/package.json +14 -14
|
@@ -14,31 +14,31 @@ import {createServer,createConnection}from'net';import {createHash,randomUUID as
|
|
|
14
14
|
`)+1)));let d=c.split(/\r?\n/).slice(-$a),l=t.length>0?Math.min(...t.map(p=>p.promptedAt)):0,u=Qa(d,l),f=[...u].reverse().find(p=>Xa(p.text,t))??u.at(-1);return f?.text?{answer:f.text,fingerprint:f.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{n!==void 0&&closeSync$1(n);}}function Xa(e,t){let n=new Set(t.flatMap(r=>r.contract.requiredSections)),o=Fo($o(e.split(/\r?\n/u)).headingLines);return [...n].every(r=>o.found.has(r))}function ze(e){return At(e,[]).answer}function Qa(e,t){let n=[];for(let o=0;o<e.length;o++){let r=e[o];if(r.trim())try{let i=JSON.parse(r),s=i.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,c=Za(i.timestamp);if(c>0&&c+5e3<t)continue;let d=s.content,l=typeof d=="string"?d:Array.isArray(d)?d.filter(u=>u&&typeof u=="object"&&u.type==="text").map(u=>u.text).filter(u=>typeof u=="string").join(`
|
|
15
15
|
`):"";if(l.trim()){let u=l.trim(),m=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof i.uuid=="string"&&i.uuid?`uuid:${i.uuid}`:`record:${String(i.timestamp??"")}:${o}:${createHash("sha256").update(r).digest("hex")}`,f=createHash("sha256").update(u).digest("hex"),p=createHash("sha256").update(`${m}\0${f}`).digest("hex");n.push({text:u,timestamp:c,fingerprint:p});}}catch{continue}}return n}function Za(e){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e!="string")return 0;let t=Date.parse(e);return Number.isFinite(t)?t:0}function Fo(e){let t=new Set,n=new Map,o;for(let r=0;r<e.length;r++){let i=e[r].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=ge.find(a=>i===a);s&&(o=s,t.add(s)),n.set(r,o);}return {found:t,byLine:n}}function Lo(e){let t;try{if(sc(e.toolResponse))return null;t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let n=t.getActiveContextReceipt(e.projectRoot,e.sessionId,e.executionId);if(!n)return null;let o=nc(e.toolInput);if(o.length===0)return null;let r=e.toolName==="Read"?oc(e.toolInput):void 0,i=r?n.selectedFiles?.find(l=>rc(e.projectRoot,l,r)):void 0,s=ic(e.toolName),a=i?"code":n.canonicalNextAction===s?"action":null,c=i&&o.includes(i)?i:a==="action"&&o.includes(s)?s:void 0;if(a&&c){let l=[n.contextHash,n.requestId??"",a,c,e.toolUseId??`${e.sessionId}:${e.executionId??n.executionId}`].join("\0");t.recordContextSelectionEvent({id:`ctxsel:${createHash("sha256").update(l).digest("hex").slice(0,32)}`,projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:n.executionId,requestId:n.requestId,selectionType:a,candidateId:c,toolName:e.toolName,toolUseId:e.toolUseId,selectedAt:Date.now()});}let d=t.listRetrievalLedgerEvents({projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:n.executionId,requestId:n.requestId}).filter(l=>l.stage==="selected"&&o.includes(l.sourceId));for(let l of d)t.appendRetrievalLedgerEvent({...l,id:retrievalLedgerTransitionId(l.id,"consumed",e.toolUseId??e.toolName),stage:"consumed",toolEvidence:[e.toolUseId??e.toolName],evidenceIds:o,actor:e.toolName,reasonCode:"structural_evidence_ref",payload:{...l.payload,consumedByTool:e.toolName},createdAt:Date.now()});return d.length>0&&ye({event:"retrieval.attribution.transitioned",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:n.executionId,requestId:n.requestId,contextReceipt:n.contextHash},level:"info",timestamp:Date.now(),data:{stage:"consumed",actor:e.toolName,consumedCount:d.length,evidenceRefCount:o.length}}),a}catch(n){throw ye({event:"hook.runtime.degraded",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:e.executionId,requestId:e.requestId},level:"warn",timestamp:Date.now(),data:{stage:"retrieval_attribution",actor:e.toolName,reason:n instanceof Error?n.message:String(n)}}),n}finally{try{t?.close();}catch{}}}function qo(e){let t=openGlobalDevFlowDatabase();try{let n=t.listRetrievalLedgerEvents(e),o=new Map(n.filter(u=>u.stage==="selected").map(u=>[Ho(u),u])),r=new Map(n.filter(u=>u.stage==="consumed").map(u=>[Ho(u),u])),i=0,s=0,a=0;for(let[u,m]of o){let f=r.get(u);f&&e.verificationReceipt&&t.appendRetrievalLedgerEvent({...f,id:retrievalLedgerTransitionId(f.id,"verified",e.verificationReceipt),stage:"verified",verificationReceipt:e.verificationReceipt,reasonCode:"same_task_verification_receipt",createdAt:e.finishedAt??Date.now()});let p=f&&e.verificationReceipt&&e.outcome!=="unknown"?e.outcome:"unknown",g=p==="positive"?"positive_outcome":p==="negative"?"negative_outcome":"unknown_outcome";t.appendRetrievalLedgerEvent({...m,id:retrievalLedgerTransitionId(m.id,g,e.verificationReceipt??e.sessionId),stage:g,reason:f?e.outcomeReason:"selected_not_consumed",toolEvidence:f?.toolEvidence??[],verificationReceipt:p==="unknown"?void 0:e.verificationReceipt,payload:{...m.payload,consumed:!!f},createdAt:e.finishedAt??Date.now()}),g==="positive_outcome"?i+=1:g==="negative_outcome"?s+=1:a+=1;}let c=e.requiredChannels.map(u=>{let m=[...o.values()].filter(p=>p.sourceType===u).length,f=[...r.values()].filter(p=>p.sourceType===u).length;return {channel:u,selected:m,consumed:f,verified:e.verificationReceipt?f:0}}),d={status:c.length>0&&c.every(u=>u.selected>0&&u.consumed===u.selected&&u.verified===u.selected)?"complete":"unavailable",channels:c},l={consumed:r.size,positive:i,negative:s,unknown:a,consumedSources:[...r.values()].map(u=>({sourceType:u.sourceType,sourceId:u.sourceId})),proof:d};return e.verificationReceipt&&r.size>0&&ye({event:"retrieval.attribution.transitioned",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:e.executionId,requestId:e.requestId},level:"info",timestamp:e.finishedAt??Date.now(),data:{stage:"verified",verifiedCount:r.size}}),ye({event:"task.proof.completed",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:e.executionId,requestId:e.requestId},level:d.status==="complete"?"info":"warn",timestamp:e.finishedAt??Date.now(),data:d}),ye({event:"retrieval.attribution.transitioned",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:e.executionId,requestId:e.requestId},level:a>0?"warn":"info",timestamp:e.finishedAt??Date.now(),data:{stage:"session_outcome",selectedCount:o.size,consumedCount:r.size,verifiedCount:e.verificationReceipt?r.size:0,positiveCount:i,negativeCount:s,unknownCount:a}}),l}finally{t.close();}}function nc(...e){let t=new Set,n=(o,r=0)=>{if(!(r>6||o==null)){if(typeof o=="string"){try{n(JSON.parse(o),r+1);}catch{}return}if(Array.isArray(o)){for(let i of o)n(i,r+1);return}if(typeof o=="object")for(let[i,s]of Object.entries(o))if((i==="evidenceRefs"||i==="_devflow_evidence_refs")&&Array.isArray(s))for(let a of s)typeof a=="string"&&a.trim()&&t.add(a.trim());else n(s,r+1);}};for(let o of e)n(o);return [...t]}function oc(e){for(let t of ["file_path","path"]){let n=e[t];if(typeof n=="string"&&n.trim())return n.trim()}}function rc(e,t,n){let o=resolve(e,t),r=isAbsolute(n)?resolve(n):resolve(e,n);return o===r}function ic(e){return e.startsWith("mcp__")?e.split("__").at(-1)??e:e}function sc(e){if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return t.ok===false||t.success===false||t.isError===true||!!t.error||["failed","rejected","unavailable"].includes(String(t.status??""))}function Ho(e){return [e.requestId,e.contextReceipt,e.sourceType,e.sourceId].join("\0")}function ye(e){try{y(e);}catch{}}var fc=8*1024*1024;function zo(e){if(!e.transcriptPath||!existsSync(e.transcriptPath))return {status:"unavailable",eventsRead:0,failuresFound:0,failuresRecorded:0,reason:"transcript_path_unavailable"};let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let n=t.getLatestTranscriptCheckpoint({projectRoot:e.projectRoot,hostId:"claude-code",sessionId:e.sessionId,sourcePath:e.transcriptPath}),o=statSync(e.transcriptPath).size,r=Math.min(n?.byteOffset??0,o),i=Math.min(fc,o-r);if(i<=0)return {status:"completed",eventsRead:0,failuresFound:0,failuresRecorded:0,checkpointId:n?.id};let s=Buffer.alloc(i),a=openSync$1(e.transcriptPath,"r");try{readSync(a,s,0,i,r);}finally{closeSync$1(a);}let c=s.toString("utf8").split(/\r?\n/u).filter(Boolean),d=t.listLatestTaskIntentArtifacts(e.projectRoot,e.sessionId),l=new Map,u=new Set,m=0,f=0;for(let h of c){let b;try{b=JSON.parse(h);}catch{continue}for(let S of Mt(b,l)){let _=claudeCodeRuntimeAdapter.normalizeToolResult(S,{projectRoot:e.projectRoot});if(_.success||!_.error)continue;let x=_.toolUseId??_.sourceHash;if(u.has(x))continue;u.add(x),m++;let T=_.toolUseId?t.getToolCallEventByToolUseId(e.sessionId,_.toolUseId):null,C=Uo(T?.input,"_devflow_turn_id"),A=Uo(T?.input,"_devflow_request_id"),M=C?d.find(D=>D.turnId===C):[...d].reverse().find(D=>(!T?.executionId||D.executionId===T.executionId)&&D.createdAt<=(T?.timestamp??_.timestamp))??d.at(-1),R=`host-failure:${_.sourceHash}`;t.insertEvent({kind:"host_transcript_tool_failure",timestamp:_.timestamp,success:!1,toolName:_.canonicalName??_.requestedName,metadata:{projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:C??M?.turnId,requestId:A??M?.requestId,sourceId:R,toolUseId:_.toolUseId,correlatedEventId:T?.eventId,requestedName:_.requestedName,canonicalName:_.canonicalName,failureCategory:_.failureCategory,error:_.error.slice(0,1e3)}}),y({event:"host.tool.result.reconciled",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:C??M?.turnId,requestId:A??M?.requestId,executionId:T?.executionId},level:"warn",timestamp:Date.now(),data:{toolUseId:_.toolUseId,toolName:_.canonicalName??_.requestedName,failureCategory:_.failureCategory,correlation:T?"tool_use_id":"timestamp_fallback"}}),f++;}}let p=createHash("sha256").update(s).digest("hex"),g=`transcript:${createHash("sha256").update(`${e.projectRoot}\0${e.sessionId}\0${e.transcriptPath}\0${r+i}\0${p}`).digest("hex").slice(0,24)}`;return t.appendTranscriptCheckpoint({id:g,projectRoot:e.projectRoot,hostId:"claude-code",sessionId:e.sessionId,sourcePath:e.transcriptPath,sourceHash:p,byteOffset:r+i,eventCount:c.length,createdAt:Date.now()}),y({event:"session.reconciled",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId},level:m>0?"warn":"info",timestamp:Date.now(),data:{stage:"transcript",eventsRead:c.length,failuresFound:m,failuresRecorded:f,checkpointId:g}}),{status:"completed",eventsRead:c.length,failuresFound:m,failuresRecorded:f,checkpointId:g}}catch(n){return {status:"degraded",eventsRead:0,failuresFound:0,failuresRecorded:0,reason:n instanceof Error?n.message:String(n)}}finally{t.close();}}function Uo(e,t){let n=e?.[t];return typeof n=="string"&&n.trim()?n.trim():void 0}function Mt(e,t,n=0){if(n>7||e===null||e===void 0)return [];if(Array.isArray(e))return e.flatMap(s=>Mt(s,t,n+1));if(typeof e!="object")return [];let o=e,r=typeof o.type=="string"?o.type:"";r==="tool_use"&&typeof o.id=="string"&&typeof o.name=="string"&&t.set(o.id,o.name);let i=[];if(r==="tool_result"){let s=typeof o.tool_use_id=="string"?o.tool_use_id:void 0;i.push({tool_name:s?t.get(s)??"unknown":"unknown",tool_use_id:s,tool_response:o.content,is_error:o.is_error===true,...o.is_error===true?{error:Ot(o.content)||"host tool result failed"}:{},timestamp:o.timestamp});}else (o.tool_name||o.toolName)&&(o.tool_response!==void 0||o.output!==void 0||o.error!==void 0)&&i.push(o);for(let[s,a]of Object.entries(o))s==="content"&&r==="tool_result"||i.push(...Mt(a,t,n+1));return i}function Ot(e){if(typeof e=="string")return e.slice(0,4e3);if(Array.isArray(e))return e.map(Ot).filter(Boolean).join(`
|
|
16
16
|
`).slice(0,4e3);if(!e||typeof e!="object")return "";let t=e;return [t.text,t.content,t.message].map(Ot).filter(Boolean).join(`
|
|
17
|
-
`).slice(0,4e3)}var yc={open:["intent_bound"],intent_bound:["context_ready","context_degraded"],context_ready:["action_required","action_not_required"],context_degraded:["action_required","action_not_required"],action_required:["action_satisfied","action_degraded","action_failed"],action_not_required:["memory_decided","memory_quarantined"],action_satisfied:["memory_decided","memory_quarantined"],action_degraded:["memory_decided","memory_quarantined"],action_failed:["action_satisfied","action_degraded"],memory_decided:["closed","closed_with_degradation","closed_with_retry_work"],memory_quarantined:["closed_with_degradation","closed_with_retry_work"],closed:[],closed_with_degradation:[],closed_with_retry_work:[]};function Bo(e){return vc(e)}function vc(e){let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let n=bc(t,e.artifact);if(kc(n.toState))return n;let o=t.getContextReceiptForRequest(e.artifact.projectRoot,e.artifact.sessionId,e.artifact.requestId),r=t.getMemoryTurn(e.artifact.turnId),i=e.artifact.intent==="memory"||r?.source==="explicit_intent";if(!o&&!i)return n;let s=o?Ic(e.artifact,o):"context_ready";n.toState==="intent_bound"&&(n=H(t,n,e,s,i?"task_context_not_required":s==="context_ready"?"canonical_context_receipt_ready":"canonical_context_receipt_degraded"));let a=o?wc(e.artifact,o):"action_not_required";if((n.toState==="context_ready"||n.toState==="context_degraded")&&(a==="action_not_required"?n=H(t,n,e,"action_not_required","task_action_not_required"):n=H(t,n,e,"action_required","canonical_action_obligation_present")),n.toState==="action_required"){if(a==="action_required")return n;if(a==="action_failed")return H(t,n,e,"action_failed","canonical_action_attempt_failed");a==="action_degraded"?n=H(t,n,e,"action_degraded","canonical_action_unavailable_or_degraded"):a==="action_satisfied"&&(n=H(t,n,e,"action_satisfied","canonical_action_succeeded"));}if(n.toState==="action_failed")if(a==="action_satisfied")n=H(t,n,e,"action_satisfied","canonical_action_retry_succeeded");else if(a==="action_degraded")n=H(t,n,e,"action_degraded","canonical_action_retry_degraded");else return n;let c=s==="context_degraded"||a==="action_degraded";return ["action_not_required","action_satisfied","action_degraded"].includes(n.toState)&&(n=H(t,n,e,e.memoryStatus==="pending"?"memory_quarantined":"memory_decided",e.memoryStatus==="pending"?e.reason:`canonical_memory_${e.memoryStatus}`)),n.toState==="memory_decided"?H(t,n,e,c?"closed_with_degradation":"closed",e.reason):n.toState==="memory_quarantined"?H(t,n,e,e.retryOwned?"closed_with_retry_work":"closed_with_degradation",e.retryOwned?"durable_retry_owner_confirmed":"terminal_obligation_unowned"):n}finally{t.close();}}function Ic(e,t){return e.intent==="memory"||e.intent==="knowledge"||(t.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function wc(e,t){let n=t.canonicalAction,r=(n?(t.actionAttempts??[]).filter(i=>i.tool===n.tool):[]).at(-1);return t.actionSatisfiedAt||r?.status==="succeeded"?"action_satisfied":r&&["failed","timeout","unavailable"].includes(r.status)?"action_failed":t.actionDegradation||n?.status==="degraded"||n?.status==="unsupported"?"action_degraded":n?.required||_c(e)?"action_required":"action_not_required"}function _c(e){return ["create","modify","debug","test","format"].includes(e.action)||["feature","refactor","performance"].includes(e.intent)}function bc(e,t){let n=e.getLatestTerminalTransition(t.projectRoot,t.sessionId,t.turnId);if(!n)throw new Error(`TERMINAL_INTENT_STATE_MISSING:${t.turnId}`);return n}function H(e,t,n,o,r){if(!yc[t.toState]?.includes(o))throw new Error(`TERMINAL_PATH_UNAVAILABLE:${t.toState}->${o}`);let i=t.sequence+1,s=`terminal:${createHash("sha256").update(`${n.artifact.artifactHash}\0${i}\0${o}`).digest("hex").slice(0,24)}`,a=e.appendTerminalTransition({projectRoot:n.artifact.projectRoot,projectId:n.artifact.projectId,hostId:n.artifact.hostId,sessionId:n.artifact.sessionId,turnId:n.artifact.turnId,requestId:n.artifact.requestId,executionId:n.artifact.executionId,sequence:i,fromState:t.toState,toState:o,receiptId:s,sourceReceiptId:n.memoryReceiptId??t.receiptId,reason:r,payload:{memoryStatus:n.memoryStatus,retryOwned:n.retryOwned??false,sourceIntentHash:n.artifact.artifactHash},createdAt:Date.now()});return y({event:"terminal.state.transitioned",identity:{projectRoot:n.artifact.projectRoot,projectId:n.artifact.projectId,hostId:n.artifact.hostId,sessionId:n.artifact.sessionId,turnId:n.artifact.turnId,requestId:n.artifact.requestId,...n.artifact.executionId?{executionId:n.artifact.executionId}:{}},level:o==="closed"?"info":o.includes("degradation")||o.includes("retry")||o==="action_failed"?"warn":"info",timestamp:Date.now(),data:{fromState:t.toState,nextState:o,receiptId:s,reason:r}}),a}function kc(e){return e==="closed"||e==="closed_with_degradation"||e==="closed_with_retry_work"}var Sc=new Set(["delivered","cancelled","rejected"]),Rc=new Set(["cancelled","rejected"]),xc=new Set(["Write","Edit","NotebookEdit","Bash"]);function Ec(e,t){if(e!=="Bash"||typeof t?.command!="string")return false;let n=t.command.trim(),r="git show [A-Za-z0-9._/:@{}^~+\\-]+(?: 2>/dev/null)?";if(new RegExp(`^${r}(?: \\|\\| ${r})*$`,"u").test(n))return true;if(/[;&|<>`$()]|\\/u.test(n))return false;let i=/^git(?:\s+-C\s+\S+)?\s+(?:show|status|diff|log|branch)(?:\s|$)/u;return /^(?:ls|pwd|find|rg|grep|cat|sed|head|tail|wc|which|stat|file)(?:\s|$)/u.test(n)||i.test(n)}function Go(e,t){let n=join(e,".devflow","delivery-line","state.db");if(!existsSync(n)||!t.trim())return 0;let o;try{o=new DatabaseSync(n,{timeout:250});let r=o.prepare("SELECT id, payload FROM delivery_cases WHERE id = ? OR json_extract(payload, '$.sessionId') = ?").all(t,t),i=0,s=!!o.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_events'").get();for(let a of r){let c="incomplete";try{let d=JSON.parse(a.payload);c=d.evidence?.some(l=>l.metadata?.trust==="external-untrusted")?"untrusted":d.stage==="delivered"?"clean":"incomplete";}catch{}if(i+=Number(o.prepare("UPDATE delivery_tasks SET lease_owner = NULL, lease_expires_at = NULL WHERE case_id = ? AND lease_owner IS NOT NULL").run(a.id).changes),s){let d=`session.closed:${a.id}:${t}`;o.prepare("INSERT OR IGNORE INTO delivery_events (id,case_id,idempotency_key,actor,type,payload,created_at,processed_at) VALUES (?,?,?,?,?,?,?,NULL)").run(d,a.id,d,JSON.stringify({id:"devflow:session-end",kind:"system"}),"session.closed",JSON.stringify({sessionId:t,releasedLeases:i,outcome:c}),Date.now());}}return i}catch{return 0}finally{o?.close();}}function Yo(e,t,n,o,r){if(n.includes("delivery_rebind_session")||!xc.has(n)||!t.trim()||Ec(n,r))return null;let i=join(e,".devflow","delivery-line","state.db");if(!existsSync(i))return null;let s;try{s=new DatabaseSync(i,{readOnly:!0,timeout:250});let a=s.prepare("SELECT id, payload, updated_at FROM delivery_cases").all(),c=new Set;if(!!s.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_workflow_bindings'").get()){let f=s.prepare("SELECT case_id, source_path, aliases FROM delivery_workflow_bindings WHERE status = 'enforced'").all();for(let p of f){let g=[];try{g=JSON.parse(p.aliases);}catch{}(p.source_path===e||g.includes(e))&&c.add(p.case_id);}}let l=[];for(let f of a){let p=JSON.parse(f.payload),g=c.has(f.id);(p.sessionId===t||t===f.id||g)&&l.push({id:f.id,payload:p,updatedAt:typeof f.updated_at=="number"?f.updated_at:typeof p.updatedAt=="number"?p.updatedAt:0});let h=typeof p.stage=="string"?p.stage:"unknown";if(!Sc.has(h)){if(o&&h==="executing"){let b=s.prepare("SELECT id, lease_owner, fencing_token FROM delivery_tasks WHERE case_id = ? AND lease_expires_at > ? AND lease_owner IS NOT NULL AND fencing_token > 0 LIMIT 1").get(f.id,Date.now()),S=typeof p.sessionId=="string"?p.sessionId:void 0,_=typeof p.executionId=="string"?p.executionId:void 0,x=o===b?.id||o===b?.lease_owner||o===_,T=t===f.id||t===S;if(b?.id&&x&&T)return null}if(p.sessionId===t||t===f.id||g)return {code:"DELIVERY_AUTHORITY_REQUIRED",caseId:f.id,stage:h,message:`Delivery case ${f.id} is ${h}; use the Delivery task lease before modifying files.`}}}let u=l.sort((f,p)=>p.updatedAt-f.updatedAt)[0],m=typeof u?.payload.stage=="string"?u.payload.stage:void 0;return u&&m&&Rc.has(m)?{code:"DELIVERY_AUTHORITY_REQUIRED",caseId:u.id,stage:m,message:`Delivery case ${u.id} is ${m}; start a new Delivery case or session before modifying files.`}:null}catch(a){return y({event:"hook.runtime.degraded",identity:{projectRoot:e},level:"warn",timestamp:Date.now(),data:{stage:"delivery_authority",operation:"delivery_write_block",reason:a instanceof Error?a.message:String(a),fallback:"fail_open_unverified_write"}}),null}finally{s?.close();}}function Pt(e){let t={committed:0,skipped:0,pending:0},n=[];for(let o of e)t[o.status]+=1,o.receiptId&&n.push(o.receiptId);return {memoryReceiptIds:[...new Set(n)],missingMemoryDecisionCount:t.pending,memoryTurnOutcomes:t}}function N(e){return (e instanceof Error?e.message:String(e)).trim().slice(0,240)||"memory_lifecycle_unavailable"}var Y=class extends Error{constructor(t,n){super(`session_finalize_${t}:${n}`),this.name="SessionFinalizationRetryableError",this.category=`session_finalize_${t}`;}};function ve(e){let t;try{t=openGlobalDevFlowDatabase();let n=(e.executionId?t.getSkillExecution(e.executionId):null)??t.getLatestSkillExecutionForSession(e.sessionId),o={stage:e.stage,reason:e.reason,degradedAt:Date.now()};n&&t.mergeSkillExecutionMetadata(n.executionId,{...e.metadata,sessionFinalizationDegradations:[o]}),t.insertEvent({kind:"session_finalize_degraded",timestamp:o.degradedAt,success:!1,metadata:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:n?.executionId,...o}}),y({event:"hook.session_end.degraded",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:n?.executionId},level:"warn",timestamp:o.degradedAt,data:{stage:e.stage,reason:e.reason}});}catch{}finally{t?.close();}}function Be(e,t=Ce(),n=true,o,r=true){let i;try{i=JSON.parse(e);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${t}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:e,sessionId:s,cleanupSharedState:n,executionId:o};try{Go(t,s);}catch{}let d;try{d=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let l=d.requestSessionClosure({receiptId:a,projectRoot:t,sessionId:s,payload:c}),u=d.getWorkByIdempotencyKey(a),m={status:l.state==="closed"||l.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:u?.state??"pending",closureState:l.state,pendingWorkCount:l.pendingWorkCount,...u?.id?{workItemId:u.id}:{}};return y({event:"hook.session_end.completed",identity:{projectRoot:t,sessionId:s,executionId:o,terminalReceipt:a},level:m.status==="completed"?"info":"debug",timestamp:Date.now(),data:{stage:"enqueue",...m}}),m}catch(l){if(!r)throw l;return Ro(t,{receiptId:a,...c}),y({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:s,executionId:o,terminalReceipt:a},level:"warn",timestamp:Date.now(),data:{stage:"enqueue",reason:N(l),fallback:"durable_spool"}}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{d?.close();}}async function Qo(e,t=Ce(),n=true,o){let r;try{r=JSON.parse(e);}catch{return}let i=r.session_id?.trim();if(!i)return;let s=new L(t),a=s.get(i),c=zo({projectRoot:t,sessionId:i,transcriptPath:r.transcript_path}),d={evidenceDegradations:a?.evidenceDegradations??[],evidenceContractOutcomes:a?.evidenceOutcomes??[],pendingEvidenceContractIds:a?.evidenceObligations.map(g=>g.contractId)??[],transcriptReconciliation:c},l=o?.telemetry??new te,u=!o?.telemetry,m=()=>{if(!n)return;try{let b=openGlobalDevFlowDatabase();try{b.deleteHookReceipt(t);}finally{b.close();}}catch{}let g=F(t),h=createHash("sha256").update(t).digest("hex").slice(0,12);for(let b of [`session-id-${h}`,"current-execution-id","current-skill.json","event-map.json"])rmSync$1(join(g,b),{force:true});},f=false,p;try{try{await l.flushAndAggregate();}catch{}let g=Date.now(),h=o?.executionId??a?.executionId,b;try{let I=openGlobalDevFlowDatabase();try{b=I.listSessionMemoryTurnsForReconciliation(t,i);for(let v of b){let k=`memory:${v.turnId}`,w=I.getSessionObligation(t,i,k);w?w.state==="open"&&v.status!=="pending"&&I.resolveSessionObligation({projectRoot:t,sessionId:i,obligationId:k,state:"satisfied",receiptId:v.receiptId,reason:v.reason,resolvedAt:v.decidedAt}):I.upsertSessionObligation({obligationId:k,projectRoot:t,sessionId:i,turnId:v.turnId,kind:"memory_decision",state:v.status==="pending"?"open":"satisfied",payload:{eventId:v.eventId,promptHash:v.promptHash},receiptId:v.receiptId,reason:v.reason,createdAt:v.createdAt,updatedAt:v.decidedAt??v.createdAt,resolvedAt:v.decidedAt});}}finally{I.close();}}catch(I){let v=N(I),k={...d,memoryEventReconciliation:{status:"degraded",stage:"turn_load",reason:v,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw ve({projectRoot:t,sessionId:i,executionId:h,stage:"turn_load",reason:v,metadata:k}),new Y("turn_load",v)}let S=Pt(b),_=o?.memory??(p=new MemoryGate(t)),x={status:"completed"};try{x=typeof _.reconcileTurnObservationLineage=="function"?{status:"completed",...await _.reconcileTurnObservationLineage(b)}:{status:"unsupported_adapter",committed:0,skipped:0,quarantined:0,unlinked:0};}catch(I){let v=N(I);throw x={status:"degraded",reason:v},ve({projectRoot:t,sessionId:i,executionId:h,stage:"memory_lineage",reason:v,metadata:{...S,...d,memoryLineageReconciliation:x}}),new Y("memory_lineage",v)}let T={status:"unknown",selected:0,consumed:0,unknown:0,positive:0,negative:0};try{let I=ze(r.transcript_path),v=openGlobalDevFlowDatabase(),k="unknown",w="no_terminal_host_action_evidence",lt,V,q,Q=[],ut=[];try{let J=v.listHostActionsForSession(t,i,h),An=J.filter(j=>j.state==="verified"),mt=J.filter(j=>["failed","cancelled","degraded"].includes(j.state));mt.length>0?(k="negative",w=`terminal_host_action_${mt[0].state}`):An.length>0&&(k="positive",w="host_action_verified");let Te=mt[0]??An.at(-1);if(lt=Te?.runId,V=Te?.contextReceipt,q=Te?.evidenceHash,ut=J.flatMap(j=>{let Z=j.report.toolUseIds;return Array.isArray(Z)?Z.filter(me=>typeof me=="string"):[]}),!Te&&h){let j=v.getSkillExecution(h),Z=j?.metadata&&typeof j.metadata=="object"&&Array.isArray(j.metadata.policyVerificationOutcomes)?j.metadata.policyVerificationOutcomes:[],me=Z.find(K=>K.status==="failed"),pt=Z.filter(K=>K.status==="passed");me?(k="negative",w="policy_verification_failed",q=typeof me.receiptId=="string"?me.receiptId:void 0):pt.length>0&&(k="positive",w="policy_verification_passed",q=typeof pt.at(-1)?.receiptId=="string"?String(pt.at(-1).receiptId):void 0),V=v.getActiveContextReceipt(t,i,h)?.contextHash,ut=Z.map(K=>K.command).filter(K=>typeof K=="string");}V&&(Q=v.getSemanticExecutionContextByHash(V)?.dispositions.filter(j=>j.requirement==="required").map(j=>j.channel)??[]);}finally{v.close();}let Tn=qo({projectRoot:t,sessionId:i,executionId:h,outcome:k,outcomeReason:w,verificationReceipt:q,requiredChannels:Q,finishedAt:g}),Hi=await _.attributeRetrievalBenefits({sessionId:i,executionId:h,outcome:k,outcomeReason:w,workflowRunId:lt,contextReceipt:V,toolEvidence:ut,verificationReceipt:q,consumedSourceIds:Tn.consumedSources.filter(J=>J.sourceType==="memory").map(J=>J.sourceId)});T={status:I?"evaluated":"unknown",...Hi,retrievalLedger:Tn};}catch(I){T={...T,status:"degraded",reason:N(I)};}let C;try{C=await _.reconcileDecidedTurnEventWindows(i,b,g);}catch(I){let v=N(I),k={...S,...d,memoryEventReconciliation:{status:"degraded",stage:"event_reconciliation",reason:v,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw ve({projectRoot:t,sessionId:i,executionId:h,stage:"event_reconciliation",reason:v,metadata:k}),new Y("event_reconciliation",v)}let A;try{A=await fe({projectRoot:t,sessionId:i,trigger:"session_end",memory:_,details:{eventReconciliation:C},strictPersistence:!0});}catch(I){let v=N(I),k={...S,...d,memoryEventReconciliation:{status:"completed",...C,checkpointPending:null},memoryCheckpointDegradation:v};throw ve({projectRoot:t,sessionId:i,executionId:h,stage:"checkpoint",reason:v,metadata:k}),new Y("checkpoint",v)}let M={memoryLineageReconciliation:x,memoryBenefitAttribution:T,memoryEventReconciliation:{status:"completed",...C,checkpointPending:A.pendingEvents},memoryDistillCheckpoint:A};try{let I=openGlobalDevFlowDatabase();try{let v=`session-finalize:${i}:events`,k=Math.max(Number(A.pendingEvents??0),Number(C.remainingUndecided??0)),w=I.getSessionObligation(t,i,v);k>0?I.upsertSessionObligation({obligationId:v,projectRoot:t,sessionId:i,executionId:h,kind:"session_finalize",state:"open",payload:{pendingEvents:k,reconciliation:C,checkpointId:A.id},reason:"active_unprocessed_session_events",createdAt:w?.createdAt??g,updatedAt:g}):w?.state==="open"&&I.resolveSessionObligation({projectRoot:t,sessionId:i,obligationId:v,state:"satisfied",reason:"session_events_reconciled",resolvedAt:g});}finally{I.close();}}catch(I){y({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:h},level:"warn",timestamp:Date.now(),data:{stage:"obligation_persistence",reason:N(I)}});}try{await _.closeSession(i),p&&(p.close(),p=void 0);}catch(I){let v=N(I),k={...S,...d,...M,memorySessionCloseDegradation:v};throw ve({projectRoot:t,sessionId:i,executionId:h,stage:"memory_close",reason:v,metadata:k}),new Y("memory_close",v)}let R={...S,...d,...M},D=[];try{let I=openGlobalDevFlowDatabase();try{let v=new Map(I.listLatestTaskIntentArtifacts(t,i).map(k=>[k.turnId,k]));for(let k of b){let w=v.get(k.turnId);if(!w)continue;let V=[I.getWorkByIdempotencyKey(`memory-turn:capture_prompt:${k.turnId}`),I.getWorkByIdempotencyKey(`memory-turn:commit_explicit:${k.turnId}`)].filter(Boolean).some(Q=>Q.state==="pending"||Q.state==="leased"||Q.state==="failed"),q=Bo({artifact:w,memoryStatus:k.status,memoryReceiptId:k.receiptId,retryOwned:V,reason:k.status==="pending"?"session_end_memory_pending":"session_end_reconciled"});D.push({turnId:k.turnId,state:q.toState,receiptId:q.receiptId});}}finally{I.close();}}catch(I){D.push({state:"terminal_integrity_failure",reason:N(I)});}R.terminalOutcomes=D,f=!0;let P;try{P=openGlobalDevFlowDatabase();let I=h;if(I)try{P.reconcileSkillExecution(I,"completed",g,R);let w=P.getSkillExecution(I);await G("/api/telemetry/skill-execution/complete",{executionId:I,finishedAt:g,status:"completed",summary:{totalToolCalls:w?.totalToolCalls??0,mcpToolCalls:w?.mcpToolCalls??0,directToolCalls:w?.directToolCalls??0,subagentCount:w?.subagentCount??0,totalDuration:w?.totalDuration??0,mcpComplianceRate:w?.mcpComplianceRate??0,missedTools:w?.missedMcpTools??[],actualFailureCount:w?.failedToolCalls??0,fallbackCount:w?.fallbackCount??0,fallbackReasons:w?.fallbackReasons??[]},metadata:R},{fallbackReason:"skill_execution_already_reconciled_locally"});}catch{}let v=P.reconcileRunningSkillExecutionsForSession(i,g,{closureReason:"session_finalize",...R});for(let w of v)await G("/api/telemetry/skill-execution/complete",{executionId:w.executionId,finishedAt:w.finishedAt,status:w.status,summary:{totalToolCalls:w.totalToolCalls??0,mcpToolCalls:w.mcpToolCalls??0,directToolCalls:w.directToolCalls??0,subagentCount:w.subagentCount??0,totalDuration:w.totalDuration??0,mcpComplianceRate:w.mcpComplianceRate??0,missedTools:w.missedMcpTools??[],actualFailureCount:w.failedToolCalls??0,fallbackCount:w.fallbackCount??0,fallbackReasons:w.fallbackReasons??[]},metadata:R},{fallbackReason:"skill_execution_already_reconciled_locally"});let k=P.getLatestSkillExecutionForSession(i);k&&!v.some(w=>w.executionId===k.executionId)&&P.mergeSkillExecutionMetadata(k.executionId,R),P.deleteContextReceipt(t,i);}catch(I){y({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:h},level:"warn",timestamp:Date.now(),data:{stage:"lifecycle_telemetry",reason:N(I),fallback:"fail_open"}});}finally{P?.close();}try{await l.endSession(i),await l.flushAndAggregate();}catch(I){y({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:h},level:"warn",timestamp:Date.now(),data:{stage:"telemetry_flush",reason:N(I),fallback:"local_state_authoritative"}});}}finally{if(p)try{p.close();}catch{}u&&l.close(),m(),f&&s.removeSession(i),y({event:f?"hook.session_end.completed":"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:o?.executionId??a?.executionId},level:f?"info":"warn",timestamp:Date.now(),data:{stage:"finalize",criticalStagesCompleted:f,transcriptStatus:c.status}});}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let e=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{t+=n;}),process.stdin.on("end",async()=>{let n=Be(t.trim()||process.argv[2]||"");n&&e(JSON.stringify(n)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var $c=/^\/(?:devflow:)?[\w-]+\b\s*/iu,Fc=/\b(?:(?:do\s+not|don't|dont|never|not)(?:\s+need\s+to)?|no\s+need\s+to)\s+(?:please\s+)?(?:remember|memorize)\b|(?:不要|别|不用|无需|不必|不需要)(?:再)?(?:记住|记|记忆)/iu,Hc=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,Nc=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function Ie(e){let t=e.trim().replace($c,"").trim();return !t||Fc.test(t)?null:(Nc.exec(t)??Hc.exec(t))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}function Lc(e){return join(getProjectStateDir(e),"memory-intents.jsonl")}function qc(e){try{return readFileSync$1(e,"utf8").split(`
|
|
18
|
-
`).filter(Boolean).flatMap(t=>{try{let n=JSON.parse(t);return typeof n.content=="string"&&typeof n.createdAt=="number"?[n]:[]}catch{return []}})}catch{return []}}function or(e){let t=
|
|
17
|
+
`).slice(0,4e3)}var yc={open:["intent_bound"],intent_bound:["context_ready","context_degraded"],context_ready:["action_required","action_not_required"],context_degraded:["action_required","action_not_required"],action_required:["action_satisfied","action_degraded","action_failed"],action_not_required:["memory_decided","memory_quarantined"],action_satisfied:["memory_decided","memory_quarantined"],action_degraded:["memory_decided","memory_quarantined"],action_failed:["action_satisfied","action_degraded"],memory_decided:["closed","closed_with_degradation","closed_with_retry_work"],memory_quarantined:["closed_with_degradation","closed_with_retry_work"],closed:[],closed_with_degradation:[],closed_with_retry_work:[]};function Bo(e){return vc(e)}function vc(e){let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let n=bc(t,e.artifact);if(kc(n.toState))return n;let o=t.getContextReceiptForRequest(e.artifact.projectRoot,e.artifact.sessionId,e.artifact.requestId),r=t.getMemoryTurn(e.artifact.turnId),i=e.artifact.intent==="memory"||r?.source==="explicit_intent";if(!o&&!i)return n;let s=o?Ic(e.artifact,o):"context_ready";n.toState==="intent_bound"&&(n=H(t,n,e,s,i?"task_context_not_required":s==="context_ready"?"canonical_context_receipt_ready":"canonical_context_receipt_degraded"));let a=o?wc(e.artifact,o):"action_not_required";if((n.toState==="context_ready"||n.toState==="context_degraded")&&(a==="action_not_required"?n=H(t,n,e,"action_not_required","task_action_not_required"):n=H(t,n,e,"action_required","canonical_action_obligation_present")),n.toState==="action_required"){if(a==="action_required")return n;if(a==="action_failed")return H(t,n,e,"action_failed","canonical_action_attempt_failed");a==="action_degraded"?n=H(t,n,e,"action_degraded","canonical_action_unavailable_or_degraded"):a==="action_satisfied"&&(n=H(t,n,e,"action_satisfied","canonical_action_succeeded"));}if(n.toState==="action_failed")if(a==="action_satisfied")n=H(t,n,e,"action_satisfied","canonical_action_retry_succeeded");else if(a==="action_degraded")n=H(t,n,e,"action_degraded","canonical_action_retry_degraded");else return n;let c=s==="context_degraded"||a==="action_degraded";return ["action_not_required","action_satisfied","action_degraded"].includes(n.toState)&&(n=H(t,n,e,e.memoryStatus==="pending"?"memory_quarantined":"memory_decided",e.memoryStatus==="pending"?e.reason:`canonical_memory_${e.memoryStatus}`)),n.toState==="memory_decided"?H(t,n,e,c?"closed_with_degradation":"closed",e.reason):n.toState==="memory_quarantined"?H(t,n,e,e.retryOwned?"closed_with_retry_work":"closed_with_degradation",e.retryOwned?"durable_retry_owner_confirmed":"terminal_obligation_unowned"):n}finally{t.close();}}function Ic(e,t){return e.intent==="memory"||e.intent==="knowledge"||(t.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function wc(e,t){let n=t.canonicalAction,r=(n?(t.actionAttempts??[]).filter(i=>i.tool===n.tool):[]).at(-1);return t.actionSatisfiedAt||r?.status==="succeeded"?"action_satisfied":r&&["failed","timeout","unavailable"].includes(r.status)?"action_failed":t.actionDegradation||n?.status==="degraded"||n?.status==="unsupported"?"action_degraded":n?.required||_c(e)?"action_required":"action_not_required"}function _c(e){return ["create","modify","debug","test","format"].includes(e.action)||["feature","refactor","performance"].includes(e.intent)}function bc(e,t){let n=e.getLatestTerminalTransition(t.projectRoot,t.sessionId,t.turnId);if(!n)throw new Error(`TERMINAL_INTENT_STATE_MISSING:${t.turnId}`);return n}function H(e,t,n,o,r){if(!yc[t.toState]?.includes(o))throw new Error(`TERMINAL_PATH_UNAVAILABLE:${t.toState}->${o}`);let i=t.sequence+1,s=`terminal:${createHash("sha256").update(`${n.artifact.artifactHash}\0${i}\0${o}`).digest("hex").slice(0,24)}`,a=e.appendTerminalTransition({projectRoot:n.artifact.projectRoot,projectId:n.artifact.projectId,hostId:n.artifact.hostId,sessionId:n.artifact.sessionId,turnId:n.artifact.turnId,requestId:n.artifact.requestId,executionId:n.artifact.executionId,sequence:i,fromState:t.toState,toState:o,receiptId:s,sourceReceiptId:n.memoryReceiptId??t.receiptId,reason:r,payload:{memoryStatus:n.memoryStatus,retryOwned:n.retryOwned??false,sourceIntentHash:n.artifact.artifactHash},createdAt:Date.now()});return y({event:"terminal.state.transitioned",identity:{projectRoot:n.artifact.projectRoot,projectId:n.artifact.projectId,hostId:n.artifact.hostId,sessionId:n.artifact.sessionId,turnId:n.artifact.turnId,requestId:n.artifact.requestId,...n.artifact.executionId?{executionId:n.artifact.executionId}:{}},level:o==="closed"?"info":o.includes("degradation")||o.includes("retry")||o==="action_failed"?"warn":"info",timestamp:Date.now(),data:{fromState:t.toState,nextState:o,receiptId:s,reason:r}}),a}function kc(e){return e==="closed"||e==="closed_with_degradation"||e==="closed_with_retry_work"}var Sc=new Set(["delivered","cancelled","rejected"]),Rc=new Set(["cancelled","rejected"]),xc=new Set(["Write","Edit","NotebookEdit","Bash"]);function Ec(e,t){if(e!=="Bash"||typeof t?.command!="string")return false;let n=t.command.trim(),r="git show [A-Za-z0-9._/:@{}^~+\\-]+(?: 2>/dev/null)?";if(new RegExp(`^${r}(?: \\|\\| ${r})*$`,"u").test(n))return true;if(/[;&|<>`$()]|\\/u.test(n))return false;let i=/^git(?:\s+-C\s+\S+)?\s+(?:show|status|diff|log|branch|worktree|remote|tag)(?:\s|$)/u;return /^(?:ls|pwd|find|rg|grep|cat|sed|head|tail|wc|which|stat|file)(?:\s|$)/u.test(n)||i.test(n)}function Tc(e){let t=e.trim();return !!(/^sqlite3\s+(?:["'][^"']*["']|\S+)\s+["']?(?:SELECT|\.tables|\.schema|PRAGMA)/iu.test(t)||/^node\s+(?:-e|--eval)\s/u.test(t)||/^node\s+--import\s+\S+\s+-e\s/u.test(t)||/^(?:npm|pnpm|yarn)\s+(?:run\s+)?(?:test|build|check|lint|type)/u.test(t)||/^(?:npm|pnpm)\s+exec\s+(?:biome|tsc|vitest|eslint|prettier)\s/u.test(t)||/^npx\s+(?:tsc|biome|vitest|eslint|prettier)\s/u.test(t))}function Ac(e,t){let n=/^cd\s+(\S+)\s*&&/u.exec(e.trim());if(!n)return false;let o=n[1];return !(o==="."||o===t||o.startsWith(t+"/"))}function Go(e,t){let n=join(e,".devflow","delivery-line","state.db");if(!existsSync(n)||!t.trim())return 0;let o;try{o=new DatabaseSync(n,{timeout:250});let r=o.prepare("SELECT id, payload FROM delivery_cases WHERE id = ? OR json_extract(payload, '$.sessionId') = ?").all(t,t),i=0,s=!!o.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_events'").get();for(let a of r){let c="incomplete";try{let d=JSON.parse(a.payload);c=d.evidence?.some(l=>l.metadata?.trust==="external-untrusted")?"untrusted":d.stage==="delivered"?"clean":"incomplete";}catch{}if(i+=Number(o.prepare("UPDATE delivery_tasks SET lease_owner = NULL, lease_expires_at = NULL WHERE case_id = ? AND lease_owner IS NOT NULL").run(a.id).changes),s){let d=`session.closed:${a.id}:${t}`;o.prepare("INSERT OR IGNORE INTO delivery_events (id,case_id,idempotency_key,actor,type,payload,created_at,processed_at) VALUES (?,?,?,?,?,?,?,NULL)").run(d,a.id,d,JSON.stringify({id:"devflow:session-end",kind:"system"}),"session.closed",JSON.stringify({sessionId:t,releasedLeases:i,outcome:c}),Date.now());}}return i}catch{return 0}finally{o?.close();}}function Yo(e,t,n,o,r){if(n.includes("delivery_rebind_session")||!xc.has(n)||!t.trim()||Ec(n,r)||n==="Bash"&&typeof r?.command=="string"&&(Tc(String(r.command))||Ac(String(r.command),e)))return null;let i=join(e,".devflow","delivery-line","state.db");if(!existsSync(i))return null;let s;try{s=new DatabaseSync(i,{readOnly:!0,timeout:250});let a=s.prepare("SELECT id, payload, updated_at FROM delivery_cases").all(),c=new Set;if(!!s.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_workflow_bindings'").get()){let f=s.prepare("SELECT case_id, source_path, aliases FROM delivery_workflow_bindings WHERE status = 'enforced'").all();for(let p of f){let g=[];try{g=JSON.parse(p.aliases);}catch{}(p.source_path===e||g.includes(e))&&c.add(p.case_id);}}let l=[];for(let f of a){let p=JSON.parse(f.payload),g=c.has(f.id);(p.sessionId===t||t===f.id||g)&&l.push({id:f.id,payload:p,updatedAt:typeof f.updated_at=="number"?f.updated_at:typeof p.updatedAt=="number"?p.updatedAt:0});let h=typeof p.stage=="string"?p.stage:"unknown";if(!Sc.has(h)){if(o&&h==="executing"){let b=s.prepare("SELECT id, lease_owner, fencing_token FROM delivery_tasks WHERE case_id = ? AND lease_expires_at > ? AND lease_owner IS NOT NULL AND fencing_token > 0 LIMIT 1").get(f.id,Date.now()),S=typeof p.sessionId=="string"?p.sessionId:void 0,_=typeof p.executionId=="string"?p.executionId:void 0,x=o===b?.id||o===b?.lease_owner||o===_,T=t===f.id||t===S;if(b?.id&&x&&T)return null}if(p.sessionId===t||t===f.id||g)return {code:"DELIVERY_AUTHORITY_REQUIRED",caseId:f.id,stage:h,message:`Delivery case ${f.id} is ${h}; use the Delivery task lease before modifying files.`}}}let u=l.sort((f,p)=>p.updatedAt-f.updatedAt)[0],m=typeof u?.payload.stage=="string"?u.payload.stage:void 0;return u&&m&&Rc.has(m)?{code:"DELIVERY_AUTHORITY_REQUIRED",caseId:u.id,stage:m,message:`Delivery case ${u.id} is ${m}; start a new Delivery case or session before modifying files.`}:null}catch(a){return y({event:"hook.runtime.degraded",identity:{projectRoot:e},level:"warn",timestamp:Date.now(),data:{stage:"delivery_authority",operation:"delivery_write_block",reason:a instanceof Error?a.message:String(a),fallback:"fail_open_unverified_write"}}),null}finally{s?.close();}}function Pt(e){let t={committed:0,skipped:0,pending:0},n=[];for(let o of e)t[o.status]+=1,o.receiptId&&n.push(o.receiptId);return {memoryReceiptIds:[...new Set(n)],missingMemoryDecisionCount:t.pending,memoryTurnOutcomes:t}}function N(e){return (e instanceof Error?e.message:String(e)).trim().slice(0,240)||"memory_lifecycle_unavailable"}var Y=class extends Error{constructor(t,n){super(`session_finalize_${t}:${n}`),this.name="SessionFinalizationRetryableError",this.category=`session_finalize_${t}`;}};function ve(e){let t;try{t=openGlobalDevFlowDatabase();let n=(e.executionId?t.getSkillExecution(e.executionId):null)??t.getLatestSkillExecutionForSession(e.sessionId),o={stage:e.stage,reason:e.reason,degradedAt:Date.now()};n&&t.mergeSkillExecutionMetadata(n.executionId,{...e.metadata,sessionFinalizationDegradations:[o]}),t.insertEvent({kind:"session_finalize_degraded",timestamp:o.degradedAt,success:!1,metadata:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:n?.executionId,...o}}),y({event:"hook.session_end.degraded",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:n?.executionId},level:"warn",timestamp:o.degradedAt,data:{stage:e.stage,reason:e.reason}});}catch{}finally{t?.close();}}function Be(e,t=Ce(),n=true,o,r=true){let i;try{i=JSON.parse(e);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${t}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:e,sessionId:s,cleanupSharedState:n,executionId:o};try{Go(t,s);}catch{}let d;try{d=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let l=d.requestSessionClosure({receiptId:a,projectRoot:t,sessionId:s,payload:c}),u=d.getWorkByIdempotencyKey(a),m={status:l.state==="closed"||l.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:u?.state??"pending",closureState:l.state,pendingWorkCount:l.pendingWorkCount,...u?.id?{workItemId:u.id}:{}};return y({event:"hook.session_end.completed",identity:{projectRoot:t,sessionId:s,executionId:o,terminalReceipt:a},level:m.status==="completed"?"info":"debug",timestamp:Date.now(),data:{stage:"enqueue",...m}}),m}catch(l){if(!r)throw l;return Ro(t,{receiptId:a,...c}),y({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:s,executionId:o,terminalReceipt:a},level:"warn",timestamp:Date.now(),data:{stage:"enqueue",reason:N(l),fallback:"durable_spool"}}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{d?.close();}}async function Qo(e,t=Ce(),n=true,o){let r;try{r=JSON.parse(e);}catch{return}let i=r.session_id?.trim();if(!i)return;let s=new L(t),a=s.get(i),c=zo({projectRoot:t,sessionId:i,transcriptPath:r.transcript_path}),d={evidenceDegradations:a?.evidenceDegradations??[],evidenceContractOutcomes:a?.evidenceOutcomes??[],pendingEvidenceContractIds:a?.evidenceObligations.map(g=>g.contractId)??[],transcriptReconciliation:c},l=o?.telemetry??new te,u=!o?.telemetry,m=()=>{if(!n)return;try{let b=openGlobalDevFlowDatabase();try{b.deleteHookReceipt(t);}finally{b.close();}}catch{}let g=F(t),h=createHash("sha256").update(t).digest("hex").slice(0,12);for(let b of [`session-id-${h}`,"current-execution-id","current-skill.json","event-map.json"])rmSync$1(join(g,b),{force:true});},f=false,p;try{try{await l.flushAndAggregate();}catch{}let g=Date.now(),h=o?.executionId??a?.executionId,b;try{let I=openGlobalDevFlowDatabase();try{b=I.listSessionMemoryTurnsForReconciliation(t,i);for(let v of b){let k=`memory:${v.turnId}`,w=I.getSessionObligation(t,i,k);w?w.state==="open"&&v.status!=="pending"&&I.resolveSessionObligation({projectRoot:t,sessionId:i,obligationId:k,state:"satisfied",receiptId:v.receiptId,reason:v.reason,resolvedAt:v.decidedAt}):I.upsertSessionObligation({obligationId:k,projectRoot:t,sessionId:i,turnId:v.turnId,kind:"memory_decision",state:v.status==="pending"?"open":"satisfied",payload:{eventId:v.eventId,promptHash:v.promptHash},receiptId:v.receiptId,reason:v.reason,createdAt:v.createdAt,updatedAt:v.decidedAt??v.createdAt,resolvedAt:v.decidedAt});}}finally{I.close();}}catch(I){let v=N(I),k={...d,memoryEventReconciliation:{status:"degraded",stage:"turn_load",reason:v,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw ve({projectRoot:t,sessionId:i,executionId:h,stage:"turn_load",reason:v,metadata:k}),new Y("turn_load",v)}let S=Pt(b),_=o?.memory??(p=new MemoryGate(t)),x={status:"completed"};try{x=typeof _.reconcileTurnObservationLineage=="function"?{status:"completed",...await _.reconcileTurnObservationLineage(b)}:{status:"unsupported_adapter",committed:0,skipped:0,quarantined:0,unlinked:0};}catch(I){let v=N(I);throw x={status:"degraded",reason:v},ve({projectRoot:t,sessionId:i,executionId:h,stage:"memory_lineage",reason:v,metadata:{...S,...d,memoryLineageReconciliation:x}}),new Y("memory_lineage",v)}let T={status:"unknown",selected:0,consumed:0,unknown:0,positive:0,negative:0};try{let I=ze(r.transcript_path),v=openGlobalDevFlowDatabase(),k="unknown",w="no_terminal_host_action_evidence",lt,V,q,Q=[],ut=[];try{let J=v.listHostActionsForSession(t,i,h),An=J.filter(j=>j.state==="verified"),mt=J.filter(j=>["failed","cancelled","degraded"].includes(j.state));mt.length>0?(k="negative",w=`terminal_host_action_${mt[0].state}`):An.length>0&&(k="positive",w="host_action_verified");let Te=mt[0]??An.at(-1);if(lt=Te?.runId,V=Te?.contextReceipt,q=Te?.evidenceHash,ut=J.flatMap(j=>{let Z=j.report.toolUseIds;return Array.isArray(Z)?Z.filter(me=>typeof me=="string"):[]}),!Te&&h){let j=v.getSkillExecution(h),Z=j?.metadata&&typeof j.metadata=="object"&&Array.isArray(j.metadata.policyVerificationOutcomes)?j.metadata.policyVerificationOutcomes:[],me=Z.find(K=>K.status==="failed"),pt=Z.filter(K=>K.status==="passed");me?(k="negative",w="policy_verification_failed",q=typeof me.receiptId=="string"?me.receiptId:void 0):pt.length>0&&(k="positive",w="policy_verification_passed",q=typeof pt.at(-1)?.receiptId=="string"?String(pt.at(-1).receiptId):void 0),V=v.getActiveContextReceipt(t,i,h)?.contextHash,ut=Z.map(K=>K.command).filter(K=>typeof K=="string");}V&&(Q=v.getSemanticExecutionContextByHash(V)?.dispositions.filter(j=>j.requirement==="required").map(j=>j.channel)??[]);}finally{v.close();}let Tn=qo({projectRoot:t,sessionId:i,executionId:h,outcome:k,outcomeReason:w,verificationReceipt:q,requiredChannels:Q,finishedAt:g}),Hi=await _.attributeRetrievalBenefits({sessionId:i,executionId:h,outcome:k,outcomeReason:w,workflowRunId:lt,contextReceipt:V,toolEvidence:ut,verificationReceipt:q,consumedSourceIds:Tn.consumedSources.filter(J=>J.sourceType==="memory").map(J=>J.sourceId)});T={status:I?"evaluated":"unknown",...Hi,retrievalLedger:Tn};}catch(I){T={...T,status:"degraded",reason:N(I)};}let C;try{C=await _.reconcileDecidedTurnEventWindows(i,b,g);}catch(I){let v=N(I),k={...S,...d,memoryEventReconciliation:{status:"degraded",stage:"event_reconciliation",reason:v,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw ve({projectRoot:t,sessionId:i,executionId:h,stage:"event_reconciliation",reason:v,metadata:k}),new Y("event_reconciliation",v)}let A;try{A=await fe({projectRoot:t,sessionId:i,trigger:"session_end",memory:_,details:{eventReconciliation:C},strictPersistence:!0});}catch(I){let v=N(I),k={...S,...d,memoryEventReconciliation:{status:"completed",...C,checkpointPending:null},memoryCheckpointDegradation:v};throw ve({projectRoot:t,sessionId:i,executionId:h,stage:"checkpoint",reason:v,metadata:k}),new Y("checkpoint",v)}let M={memoryLineageReconciliation:x,memoryBenefitAttribution:T,memoryEventReconciliation:{status:"completed",...C,checkpointPending:A.pendingEvents},memoryDistillCheckpoint:A};try{let I=openGlobalDevFlowDatabase();try{let v=`session-finalize:${i}:events`,k=Math.max(Number(A.pendingEvents??0),Number(C.remainingUndecided??0)),w=I.getSessionObligation(t,i,v);k>0?I.upsertSessionObligation({obligationId:v,projectRoot:t,sessionId:i,executionId:h,kind:"session_finalize",state:"open",payload:{pendingEvents:k,reconciliation:C,checkpointId:A.id},reason:"active_unprocessed_session_events",createdAt:w?.createdAt??g,updatedAt:g}):w?.state==="open"&&I.resolveSessionObligation({projectRoot:t,sessionId:i,obligationId:v,state:"satisfied",reason:"session_events_reconciled",resolvedAt:g});}finally{I.close();}}catch(I){y({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:h},level:"warn",timestamp:Date.now(),data:{stage:"obligation_persistence",reason:N(I)}});}try{await _.closeSession(i),p&&(p.close(),p=void 0);}catch(I){let v=N(I),k={...S,...d,...M,memorySessionCloseDegradation:v};throw ve({projectRoot:t,sessionId:i,executionId:h,stage:"memory_close",reason:v,metadata:k}),new Y("memory_close",v)}let R={...S,...d,...M},D=[];try{let I=openGlobalDevFlowDatabase();try{let v=new Map(I.listLatestTaskIntentArtifacts(t,i).map(k=>[k.turnId,k]));for(let k of b){let w=v.get(k.turnId);if(!w)continue;let V=[I.getWorkByIdempotencyKey(`memory-turn:capture_prompt:${k.turnId}`),I.getWorkByIdempotencyKey(`memory-turn:commit_explicit:${k.turnId}`)].filter(Boolean).some(Q=>Q.state==="pending"||Q.state==="leased"||Q.state==="failed"),q=Bo({artifact:w,memoryStatus:k.status,memoryReceiptId:k.receiptId,retryOwned:V,reason:k.status==="pending"?"session_end_memory_pending":"session_end_reconciled"});D.push({turnId:k.turnId,state:q.toState,receiptId:q.receiptId});}}finally{I.close();}}catch(I){D.push({state:"terminal_integrity_failure",reason:N(I)});}R.terminalOutcomes=D,f=!0;let P;try{P=openGlobalDevFlowDatabase();let I=h;if(I)try{P.reconcileSkillExecution(I,"completed",g,R);let w=P.getSkillExecution(I);await G("/api/telemetry/skill-execution/complete",{executionId:I,finishedAt:g,status:"completed",summary:{totalToolCalls:w?.totalToolCalls??0,mcpToolCalls:w?.mcpToolCalls??0,directToolCalls:w?.directToolCalls??0,subagentCount:w?.subagentCount??0,totalDuration:w?.totalDuration??0,mcpComplianceRate:w?.mcpComplianceRate??0,missedTools:w?.missedMcpTools??[],actualFailureCount:w?.failedToolCalls??0,fallbackCount:w?.fallbackCount??0,fallbackReasons:w?.fallbackReasons??[]},metadata:R},{fallbackReason:"skill_execution_already_reconciled_locally"});}catch{}let v=P.reconcileRunningSkillExecutionsForSession(i,g,{closureReason:"session_finalize",...R});for(let w of v)await G("/api/telemetry/skill-execution/complete",{executionId:w.executionId,finishedAt:w.finishedAt,status:w.status,summary:{totalToolCalls:w.totalToolCalls??0,mcpToolCalls:w.mcpToolCalls??0,directToolCalls:w.directToolCalls??0,subagentCount:w.subagentCount??0,totalDuration:w.totalDuration??0,mcpComplianceRate:w.mcpComplianceRate??0,missedTools:w.missedMcpTools??[],actualFailureCount:w.failedToolCalls??0,fallbackCount:w.fallbackCount??0,fallbackReasons:w.fallbackReasons??[]},metadata:R},{fallbackReason:"skill_execution_already_reconciled_locally"});let k=P.getLatestSkillExecutionForSession(i);k&&!v.some(w=>w.executionId===k.executionId)&&P.mergeSkillExecutionMetadata(k.executionId,R),P.deleteContextReceipt(t,i);}catch(I){y({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:h},level:"warn",timestamp:Date.now(),data:{stage:"lifecycle_telemetry",reason:N(I),fallback:"fail_open"}});}finally{P?.close();}try{await l.endSession(i),await l.flushAndAggregate();}catch(I){y({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:h},level:"warn",timestamp:Date.now(),data:{stage:"telemetry_flush",reason:N(I),fallback:"local_state_authoritative"}});}}finally{if(p)try{p.close();}catch{}u&&l.close(),m(),f&&s.removeSession(i),y({event:f?"hook.session_end.completed":"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:o?.executionId??a?.executionId},level:f?"info":"warn",timestamp:Date.now(),data:{stage:"finalize",criticalStagesCompleted:f,transcriptStatus:c.status}});}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let e=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{t+=n;}),process.stdin.on("end",async()=>{let n=Be(t.trim()||process.argv[2]||"");n&&e(JSON.stringify(n)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var Hc=/^\/(?:devflow:)?[\w-]+\b\s*/iu,Nc=/\b(?:(?:do\s+not|don't|dont|never|not)(?:\s+need\s+to)?|no\s+need\s+to)\s+(?:please\s+)?(?:remember|memorize)\b|(?:不要|别|不用|无需|不必|不需要)(?:再)?(?:记住|记|记忆)/iu,Lc=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,qc=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function Ie(e){let t=e.trim().replace(Hc,"").trim();return !t||Nc.test(t)?null:(qc.exec(t)??Lc.exec(t))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}function Wc(e){return join(getProjectStateDir(e),"memory-intents.jsonl")}function Uc(e){try{return readFileSync$1(e,"utf8").split(`
|
|
18
|
+
`).filter(Boolean).flatMap(t=>{try{let n=JSON.parse(t);return typeof n.content=="string"&&typeof n.createdAt=="number"?[n]:[]}catch{return []}})}catch{return []}}function or(e){let t=Wc(e),n=`${t}.claim-`,o=`${basename(t)}.claim-`,r=(()=>{try{return readdirSync$1(dirname$1(t)).filter(a=>a.startsWith(o)&&!a.includes(".tmp-")).sort()[0]}catch{return}})(),i=r?join(dirname$1(t),r):`${n}${Date.now()}-${process.pid}`;if(!r)try{renameSync(t,i);}catch{return null}let s=Uc(i);if(s.length===0){try{unlinkSync$1(i);}catch{}return null}return {path:i,intents:s}}function jt(e){if(e.intents.shift(),e.intents.length===0){try{unlinkSync$1(e.path);}catch{}return}let t=`${e.path}.tmp-${process.pid}`;writeFileSync$1(t,e.intents.map(n=>JSON.stringify(n)).join(`
|
|
19
19
|
`)+`
|
|
20
|
-
`,{mode:384}),renameSync(t,e.path);}function Ve(e){let t=e.trim().replace(/^\//,"");if(!t.startsWith("devflow:"))return null;let n=t.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(n)?`devflow:${n.toLowerCase()}`:null}function rr(e){let t=e.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!t)return null;let n=Ve(t[1]);return n?{rawName:t[1],skillName:n}:null}function we(e,t){return t?`evt_tool_${createHash$1("sha256").update(`${e}\0${t}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}var be=1,Wt="memory-snapshot-v1.json",hr=512*1024,yr=256*1024,vr=2e3,
|
|
20
|
+
`,{mode:384}),renameSync(t,e.path);}function Ve(e){let t=e.trim().replace(/^\//,"");if(!t.startsWith("devflow:"))return null;let n=t.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(n)?`devflow:${n.toLowerCase()}`:null}function rr(e){let t=e.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!t)return null;let n=Ve(t[1]);return n?{rawName:t[1],skillName:n}:null}function we(e,t){return t?`evt_tool_${createHash$1("sha256").update(`${e}\0${t}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}var be=1,Wt="memory-snapshot-v1.json",hr=512*1024,yr=256*1024,vr=2e3,Xc=500,Qc=10,Zc=240,ed=300*1e3,td=720*60*60*1e3,Ir=2147483647,nd=100,cr=250,od=3e4,rd=10,Je=new Map;function wr(e){return e.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:e.ownerUid===e.currentUid,modeSafe:(e.mode&18)===0}}function X(e){return resolve(e)}function ae(e){return createHash("sha256").update(X(e)).digest("hex").slice(0,16)}function Ut(e,t={}){let n=ae(e),o=t.stateRoot?join(t.stateRoot,n):getProjectStateDir(X(e));return join(o,Wt)}function Ge(e,t){let o=(e instanceof Error?e.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return o?`${t}:${o}`:t}function zt(e,t){return Array.isArray(e)&&e.length<=t&&e.every(n=>typeof n=="string"&&n.length>0&&n.length<=512)}function id(e){if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return typeof t.id=="string"&&t.id.length>0&&t.id.length<=512&&typeof t.kind=="string"&&t.kind.length>0&&t.kind.length<=128&&(t.family===void 0||typeof t.family=="string"&&t.family.length>0&&t.family.length<=256)&&(t.entity===void 0||typeof t.entity=="string"&&t.entity.length>0&&t.entity.length<=256)&&zt(t.memoryIds,100)&&(t.status==="withheld"||t.status==="resolved")&&(t.summary===void 0||typeof t.summary=="string"&&t.summary.length<=2e3)}function sd(e){if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return typeof t.reason=="string"&&t.reason.length>0&&t.reason.length<=512&&(t.stale===void 0||typeof t.stale=="boolean")}function Bt(e,t,n){if(!e||typeof e!="object"||Array.isArray(e))return null;let o=e,r=X(t),i=ae(r),s=o.generation===void 0?0:o.generation;return o.version!==be||o.projectRoot!==r||o.projectHash!==i||typeof o.markdown!="string"||Buffer.byteLength(o.markdown,"utf8")>yr||!zt(o.memoryIds,vr)||!Array.isArray(o.conflicts)||o.conflicts.length>Xc||!o.conflicts.every(id)||typeof o.generatedAt!="number"||!Number.isFinite(o.generatedAt)||o.generatedAt<0||o.generatedAt>n+ed||!Number.isInteger(s)||s<0||s>Ir||!["ready","pending","degraded","disabled"].includes(String(o.status))||o.degradation!==void 0&&!sd(o.degradation)?null:{...o,generation:s}}function Vt(e,t,n,o,r=0){let i=X(e);return {version:be,projectRoot:i,projectHash:ae(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:o,generation:r,status:t,degradation:{reason:n}}}function ie(e,t={}){let n=t.now??Date.now(),o=Ut(e,t),r;try{r=openSync$1(o,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync$1(r);if(!i.isFile()||i.size<=0||i.size>hr)throw new Error("cache_size_invalid");let s=wr({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync$1(r,"utf8")),c=Bt(a,e,n);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&n-c.generatedAt>td?{snapshot:{...c,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:c,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:Vt(e,a?"pending":"degraded",a?"cache_missing":Ge(i,"cache_invalid"),n),source:"none",valid:false,stale:false}}finally{if(r!==void 0)try{closeSync$1(r);}catch{}}}function dr(e){if(!Number.isInteger(e)||e<0||e>=Ir)throw new Error("memory_snapshot_generation_exhausted");return e+1}function ad(e){let t=dirname$1(e);mkdirSync$1(t,{recursive:true,mode:448}),chmodSync(t,448);}function cd(e){ad(e);let t=`${e}.lock`,n={pid:process.pid,createdAt:Date.now(),token:randomUUID$1()},o=JSON.stringify(n),r;try{return r=openSync$1(t,"wx",384),writeFileSync$1(r,o),fsyncSync(r),{fd:r,path:t,contents:o}}catch(i){if(r!==void 0){try{closeSync$1(r);}catch{}try{unlinkSync$1(t);}catch{}}if(i.code==="EEXIST")return null;throw i}}function dd(e){if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return Number.isInteger(t.pid)&&Number(t.pid)>0&&typeof t.createdAt=="number"&&Number.isFinite(t.createdAt)&&typeof t.token=="string"&&t.token.length>0}function ld(e){try{return process.kill(e,0),!1}catch(t){return t.code==="ESRCH"}}function ud(e){return !e.canonicalCachePath||!e.directoryIsSafe||!e.lockIsRegularFile||!e.metadataValid||!e.contentsUnchanged||!e.ownerDead&&!e.stale?false:e.currentUid!==void 0?e.directoryUid===e.currentUid&&e.lockUid===e.currentUid:true}function md(e){return isAbsolute(e)&&resolve(e)===e&&basename(e)===Wt&&/^[a-f0-9]{16}$/u.test(basename(dirname$1(e)))}function pd(e,t){let n=`${e}.lock`;try{let o=lstatSync$1(dirname$1(e)),r=lstatSync$1(n),i=readFileSync$1(n,"utf8"),s=null;try{let f=JSON.parse(i);dd(f)&&(s=f);}catch{}let a=s?.createdAt??r.mtimeMs,c=Date.now()-a>t,d=s?ld(s.pid):!1,l=readFileSync$1(n,"utf8")===i,u=typeof process.getuid=="function"?process.getuid():void 0,m=wr({...u!==void 0?{currentUid:u}:{},ownerUid:o.uid,mode:o.mode});return ud({canonicalCachePath:md(e),directoryIsSafe:o.isDirectory()&&!o.isSymbolicLink()&&m.modeSafe,lockIsRegularFile:r.isFile()&&!r.isSymbolicLink(),metadataValid:s!==null,ownerDead:d,stale:c,contentsUnchanged:l,...u!==void 0?{currentUid:u}:{},directoryUid:o.uid,lockUid:r.uid})?(unlinkSync$1(n),!0):!1}catch{return false}}function fd(e){try{closeSync$1(e.fd);}catch{}try{readFileSync$1(e.path,"utf8")===e.contents&&unlinkSync$1(e.path);}catch{}}function gd(e){return new Promise(t=>setTimeout(t,e))}function $t(e,t,n,o){let r=Number.isFinite(e)?Math.floor(e):t;return Math.min(o,Math.max(n,r))}async function hd(e,t){let n=$t(t.lockTimeoutMs,nd,0,cr),o=$t(t.lockRetryMs,rd,1,cr),r=$t(t.lockStaleMs,od,0,Number.MAX_SAFE_INTEGER),i=Date.now()+n;for(;;){let s=cd(e);if(s)return s;if(pd(e,r))continue;let a=i-Date.now();if(a<=0)throw new Error("memory_snapshot_cache_lock_timeout");await gd(Math.min(o,a));}}async function lr(e,t,n){let o=await hd(e,t);try{return await n()}finally{fd(o);}}function ur(e,t,n,o){let r=o.now??Date.now(),i=X(e),s={version:be,projectRoot:i,projectHash:ae(i),markdown:t.markdown,memoryIds:t.memoryIds??[],conflicts:t.conflicts??[],generatedAt:r,generation:n,status:t.status??"ready",...t.degradation?{degradation:t.degradation}:{}};if(!Bt(s,e,r))throw new Error("memory_snapshot_payload_invalid");let a=JSON.stringify(s);if(Buffer.byteLength(a,"utf8")>hr)throw new Error("memory_snapshot_cache_too_large");let c=Ut(e,o),d=dirname$1(c);mkdirSync$1(d,{recursive:true,mode:448}),chmodSync(d,448);let l=join(d,`.${Wt}.${process.pid}.${randomUUID$1()}.tmp`),u;try{u=openSync$1(l,"wx",384),writeFileSync$1(u,a),fsyncSync(u),closeSync$1(u),u=void 0,chmodSync(l,384),renameSync(l,c),chmodSync(c,384);let m;try{m=openSync$1(d,"r");try{fsyncSync(m);}catch{}}finally{m!==void 0&&closeSync$1(m);}return s}finally{if(u!==void 0)try{closeSync$1(u);}catch{}rmSync$1(l,{force:true});}}function yd(e,t){let o=(Je.get(e)??Promise.resolve()).catch(()=>{}).then(t),r=o.then(()=>{},()=>{});return Je.set(e,r),o.finally(()=>{Je.get(e)===r&&Je.delete(e);})}function Ft(e,t,n,o,r){return e.valid?e.snapshot.generation>r?{...e,persisted:false}:{...e,snapshot:{...e.snapshot,status:"degraded",degradation:{reason:n,stale:e.stale||void 0}},persisted:false}:{snapshot:Vt(t,"degraded",n,o,r),source:"none",valid:false,stale:false,persisted:false}}async function Jt(e){let t=Ut(e.projectRoot,e.cacheOptions);return yd(t,async()=>{let n=ie(e.projectRoot,e.cacheOptions),o=n.valid?n.snapshot.generation:0,r;try{r=await e.load();}catch(i){let s=Ge(i,`refresh_failed:${e.reason}`);try{return await lr(t,e.cacheOptions??{},()=>{let a=ie(e.projectRoot,e.cacheOptions);if(a.valid)return Ft(a,e.projectRoot,s,e.cacheOptions?.now??Date.now(),o);let c=dr(o),d=Vt(e.projectRoot,"degraded",s,e.cacheOptions?.now??Date.now(),c);return {snapshot:ur(e.projectRoot,d,c,e.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(a){let c=ie(e.projectRoot,e.cacheOptions);return Ft(c,e.projectRoot,Ge(a,s),e.cacheOptions?.now??Date.now(),o)}}try{return await lr(t,e.cacheOptions??{},()=>{let i=ie(e.projectRoot,e.cacheOptions);if(i.valid&&i.snapshot.generation>o)return {...i,persisted:!1};let s=dr(Math.max(o,i.valid?i.snapshot.generation:0));return {snapshot:ur(e.projectRoot,r,s,e.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(i){let s=ie(e.projectRoot,e.cacheOptions);return Ft(s,e.projectRoot,Ge(i,`refresh_commit_failed:${e.reason}`),e.cacheOptions?.now??Date.now(),o)}})}async function Qe(e){return Jt({projectRoot:e.projectRoot,reason:e.reason,cacheOptions:e.cacheOptions,load:async()=>{if(e.injectConfig===false)return {status:"disabled",markdown:"",memoryIds:[],conflicts:[]};let t=typeof e.injectConfig=="object"?e.injectConfig:{},n=Number.isFinite(t.topN)?Math.max(0,Math.floor(t.topN)):4,o=Number.isFinite(t.budgetTokens)?Math.max(1,Math.floor(t.budgetTokens)):400,r=await e.memory.getAll({purpose:"session_bootstrap",budgetTokens:o,limit:n}),s=Number.isInteger(r.truncatedCount)&&r.truncatedCount>=0?r.truncatedCount:null,a=r.memories.length===0&&s!==0,c=s!==null&&s>0?"snapshot_results_truncated":"snapshot_truncation_unknown",d=(r.conflicts??[]).map(u=>({id:u.id,kind:u.kind,family:u.family,entity:u.entity,memoryIds:u.memoryIds,status:u.status,...u.summary?{summary:u.summary}:{}})),l=a?`## Project memory
|
|
21
21
|
DevFlow memory snapshot=degraded; reason=${c}. Memory result completeness is not authoritative; do not conclude that the project has no memories.`:r.memories.length===0&&d.length>0?`## Project memory
|
|
22
22
|
${d.length} explicit preference conflict(s) are withheld from automatic guidance; an explicit choice is required.`:r.memories.length===0?`## Project memory
|
|
23
23
|
\u672C\u9879\u76EE\u6682\u65E0\u8BB0\u5FC6`:`## Project memory (auto-injected, ${r.memories.length} items, ${r.tokenCount} tokens)
|
|
24
24
|
${r.memories.map(u=>`- **${u.title||u.type}**: ${u.content} (confidence ${u.confidence.toFixed(2)}, ${u.source})`).join(`
|
|
25
|
-
`)}`;return {status:a?"degraded":"ready",markdown:l,memoryIds:r.memories.map(u=>u.id),conflicts:d,...a?{degradation:{reason:c}}:{}}}})}function
|
|
25
|
+
`)}`;return {status:a?"degraded":"ready",markdown:l,memoryIds:r.memories.map(u=>u.id),conflicts:d,...a?{degradation:{reason:c}}:{}}}})}function vd(e){if(!e)return true;try{return JSON.parse(readFileSync$1(e,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function Id(e,t,n){if(!t.trim())return null;try{let o=JSON.parse(t);if(o.status!=="ok"&&o.status!=="degraded")return null;if(o.enabled===!1){let i=X(e);return {version:be,projectRoot:i,projectHash:ae(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:n,generation:0,status:"disabled"}}let r=Bt(o.snapshot,e,n);if(r)return r;if(o.status==="ok"&&typeof o.markdown=="string"&&o.markdown.length>0&&Buffer.byteLength(o.markdown,"utf8")<=yr){let i=X(e);return {version:be,projectRoot:i,projectHash:ae(i),markdown:o.markdown,memoryIds:zt(o.memoryIds,vr)?o.memoryIds:[],conflicts:[],generatedAt:n,generation:0,status:"ready"}}}catch{}return null}function Ht(e,t){return [...(e??t).replace(/[\r\n\t|]+/gu," ").trim()||t].slice(0,Zc).join("")}function wd(e){if(e.length===0)return "";let t=e.slice(0,Qc),n=t.map(o=>{let r=Ht(o.family,"unknown"),i=Ht(o.entity,"unknown"),s=Ht(o.summary,"Explicit choice required.");return `- family=${r}; entity=${i}; status=${o.status}; summary=${s}`});return e.length>t.length&&n.push(`- ${e.length-t.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${e.length})
|
|
26
26
|
${n.join(`
|
|
27
|
-
`)}`}function
|
|
28
|
-
DevFlow memory snapshot=pending; source=${o.source}; reason=previous_snapshot_disabled. Memory availability is not yet known; do not conclude that the project has no memories.`;let i=new Date(r.generatedAt).toISOString(),s=r.degradation?.reason?`; reason=${r.degradation.reason}`:"",a=`DevFlow memory snapshot=${r.status}; source=${o.source}; generatedAt=${i}${s}.`,c=
|
|
27
|
+
`)}`}function _d(e){let t=e.now??Date.now();if(vd(e.configPath)===false)return "";let n=Id(e.projectRoot,e.daemonResponse??"",t),o=n?{snapshot:n,source:"daemon"}:ie(e.projectRoot,{...e.cacheOptions,now:t}),{snapshot:r}=o;if(r.status==="disabled")return `## Project memory
|
|
28
|
+
DevFlow memory snapshot=pending; source=${o.source}; reason=previous_snapshot_disabled. Memory availability is not yet known; do not conclude that the project has no memories.`;let i=new Date(r.generatedAt).toISOString(),s=r.degradation?.reason?`; reason=${r.degradation.reason}`:"",a=`DevFlow memory snapshot=${r.status}; source=${o.source}; generatedAt=${i}${s}.`,c=wd(r.conflicts);return r.markdown?[r.markdown,c,a].filter(Boolean).join(`
|
|
29
29
|
`):["## Project memory",c,`${a} Memory availability is not yet known; do not conclude that the project has no memories.`].filter(Boolean).join(`
|
|
30
|
-
`)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,e,t,n]=process.argv;e!=="session-start"||!t?process.exitCode=2:process.stdout.write(Id({projectRoot:t,configPath:n,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}var Sd=/^(?:ok(?:ay)?|yes|no|thanks?|thank you|continue|好的?|可以|行|是|否|谢谢|继续|收到|明白了?)[.!。!\s]*$/iu,Rd=/(?:记住|记下|保存|持久化|跨会话|以后|始终|永远|统一使用|项目约定|团队约定|偏好|决定采用|保留可复用|提炼结论|沉淀|记录(?:下来|为|成)?(?:架构|规则|约定|知识|结论))|\b(?:remember|memorize|persist|across sessions|from now on|always|project convention|team convention|preference|we use|adopt|retain reusable|distill)\b/iu,xd=/(?:分析|审查|检查|评估|性能|生成|创建|新建|添加|编写|实现|开发|设计|撰写|总结|修改|重构|修复|调试|解释|查看)|\b(?:analy[sz]e|review|inspect|audit|performance|generate|create|add|build|implement|develop|design|write|summarize|modify|refactor|fix|debug|explain)\b/iu,Ed=/(?:召回|查询|检索|查找|定位|询问|什么|如何|是否|哪里|哪个)|\b(?:recall|query|search|find|locate|ask|what|how|whether|where|which)\b/iu;function Td(e){let t=e.trim();return t.length>0&&!Sd.test(t)}function Ad(e,t){if(!t.trim())return false;let n=join(e,".devflow","delivery-line","state.db");if(!existsSync(n))return false;let o;try{return o=new DatabaseSync(n,{readOnly:!0,timeout:250}),o.prepare("SELECT payload FROM delivery_cases").all().some(i=>{try{let s=JSON.parse(i.payload);return s.sessionId===t&&!["delivered","cancelled","rejected"].includes(String(s.stage??""))}catch{return !1}})}catch{return false}finally{o?.close();}}function Dd(e){let t=e.normalize("NFKC").trim(),n=Ed.test(t);return t.length>=4&&(xd.test(t)||n)&&(!Rd.test(t)||n)&&Ie(t)===null}function Cd(e,t,n=Date.now()){let o=createHash("sha256").update(t.trim()).digest("hex"),r=createHash("sha256").update(`${e}\0${n}\0${o}`).digest("hex").slice(0,24);return {turnId:`turn:${r}`,eventId:`memory-turn:${r}`,promptHash:o,createdAt:n}}function Re(e,t,n=[]){return `memory-receipt:${createHash("sha256").update(`${e}\0${t}\0${[...n].sort().join("\0")}`).digest("hex").slice(0,24)}`}function Ze(e){return `DevFlow memory decision required for ${e.turnId}. Before the final response, semantically decide whether this turn contains durable project knowledge. Call ${projectClaudeToolName("memory_commit_turn")} with evidence-bound candidates, or ${projectClaudeToolName("memory_skip_turn")} with a concrete reason. Do not claim memory success without a canonical receipt. For candidates, copy exact evidenceSpans from this user prompt, preserve package names, flags, versions, paths, and identifiers, and provide subject, predicate, value, polarity, and entities when known. To replace or retire an existing fact, provide operation=supersede or operation=retire plus referencedFactIds from the canonical memory receipt; aliases and entity names are not fact identity. Do not save assistant echoes, task narration, retries, or unverified guesses. Express a change from an old choice as the new durable value. If the decision tool remains unavailable, explicitly state that the memory was not saved.`}function ke(e){let t=e.memoryIds.length>0?e.memoryIds.join(","):"none",n=e.status==="committed"?"accepted":e.status,o=e.status==="committed"?"; indexStatus=pending":"",r=e.memoryIds.some(a=>a.startsWith("raw-memory:")),i=e.status==="committed"&&e.source==="explicit_intent"&&!r?"; memoryOnlyCompleted=true; skipProjectContext=true; hostRefinementRequired=true":e.status==="committed"&&e.source==="explicit_intent"?"; asyncReadiness=queued; hostRefinementRequired=true":"",s=e.status==="committed"&&e.source==="explicit_intent"?` The deterministic explicit-memory save is complete and remains authoritative if refinement fails. Before the final response, call ${projectClaudeToolName("memory_commit_turn")} once with turnId=${e.turnId} and semantic candidates. Split every distinct reusable fact into a durable_memory candidate, classify instructions that apply only to this turn as turn_constraint, and include evidenceSpans copied verbatim from the user prompt for every candidate. Preserve exact flags, package names, versions, paths, and identifiers. Keep narrative and value in the user prompt language; do not translate evidence into a different surface form. The tool refines the existing receipt idempotently; it must not create native Claude memory. If refinement is unavailable, return the existing canonical receipt without claiming refinement.`:"";return `DevFlow canonical memory receipt: status=${n}; receiptId=${e.receiptId??"missing"}; turnId=${e.turnId}; memoryIds=${t}; source=${e.source??"unknown"}${o}${i}.`+s}function Gt(e){if(!Td(e.prompt))return null;let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let n=e.prompt.trim().slice(0,4e3),o=createHash("sha256").update(n).digest("hex"),r=t.listMemoryTurns(e.projectRoot,e.sessionId,5).find(m=>m.promptHash===o&&Date.now()-m.createdAt<1e4),i=r?{turnId:r.turnId,eventId:r.eventId,promptHash:r.promptHash,createdAt:r.createdAt}:e.identity??Cd(e.sessionId,n),s=r??t.beginMemoryTurn({...i,projectRoot:e.projectRoot,sessionId:e.sessionId});if(s.status!=="pending")return {turn:s,additionalContext:ke(s),skipSkillRouting:s.source==="explicit_intent"};let c=(e.activation?.semantic??"degraded_structural")==="degraded_structural"?Ie(n)??void 0:void 0,d=Ad(e.projectRoot,e.sessionId);if(!c&&!d&&Dd(n)){let m=Re(s.turnId,"skipped"),f=t.skipMemoryTurn({turnId:s.turnId,receiptId:m,source:"automatic_transient_skip",reason:"high_confidence_transient_task"});return O({projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId,kind:"memory.skipped",payload:{receiptId:m,reasonCode:"high_confidence_transient_task"},dedupeKey:m,producer:"devflow-memory-turn"}),y({event:"memory.semantic.decided",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId},level:"info",timestamp:Date.now(),data:{status:"semantic_empty",operation:"none",reason:"high_confidence_transient_task"}}),{turn:f,additionalContext:ke(f),skipSkillRouting:!1}}let l=c?"commit_explicit":"capture_prompt",u=t.enqueueWork({idempotencyKey:`memory-turn:${l}:${s.turnId}`,kind:c?"memory.explicit_commit":"memory.turn_capture",projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId,payload:{operation:l,turnId:s.turnId,eventId:s.eventId,sessionId:e.sessionId,prompt:n,explicitContent:c,createdAt:s.createdAt}});if(c){let m=`raw-memory:${createHash("sha256").update(`${e.projectRoot}\0${i.turnId}\0${c}`).digest("hex").slice(0,24)}`,f=Re(s.turnId,"committed",[m]),p=t.commitMemoryTurn({turnId:s.turnId,receiptId:f,memoryIds:[m],source:"explicit_intent",reason:"explicit_raw_queued",decidedAt:Date.now()});return O({projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId,kind:"durable_work.owned",payload:{workId:u.id,obligation:"memory"},dedupeKey:`${u.id}:owned`,producer:"devflow-memory-turn"}),O({projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId,kind:"memory.committed",payload:{receiptId:f,reasonCode:"explicit_raw_queued"},dedupeKey:f,producer:"devflow-memory-turn"}),y({event:"memory.write.completed",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId,actionReceipt:f},level:"info",timestamp:Date.now(),data:{stage:"explicit_fast_ack",durable:!0,rawMemoryId:m,receiptLatencyMs:Date.now()-i.createdAt,asyncReadiness:"queued"}}),{turn:p,explicitContent:c,additionalContext:ke(p),skipSkillRouting:!0}}return O({projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId,kind:"memory.pending",payload:{reasonCode:"semantic_decision_queued"},dedupeKey:`${s.turnId}:pending`,producer:"devflow-memory-turn"}),O({projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId,kind:"durable_work.owned",payload:{workId:u.id,obligation:"memory"},dedupeKey:`${u.id}:owned`,producer:"devflow-memory-turn"}),{turn:s,explicitContent:c,additionalContext:Ze(s),skipSkillRouting:!1}}finally{t.close();}}async function Yt(e){let{payload:t,memory:n,projectRoot:o}=e,r=openGlobalDevFlowDatabase();try{let i=r.getMemoryTurn(t.turnId);if(!i)throw new Error(`Memory turn ${t.turnId} does not exist`);let s=t.operation==="commit_explicit"&&i.status==="committed"&&i.source==="explicit_intent"&&i.memoryIds.some(u=>u.startsWith("raw-memory:"));if(i.status!=="pending"&&!s){if(i.receiptId&&typeof n.reconcileTurnObservationLineage=="function")try{await n.reconcileTurnObservationLineage([i]);}catch{}return {turn:i,additionalContext:ke(i),skipSkillRouting:i.source==="explicit_intent"}}if(await n.recordUserMessage(t.prompt,t.sessionId,t.prompt.slice(0,200)),await n.recordEvent({id:t.eventId,sessionId:t.sessionId,tool:"UserPromptSubmit",kind:"user_message",payload:{prompt:t.prompt,turnId:t.turnId},createdAt:t.createdAt}),t.operation==="capture_prompt"||!t.explicitContent)return {turn:i,additionalContext:Ze(i),skipSkillRouting:!1};let a=await n.saveExplicitMemoryIntent(t.explicitContent,{actorId:"actor:claude-code",sessionId:t.sessionId},t.eventId),c=[...new Set([a.id,...a.relatedMemoryIds??[]])];y({event:"memory.semantic.decided",identity:{projectRoot:o,sessionId:i.sessionId,turnId:i.turnId},level:a.semanticDecision?.status==="semantic_ready"?"info":"warn",timestamp:Date.now(),data:{status:a.semanticDecision?.status??"semantic_unavailable",operations:a.semanticDecision?.operations??["add"],memoryIds:c,rejectedCount:a.semanticDecision?.rejectedCount??0,durable:a.durable,lexicallyReady:a.lexicallyReady,policyReady:a.policyReady,vectorStatus:a.vectorStatus}});let d=i.receiptId??Re(i.turnId,"committed",c),l=s?r.updateCommittedMemoryTurnProjection({turnId:i.turnId,memoryIds:c,reason:"explicit_async_ready"}):r.commitMemoryTurn({turnId:i.turnId,receiptId:d,memoryIds:c,source:"explicit_intent",reason:"explicit_user_request"});O({projectRoot:o,sessionId:i.sessionId,turnId:i.turnId,kind:"memory.committed",payload:{receiptId:d,reasonCode:"explicit_async_ready"},dedupeKey:`${d}:async_ready`,producer:"devflow-memory-worker"}),y({event:"memory.write.completed",identity:{projectRoot:o,sessionId:i.sessionId,turnId:i.turnId,actionReceipt:d},level:"info",timestamp:Date.now(),data:{stage:"explicit_async_ready",durable:!0,memoryIds:c,receiptLatencyMs:Math.max(0,(i.decidedAt??Date.now())-i.createdAt),asyncReadinessMs:Math.max(0,Date.now()-i.createdAt),vectorStatus:a.vectorStatus}});try{typeof n.finalizeTurnDecision=="function"&&await n.finalizeTurnDecision({turnEventId:i.eventId,sessionId:i.sessionId,turnId:i.turnId,receiptId:d,status:"committed",memoryIds:c,reason:"explicit_user_request"});}catch(u){y({event:"memory.write.degraded",identity:{projectRoot:o,sessionId:t.sessionId,turnId:i.turnId},level:"warn",timestamp:Date.now(),data:{stage:"lineage_finalize",reason:u.message,fallback:"session_end_reconciliation"}});}try{await n.enrichExplicitMemoryObservation(a.id);}catch(u){y({event:"memory.write.degraded",identity:{projectRoot:o,sessionId:t.sessionId,turnId:i.turnId},level:"warn",timestamp:Date.now(),data:{stage:"explicit_enrichment",memoryId:a.id,reason:u.message,fallback:"durable_work_queue"}}),r.enqueueWork({idempotencyKey:`explicit-enrichment:${o}:${a.id}`,kind:"memory.explicit_enrichment",projectRoot:o,sessionId:t.sessionId,turnId:l.turnId,payload:{observationId:a.id},maxAttempts:20});}r.enqueueWork({idempotencyKey:`vector:${o}:${a.id}`,kind:"memory.vector_backfill",projectRoot:o,sessionId:t.sessionId,turnId:l.turnId,payload:{observationId:a.id},maxAttempts:20});try{await Qe({projectRoot:o,memory:n,injectConfig:loadConfig(o).sessionStart?.injectMemories,reason:"explicit_memory_commit"});}catch(u){y({event:"memory.write.degraded",identity:{projectRoot:o,sessionId:t.sessionId,turnId:i.turnId},level:"warn",timestamp:Date.now(),data:{stage:"snapshot_refresh",reason:u.message,fallback:"durable_memory_authoritative"}});}return {turn:l,explicitContent:t.explicitContent,additionalContext:ke(l),skipSkillRouting:!0}}finally{r.close();}}var jd=new Set(["Write","Edit","NotebookEdit"]),br=`Claude native memory writes are disabled for this project. Use DevFlow explicit memory or ${projectClaudeToolName("memory_commit_turn")} so a canonical receipt is created.`;function Er(e){if(!jd.has(e.toolName))return null;let t=$d(e.toolInput);if(!t)return null;let n=Fd(t,e.projectRoot),o=resolve(e.projectRoot,".claude");if(kr(n,o)&&basename(n).toLocaleUpperCase("en-US")==="MEMORY.MD")return br;let r=resolve(e.home??homedir(),".claude","projects");return kr(n,r)&&relative(r,n).split(sep).some(s=>s.toLocaleLowerCase("en-US")==="memory")?br:null}function $d(e){for(let t of ["file_path","notebook_path","path"]){let n=e[t];if(typeof n=="string"&&n.trim())return n.trim()}return null}function Fd(e,t){return resolve(isAbsolute(e)?e:resolve(t,e))}function kr(e,t){let n=relative(t,e);return n===""||!n.startsWith(`..${sep}`)&&n!==".."&&!isAbsolute(n)}var Ud=1024*1024;function Dr(e){let t=join(getProjectStateDir(e),"session-start-pending");mkdirSync$1(t,{recursive:true,mode:448});let n=readdirSync$1(t).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!n)return null;let o=join(t,n),r=/\.json\.claim-\d+$/u.test(n),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=readFileSync$1(i,"utf8");if(Buffer.byteLength(s,"utf8")>Ud)throw unlinkSync$1(i),new Error("session_start_spool_input_too_large");return {receiptId:basename(n).replace(/\.json(?:\.claim-\d+)?$/u,""),input:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function Cr(e){unlinkSync$1(e.path);}function Mr(e){let t=e.path.replace(/\.claim-\d+$/u,"");try{renameSync(e.path,t);}catch{}}var Gd=2*1024*1024;function Yd(e){return join(getProjectStateDir(e),"user-prompt-submit-pending")}function jr(e){let t=Yd(e);mkdirSync$1(t,{recursive:true,mode:448});let n=readdirSync$1(t).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!n)return null;let o=join(t,n),r=/\.json\.claim-\d+$/u.test(n),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=readFileSync$1(i,"utf8");if(Buffer.byteLength(s,"utf8")>Gd)throw unlinkSync$1(i),new Error("user_prompt_submit_input_too_large");return {receiptId:basename(n).replace(/\.json(?:\.claim-\d+)?$/u,""),input:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function $r(e){unlinkSync$1(e.path);}function Fr(e){let t=e.path.replace(/\.claim-\d+$/u,"");try{renameSync(e.path,t);}catch{}}function Nr(e,t){let n=Ur(e);mkdirSync$1(n,{recursive:true,mode:448});let o=`memory-turn-spool-${Date.now()}-${process.pid}-${randomUUID$1()}`,r=join(n,`${o}.json`),i=`${r}.tmp`;return writeFileSync$1(i,JSON.stringify({...t,prompt:t.prompt.trim().slice(0,4e3)}),{mode:384}),renameSync(i,r),o}function Lr(e){let t=Ur(e);mkdirSync$1(t,{recursive:true,mode:448});let n=readdirSync$1(t).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!n)return null;let o=join(t,n),r=/\.json\.claim-\d+$/u.test(n),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=JSON.parse(readFileSync$1(i,"utf8"));if(typeof s.sessionId!="string"||typeof s.prompt!="string"||typeof s.createdAt!="number")throw unlinkSync$1(i),new Error("memory_turn_spool_payload_invalid");return {receiptId:basename(n).replace(/\.json(?:\.claim-\d+)?$/u,""),payload:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function qr(e){unlinkSync$1(e.path);}function Wr(e){try{renameSync(e.path,e.path.replace(/\.claim-\d+$/u,""));}catch{}}function Ur(e){return join(F(e),"memory-turn-pending")}var E=class extends Error{constructor(t,n){super(n),this.name="PermanentWorkError",this.category=t;}},rl=1e3,il=3e4,sl=1,al=5*6e4,tt=class{constructor(t){this.timer=null;this.draining=null;this.stopped=true;this.projectRoot=t.projectRoot,this.handlers=t.handlers,this.pollIntervalMs=nn(t.pollIntervalMs,rl),this.leaseMs=nn(t.leaseMs,il),this.batchSize=nn(t.batchSize,sl),this.owner=t.owner??`hook-daemon:${process.pid}:${randomUUID$1()}`,this.now=t.now??Date.now,this.random=t.random??Math.random,this.openDatabase=t.openDatabase??(()=>openGlobalDevFlowDatabase()),this.afterComplete=t.afterComplete;}start(){this.stopped&&(this.stopped=false,this.schedule(0));}stop(){this.stopped=true,this.timer&&clearTimeout(this.timer),this.timer=null;}drainOnce(){return this.draining?this.draining:(this.draining=this.performDrain().finally(()=>{this.draining=null;}),this.draining)}async drainWorkItemOnce(t){return t.trim()?(this.draining&&await this.draining,this.draining=this.performDrain(void 0,new Set([t])).finally(()=>{this.draining=null;}),this.draining):0}schedule(t){this.stopped||(this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>{this.timer=null,this.drainOnce().catch(n=>this.logDegradation("drain",n)).finally(()=>this.schedule(this.pollIntervalMs));},t),this.timer.unref());}async performDrain(t,n){let o=Object.keys(this.handlers).filter(i=>!t||t.has(i));if(o.length===0)return 0;let r=this.openDatabase();try{let i=this.now();r.recoverExpiredWork(this.projectRoot,i);let s=r.leaseWork({projectRoot:this.projectRoot,owner:this.owner,kinds:o,workItemIds:n?[...n]:void 0,limit:this.batchSize,leaseMs:this.leaseMs,now:i});for(let a of s)await this.processItem(r,a);return s.length}finally{r.close();}}async processItem(t,n){let o=this.handlers[n.kind];if(!o){t.deadLetterWork(n.id,this.owner,{category:"unsupported_work_kind",message:`No work handler is registered for ${n.kind}`}),this.logWorkTransition("dead_letter",n,{errorCategory:"unsupported_work_kind"},"error");return}let r=setInterval(()=>{t.heartbeatWork(n.id,this.owner,this.leaseMs,this.now())||this.logDegradation("lease_heartbeat",new Error("work_lease_heartbeat_rejected"),n);},Math.max(1e3,Math.floor(this.leaseMs/3)));r.unref();try{if(await o({item:n}),!t.completeWork(n.id,this.owner,this.now()))throw new Error(`Work lease was lost before completion: ${n.id}`);this.logWorkTransition("completed",n,{attempt:n.attempts});try{await this.afterComplete?.({item:n,database:t});}catch(i){this.logDegradation("completion_follow_up",i,n);}}catch(i){let s=cl(i);if(i instanceof E||s.permanent){t.deadLetterWork(n.id,this.owner,s),this.logWorkTransition("dead_letter",n,{attempt:n.attempts,errorCategory:s.category},"error");return}let a=this.now()+Math.max(dl(n.attempts,this.random()),s.retryAfterMs??0);if(s.retryWithoutAttempt){t.deferWork(n.id,this.owner,s,a),this.logWorkTransition("deferred",n,{attempt:n.attempts,nextAttemptAt:a,errorCategory:s.category},"warn");return}t.retryWork(n.id,this.owner,s,a),this.logWorkTransition("retry_wait",n,{attempt:n.attempts,nextAttemptAt:a,errorCategory:s.category},"warn");}finally{clearInterval(r);}}logDegradation(t,n,o){y({event:"hook.runtime.degraded",identity:{projectRoot:this.projectRoot,sessionId:o?.sessionId,turnId:o?.turnId,executionId:o?.executionId},level:"warn",timestamp:this.now(),data:{stage:`work_${t}`,workId:o?.id,workKind:o?.kind,reason:zr(n)}});}logWorkTransition(t,n,o,r="info"){try{y({event:"durable.work.transitioned",identity:{projectRoot:this.projectRoot,sessionId:n.sessionId,turnId:n.turnId,executionId:n.executionId},level:r,timestamp:this.now(),data:{stage:t,workId:n.id,workKind:n.kind,...o}});}catch{}}};function nn(e,t){return Number.isSafeInteger(e)&&e>0?e:t}function cl(e){if(e instanceof E)return {category:e.category,message:e.message};let t=e&&typeof e=="object"?e:null,n=typeof t?.category=="string"?t.category:"runtime_error";return {category:n,message:zr(e),retryAfterMs:typeof t?.retryAfterMs=="number"&&Number.isFinite(t.retryAfterMs)?Math.max(0,t.retryAfterMs):void 0,retryWithoutAttempt:t?.retryWithoutAttempt===true,permanent:n==="policy_verification_failed"||n==="invalid_payload"}}function dl(e,t){let n=Math.min(al,500*2**Math.max(0,e-1)),o=Math.floor(n*.2*Math.max(0,Math.min(1,t)));return n+o}function zr(e){return e instanceof Error?e.message:String(e)}var fl=250;function Jr(e,t=process.env){let n=Vr(join(getDevFlowStateRoot({env:t}),"config.json")),o=Vr(join(e,".devflow","config.json")),r=on(t.DEVFLOW_HOOK_PROFILE)??on(o.profile)??on(n.profile)??"standard",i=Number(t.DEVFLOW_HOOK_ACK_BUDGET_MS??o.acknowledgementBudgetMs??n.acknowledgementBudgetMs),s=Number.isSafeInteger(i)&&i>0?Math.min(i,5e3):fl,a=new Set([...rn(n.disabledHandlers),...rn(o.disabledHandlers),...rn(t.DEVFLOW_DISABLED_HOOK_HANDLERS?.split(","))].map(vl).filter(c=>!!c));return {profile:r,acknowledgementBudgetMs:s,disabledHandlers:a}}async function Kr(e,t,n,o,r=process.env.CLAUDE_PROJECT_DIR||process.cwd()){let i,s=new Promise(a=>{i=setTimeout(()=>{y({event:"hook.runtime.degraded",identity:{projectRoot:r},level:"warn",timestamp:Date.now(),data:{stage:"acknowledgement_budget",eventName:e,budgetMs:t,fallback:"timeout_result"}}),a(o());},t),i.unref();});try{return await Promise.race([Promise.resolve().then(n),s])}finally{i&&clearTimeout(i);}}async function Gr(e,t=process.env){let n=t.DEVFLOW_HOST_ADAPTER??(t.CLAUDE_PROJECT_DIR||t.CLAUDE_PLUGIN_ROOT||t.CLAUDE_CODE_ENTRYPOINT?"claude-code":void 0),o=await selectHostAdapter({projectRoot:e,env:t,explicitHost:n});if(o.status==="failed")throw new Error(`host_adapter_selection_failed:${o.code}:${o.reason}`);let r=await o.adapter.capabilities({projectRoot:e,env:t,explicitHost:n});return {hostId:o.adapter.id,capabilities:new Map(r.map(i=>[i.capability,i])),profiles:new Set(o.adapter.hooks?.profileSupport??[])}}function sn(e,t,n){let o=yl(e,t.profile),r=t.profile==="advise"?"standard":t.profile;if(!n.profiles.has(r))return {enabled:false,policy:"fail_open",reason:`hook_profile_${t.profile}_unsupported_by_${n.hostId}`,fallback:"host_event_continues_without_devflow_handler"};if(t.disabledHandlers.has(e))return {enabled:false,policy:"fail_open",reason:"hook_handler_disabled",fallback:"host_event_continues_without_devflow_handler"};if(t.profile==="minimal"&&!gl.has(e))return {enabled:false,policy:"fail_open",reason:"hook_handler_not_in_minimal_profile",fallback:"critical_receipts_only"};let i=hl[e];if(!i)return {enabled:true,policy:o};let s=n.capabilities.get(i);return !s||s.status!=="supported"?{enabled:false,policy:"fail_open",reason:s?.reason??`${i}_unsupported_by_${n.hostId}`,fallback:s?.fallback??"host_event_continues_without_native_hook_processing"}:{enabled:true,policy:o}}var gl=new Set(["session-start","user-prompt-submit","stop","session-end","memory-snapshot"]),hl={"session-start":"hooks.session_start","user-prompt-submit":"hooks.prompt_submit","pre-tool-use":"hooks.pre_tool_use","post-tool-use":"hooks.post_tool_use","post-tool-use-failure":"hooks.post_tool_use",stop:"hooks.stop","session-end":"hooks.session_end"};function yl(e,t){return e==="user-prompt-submit"||e==="stop"||e==="session-end"?"enqueue_and_open":e==="pre-tool-use"&&t==="strict"?"fail_closed":"fail_open"}function Vr(e){if(!existsSync(e))return {};try{let n=JSON.parse(readFileSync$1(e,"utf8")).hooks;return n&&typeof n=="object"&&!Array.isArray(n)?n:{}}catch{return {}}}function on(e){return e==="minimal"||e==="standard"||e==="strict"||e==="advise"?e:void 0}function rn(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function vl(e){let t=e.trim().replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/_/g,"-").toLowerCase();return ({sessionstart:"session-start",userpromptsubmit:"user-prompt-submit",pretooluse:"pre-tool-use",posttooluse:"post-tool-use",posttoolusefailure:"post-tool-use-failure",sessionend:"session-end",precompact:"pre-compact",memorysnapshot:"memory-snapshot"}[t.replace(/-/g,"")]??t)||void 0}var nt=class{decode(t){let n;try{let d=JSON.parse(t.rawInput);if(!d||typeof d!="object"||Array.isArray(d))return null;n=d;}catch{return null}let o=wl[t.requestType];if(typeof n.hook_event_name=="string"&&n.hook_event_name!==o)return null;let r=resolve(cn(n.cwd)??t.projectRoot??process.cwd()),i=cn(n.session_id),s=cn(n.tool_use_id),a=t.receivedAt??Date.now(),c={requestType:t.requestType,projectRoot:r,sessionId:i??"",toolUseId:s??"",payloadHash:stableRuntimeHash(n)};return {schemaVersion:"normalized-hook-event.v1",eventId:`hook-event:${stableRuntimeHash(c).slice(0,32)}`,requestType:t.requestType,eventName:o,projectRoot:r,...i?{sessionId:i}:{},...s?{toolUseId:s}:{},retryKey:`${t.requestType}:${stableRuntimeHash(c).slice(0,24)}`,receivedAt:a,rawInput:t.rawInput,payload:n}}},wl={"session-start":"SessionStart","user-prompt-submit":"UserPromptSubmit","pre-tool-use":"PreToolUse","post-tool-use":"PostToolUse","post-tool-use-failure":"PostToolUseFailure",stop:"Stop","session-end":"SessionEnd","pre-compact":"PreCompact","memory-snapshot":"MemorySnapshot"};function cn(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Yr(e){let t=Object.keys(e.handlers).map(n=>{let o=bl[n];return [n,{requestType:n,eventName:o,capability:kl[n],failurePolicy:e.failurePolicy(n),acknowledgeWithinBudget:_l.has(n),handler:e.handlers[n],timeoutResult:()=>Sl(n)}]});return new Map(t)}async function Xr(e){let t=e.registry.get(e.requestType);if(!t)return {status:"degraded",reason:"unknown_hook_handler",fallback:"host_event_continues"};let n=new nt().decode({requestType:e.requestType,rawInput:e.rawInput,projectRoot:e.projectRoot}),o=()=>Promise.resolve(t.handler(n?.rawInput??e.rawInput));return t.acknowledgeWithinBudget?Kr(t.eventName,e.acknowledgementBudgetMs,o,t.timeoutResult,e.projectRoot):o()}var _l=new Set(["stop","session-end","user-prompt-submit"]),bl={"session-start":"SessionStart","user-prompt-submit":"UserPromptSubmit","pre-tool-use":"PreToolUse","post-tool-use":"PostToolUse","post-tool-use-failure":"PostToolUseFailure",stop:"Stop","session-end":"SessionEnd","pre-compact":"PreCompact","memory-snapshot":"MemorySnapshot"},kl={"session-start":"hooks.session_start","user-prompt-submit":"hooks.prompt_submit","pre-tool-use":"hooks.pre_tool_use","post-tool-use":"hooks.post_tool_use","post-tool-use-failure":"hooks.post_tool_use",stop:"hooks.stop","session-end":"hooks.session_end"};function Sl(e){return e==="user-prompt-submit"?{hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",additionalContext:"DevFlow background processing exceeded its acknowledgement budget; continue in degraded mode and do not claim unreceipted work completed."}}:{status:"degraded",reason:"hook_budget_exceeded",fallback:e==="session-end"?"durable_session_recovery":"background_processing"}}var rt=class{constructor(t){this.records=new Map;this.path=join(F(t),"hook-handler-health.json"),this.load();}recordSuccess(t,n,o=Date.now()){let r={handler:t,host:n,status:"healthy",consecutiveFailures:0,lastSuccessAt:o,updatedAt:o};return this.records.set(ot(t,n),r),this.persist(),r}recordFailure(t,n,o,r,i=Date.now()){let s=this.records.get(ot(t,n)),a=(s?.consecutiveFailures??0)+1,c=Math.min(5*6e4,1e3*2**Math.min(8,a-1)),d={handler:t,host:n,status:"degraded",consecutiveFailures:a,lastFailureCategory:o,lastFailureReason:r.slice(0,500),retryAt:i+c,lastSuccessAt:s?.lastSuccessAt,updatedAt:i};return this.records.set(ot(t,n),d),this.persist(),d}list(){return [...this.records.values()].sort((t,n)=>t.handler.localeCompare(n.handler))}load(){try{let t=JSON.parse(readFileSync$1(this.path,"utf8"));for(let n of t)n?.handler&&n?.host&&this.records.set(ot(n.handler,n.host),n);}catch{}}persist(){try{mkdirSync$1(dirname$1(this.path),{recursive:!0,mode:448});let t=`${this.path}.${process.pid}.tmp`;writeFileSync$1(t,JSON.stringify(this.list(),null,2),{mode:384}),renameSync(t,this.path);}catch{}}};function ot(e,t){return `${t}\0${e}`}function Qr(e,t){return t||(e==="post-tool-use"||e==="post-tool-use-failure"?{status:"ok"}:{status:"ok"})}function Zr(e){let t=e instanceof Error?e.message:String(e??"hook_handler_failed");return {category:/timeout|budget|deadline/iu.test(t)?"timeout":/sqlite|database|locked|busy/iu.test(t)?"storage":/socket|connect|unreachable/iu.test(t)?"transport":/json|parse|schema|invalid/iu.test(t)?"protocol":"handler",reason:t}}function ei(e){let t=Po({projectRoot:e.projectRoot,sessionId:e.sessionId,transcriptPath:e.transcriptPath,runtimeStore:e.runtimeStore}),n=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{$l(e.runtimeStore,e.sessionId,n);let o=n.getPendingMemoryTurn(e.projectRoot,e.sessionId),r=o?n.markMemoryTurnStopPrompted(o.turnId):!1,i=[];t&&i.push(t.reason),o&&r&&i.push(Ze(o)),o&&!r&&Pl(n,o.turnId)&&jl(ze(e.transcriptPath))&&i.push(`DevFlow explicit memory ${o.turnId} still has no canonical receipt. Remove the memory-success claim and tell the user that the memory was not saved, or complete the pending turn.`);let a=n.listSessionObligations(e.projectRoot,e.sessionId,["open"]).map(c=>({obligationId:c.obligationId,kind:c.kind,action:c.kind==="memory_decision"?`Call ${projectClaudeToolName("memory_decide_turn")} using the canonical turn ID.`:c.kind==="evidence_contract"?c.payload.subtype==="policy_verification"?`Complete the required project verification: ${String(c.payload.command??c.payload.verificationKind??"unknown command")}.`:"Return a final answer that satisfies the canonical evidence contract.":"Allow SessionEnd durable finalization to complete.",canonicalInput:c.kind==="memory_decision"&&c.turnId?{turnId:c.turnId}:void 0}));return i.length>0?{decision:"block_once",unresolved:a,additionalContext:["DevFlow has unresolved terminal obligations. Complete all actions below before stopping.",...i].join(`
|
|
30
|
+
`)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,e,t,n]=process.argv;e!=="session-start"||!t?process.exitCode=2:process.stdout.write(_d({projectRoot:t,configPath:n,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}var xd=/^(?:ok(?:ay)?|yes|no|thanks?|thank you|continue|好的?|可以|行|是|否|谢谢|继续|收到|明白了?)[.!。!\s]*$/iu,Ed=/(?:记住|记下|保存|持久化|跨会话|以后|始终|永远|统一使用|项目约定|团队约定|偏好|决定采用|保留可复用|提炼结论|沉淀|记录(?:下来|为|成)?(?:架构|规则|约定|知识|结论))|\b(?:remember|memorize|persist|across sessions|from now on|always|project convention|team convention|preference|we use|adopt|retain reusable|distill)\b/iu,Td=/(?:分析|审查|检查|评估|性能|生成|创建|新建|添加|编写|实现|开发|设计|撰写|总结|修改|重构|修复|调试|解释|查看)|\b(?:analy[sz]e|review|inspect|audit|performance|generate|create|add|build|implement|develop|design|write|summarize|modify|refactor|fix|debug|explain)\b/iu,Ad=/(?:召回|查询|检索|查找|定位|询问|什么|如何|是否|哪里|哪个)|\b(?:recall|query|search|find|locate|ask|what|how|whether|where|which)\b/iu;function Dd(e){let t=e.trim();return t.length>0&&!xd.test(t)}function Cd(e,t){if(!t.trim())return false;let n=join(e,".devflow","delivery-line","state.db");if(!existsSync(n))return false;let o;try{return o=new DatabaseSync(n,{readOnly:!0,timeout:250}),o.prepare("SELECT payload FROM delivery_cases").all().some(i=>{try{let s=JSON.parse(i.payload);return s.sessionId===t&&!["delivered","cancelled","rejected"].includes(String(s.stage??""))}catch{return !1}})}catch{return false}finally{o?.close();}}function Md(e){let t=e.normalize("NFKC").trim(),n=Ad.test(t);return t.length>=4&&(Td.test(t)||n)&&(!Ed.test(t)||n)&&Ie(t)===null}function Od(e,t,n=Date.now()){let o=createHash("sha256").update(t.trim()).digest("hex"),r=createHash("sha256").update(`${e}\0${n}\0${o}`).digest("hex").slice(0,24);return {turnId:`turn:${r}`,eventId:`memory-turn:${r}`,promptHash:o,createdAt:n}}function Re(e,t,n=[]){return `memory-receipt:${createHash("sha256").update(`${e}\0${t}\0${[...n].sort().join("\0")}`).digest("hex").slice(0,24)}`}function Ze(e){return `DevFlow memory decision required for ${e.turnId}. Before the final response, semantically decide whether this turn contains durable project knowledge. Call ${projectClaudeToolName("memory_commit_turn")} with evidence-bound candidates, or ${projectClaudeToolName("memory_skip_turn")} with a concrete reason. Do not claim memory success without a canonical receipt. For candidates, copy exact evidenceSpans from this user prompt, preserve package names, flags, versions, paths, and identifiers, and provide subject, predicate, value, polarity, and entities when known. To replace or retire an existing fact, provide operation=supersede or operation=retire plus referencedFactIds from the canonical memory receipt; aliases and entity names are not fact identity. Do not save assistant echoes, task narration, retries, or unverified guesses. Express a change from an old choice as the new durable value. If the decision tool remains unavailable, explicitly state that the memory was not saved.`}function ke(e){let t=e.memoryIds.length>0?e.memoryIds.join(","):"none",n=e.status==="committed"?"accepted":e.status,o=e.status==="committed"?"; indexStatus=pending":"",r=e.memoryIds.some(a=>a.startsWith("raw-memory:")),i=e.status==="committed"&&e.source==="explicit_intent"&&!r?"; memoryOnlyCompleted=true; skipProjectContext=true; hostRefinementRequired=true":e.status==="committed"&&e.source==="explicit_intent"?"; asyncReadiness=queued; hostRefinementRequired=true":"",s=e.status==="committed"&&e.source==="explicit_intent"?` The deterministic explicit-memory save is complete and remains authoritative if refinement fails. Before the final response, call ${projectClaudeToolName("memory_commit_turn")} once with turnId=${e.turnId} and semantic candidates. Split every distinct reusable fact into a durable_memory candidate, classify instructions that apply only to this turn as turn_constraint, and include evidenceSpans copied verbatim from the user prompt for every candidate. Preserve exact flags, package names, versions, paths, and identifiers. Keep narrative and value in the user prompt language; do not translate evidence into a different surface form. The tool refines the existing receipt idempotently; it must not create native Claude memory. If refinement is unavailable, return the existing canonical receipt without claiming refinement.`:"";return `DevFlow canonical memory receipt: status=${n}; receiptId=${e.receiptId??"missing"}; turnId=${e.turnId}; memoryIds=${t}; source=${e.source??"unknown"}${o}${i}.`+s}function Gt(e){if(!Dd(e.prompt))return null;let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let n=e.prompt.trim().slice(0,4e3),o=createHash("sha256").update(n).digest("hex"),r=t.listMemoryTurns(e.projectRoot,e.sessionId,5).find(m=>m.promptHash===o&&Date.now()-m.createdAt<1e4),i=r?{turnId:r.turnId,eventId:r.eventId,promptHash:r.promptHash,createdAt:r.createdAt}:e.identity??Od(e.sessionId,n),s=r??t.beginMemoryTurn({...i,projectRoot:e.projectRoot,sessionId:e.sessionId});if(s.status!=="pending")return {turn:s,additionalContext:ke(s),skipSkillRouting:s.source==="explicit_intent"};let c=(e.activation?.semantic??"degraded_structural")==="degraded_structural"?Ie(n)??void 0:void 0,d=Cd(e.projectRoot,e.sessionId);if(!c&&!d&&Md(n)){let m=Re(s.turnId,"skipped"),f=t.skipMemoryTurn({turnId:s.turnId,receiptId:m,source:"automatic_transient_skip",reason:"high_confidence_transient_task"});return O({projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId,kind:"memory.skipped",payload:{receiptId:m,reasonCode:"high_confidence_transient_task"},dedupeKey:m,producer:"devflow-memory-turn"}),y({event:"memory.semantic.decided",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId},level:"info",timestamp:Date.now(),data:{status:"semantic_empty",operation:"none",reason:"high_confidence_transient_task"}}),{turn:f,additionalContext:ke(f),skipSkillRouting:!1}}let l=c?"commit_explicit":"capture_prompt",u=t.enqueueWork({idempotencyKey:`memory-turn:${l}:${s.turnId}`,kind:c?"memory.explicit_commit":"memory.turn_capture",projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId,payload:{operation:l,turnId:s.turnId,eventId:s.eventId,sessionId:e.sessionId,prompt:n,explicitContent:c,createdAt:s.createdAt}});if(c){let m=`raw-memory:${createHash("sha256").update(`${e.projectRoot}\0${i.turnId}\0${c}`).digest("hex").slice(0,24)}`,f=Re(s.turnId,"committed",[m]),p=t.commitMemoryTurn({turnId:s.turnId,receiptId:f,memoryIds:[m],source:"explicit_intent",reason:"explicit_raw_queued",decidedAt:Date.now()});return O({projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId,kind:"durable_work.owned",payload:{workId:u.id,obligation:"memory"},dedupeKey:`${u.id}:owned`,producer:"devflow-memory-turn"}),O({projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId,kind:"memory.committed",payload:{receiptId:f,reasonCode:"explicit_raw_queued"},dedupeKey:f,producer:"devflow-memory-turn"}),y({event:"memory.write.completed",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId,actionReceipt:f},level:"info",timestamp:Date.now(),data:{stage:"explicit_fast_ack",durable:!0,rawMemoryId:m,receiptLatencyMs:Date.now()-i.createdAt,asyncReadiness:"queued"}}),{turn:p,explicitContent:c,additionalContext:ke(p),skipSkillRouting:!0}}return O({projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId,kind:"memory.pending",payload:{reasonCode:"semantic_decision_queued"},dedupeKey:`${s.turnId}:pending`,producer:"devflow-memory-turn"}),O({projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:s.turnId,kind:"durable_work.owned",payload:{workId:u.id,obligation:"memory"},dedupeKey:`${u.id}:owned`,producer:"devflow-memory-turn"}),{turn:s,explicitContent:c,additionalContext:Ze(s),skipSkillRouting:!1}}finally{t.close();}}async function Yt(e){let{payload:t,memory:n,projectRoot:o}=e,r=openGlobalDevFlowDatabase();try{let i=r.getMemoryTurn(t.turnId);if(!i)throw new Error(`Memory turn ${t.turnId} does not exist`);let s=t.operation==="commit_explicit"&&i.status==="committed"&&i.source==="explicit_intent"&&i.memoryIds.some(u=>u.startsWith("raw-memory:"));if(i.status!=="pending"&&!s){if(i.receiptId&&typeof n.reconcileTurnObservationLineage=="function")try{await n.reconcileTurnObservationLineage([i]);}catch{}return {turn:i,additionalContext:ke(i),skipSkillRouting:i.source==="explicit_intent"}}if(await n.recordUserMessage(t.prompt,t.sessionId,t.prompt.slice(0,200)),await n.recordEvent({id:t.eventId,sessionId:t.sessionId,tool:"UserPromptSubmit",kind:"user_message",payload:{prompt:t.prompt,turnId:t.turnId},createdAt:t.createdAt}),t.operation==="capture_prompt"||!t.explicitContent)return {turn:i,additionalContext:Ze(i),skipSkillRouting:!1};let a=await n.saveExplicitMemoryIntent(t.explicitContent,{actorId:"actor:claude-code",sessionId:t.sessionId},t.eventId),c=[...new Set([a.id,...a.relatedMemoryIds??[]])];y({event:"memory.semantic.decided",identity:{projectRoot:o,sessionId:i.sessionId,turnId:i.turnId},level:a.semanticDecision?.status==="semantic_ready"?"info":"warn",timestamp:Date.now(),data:{status:a.semanticDecision?.status??"semantic_unavailable",operations:a.semanticDecision?.operations??["add"],memoryIds:c,rejectedCount:a.semanticDecision?.rejectedCount??0,durable:a.durable,lexicallyReady:a.lexicallyReady,policyReady:a.policyReady,vectorStatus:a.vectorStatus}});let d=i.receiptId??Re(i.turnId,"committed",c),l=s?r.updateCommittedMemoryTurnProjection({turnId:i.turnId,memoryIds:c,reason:"explicit_async_ready"}):r.commitMemoryTurn({turnId:i.turnId,receiptId:d,memoryIds:c,source:"explicit_intent",reason:"explicit_user_request"});O({projectRoot:o,sessionId:i.sessionId,turnId:i.turnId,kind:"memory.committed",payload:{receiptId:d,reasonCode:"explicit_async_ready"},dedupeKey:`${d}:async_ready`,producer:"devflow-memory-worker"}),y({event:"memory.write.completed",identity:{projectRoot:o,sessionId:i.sessionId,turnId:i.turnId,actionReceipt:d},level:"info",timestamp:Date.now(),data:{stage:"explicit_async_ready",durable:!0,memoryIds:c,receiptLatencyMs:Math.max(0,(i.decidedAt??Date.now())-i.createdAt),asyncReadinessMs:Math.max(0,Date.now()-i.createdAt),vectorStatus:a.vectorStatus}});try{typeof n.finalizeTurnDecision=="function"&&await n.finalizeTurnDecision({turnEventId:i.eventId,sessionId:i.sessionId,turnId:i.turnId,receiptId:d,status:"committed",memoryIds:c,reason:"explicit_user_request"});}catch(u){y({event:"memory.write.degraded",identity:{projectRoot:o,sessionId:t.sessionId,turnId:i.turnId},level:"warn",timestamp:Date.now(),data:{stage:"lineage_finalize",reason:u.message,fallback:"session_end_reconciliation"}});}try{await n.enrichExplicitMemoryObservation(a.id);}catch(u){y({event:"memory.write.degraded",identity:{projectRoot:o,sessionId:t.sessionId,turnId:i.turnId},level:"warn",timestamp:Date.now(),data:{stage:"explicit_enrichment",memoryId:a.id,reason:u.message,fallback:"durable_work_queue"}}),r.enqueueWork({idempotencyKey:`explicit-enrichment:${o}:${a.id}`,kind:"memory.explicit_enrichment",projectRoot:o,sessionId:t.sessionId,turnId:l.turnId,payload:{observationId:a.id},maxAttempts:20});}r.enqueueWork({idempotencyKey:`vector:${o}:${a.id}`,kind:"memory.vector_backfill",projectRoot:o,sessionId:t.sessionId,turnId:l.turnId,payload:{observationId:a.id},maxAttempts:20});try{await Qe({projectRoot:o,memory:n,injectConfig:loadConfig(o).sessionStart?.injectMemories,reason:"explicit_memory_commit"});}catch(u){y({event:"memory.write.degraded",identity:{projectRoot:o,sessionId:t.sessionId,turnId:i.turnId},level:"warn",timestamp:Date.now(),data:{stage:"snapshot_refresh",reason:u.message,fallback:"durable_memory_authoritative"}});}return {turn:l,explicitContent:t.explicitContent,additionalContext:ke(l),skipSkillRouting:!0}}finally{r.close();}}var Fd=new Set(["Write","Edit","NotebookEdit"]),br=`Claude native memory writes are disabled for this project. Use DevFlow explicit memory or ${projectClaudeToolName("memory_commit_turn")} so a canonical receipt is created.`;function Er(e){if(!Fd.has(e.toolName))return null;let t=Hd(e.toolInput);if(!t)return null;let n=Nd(t,e.projectRoot),o=resolve(e.projectRoot,".claude");if(kr(n,o)&&basename(n).toLocaleUpperCase("en-US")==="MEMORY.MD")return br;let r=resolve(e.home??homedir(),".claude","projects");return kr(n,r)&&relative(r,n).split(sep).some(s=>s.toLocaleLowerCase("en-US")==="memory")?br:null}function Hd(e){for(let t of ["file_path","notebook_path","path"]){let n=e[t];if(typeof n=="string"&&n.trim())return n.trim()}return null}function Nd(e,t){return resolve(isAbsolute(e)?e:resolve(t,e))}function kr(e,t){let n=relative(t,e);return n===""||!n.startsWith(`..${sep}`)&&n!==".."&&!isAbsolute(n)}var Bd=1024*1024;function Dr(e){let t=join(getProjectStateDir(e),"session-start-pending");mkdirSync$1(t,{recursive:true,mode:448});let n=readdirSync$1(t).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!n)return null;let o=join(t,n),r=/\.json\.claim-\d+$/u.test(n),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=readFileSync$1(i,"utf8");if(Buffer.byteLength(s,"utf8")>Bd)throw unlinkSync$1(i),new Error("session_start_spool_input_too_large");return {receiptId:basename(n).replace(/\.json(?:\.claim-\d+)?$/u,""),input:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function Cr(e){unlinkSync$1(e.path);}function Mr(e){let t=e.path.replace(/\.claim-\d+$/u,"");try{renameSync(e.path,t);}catch{}}var Xd=2*1024*1024;function Qd(e){return join(getProjectStateDir(e),"user-prompt-submit-pending")}function jr(e){let t=Qd(e);mkdirSync$1(t,{recursive:true,mode:448});let n=readdirSync$1(t).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!n)return null;let o=join(t,n),r=/\.json\.claim-\d+$/u.test(n),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=readFileSync$1(i,"utf8");if(Buffer.byteLength(s,"utf8")>Xd)throw unlinkSync$1(i),new Error("user_prompt_submit_input_too_large");return {receiptId:basename(n).replace(/\.json(?:\.claim-\d+)?$/u,""),input:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function $r(e){unlinkSync$1(e.path);}function Fr(e){let t=e.path.replace(/\.claim-\d+$/u,"");try{renameSync(e.path,t);}catch{}}function Nr(e,t){let n=Ur(e);mkdirSync$1(n,{recursive:true,mode:448});let o=`memory-turn-spool-${Date.now()}-${process.pid}-${randomUUID$1()}`,r=join(n,`${o}.json`),i=`${r}.tmp`;return writeFileSync$1(i,JSON.stringify({...t,prompt:t.prompt.trim().slice(0,4e3)}),{mode:384}),renameSync(i,r),o}function Lr(e){let t=Ur(e);mkdirSync$1(t,{recursive:true,mode:448});let n=readdirSync$1(t).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!n)return null;let o=join(t,n),r=/\.json\.claim-\d+$/u.test(n),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=JSON.parse(readFileSync$1(i,"utf8"));if(typeof s.sessionId!="string"||typeof s.prompt!="string"||typeof s.createdAt!="number")throw unlinkSync$1(i),new Error("memory_turn_spool_payload_invalid");return {receiptId:basename(n).replace(/\.json(?:\.claim-\d+)?$/u,""),payload:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function qr(e){unlinkSync$1(e.path);}function Wr(e){try{renameSync(e.path,e.path.replace(/\.claim-\d+$/u,""));}catch{}}function Ur(e){return join(F(e),"memory-turn-pending")}var E=class extends Error{constructor(t,n){super(n),this.name="PermanentWorkError",this.category=t;}},sl=1e3,al=3e4,cl=1,dl=5*6e4,tt=class{constructor(t){this.timer=null;this.draining=null;this.stopped=true;this.projectRoot=t.projectRoot,this.handlers=t.handlers,this.pollIntervalMs=nn(t.pollIntervalMs,sl),this.leaseMs=nn(t.leaseMs,al),this.batchSize=nn(t.batchSize,cl),this.owner=t.owner??`hook-daemon:${process.pid}:${randomUUID$1()}`,this.now=t.now??Date.now,this.random=t.random??Math.random,this.openDatabase=t.openDatabase??(()=>openGlobalDevFlowDatabase()),this.afterComplete=t.afterComplete;}start(){this.stopped&&(this.stopped=false,this.schedule(0));}stop(){this.stopped=true,this.timer&&clearTimeout(this.timer),this.timer=null;}drainOnce(){return this.draining?this.draining:(this.draining=this.performDrain().finally(()=>{this.draining=null;}),this.draining)}async drainWorkItemOnce(t){return t.trim()?(this.draining&&await this.draining,this.draining=this.performDrain(void 0,new Set([t])).finally(()=>{this.draining=null;}),this.draining):0}schedule(t){this.stopped||(this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>{this.timer=null,this.drainOnce().catch(n=>this.logDegradation("drain",n)).finally(()=>this.schedule(this.pollIntervalMs));},t),this.timer.unref());}async performDrain(t,n){let o=Object.keys(this.handlers).filter(i=>!t||t.has(i));if(o.length===0)return 0;let r=this.openDatabase();try{let i=this.now();r.recoverExpiredWork(this.projectRoot,i);let s=r.leaseWork({projectRoot:this.projectRoot,owner:this.owner,kinds:o,workItemIds:n?[...n]:void 0,limit:this.batchSize,leaseMs:this.leaseMs,now:i});for(let a of s)await this.processItem(r,a);return s.length}finally{r.close();}}async processItem(t,n){let o=this.handlers[n.kind];if(!o){t.deadLetterWork(n.id,this.owner,{category:"unsupported_work_kind",message:`No work handler is registered for ${n.kind}`}),this.logWorkTransition("dead_letter",n,{errorCategory:"unsupported_work_kind"},"error");return}let r=setInterval(()=>{t.heartbeatWork(n.id,this.owner,this.leaseMs,this.now())||this.logDegradation("lease_heartbeat",new Error("work_lease_heartbeat_rejected"),n);},Math.max(1e3,Math.floor(this.leaseMs/3)));r.unref();try{if(await o({item:n}),!t.completeWork(n.id,this.owner,this.now()))throw new Error(`Work lease was lost before completion: ${n.id}`);this.logWorkTransition("completed",n,{attempt:n.attempts});try{await this.afterComplete?.({item:n,database:t});}catch(i){this.logDegradation("completion_follow_up",i,n);}}catch(i){let s=ll(i);if(i instanceof E||s.permanent){t.deadLetterWork(n.id,this.owner,s),this.logWorkTransition("dead_letter",n,{attempt:n.attempts,errorCategory:s.category},"error");return}let a=this.now()+Math.max(ul(n.attempts,this.random()),s.retryAfterMs??0);if(s.retryWithoutAttempt){t.deferWork(n.id,this.owner,s,a),this.logWorkTransition("deferred",n,{attempt:n.attempts,nextAttemptAt:a,errorCategory:s.category},"warn");return}t.retryWork(n.id,this.owner,s,a),this.logWorkTransition("retry_wait",n,{attempt:n.attempts,nextAttemptAt:a,errorCategory:s.category},"warn");}finally{clearInterval(r);}}logDegradation(t,n,o){y({event:"hook.runtime.degraded",identity:{projectRoot:this.projectRoot,sessionId:o?.sessionId,turnId:o?.turnId,executionId:o?.executionId},level:"warn",timestamp:this.now(),data:{stage:`work_${t}`,workId:o?.id,workKind:o?.kind,reason:zr(n)}});}logWorkTransition(t,n,o,r="info"){try{y({event:"durable.work.transitioned",identity:{projectRoot:this.projectRoot,sessionId:n.sessionId,turnId:n.turnId,executionId:n.executionId},level:r,timestamp:this.now(),data:{stage:t,workId:n.id,workKind:n.kind,...o}});}catch{}}};function nn(e,t){return Number.isSafeInteger(e)&&e>0?e:t}function ll(e){if(e instanceof E)return {category:e.category,message:e.message};let t=e&&typeof e=="object"?e:null,n=typeof t?.category=="string"?t.category:"runtime_error";return {category:n,message:zr(e),retryAfterMs:typeof t?.retryAfterMs=="number"&&Number.isFinite(t.retryAfterMs)?Math.max(0,t.retryAfterMs):void 0,retryWithoutAttempt:t?.retryWithoutAttempt===true,permanent:n==="policy_verification_failed"||n==="invalid_payload"}}function ul(e,t){let n=Math.min(dl,500*2**Math.max(0,e-1)),o=Math.floor(n*.2*Math.max(0,Math.min(1,t)));return n+o}function zr(e){return e instanceof Error?e.message:String(e)}var hl=250;function Jr(e,t=process.env){let n=Vr(join(getDevFlowStateRoot({env:t}),"config.json")),o=Vr(join(e,".devflow","config.json")),r=on(t.DEVFLOW_HOOK_PROFILE)??on(o.profile)??on(n.profile)??"standard",i=Number(t.DEVFLOW_HOOK_ACK_BUDGET_MS??o.acknowledgementBudgetMs??n.acknowledgementBudgetMs),s=Number.isSafeInteger(i)&&i>0?Math.min(i,5e3):hl,a=new Set([...rn(n.disabledHandlers),...rn(o.disabledHandlers),...rn(t.DEVFLOW_DISABLED_HOOK_HANDLERS?.split(","))].map(wl).filter(c=>!!c));return {profile:r,acknowledgementBudgetMs:s,disabledHandlers:a}}async function Kr(e,t,n,o,r=process.env.CLAUDE_PROJECT_DIR||process.cwd()){let i,s=new Promise(a=>{i=setTimeout(()=>{y({event:"hook.runtime.degraded",identity:{projectRoot:r},level:"warn",timestamp:Date.now(),data:{stage:"acknowledgement_budget",eventName:e,budgetMs:t,fallback:"timeout_result"}}),a(o());},t),i.unref();});try{return await Promise.race([Promise.resolve().then(n),s])}finally{i&&clearTimeout(i);}}async function Gr(e,t=process.env){let n=t.DEVFLOW_HOST_ADAPTER??(t.CLAUDE_PROJECT_DIR||t.CLAUDE_PLUGIN_ROOT||t.CLAUDE_CODE_ENTRYPOINT?"claude-code":void 0),o=await selectHostAdapter({projectRoot:e,env:t,explicitHost:n});if(o.status==="failed")throw new Error(`host_adapter_selection_failed:${o.code}:${o.reason}`);let r=await o.adapter.capabilities({projectRoot:e,env:t,explicitHost:n});return {hostId:o.adapter.id,capabilities:new Map(r.map(i=>[i.capability,i])),profiles:new Set(o.adapter.hooks?.profileSupport??[])}}function sn(e,t,n){let o=Il(e,t.profile),r=t.profile==="advise"?"standard":t.profile;if(!n.profiles.has(r))return {enabled:false,policy:"fail_open",reason:`hook_profile_${t.profile}_unsupported_by_${n.hostId}`,fallback:"host_event_continues_without_devflow_handler"};if(t.disabledHandlers.has(e))return {enabled:false,policy:"fail_open",reason:"hook_handler_disabled",fallback:"host_event_continues_without_devflow_handler"};if(t.profile==="minimal"&&!yl.has(e))return {enabled:false,policy:"fail_open",reason:"hook_handler_not_in_minimal_profile",fallback:"critical_receipts_only"};let i=vl[e];if(!i)return {enabled:true,policy:o};let s=n.capabilities.get(i);return !s||s.status!=="supported"?{enabled:false,policy:"fail_open",reason:s?.reason??`${i}_unsupported_by_${n.hostId}`,fallback:s?.fallback??"host_event_continues_without_native_hook_processing"}:{enabled:true,policy:o}}var yl=new Set(["session-start","user-prompt-submit","stop","session-end","memory-snapshot"]),vl={"session-start":"hooks.session_start","user-prompt-submit":"hooks.prompt_submit","pre-tool-use":"hooks.pre_tool_use","post-tool-use":"hooks.post_tool_use","post-tool-use-failure":"hooks.post_tool_use",stop:"hooks.stop","session-end":"hooks.session_end"};function Il(e,t){return e==="user-prompt-submit"||e==="stop"||e==="session-end"?"enqueue_and_open":e==="pre-tool-use"&&t==="strict"?"fail_closed":"fail_open"}function Vr(e){if(!existsSync(e))return {};try{let n=JSON.parse(readFileSync$1(e,"utf8")).hooks;return n&&typeof n=="object"&&!Array.isArray(n)?n:{}}catch{return {}}}function on(e){return e==="minimal"||e==="standard"||e==="strict"||e==="advise"?e:void 0}function rn(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function wl(e){let t=e.trim().replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/_/g,"-").toLowerCase();return ({sessionstart:"session-start",userpromptsubmit:"user-prompt-submit",pretooluse:"pre-tool-use",posttooluse:"post-tool-use",posttoolusefailure:"post-tool-use-failure",sessionend:"session-end",precompact:"pre-compact",memorysnapshot:"memory-snapshot"}[t.replace(/-/g,"")]??t)||void 0}var nt=class{decode(t){let n;try{let d=JSON.parse(t.rawInput);if(!d||typeof d!="object"||Array.isArray(d))return null;n=d;}catch{return null}let o=bl[t.requestType];if(typeof n.hook_event_name=="string"&&n.hook_event_name!==o)return null;let r=resolve(cn(n.cwd)??t.projectRoot??process.cwd()),i=cn(n.session_id),s=cn(n.tool_use_id),a=t.receivedAt??Date.now(),c={requestType:t.requestType,projectRoot:r,sessionId:i??"",toolUseId:s??"",payloadHash:stableRuntimeHash(n)};return {schemaVersion:"normalized-hook-event.v1",eventId:`hook-event:${stableRuntimeHash(c).slice(0,32)}`,requestType:t.requestType,eventName:o,projectRoot:r,...i?{sessionId:i}:{},...s?{toolUseId:s}:{},retryKey:`${t.requestType}:${stableRuntimeHash(c).slice(0,24)}`,receivedAt:a,rawInput:t.rawInput,payload:n}}},bl={"session-start":"SessionStart","user-prompt-submit":"UserPromptSubmit","pre-tool-use":"PreToolUse","post-tool-use":"PostToolUse","post-tool-use-failure":"PostToolUseFailure",stop:"Stop","session-end":"SessionEnd","pre-compact":"PreCompact","memory-snapshot":"MemorySnapshot"};function cn(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Yr(e){let t=Object.keys(e.handlers).map(n=>{let o=Sl[n];return [n,{requestType:n,eventName:o,capability:Rl[n],failurePolicy:e.failurePolicy(n),acknowledgeWithinBudget:kl.has(n),handler:e.handlers[n],timeoutResult:()=>xl(n)}]});return new Map(t)}async function Xr(e){let t=e.registry.get(e.requestType);if(!t)return {status:"degraded",reason:"unknown_hook_handler",fallback:"host_event_continues"};let n=new nt().decode({requestType:e.requestType,rawInput:e.rawInput,projectRoot:e.projectRoot}),o=()=>Promise.resolve(t.handler(n?.rawInput??e.rawInput));return t.acknowledgeWithinBudget?Kr(t.eventName,e.acknowledgementBudgetMs,o,t.timeoutResult,e.projectRoot):o()}var kl=new Set(["stop","session-end","user-prompt-submit"]),Sl={"session-start":"SessionStart","user-prompt-submit":"UserPromptSubmit","pre-tool-use":"PreToolUse","post-tool-use":"PostToolUse","post-tool-use-failure":"PostToolUseFailure",stop:"Stop","session-end":"SessionEnd","pre-compact":"PreCompact","memory-snapshot":"MemorySnapshot"},Rl={"session-start":"hooks.session_start","user-prompt-submit":"hooks.prompt_submit","pre-tool-use":"hooks.pre_tool_use","post-tool-use":"hooks.post_tool_use","post-tool-use-failure":"hooks.post_tool_use",stop:"hooks.stop","session-end":"hooks.session_end"};function xl(e){return e==="user-prompt-submit"?{hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",additionalContext:"DevFlow background processing exceeded its acknowledgement budget; continue in degraded mode and do not claim unreceipted work completed."}}:{status:"degraded",reason:"hook_budget_exceeded",fallback:e==="session-end"?"durable_session_recovery":"background_processing"}}var rt=class{constructor(t){this.records=new Map;this.path=join(F(t),"hook-handler-health.json"),this.load();}recordSuccess(t,n,o=Date.now()){let r={handler:t,host:n,status:"healthy",consecutiveFailures:0,lastSuccessAt:o,updatedAt:o};return this.records.set(ot(t,n),r),this.persist(),r}recordFailure(t,n,o,r,i=Date.now()){let s=this.records.get(ot(t,n)),a=(s?.consecutiveFailures??0)+1,c=Math.min(5*6e4,1e3*2**Math.min(8,a-1)),d={handler:t,host:n,status:"degraded",consecutiveFailures:a,lastFailureCategory:o,lastFailureReason:r.slice(0,500),retryAt:i+c,lastSuccessAt:s?.lastSuccessAt,updatedAt:i};return this.records.set(ot(t,n),d),this.persist(),d}list(){return [...this.records.values()].sort((t,n)=>t.handler.localeCompare(n.handler))}load(){try{let t=JSON.parse(readFileSync$1(this.path,"utf8"));for(let n of t)n?.handler&&n?.host&&this.records.set(ot(n.handler,n.host),n);}catch{}}persist(){try{mkdirSync$1(dirname$1(this.path),{recursive:!0,mode:448});let t=`${this.path}.${process.pid}.tmp`;writeFileSync$1(t,JSON.stringify(this.list(),null,2),{mode:384}),renameSync(t,this.path);}catch{}}};function ot(e,t){return `${t}\0${e}`}function Qr(e,t){return t||(e==="post-tool-use"||e==="post-tool-use-failure"?{status:"ok"}:{status:"ok"})}function Zr(e){let t=e instanceof Error?e.message:String(e??"hook_handler_failed");return {category:/timeout|budget|deadline/iu.test(t)?"timeout":/sqlite|database|locked|busy/iu.test(t)?"storage":/socket|connect|unreachable/iu.test(t)?"transport":/json|parse|schema|invalid/iu.test(t)?"protocol":"handler",reason:t}}function ei(e){let t=Po({projectRoot:e.projectRoot,sessionId:e.sessionId,transcriptPath:e.transcriptPath,runtimeStore:e.runtimeStore}),n=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{Hl(e.runtimeStore,e.sessionId,n);let o=n.getPendingMemoryTurn(e.projectRoot,e.sessionId),r=o?n.markMemoryTurnStopPrompted(o.turnId):!1,i=[];t&&i.push(t.reason),o&&r&&i.push(Ze(o)),o&&!r&&$l(n,o.turnId)&&Fl(ze(e.transcriptPath))&&i.push(`DevFlow explicit memory ${o.turnId} still has no canonical receipt. Remove the memory-success claim and tell the user that the memory was not saved, or complete the pending turn.`);let a=n.listSessionObligations(e.projectRoot,e.sessionId,["open"]).map(c=>({obligationId:c.obligationId,kind:c.kind,action:c.kind==="memory_decision"?`Call ${projectClaudeToolName("memory_decide_turn")} using the canonical turn ID.`:c.kind==="evidence_contract"?c.payload.subtype==="policy_verification"?`Complete the required project verification: ${String(c.payload.command??c.payload.verificationKind??"unknown command")}.`:"Return a final answer that satisfies the canonical evidence contract.":"Allow SessionEnd durable finalization to complete.",canonicalInput:c.kind==="memory_decision"&&c.turnId?{turnId:c.turnId}:void 0}));return i.length>0?{decision:"block_once",unresolved:a,additionalContext:["DevFlow has unresolved terminal obligations. Complete all actions below before stopping.",...i].join(`
|
|
31
31
|
|
|
32
|
-
`)}:a.length>0?{decision:"degrade",unresolved:a,additionalContext:"DevFlow terminal obligations remain unresolved after their one-shot correction budget."}:{decision:"allow",unresolved:[]}}finally{n.close();}}function
|
|
33
|
-
${JSON.stringify(e.trigger)}`,n=[];Fl.some(r=>r.test(t))&&n.push("high_risk_operation"),Hl.some(r=>r.test(t))&&n.push("broad_or_migrating_change"),e.kind==="correction"&&n.push("user_correction_requires_observation");let o=n.includes("high_risk_operation")?"high":n.includes("broad_or_migrating_change")||e.scope==="global"?"medium":"low";return {risk:o,manualOnly:o==="high"||n.includes("broad_or_migrating_change"),reasons:n}}var Nl=new Set(["project_convention","user_preference","decision_made","config_discovery"]);function un(e){let t=e.payload.executionId?e.database.getSkillExecution(e.payload.executionId):e.database.getLatestSkillExecutionForSession(e.payload.sessionId),n=e.database.listHostActionsForSession(e.payload.projectRoot,e.payload.sessionId,e.payload.executionId),o=n.find(l=>l.state==="verified"),r=n.find(l=>["failed","cancelled","degraded"].includes(l.state)),i=r?"negative":o?"positive":"unknown",s=new Set,a=[],c=0,d=0;for(let l of e.evidence){if(!Ll(l)){d+=1;continue}let u=ri(l),m=ql(l,t?.skillName),f=ii(l),p=zl(e.payload.projectRoot,u,l.facetKey??l.semanticKey??l.id,m),g=e.database.getLearningCandidate(p),h=dn({scope:"project",kind:u,instruction:f,trigger:m});e.database.upsertLearningCandidate({id:p,projectRoot:e.payload.projectRoot,scope:"project",kind:u,trigger:m,instruction:f,confidence:Wl(l),manualOnly:h.manualOnly,risk:h.risk});g&&g.instruction!==f&&e.database.addLearningCandidateEvidence({id:ti(p,e.payload.sessionId,l.id,"contradicting"),candidateId:p,projectRoot:e.payload.projectRoot,sessionId:e.payload.sessionId,executionId:e.payload.executionId,memoryObservationId:l.id,sourceType:"correction",polarity:"contradicting",outcome:i,evidenceHash:ni(p,e.payload,l,"contradicting"),receipt:e.payload.closureReceipt,payload:{previousInstruction:g.instruction,replacementInstruction:f,projectRevision:e.payload.projectRevision},createdAt:l.createdAt});let S=e.database.addLearningCandidateEvidence({id:ti(p,e.payload.sessionId,l.id,"supporting"),candidateId:p,projectRoot:e.payload.projectRoot,sessionId:e.payload.sessionId,executionId:e.payload.executionId,memoryObservationId:l.id,outcomeId:o?.id??r?.id,sourceType:Ul(l),polarity:"supporting",outcome:i,evidenceHash:ni(p,e.payload,l,"supporting"),receipt:e.payload.closureReceipt,payload:{semanticKey:l.semanticKey,facetKey:l.facetKey,evidenceStatus:l.evidenceStatus,source:l.source,projectRevision:e.payload.projectRevision,executionStatus:t?.status,policyReasons:h.reasons},createdAt:l.createdAt});c+=1,s.add(p),e.rolloutMode!=="off"&&S.state==="candidate"&&S.supportingSessions>=3&&S.successfulOutcomes>=2&&e.database.transitionLearningCandidate(p,{target:"shadow",reason:"evidence_threshold_satisfied"}).state==="shadow"&&a.push(p);}return {considered:e.evidence.length,accepted:c,excluded:d,candidateIds:[...s],promotedToShadow:a}}function Ll(e){return !(!Nl.has(e.type)||e.source!=="explicit_intent"&&e.source!=="manual"&&e.evidenceStatus!=="verified"||!e.narrative.trim()&&!e.title.trim())}function ri(e){return e.type==="decision_made"?"workflow":e.type==="user_preference"&&(e.semanticValue.startsWith("--")||e.tools.length>0)?"tool_preference":"convention"}function ql(e,t){return {...t?{skills:[t]}:{},...e.entities.length>0?{entities:[...new Set(e.entities)].slice(0,8)}:{},...e.files.length>0?{files:[...new Set(e.files)].slice(0,8)}:{},...e.tools.length>0?{commands:[...new Set(e.tools)].slice(0,8)}:{},semantic:{subject:e.semanticSubject,predicate:e.semanticPredicate,value:e.semanticValue,polarity:e.semanticPolarity}}}function ii(e){return (e.narrative.trim()||e.title.trim()).replace(/\s+/gu," ").slice(0,1200)}function Wl(e){let t=e.source==="explicit_intent"?.08:0;return Math.max(0,Math.min(1,e.confidence+t))}function Ul(e){return e.semanticPolarity==="negative"?"correction":ri(e)==="tool_preference"?"tool_preference":e.source==="explicit_intent"?"memory":"convention"}function zl(e,t,n,o){let r={...o,semantic:void 0};return `learning:${createHash("sha256").update(`${e}\0project\0${t}\0${n}\0${stableLearningJson(r)}`).digest("hex").slice(0,24)}`}function ti(e,t,n,o){return `learning-evidence:${createHash("sha256").update(`${e}\0${t}\0${n}\0${o}`).digest("hex").slice(0,24)}`}function ni(e,t,n,o){return createHash("sha256").update(stableLearningJson({candidateId:e,sessionId:t.sessionId,executionId:t.executionId,closureReceipt:t.closureReceipt,projectRevision:t.projectRevision,observationId:n.id,instruction:ii(n),polarity:o})).digest("hex")}var ce=3e4,fn=1e3,su=new Set(["git","npm","pnpm","yarn"]);function si(e){return {"workflow.worker_start":async({item:t})=>au(e,t),"workflow.worker_monitor":async({item:t})=>cu(e,t),"workflow.worker_verify":async({item:t})=>du(e,t),"workflow.worker_merge":async({item:t})=>lu(e,t),"workflow.worker_cleanup":async({item:t})=>uu(e,t)}}async function au(e,t){await Ee(e,t,async(n,o)=>{if(o.state==="running"||o.state==="starting"){mn(n,o);return}if(o.state!=="planned")return;let r=`worker-plane:${process.pid}`;n.leaseWorkflowWorker(e,o.workerId,r,ce);let i=await createManagedWorktree({projectRoot:e,runId:o.runId,stepId:o.stepId,baseRevision:o.baseRevision,registered:!0});if(i.worktreePath!==o.worktreePath||i.branch!==o.branch){n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"hold",leaseOwner:r,reason:"managed_worktree_identity_mismatch"});return}n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"starting",leaseOwner:r});let s=di(o.workerId),a=mu(o);createWorkerArtifacts(s,a);let d=createDefaultHostAdapterRegistry().list().find(f=>f.id===o.host);if(!d)throw new E("unsupported_worker_host",`Unsupported worker host ${o.host}`);let l=de(o.handoff.actionId,"actionId"),u=n.getHostAction(e,l);if(!u)throw new E("worker_host_action_missing",`Host action ${l} was not found`);u.state==="waiting"&&n.startHostAction({actionId:l,projectRoot:e});let m=launchWorker(d,{workerId:o.workerId,runId:o.runId,stepId:o.stepId,host:o.host==="codex"?"codex":"claude-code",worktreePath:o.worktreePath,taskFile:s.taskFile,handoffFile:s.handoffFile,statusFile:s.statusFile,sessionId:o.sessionId??"worker",executionId:o.executionId??o.workerId,contextReceipt:o.contextReceipt,timeoutMs:30*6e4},s,{onHeartbeat:()=>{let f=openGlobalDevFlowDatabase();try{f.heartbeatWorkflowWorker(e,o.workerId,r,ce);}catch{}finally{f.close();}}});pu(s,{state:"running",pid:m.child.pid,owner:r,startedAt:Date.now()}),n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"running",leaseOwner:r,heartbeatAt:Date.now(),leaseExpiresAt:Date.now()+ce}),mn(n,o),m.completion.finally(()=>{let f=openGlobalDevFlowDatabase();try{mn(f,o,Date.now());}finally{f.close();}});});}async function cu(e,t){await Ee(e,t,async(n,o)=>{if(o.state!=="running"&&o.state!=="starting")return;let r=di(o.workerId);if(existsSync(r.handoffFile)){let c=readWorkerHandoff(r.handoffFile,{workerId:o.workerId,runId:o.runId,stepId:o.stepId,contextReceipt:o.contextReceipt,worktreePath:o.worktreePath}),d=de(o.handoff.actionId,"actionId");n.reportHostAction({actionId:d,projectRoot:e,report:{workerId:o.workerId,handoff:c},evidenceHash:ui(c)}),n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"reported",leaseOwner:o.leaseOwner,finalRevision:c.finalRevision,handoff:{...o.handoff,terminalHandoff:c}}),n.enqueueWork({idempotencyKey:`workflow-worker-verify:${o.workerId}:${c.finalRevision}`,kind:"workflow.worker_verify",projectRoot:e,payload:{workerId:o.workerId}});return}let i=fu(r),s=typeof i?.pid=="number"?i.pid:void 0;if(s&&hu(s)){let c=typeof i?.startedAt=="number"?i.startedAt:o.updatedAt;if(Date.now()-c>30*6e4){try{process.kill(s,"SIGTERM");}catch{}n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"failed",leaseOwner:o.leaseOwner,reason:"worker_process_timeout"});let l=de(o.handoff.actionId,"actionId");n.failHostAction({actionId:l,projectRoot:e,report:{reason:"worker_process_timeout"}});return}let d=o.leaseOwner??(typeof i?.owner=="string"?i.owner:void 0);throw d?(n.heartbeatWorkflowWorker(e,o.workerId,d,ce),li("worker_running",fn)):new E("worker_lease_owner_missing","Worker lease owner is missing")}n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"failed",leaseOwner:o.leaseOwner,reason:"worker_exited_without_handoff"});let a=de(o.handoff.actionId,"actionId");n.failHostAction({actionId:a,projectRoot:e,report:{reason:"worker_exited_without_handoff"}});});}async function du(e,t){await Ee(e,t,async(n,o)=>{if(o.state!=="reported")return;n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"verifying",leaseOwner:o.leaseOwner});let r=o.handoff.terminalHandoff;if(!r)throw new E("worker_handoff_missing","Persisted worker handoff is missing");let i=de(o.handoff.actionId,"actionId"),s=n.getHostAction(e,i);if(!s)throw new E("worker_host_action_missing",`Host action ${i} was not found`);let a=ci(o),c=new GraderRegistry,d=await ai(n,o,async()=>verifyWorkerOutput({workerId:o.workerId,projectRoot:e,worktreePath:o.worktreePath,baseRevision:o.baseRevision,parentRevision:await gu(e),contextReceipt:o.contextReceipt,allowedFiles:o.allowedFiles,handoff:r,hostAction:s,verificationCommands:a,graderIds:["receipt_validity","lifecycle_terminal_state","workflow_evidence"],graderRunner:{run:async l=>{let u=await c.run({taskId:o.stepId,taskKind:l.taskKind,projectRoot:l.projectRoot,acceptanceCriteria:[],evidence:l.evidence});return {...u,unavailableBlocking:u.unavailableRequired}}}}));if(!d.passed){n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:d.state,leaseOwner:o.leaseOwner,reason:d.reason}),d.state==="failed"&&n.failHostAction({actionId:i,projectRoot:e,outcome:"failed",report:{...s.report,verification:d},evidenceHash:d.simulationHash});return}n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"merge_ready",leaseOwner:o.leaseOwner,finalRevision:d.finalRevision,handoff:{...o.handoff,terminalHandoff:r,verification:d}}),n.enqueueWork({idempotencyKey:`workflow-worker-merge:${o.workerId}:${d.finalRevision}`,kind:"workflow.worker_merge",projectRoot:e,payload:{workerId:o.workerId}});});}async function lu(e,t){await Ee(e,t,async(n,o)=>{if(o.state!=="merge_ready")return;let r=o.handoff.verification;if(!r?.passed)throw new E("worker_verification_missing","Verified merge evidence is missing");let i=de(o.handoff.actionId,"actionId"),s=new SerializedWorkerMergeQueue(n,{onMerged:async({mergeCommit:c})=>{n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"merged",leaseOwner:o.leaseOwner,finalRevision:o.finalRevision,reason:`merged:${c}`});let d=n.getHostAction(e,i);n.verifyHostAction({actionId:i,projectRoot:e,report:{...d?.report??{},mergeCommit:c,verification:r},evidenceHash:ui({mergeCommit:c,verification:r})});},scheduleCleanup:()=>{n.enqueueWork({idempotencyKey:`workflow-worker-cleanup:${o.workerId}:merged`,kind:"workflow.worker_cleanup",projectRoot:e,payload:{workerId:o.workerId}});}}),a=await ai(n,o,()=>s.enqueueAndMerge({workerId:o.workerId,projectRoot:e,baseRevision:o.baseRevision,verification:r,message:`merge(devflow-worker): ${o.runId}/${o.stepId}`}));a.state==="conflict"&&n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"hold",leaseOwner:o.leaseOwner,reason:a.reason??"merge_conflict"});});}async function uu(e,t){await Ee(e,t,async(n,o)=>{let r=t.payload,i=await cleanupManagedWorktree({repositoryRoot:e,worktreePath:o.worktreePath,branch:o.branch,registered:!0,handoffDurable:!!o.handoff.terminalHandoff||r.operatorApproved===!0});if(!i.cleaned)throw li(`cleanup_${i.reason??"refused"}`,3e4)});}async function ai(e,t,n){let o=t.leaseOwner;if(!o)return n();let r=setInterval(()=>{try{e.heartbeatWorkflowWorker(t.projectRoot,t.workerId,o,ce);}catch{}},Math.floor(ce/3));r.unref();try{return await n()}finally{clearInterval(r);}}async function Ee(e,t,n){let o=yu(t.payload),r=openGlobalDevFlowDatabase();try{let i=r.getWorkflowWorker(e,o);if(!i)throw new E("worker_not_found",`Worker ${o} was not found`);await n(r,i);}finally{r.close();}}function mu(e){let t=e.handoff.task;if(!t||typeof t!="object"||Array.isArray(t))throw new E("worker_task_missing","Worker task envelope is missing");let n=ci(e);return {workerId:e.workerId,runId:e.runId,stepId:e.stepId,projectRoot:e.projectRoot,worktreePath:e.worktreePath,baseRevision:e.baseRevision,contextReceipt:e.contextReceipt,retrievalSessionId:e.retrievalSessionId,allowedFiles:e.allowedFiles,requiredTools:[],task:t,verification:{commands:n,graders:["receipt_validity","lifecycle_terminal_state","workflow_evidence"]},constraints:{recursiveWorkers:false,maxContextCycles:3}}}function ci(e){let t=e.handoff.verificationCommands;if(!Array.isArray(t)||t.length===0)throw new E("verification_contract_missing","Worker verification commands are missing");return t.map(n=>{if(!n||typeof n!="object"||Array.isArray(n))throw new E("verification_contract_invalid","Worker verification command is malformed");let o=n;if(typeof o.command!="string"||!su.has(o.command)||!Array.isArray(o.args)||o.args.some(r=>typeof r!="string"))throw new E("verification_contract_invalid","Worker verification command is not allowlisted");return {command:o.command,args:o.args}})}function di(e){let t=workerCoordinationRoot(e,homedir());return {root:t,taskFile:join(t,"task.json"),handoffFile:join(t,"handoff.json"),statusFile:join(t,"status.json"),stdoutFile:join(t,"stdout.log"),stderrFile:join(t,"stderr.log")}}function pu(e,t){writeJsonAtomic(e.statusFile,t);}function fu(e){try{return JSON.parse(readFileSync$1(e.statusFile,"utf8"))}catch{return null}}function mn(e,t,n=Date.now()+fn){e.enqueueWork({idempotencyKey:`workflow-worker-monitor:${t.workerId}:${Math.floor(n/fn)}`,kind:"workflow.worker_monitor",projectRoot:t.projectRoot,payload:{workerId:t.workerId},nextAttemptAt:n,maxAttempts:1e3});}async function gu(e){let{gitRevision:t}=await import('@devflow-tools/workflow-engine');return t(e,"HEAD")}function hu(e){try{return process.kill(e,0),!0}catch{return false}}function li(e,t){return Object.assign(new Error(e),{category:e,retryAfterMs:t,retryWithoutAttempt:true})}function yu(e){if(!e||typeof e!="object"||typeof e.workerId!="string")throw new E("invalid_worker_payload","Worker work item requires workerId");return e.workerId}function de(e,t){if(typeof e!="string"||!e.trim())throw new E("worker_identity_missing",`Worker ${t} is missing`);return e}function ui(e){return createHash("sha256").update(JSON.stringify(e)).digest("hex")}var wu=new Set(["Write","Edit","NotebookEdit"]);function gi(e){if(!wu.has(e.toolName)||Ru(e.toolResponse))return null;let t=Su(e.projectRoot,e.toolInput);if(!t)return null;let n=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let o=n.getActiveContextReceipt(e.projectRoot,e.sessionId,e.executionId),r=o?.canonicalAction?.verificationPlan??[];if(!o||r.length===0)return null;let i=[],s=[];for(let c of r){let d=_u({projectRoot:e.projectRoot,targetFile:t,kind:c.kind,mode:c.mode==="write"?"write":"check",required:c.required===!0,contextReceipt:o.contextHash}),l=`${o.contextHash}\0${e.toolUseId??t}\0${c.kind}\0${t}`,u=`policy-verification:${createHash("sha256").update(l).digest("hex")}`,m=Date.now();if(!d){let g=`verification_unavailable:${c.kind}`;n.upsertSessionObligation({obligationId:u,projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:e.executionId,kind:"evidence_contract",state:"degraded",payload:{subtype:"policy_verification",status:"unknown",verificationKind:c.kind,targetFile:t,contextReceipt:o.contextHash},reason:g,createdAt:m,updatedAt:m,resolvedAt:m}),s.push(c.kind),c.required===!0&&O({projectRoot:e.projectRoot,sessionId:e.sessionId,requestId:o.requestId,executionId:e.executionId,kind:"verification.failed",payload:{receiptId:u,reasonCode:g},dedupeKey:`${u}:unavailable`,producer:"devflow-verification-scheduler"});continue}let f={...d,obligationId:u,sessionId:e.sessionId,executionId:e.executionId,requestId:o.requestId};n.upsertSessionObligation({obligationId:u,projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:e.executionId,kind:"evidence_contract",state:"open",payload:{subtype:"policy_verification",status:"scheduled",verificationKind:c.kind,command:d.display,targetFile:t,contextReceipt:o.contextHash,required:c.required===!0},createdAt:m,updatedAt:m});let p=n.enqueueWork({idempotencyKey:u,kind:"verification.policy",projectRoot:e.projectRoot,sessionId:e.sessionId,payload:f,maxAttempts:2,nextAttemptAt:m});O({projectRoot:e.projectRoot,sessionId:e.sessionId,requestId:o.requestId,executionId:e.executionId,kind:"durable_work.owned",payload:{workId:p.id,obligation:"verification"},dedupeKey:`${p.id}:owned`,producer:"devflow-verification-scheduler"}),i.push(d.display);}return [i.length>0?`DevFlow scheduled policy verification: ${i.join(" && ")}`:"",s.length>0?`Verification unavailable and recorded as unknown: ${s.join(", ")}`:""].filter(Boolean).join(`
|
|
34
|
-
`)||null}finally{n.close();}}async function hi(e,t){let n=
|
|
35
|
-
${l.message}`.slice(-32768)});}),o.on("close",l=>{clearTimeout(d),s({exitCode:l,timedOut:c,spawnError:false,output:r});});})}function Su(e,t){let n=t.file_path??t.notebook_path;if(typeof n!="string"||!n.trim())return null;let o=isAbsolute(n)?resolve(n):resolve(e,n);return yi(e,o)?relative(e,o).split(sep).join("/"):null}function yi(e,t){let n=isAbsolute(t)?resolve(t):resolve(e,t),o=relative(resolve(e),n);return o!==""&&o!==".."&&!o.startsWith(`..${sep}`)&&!isAbsolute(o)}function Ru(e){if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return t.ok===false||t.success===false||t.isError===true||!!t.error}function xu(e){try{return JSON.parse(readFileSync$1(join(e,"package.json"),"utf8"))}catch{return null}}function Eu(e){return existsSync(join(e,"pnpm-lock.yaml"))?"pnpm":existsSync(join(e,"yarn.lock"))?"yarn":existsSync(join(e,"bun.lockb"))||existsSync(join(e,"bun.lock"))?"bun":"npm"}function Tu(e){return [".prettierrc",".prettierrc.json",".prettierrc.js",".prettierrc.cjs","prettier.config.js","prettier.config.cjs"].some(t=>existsSync(join(e,t)))}function yn(e,t){return t.find(n=>typeof e[n]=="string"&&e[n].trim())??null}function Au(e,t){let n=t.replace(/\.[^.]+$/u,""),o=[".test.ts",".test.tsx",".spec.ts",".spec.tsx",".test.js",".spec.js"];for(let s of o){let a=`${n}${s}`;if(existsSync(join(e,a)))return a}let r=join(e,t.split("/").slice(0,-1).join("/")),i=t.split("/").at(-1)?.replace(/\.[^.]+$/u,"");if(!i||!existsSync(r))return null;try{return readdirSync$1(r).filter(s=>s.startsWith(`${i}.`)&&/\.(?:test|spec)\.[cm]?[jt]sx?$/u.test(s)).map(s=>relative(e,join(r,s)).split(sep).join("/"))[0]??null}catch{return null}}function Du(e,t,n){let o=t.split(sep).join("/"),r=resolve(n,t).split(sep).join("/"),i=e.split(/\r?\n/u).map(s=>s.trim().split(sep).join("/")).filter(s=>s.includes(o)||s.includes(r)).map(s=>s.replace(/:\d+:\d+/gu,":#:#").replace(/\(\d+,\d+\)/gu,"(#,#)")).filter(s=>/\berror\s+TS\d+\b/iu.test(s));return [...new Set(i.map(s=>createHash("sha256").update(s).digest("hex")))]}function Cu(e,t,n){if(!t.executionId)return;let o=e.getSkillExecution(t.executionId);if(!o)return;let r=o.metadata&&typeof o.metadata=="object"?o.metadata:{},i=Array.isArray(r.policyVerificationOutcomes)?r.policyVerificationOutcomes:[];e.updateSkillExecution(t.executionId,{metadata:{...r,policyVerificationOutcomes:[...i,n]}});}function Mu(e){try{let t=readFileSync$1(join(e,".git","HEAD"),"utf8").trim();return t.startsWith("ref:")?readFileSync$1(join(e,".git",t.slice(5).trim()),"utf8").trim():t}catch{return}}function pi(e){return createHash("sha256").update(JSON.stringify(e)).digest("hex")}function Ou(e){return /^[A-Za-z0-9_./:@=-]+$/u.test(e)?e:JSON.stringify(e)}async function _i(e){let t=Date.now(),n=Vu(e.projectRoot),o=claudeCodeRuntimeAdapter.normalizePrompt(e.hostEvent??{session_id:e.sessionId,prompt:e.prompt},{projectRoot:n}),r=semanticTextHash(wi(o.rawPrompt)),i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100});try{let s=i.getTaskIntentArtifactBySource({projectRoot:n,sessionId:e.sessionId,sourceHash:r});if(s){let h=vi(s).identity,b=i.getRuntimeActivation(h.projectRoot,h.sessionId,h.turnId,s.version);if(!b)throw new Error(`RUNTIME_ACTIVATION_MISSING:${s.artifactHash}`);return {artifact:vi(s),memoryIdentity:Ii(s),activation:b,reused:!0}}let a=`turn:${at(`${e.sessionId}\0${r}`)}`,c=`request:${at(`${n}\0${e.sessionId}\0${a}`)}`,d={projectRoot:n,projectId:`project:${stableRuntimeHash(n).slice(0,20)}`,hostId:o.hostId,sessionId:e.sessionId,executionId:e.sessionId,turnId:a,requestId:c},l=1,u=resolveRuntimeActivationSnapshot({projectRoot:n,createdAt:o.timestamp}),m=zu(o.rawPrompt),f={identity:d,version:l,rawPrompt:o.rawPrompt,normalizedPrompt:wi(o.rawPrompt),...o.command?{command:o.command}:{},slashArgs:o.slashArgs,...o.activeSkill?{activeSkill:o.activeSkill}:{},intent:"unknown",action:"unknown",entities:[],targetAnchors:m,policyConstraints:[],classificationEvidence:[],sourceEventIds:[o.sourceEventId??`host-event:${r.slice(0,24)}`],sourceHash:r,createdAt:o.timestamp},p={...f,artifactHash:Ju(f)};i.appendTaskIntentArtifact(Wu(p)),i.bindRuntimeActivation({identity:d,revision:l,snapshot:u});let g=qu(i,p);return y({event:"host.prompt.normalized",identity:d,level:"info",timestamp:Date.now(),data:{sourceHash:r,command:p.command,activeSkill:p.activeSkill,rawPromptBytes:Buffer.byteLength(p.rawPrompt)}}),y({event:"intent.artifact.created",identity:d,level:"info",timestamp:Date.now(),data:{artifactHash:p.artifactHash,targetCount:m.length}}),y({event:"intent.artifact.persisted",identity:d,level:"info",timestamp:Date.now(),data:{artifactHash:p.artifactHash,version:p.version,sourceHash:p.sourceHash,authority:"immutable-intent",captureLatencyMs:Date.now()-t}}),y({event:"terminal.transition.persisted",identity:d,level:"info",timestamp:Date.now(),data:{state:"intent_bound",receiptId:g,sourceIntentHash:p.artifactHash}}),{artifact:p,memoryIdentity:Ii(p),activation:u,reused:!1}}finally{i.close();}}function qu(e,t){let n=e.getLatestTerminalTransition(t.identity.projectRoot,t.identity.sessionId,t.identity.turnId);if(n)return n.receiptId;let o=`terminal:${at(`${t.artifactHash}\0open`)}`;return e.appendTerminalTransition({...t.identity,sequence:1,toState:"open",receiptId:o,reason:"host_prompt_accepted",payload:{sourceHash:t.sourceHash},createdAt:t.createdAt}),e.appendTerminalTransition({...t.identity,sequence:2,fromState:"open",toState:"intent_bound",receiptId:`terminal:${at(`${t.artifactHash}\0intent_bound`)}`,sourceReceiptId:o,reason:"immutable_intent_persisted",payload:{intentArtifactHash:t.artifactHash},createdAt:Math.max(t.createdAt,Date.now())}).receiptId}function Wu(e){return {...e.identity,version:e.version,supersedesHash:e.supersedesHash,rawPrompt:e.rawPrompt,normalizedPrompt:e.normalizedPrompt,command:e.command,slashArgs:e.slashArgs,activeSkill:e.activeSkill,intent:e.intent,action:e.action,entities:e.entities,targetAnchors:e.targetAnchors,policyConstraints:e.policyConstraints,classificationEvidence:e.classificationEvidence.map(t=>({...t})),sourceEventIds:e.sourceEventIds,sourceHash:e.sourceHash,artifactHash:e.artifactHash,createdAt:e.createdAt}}function vi(e){return {identity:Uu(e),version:e.version,...e.supersedesHash?{supersedesHash:e.supersedesHash}:{},rawPrompt:e.rawPrompt,normalizedPrompt:e.normalizedPrompt,...e.command?{command:e.command}:{},slashArgs:e.slashArgs,...e.activeSkill?{activeSkill:e.activeSkill}:{},intent:e.intent,action:e.action,entities:e.entities,targetAnchors:e.targetAnchors,policyConstraints:e.policyConstraints,classificationEvidence:e.classificationEvidence,sourceEventIds:e.sourceEventIds,sourceHash:e.sourceHash,artifactHash:e.artifactHash,createdAt:e.createdAt}}function Uu(e){return {projectRoot:e.projectRoot,projectId:e.projectId,hostId:e.hostId,sessionId:e.sessionId,turnId:e.turnId,requestId:e.requestId,...e.executionId?{executionId:e.executionId}:{}}}function Ii(e){let t=e.rawPrompt.trim().slice(0,4e3),n="identity"in e?e.identity.turnId:e.turnId;return {turnId:n,eventId:`memory-turn:${n.replace(/^turn:/u,"")}`,promptHash:createHash("sha256").update(t).digest("hex"),createdAt:e.createdAt}}function zu(e){let t=e.match(/(?:^|[\s`'"(])((?:\.{0,2}\/)?(?:[A-Za-z0-9_@.-]+\/)+[A-Za-z0-9_@.-]+(?:\.[A-Za-z0-9]+)?)/gu)??[];return Bu(t.map(n=>n.trim().replace(/^[`'"(]+|[`'"),.;:,。;:]+$/gu,"")).filter(n=>!n.startsWith("/")||/\.[A-Za-z0-9]+$/u.test(n))).slice(0,16)}function wi(e){return e.normalize("NFKC").replace(/\s+/gu," ").trim().slice(0,4e3)}function Bu(e){return [...new Set(e.filter(Boolean))]}function Vu(e){let t=resolve(e);try{return realpathSync(t)}catch{return t}}function Ju(e){return createHash("sha256").update(_n(e)).digest("hex")}function at(e){return createHash("sha256").update(e).digest("hex").slice(0,24)}function _n(e){if(e===null||typeof e=="string"||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="number")return Number.isFinite(e)?JSON.stringify(e):"null";if(Array.isArray(e))return `[${e.map(_n).join(",")}]`;if(!e||typeof e!="object")return JSON.stringify(String(e));let t=e;return `{${Object.keys(t).sort().map(n=>`${JSON.stringify(n)}:${_n(t[n])}`).join(",")}}`}function kn(){return generateKeyPairSync("ed25519")}function Sn(e){let t=parseTrustedDecisionCommand(e.rawUserEvent,e.allowedOptionIds),n=e.now??Date.now(),o={schemaVersion:"delivery-user-attestation.v1",issuer:e.issuer,keyId:e.keyId,purpose:t.purpose,decisionId:t.decisionId,caseId:e.caseId,caseVersion:e.caseVersion,sessionId:e.sessionId,sourceTurnId:e.sourceTurnId,actorId:e.actorId,targetDecisionHash:e.targetDecisionHash,rawUserEvent:e.rawUserEvent,rawUserEventHash:domainHash("raw-user-event",e.rawUserEvent),selectedValueHash:domainHash("decision-value",{decisionId:t.decisionId,purpose:t.purpose,value:encodeDecisionValue(t.purpose,t.value)}),eventSequence:e.eventSequence,issuedAt:new Date(n).toISOString(),expiresAt:new Date(n+6e4).toISOString(),nonce:e.nonce};return {...o,attestation:sign(null,canonicalJsonBytes(o),e.privateKey).toString("base64url")}}var ki=new Map;function Si(e){if(typeof e=="string")return /\bDevFlow decision ([A-Za-z0-9._:-]+)/u.exec(z(e))?.[1]}function z(e){return e.replace(/[\u0000-\u001f\u007f\ufffd]+/gu,"").replace(/\s+/gu," ").trim()}function nm(e){if(typeof e=="string")return e.trim()||void 0;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e.answers;if(!t||typeof t!="object"||Array.isArray(t))return;let n=Object.values(t);if(n.length!==1)return;let o=n[0];if(!(Array.isArray(o)||typeof o!="string"))return o.trim()||void 0}async function xi(e){if(e.toolName!=="AskUserQuestion")return {handled:false};let t=e.toolInput&&typeof e.toolInput=="object"&&!Array.isArray(e.toolInput)?e.toolInput:{};if(!Array.isArray(t.questions)||t.questions.length!==1)return {handled:false};let n=t.questions[0],o=Ti(e.projectRoot),r=Si(n.header)??Si(n.question);if(!r){let h=await o.pendingDecisionForSession(e.sessionId);if(!h||"ambiguous"in h||!["artifact_approval","trusted_action"].includes(h.decision.kind))return {handled:false};r=h.decision.id;}let i=r.split(":")[0],s=await o.pendingDecision(i);if(!s||s.id!==r)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: no pending decision matches ${r}. Refresh delivery_status.`};let a=Array.isArray(n.options)?n.options.map(h=>({label:typeof h.label=="string"?z(h.label):"",description:typeof h.description=="string"?z(h.description):""})):[],c=createHash("sha256").update(JSON.stringify({decisionId:r,question:z(String(n.question??"")),options:a})).digest("hex"),d=nm(e.toolResponse),l=d?z(d):void 0;if(!l)return (typeof o.recordDecisionPresentation=="function"?await o.recordDecisionPresentation({caseId:i,decisionId:r,caseVersion:s.caseVersion,presentationHash:c,sourceTurnId:e.sourceTurnId??e.toolUseId}):true)?{handled:true,resolved:false,message:`DevFlow interactive decision rejected: AskUserQuestion returned no single answer for ${r}. Use /devflow:decide ${r} -- <answer> if this is a free-form clarification.`}:{handled:true,resolved:false,message:`DevFlow interactive decision ${r} was already presented. Reuse the existing answer or refresh delivery_status after resolution.`};if(n.multiSelect===true)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: ${r} must be a single selection.`};let u;if(s.options.length>0){let h=s.options.map(S=>({label:z(S.label),description:S.description?z(S.description):""}));if(a.length!==h.length||a.some((S,_)=>{let x=h[_];return S.label!==x?.label||x?.description&&!S.description}))return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: the displayed options do not match the pending decision ${r}. Refresh delivery_status and render its options verbatim.`};let b=s.options.find(S=>z(S.label)===l);if(!b)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: answer does not match a pending option for ${r}.`};s.kind==="artifact_approval"?u=b.id==="approve"?`/devflow:approve ${r}`:`/devflow:reject ${r} -- ${l}`:u=`/devflow:decide ${r} ${b.id}`;}else {if(a.length>0)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: ${r} is a free-form clarification and must not be rendered as a choice list.`};u=`/devflow:decide ${r} -- ${l}`;}if(!(typeof o.recordDecisionPresentation=="function"?await o.recordDecisionPresentation({caseId:i,decisionId:r,caseVersion:s.caseVersion,presentationHash:c,sourceTurnId:e.sourceTurnId??e.toolUseId}):true))return {handled:true,resolved:false,message:`DevFlow interactive decision ${r} was already presented. Reuse the existing answer or refresh delivery_status after resolution.`};let f=process.env.DEVFLOW_HOST_ACTOR_ID?.trim()||`user:${process.env.USER?.trim()||"local"}`,p=kn(),g=Sn({rawUserEvent:u,issuer:"claude-code",keyId:"session-ephemeral",caseId:i,caseVersion:s.caseVersion,sessionId:e.sessionId,sourceTurnId:e.sourceTurnId?.trim()||e.toolUseId?.trim()||`host-turn:${e.sessionId}:${Date.now()}`,actorId:f,targetDecisionHash:s.targetDecisionHash,eventSequence:Date.now(),nonce:randomUUID$1(),privateKey:p.privateKey,allowedOptionIds:s.options.map(h=>h.id)});try{return await o.resolveTrustedDecision({evidence:g,publicKey:p.publicKey,expectedIssuer:"claude-code",expectedKeyId:"session-ephemeral"}),{handled:!0,resolved:!0,message:`DevFlow interactive decision resolved for ${i}. Refresh delivery_status and follow nextActions.`}}catch(h){return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: ${h instanceof Error?h.message:String(h)}`}}}async function Ei(e){let t=e.prompt.trim();if(!/^\/devflow:(?:decide|approve|reject|revise|cancel|exit)\b/u.test(t))return {handled:false};let n=Ti(e.projectRoot),o=t;if(t==="/devflow:approve"||t==="/devflow:approve current"){let l=await n.pendingDecisionForSession(e.sessionId);if(!l)return {handled:true,resolved:false,message:"DevFlow approval not found: there is no pending decision for this session."};if("ambiguous"in l)return {handled:true,resolved:false,message:`DevFlow approval is ambiguous: multiple pending cases exist (${l.caseIds.join(", ")}). Use the approval choices shown by the host.`};if(l.decision.kind!=="artifact_approval")return {handled:true,resolved:false,message:"DevFlow approval is not available yet: the current pending item is a clarification, not an artifact gate."};o=`/devflow:approve ${l.decision.id}`;}let r;try{r=parseTrustedDecisionCommand(o);}catch(l){return {handled:true,resolved:false,message:`DevFlow trusted decision rejected: ${l instanceof Error?l.message:String(l)}`}}let i=r.decisionId.split(":")[0],s=await n.pendingDecision(i);if(!s||s.id!==r.decisionId)return {handled:true,resolved:false,message:`DevFlow trusted decision rejected: no pending decision matches ${r.decisionId}. Refresh delivery_status.`};let a=process.env.DEVFLOW_HOST_ACTOR_ID?.trim()||`user:${process.env.USER?.trim()||"local"}`,c=kn(),d=Sn({rawUserEvent:o,issuer:"claude-code",keyId:"session-ephemeral",caseId:i,caseVersion:s.caseVersion,sessionId:e.sessionId,sourceTurnId:e.sourceTurnId?.trim()||`host-turn:${e.sessionId}:${Date.now()}`,actorId:a,targetDecisionHash:s.targetDecisionHash,eventSequence:Date.now(),nonce:randomUUID$1(),privateKey:c.privateKey,allowedOptionIds:s.options.map(l=>l.id)});try{return await n.resolveTrustedDecision({evidence:d,publicKey:c.publicKey,expectedIssuer:"claude-code",expectedKeyId:"session-ephemeral"}),{handled:!0,resolved:!0,message:`DevFlow trusted decision resolved for ${i}. Refresh delivery_status and follow nextActions.`}}catch(l){return {handled:true,resolved:false,message:`DevFlow trusted decision rejected: ${l instanceof Error?l.message:String(l)}`}}}function Ti(e){let t=ki.get(e);if(t)return t;let n=createTrustedDeliveryFacade(e);return ki.set(e,n),n}function Ai(e=process.env){if(e.DEVFLOW_DISABLED==="1")return true;try{return existsSync(join(getDevFlowStateRoot({env:e}),"disable"))}catch{return false}}function Di(e){y({event:"hook.enforcement.shadow",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId},level:"warn",timestamp:Date.now(),data:{tool:e.toolName,code:e.code??"DEVFLOW_POLICY",reason:e.reason.slice(0,500)}});try{process.stderr.write(`[devflow][shadow] would deny ${e.toolName}: ${e.reason}
|
|
36
|
-
`);}catch{}return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:`DevFlow shadow enforcement: this call would be denied under enforce mode (${e.code??"DEVFLOW_POLICY"}). Proceeding; the decision is recorded for graduation review.`}}}var
|
|
37
|
-
`);if(n=u.pop()??"",Buffer.byteLength(n,"utf8")>ji){a();return}if(u.length===0)return;let m=0;for(let f of u){let p=Buffer.byteLength(f,"utf8");if(p>ji){a();return}m+=p+1;}if(i+m>
|
|
32
|
+
`)}:a.length>0?{decision:"degrade",unresolved:a,additionalContext:"DevFlow terminal obligations remain unresolved after their one-shot correction budget."}:{decision:"allow",unresolved:[]}}finally{n.close();}}function $l(e,t){return !!e.getWorkByIdempotencyKey(`memory-turn:commit_explicit:${t}`)}function Fl(e){if(!e)return false;let t=e.normalize("NFKC").replace(/\s+/gu," ");return /(?:未|没有|无法|失败|暂未|尚未).{0,24}(?:记住|记下|记录|保存|持久化|回执)|(?:memory|receipt).{0,24}(?:failed|missing|pending|degraded|not saved)|status=(?:pending|degraded|rejected|failed)/iu.test(t)?false:/(?:已|已经|成功).{0,20}(?:记住|记下|记录|保存|持久化)|跨会话生效|(?:memory|preference).{0,20}(?:saved|remembered|persisted)|status=(?:accepted|committed)/iu.test(t)}function Hl(e,t,n){let o=e.get(t);if(o){for(let r of o.evidenceObligations)n.upsertSessionObligation({obligationId:`evidence:${r.obligationId}`,projectRoot:o.projectRoot,sessionId:t,executionId:o.executionId,kind:"evidence_contract",state:"open",payload:{contract:r.contract,runtimeObligationId:r.obligationId},createdAt:r.promptedAt,updatedAt:o.lastActivityAt});for(let r of o.evidenceOutcomes){let i=`evidence:${r.obligationId}`,s=n.getSessionObligation(o.projectRoot,t,i);if(!s||s.state!=="open"&&!(s.state==="degraded"&&r.status==="resolved"))continue;let a=r.status==="resolved"?`evidence-receipt:${createHash("sha256").update(`${r.obligationId}\0${r.completedAt}\0${r.attempt}`).digest("hex").slice(0,24)}`:void 0;n.resolveSessionObligation({projectRoot:o.projectRoot,sessionId:t,obligationId:i,state:r.status==="resolved"?"satisfied":"degraded",receiptId:a,reason:r.reason,resolvedAt:r.completedAt});}}}var Nl=[/\b(?:rm\s+-rf|sudo|chmod|chown|force\s+push|reset\s+--hard|publish|release|deploy)\b/iu,/\b(?:secret|credential|token|password|security|authentication|authorization)\b/iu,/(?:删除|强制推送|发布|部署|凭据|密钥|安全|权限)/u],Ll=[/\b(?:migration|upgrade|dependency|dependencies|generated files?|write all|rewrite)\b/iu,/(?:迁移|升级|依赖|生成文件|批量写入)/u];function dn(e){let t=`${e.instruction}
|
|
33
|
+
${JSON.stringify(e.trigger)}`,n=[];Nl.some(r=>r.test(t))&&n.push("high_risk_operation"),Ll.some(r=>r.test(t))&&n.push("broad_or_migrating_change"),e.kind==="correction"&&n.push("user_correction_requires_observation");let o=n.includes("high_risk_operation")?"high":n.includes("broad_or_migrating_change")||e.scope==="global"?"medium":"low";return {risk:o,manualOnly:o==="high"||n.includes("broad_or_migrating_change"),reasons:n}}var ql=new Set(["project_convention","user_preference","decision_made","config_discovery"]);function un(e){let t=e.payload.executionId?e.database.getSkillExecution(e.payload.executionId):e.database.getLatestSkillExecutionForSession(e.payload.sessionId),n=e.database.listHostActionsForSession(e.payload.projectRoot,e.payload.sessionId,e.payload.executionId),o=n.find(l=>l.state==="verified"),r=n.find(l=>["failed","cancelled","degraded"].includes(l.state)),i=r?"negative":o?"positive":"unknown",s=new Set,a=[],c=0,d=0;for(let l of e.evidence){if(!Wl(l)){d+=1;continue}let u=ri(l),m=Ul(l,t?.skillName),f=ii(l),p=Vl(e.payload.projectRoot,u,l.facetKey??l.semanticKey??l.id,m),g=e.database.getLearningCandidate(p),h=dn({scope:"project",kind:u,instruction:f,trigger:m});e.database.upsertLearningCandidate({id:p,projectRoot:e.payload.projectRoot,scope:"project",kind:u,trigger:m,instruction:f,confidence:zl(l),manualOnly:h.manualOnly,risk:h.risk});g&&g.instruction!==f&&e.database.addLearningCandidateEvidence({id:ti(p,e.payload.sessionId,l.id,"contradicting"),candidateId:p,projectRoot:e.payload.projectRoot,sessionId:e.payload.sessionId,executionId:e.payload.executionId,memoryObservationId:l.id,sourceType:"correction",polarity:"contradicting",outcome:i,evidenceHash:ni(p,e.payload,l,"contradicting"),receipt:e.payload.closureReceipt,payload:{previousInstruction:g.instruction,replacementInstruction:f,projectRevision:e.payload.projectRevision},createdAt:l.createdAt});let S=e.database.addLearningCandidateEvidence({id:ti(p,e.payload.sessionId,l.id,"supporting"),candidateId:p,projectRoot:e.payload.projectRoot,sessionId:e.payload.sessionId,executionId:e.payload.executionId,memoryObservationId:l.id,outcomeId:o?.id??r?.id,sourceType:Bl(l),polarity:"supporting",outcome:i,evidenceHash:ni(p,e.payload,l,"supporting"),receipt:e.payload.closureReceipt,payload:{semanticKey:l.semanticKey,facetKey:l.facetKey,evidenceStatus:l.evidenceStatus,source:l.source,projectRevision:e.payload.projectRevision,executionStatus:t?.status,policyReasons:h.reasons},createdAt:l.createdAt});c+=1,s.add(p),e.rolloutMode!=="off"&&S.state==="candidate"&&S.supportingSessions>=3&&S.successfulOutcomes>=2&&e.database.transitionLearningCandidate(p,{target:"shadow",reason:"evidence_threshold_satisfied"}).state==="shadow"&&a.push(p);}return {considered:e.evidence.length,accepted:c,excluded:d,candidateIds:[...s],promotedToShadow:a}}function Wl(e){return !(!ql.has(e.type)||e.source!=="explicit_intent"&&e.source!=="manual"&&e.evidenceStatus!=="verified"||!e.narrative.trim()&&!e.title.trim())}function ri(e){return e.type==="decision_made"?"workflow":e.type==="user_preference"&&(e.semanticValue.startsWith("--")||e.tools.length>0)?"tool_preference":"convention"}function Ul(e,t){return {...t?{skills:[t]}:{},...e.entities.length>0?{entities:[...new Set(e.entities)].slice(0,8)}:{},...e.files.length>0?{files:[...new Set(e.files)].slice(0,8)}:{},...e.tools.length>0?{commands:[...new Set(e.tools)].slice(0,8)}:{},semantic:{subject:e.semanticSubject,predicate:e.semanticPredicate,value:e.semanticValue,polarity:e.semanticPolarity}}}function ii(e){return (e.narrative.trim()||e.title.trim()).replace(/\s+/gu," ").slice(0,1200)}function zl(e){let t=e.source==="explicit_intent"?.08:0;return Math.max(0,Math.min(1,e.confidence+t))}function Bl(e){return e.semanticPolarity==="negative"?"correction":ri(e)==="tool_preference"?"tool_preference":e.source==="explicit_intent"?"memory":"convention"}function Vl(e,t,n,o){let r={...o,semantic:void 0};return `learning:${createHash("sha256").update(`${e}\0project\0${t}\0${n}\0${stableLearningJson(r)}`).digest("hex").slice(0,24)}`}function ti(e,t,n,o){return `learning-evidence:${createHash("sha256").update(`${e}\0${t}\0${n}\0${o}`).digest("hex").slice(0,24)}`}function ni(e,t,n,o){return createHash("sha256").update(stableLearningJson({candidateId:e,sessionId:t.sessionId,executionId:t.executionId,closureReceipt:t.closureReceipt,projectRevision:t.projectRevision,observationId:n.id,instruction:ii(n),polarity:o})).digest("hex")}var ce=3e4,fn=1e3,cu=new Set(["git","npm","pnpm","yarn"]);function si(e){return {"workflow.worker_start":async({item:t})=>du(e,t),"workflow.worker_monitor":async({item:t})=>lu(e,t),"workflow.worker_verify":async({item:t})=>uu(e,t),"workflow.worker_merge":async({item:t})=>mu(e,t),"workflow.worker_cleanup":async({item:t})=>pu(e,t)}}async function du(e,t){await Ee(e,t,async(n,o)=>{if(o.state==="running"||o.state==="starting"){mn(n,o);return}if(o.state!=="planned")return;let r=`worker-plane:${process.pid}`;n.leaseWorkflowWorker(e,o.workerId,r,ce);let i=await createManagedWorktree({projectRoot:e,runId:o.runId,stepId:o.stepId,baseRevision:o.baseRevision,registered:!0});if(i.worktreePath!==o.worktreePath||i.branch!==o.branch){n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"hold",leaseOwner:r,reason:"managed_worktree_identity_mismatch"});return}n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"starting",leaseOwner:r});let s=di(o.workerId),a=fu(o);createWorkerArtifacts(s,a);let d=createDefaultHostAdapterRegistry().list().find(f=>f.id===o.host);if(!d)throw new E("unsupported_worker_host",`Unsupported worker host ${o.host}`);let l=de(o.handoff.actionId,"actionId"),u=n.getHostAction(e,l);if(!u)throw new E("worker_host_action_missing",`Host action ${l} was not found`);u.state==="waiting"&&n.startHostAction({actionId:l,projectRoot:e});let m=launchWorker(d,{workerId:o.workerId,runId:o.runId,stepId:o.stepId,host:o.host==="codex"?"codex":"claude-code",worktreePath:o.worktreePath,taskFile:s.taskFile,handoffFile:s.handoffFile,statusFile:s.statusFile,sessionId:o.sessionId??"worker",executionId:o.executionId??o.workerId,contextReceipt:o.contextReceipt,timeoutMs:30*6e4},s,{onHeartbeat:()=>{let f=openGlobalDevFlowDatabase();try{f.heartbeatWorkflowWorker(e,o.workerId,r,ce);}catch{}finally{f.close();}}});gu(s,{state:"running",pid:m.child.pid,owner:r,startedAt:Date.now()}),n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"running",leaseOwner:r,heartbeatAt:Date.now(),leaseExpiresAt:Date.now()+ce}),mn(n,o),m.completion.finally(()=>{let f=openGlobalDevFlowDatabase();try{mn(f,o,Date.now());}finally{f.close();}});});}async function lu(e,t){await Ee(e,t,async(n,o)=>{if(o.state!=="running"&&o.state!=="starting")return;let r=di(o.workerId);if(existsSync(r.handoffFile)){let c=readWorkerHandoff(r.handoffFile,{workerId:o.workerId,runId:o.runId,stepId:o.stepId,contextReceipt:o.contextReceipt,worktreePath:o.worktreePath}),d=de(o.handoff.actionId,"actionId");n.reportHostAction({actionId:d,projectRoot:e,report:{workerId:o.workerId,handoff:c},evidenceHash:ui(c)}),n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"reported",leaseOwner:o.leaseOwner,finalRevision:c.finalRevision,handoff:{...o.handoff,terminalHandoff:c}}),n.enqueueWork({idempotencyKey:`workflow-worker-verify:${o.workerId}:${c.finalRevision}`,kind:"workflow.worker_verify",projectRoot:e,payload:{workerId:o.workerId}});return}let i=hu(r),s=typeof i?.pid=="number"?i.pid:void 0;if(s&&vu(s)){let c=typeof i?.startedAt=="number"?i.startedAt:o.updatedAt;if(Date.now()-c>30*6e4){try{process.kill(s,"SIGTERM");}catch{}n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"failed",leaseOwner:o.leaseOwner,reason:"worker_process_timeout"});let l=de(o.handoff.actionId,"actionId");n.failHostAction({actionId:l,projectRoot:e,report:{reason:"worker_process_timeout"}});return}let d=o.leaseOwner??(typeof i?.owner=="string"?i.owner:void 0);throw d?(n.heartbeatWorkflowWorker(e,o.workerId,d,ce),li("worker_running",fn)):new E("worker_lease_owner_missing","Worker lease owner is missing")}n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"failed",leaseOwner:o.leaseOwner,reason:"worker_exited_without_handoff"});let a=de(o.handoff.actionId,"actionId");n.failHostAction({actionId:a,projectRoot:e,report:{reason:"worker_exited_without_handoff"}});});}async function uu(e,t){await Ee(e,t,async(n,o)=>{if(o.state!=="reported")return;n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"verifying",leaseOwner:o.leaseOwner});let r=o.handoff.terminalHandoff;if(!r)throw new E("worker_handoff_missing","Persisted worker handoff is missing");let i=de(o.handoff.actionId,"actionId"),s=n.getHostAction(e,i);if(!s)throw new E("worker_host_action_missing",`Host action ${i} was not found`);let a=ci(o),c=new GraderRegistry,d=await ai(n,o,async()=>verifyWorkerOutput({workerId:o.workerId,projectRoot:e,worktreePath:o.worktreePath,baseRevision:o.baseRevision,parentRevision:await yu(e),contextReceipt:o.contextReceipt,allowedFiles:o.allowedFiles,handoff:r,hostAction:s,verificationCommands:a,graderIds:["receipt_validity","lifecycle_terminal_state","workflow_evidence"],graderRunner:{run:async l=>{let u=await c.run({taskId:o.stepId,taskKind:l.taskKind,projectRoot:l.projectRoot,acceptanceCriteria:[],evidence:l.evidence});return {...u,unavailableBlocking:u.unavailableRequired}}}}));if(!d.passed){n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:d.state,leaseOwner:o.leaseOwner,reason:d.reason}),d.state==="failed"&&n.failHostAction({actionId:i,projectRoot:e,outcome:"failed",report:{...s.report,verification:d},evidenceHash:d.simulationHash});return}n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"merge_ready",leaseOwner:o.leaseOwner,finalRevision:d.finalRevision,handoff:{...o.handoff,terminalHandoff:r,verification:d}}),n.enqueueWork({idempotencyKey:`workflow-worker-merge:${o.workerId}:${d.finalRevision}`,kind:"workflow.worker_merge",projectRoot:e,payload:{workerId:o.workerId}});});}async function mu(e,t){await Ee(e,t,async(n,o)=>{if(o.state!=="merge_ready")return;let r=o.handoff.verification;if(!r?.passed)throw new E("worker_verification_missing","Verified merge evidence is missing");let i=de(o.handoff.actionId,"actionId"),s=new SerializedWorkerMergeQueue(n,{onMerged:async({mergeCommit:c})=>{n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"merged",leaseOwner:o.leaseOwner,finalRevision:o.finalRevision,reason:`merged:${c}`});let d=n.getHostAction(e,i);n.verifyHostAction({actionId:i,projectRoot:e,report:{...d?.report??{},mergeCommit:c,verification:r},evidenceHash:ui({mergeCommit:c,verification:r})});},scheduleCleanup:()=>{n.enqueueWork({idempotencyKey:`workflow-worker-cleanup:${o.workerId}:merged`,kind:"workflow.worker_cleanup",projectRoot:e,payload:{workerId:o.workerId}});}}),a=await ai(n,o,()=>s.enqueueAndMerge({workerId:o.workerId,projectRoot:e,baseRevision:o.baseRevision,verification:r,message:`merge(devflow-worker): ${o.runId}/${o.stepId}`}));a.state==="conflict"&&n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"hold",leaseOwner:o.leaseOwner,reason:a.reason??"merge_conflict"});});}async function pu(e,t){await Ee(e,t,async(n,o)=>{let r=t.payload,i=await cleanupManagedWorktree({repositoryRoot:e,worktreePath:o.worktreePath,branch:o.branch,registered:!0,handoffDurable:!!o.handoff.terminalHandoff||r.operatorApproved===!0});if(!i.cleaned)throw li(`cleanup_${i.reason??"refused"}`,3e4)});}async function ai(e,t,n){let o=t.leaseOwner;if(!o)return n();let r=setInterval(()=>{try{e.heartbeatWorkflowWorker(t.projectRoot,t.workerId,o,ce);}catch{}},Math.floor(ce/3));r.unref();try{return await n()}finally{clearInterval(r);}}async function Ee(e,t,n){let o=Iu(t.payload),r=openGlobalDevFlowDatabase();try{let i=r.getWorkflowWorker(e,o);if(!i)throw new E("worker_not_found",`Worker ${o} was not found`);await n(r,i);}finally{r.close();}}function fu(e){let t=e.handoff.task;if(!t||typeof t!="object"||Array.isArray(t))throw new E("worker_task_missing","Worker task envelope is missing");let n=ci(e);return {workerId:e.workerId,runId:e.runId,stepId:e.stepId,projectRoot:e.projectRoot,worktreePath:e.worktreePath,baseRevision:e.baseRevision,contextReceipt:e.contextReceipt,retrievalSessionId:e.retrievalSessionId,allowedFiles:e.allowedFiles,requiredTools:[],task:t,verification:{commands:n,graders:["receipt_validity","lifecycle_terminal_state","workflow_evidence"]},constraints:{recursiveWorkers:false,maxContextCycles:3}}}function ci(e){let t=e.handoff.verificationCommands;if(!Array.isArray(t)||t.length===0)throw new E("verification_contract_missing","Worker verification commands are missing");return t.map(n=>{if(!n||typeof n!="object"||Array.isArray(n))throw new E("verification_contract_invalid","Worker verification command is malformed");let o=n;if(typeof o.command!="string"||!cu.has(o.command)||!Array.isArray(o.args)||o.args.some(r=>typeof r!="string"))throw new E("verification_contract_invalid","Worker verification command is not allowlisted");return {command:o.command,args:o.args}})}function di(e){let t=workerCoordinationRoot(e,homedir());return {root:t,taskFile:join(t,"task.json"),handoffFile:join(t,"handoff.json"),statusFile:join(t,"status.json"),stdoutFile:join(t,"stdout.log"),stderrFile:join(t,"stderr.log")}}function gu(e,t){writeJsonAtomic(e.statusFile,t);}function hu(e){try{return JSON.parse(readFileSync$1(e.statusFile,"utf8"))}catch{return null}}function mn(e,t,n=Date.now()+fn){e.enqueueWork({idempotencyKey:`workflow-worker-monitor:${t.workerId}:${Math.floor(n/fn)}`,kind:"workflow.worker_monitor",projectRoot:t.projectRoot,payload:{workerId:t.workerId},nextAttemptAt:n,maxAttempts:1e3});}async function yu(e){let{gitRevision:t}=await import('@devflow-tools/workflow-engine');return t(e,"HEAD")}function vu(e){try{return process.kill(e,0),!0}catch{return false}}function li(e,t){return Object.assign(new Error(e),{category:e,retryAfterMs:t,retryWithoutAttempt:true})}function Iu(e){if(!e||typeof e!="object"||typeof e.workerId!="string")throw new E("invalid_worker_payload","Worker work item requires workerId");return e.workerId}function de(e,t){if(typeof e!="string"||!e.trim())throw new E("worker_identity_missing",`Worker ${t} is missing`);return e}function ui(e){return createHash("sha256").update(JSON.stringify(e)).digest("hex")}var bu=new Set(["Write","Edit","NotebookEdit"]);function gi(e){if(!bu.has(e.toolName)||Eu(e.toolResponse))return null;let t=xu(e.projectRoot,e.toolInput);if(!t)return null;let n=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let o=n.getActiveContextReceipt(e.projectRoot,e.sessionId,e.executionId),r=o?.canonicalAction?.verificationPlan??[];if(!o||r.length===0)return null;let i=[],s=[];for(let c of r){let d=ku({projectRoot:e.projectRoot,targetFile:t,kind:c.kind,mode:c.mode==="write"?"write":"check",required:c.required===!0,contextReceipt:o.contextHash}),l=`${o.contextHash}\0${e.toolUseId??t}\0${c.kind}\0${t}`,u=`policy-verification:${createHash("sha256").update(l).digest("hex")}`,m=Date.now();if(!d){let g=`verification_unavailable:${c.kind}`;n.upsertSessionObligation({obligationId:u,projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:e.executionId,kind:"evidence_contract",state:"degraded",payload:{subtype:"policy_verification",status:"unknown",verificationKind:c.kind,targetFile:t,contextReceipt:o.contextHash},reason:g,createdAt:m,updatedAt:m,resolvedAt:m}),s.push(c.kind),c.required===!0&&O({projectRoot:e.projectRoot,sessionId:e.sessionId,requestId:o.requestId,executionId:e.executionId,kind:"verification.failed",payload:{receiptId:u,reasonCode:g},dedupeKey:`${u}:unavailable`,producer:"devflow-verification-scheduler"});continue}let f={...d,obligationId:u,sessionId:e.sessionId,executionId:e.executionId,requestId:o.requestId};n.upsertSessionObligation({obligationId:u,projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:e.executionId,kind:"evidence_contract",state:"open",payload:{subtype:"policy_verification",status:"scheduled",verificationKind:c.kind,command:d.display,targetFile:t,contextReceipt:o.contextHash,required:c.required===!0},createdAt:m,updatedAt:m});let p=n.enqueueWork({idempotencyKey:u,kind:"verification.policy",projectRoot:e.projectRoot,sessionId:e.sessionId,payload:f,maxAttempts:2,nextAttemptAt:m});O({projectRoot:e.projectRoot,sessionId:e.sessionId,requestId:o.requestId,executionId:e.executionId,kind:"durable_work.owned",payload:{workId:p.id,obligation:"verification"},dedupeKey:`${p.id}:owned`,producer:"devflow-verification-scheduler"}),i.push(d.display);}return [i.length>0?`DevFlow scheduled policy verification: ${i.join(" && ")}`:"",s.length>0?`Verification unavailable and recorded as unknown: ${s.join(", ")}`:""].filter(Boolean).join(`
|
|
34
|
+
`)||null}finally{n.close();}}async function hi(e,t){let n=Su(e,t.payload),o=await Ru(n,e),r=n.kind==="typecheck"?Mu(o.output,n.targetFile,e):[],i=pi({command:n.command,args:n.args}),s=openGlobalDevFlowDatabase();try{let a=Pu(e),c=n.kind==="typecheck"?s.getPolicyVerificationBaseline(e,n.kind,i):null,d=c&&c.sourceRevision===a?c:null,l=d?r.filter(b=>!d.diagnosticHashes.includes(b)):[],u;o.spawnError||/could not determine executable|command not found|not recognized as an internal|ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL/iu.test(o.output)?u="unavailable":o.timedOut?u="unknown":o.exitCode===0?u="passed":n.kind==="typecheck"&&!d?u="unknown":n.kind==="typecheck"&&l.length===0?u="passed":u="failed";let m=createHash("sha256").update(o.output).digest("hex"),f=`verification-receipt:${pi({obligationId:n.obligationId,commandHash:i,exitCode:o.exitCode,timedOut:o.timedOut,outputHash:m,diagnosticHashes:r,introduced:l,status:u})}`,p={status:u,kind:n.kind,command:n.display,exitCode:o.exitCode,timedOut:o.timedOut,outputHash:m,diagnosticHashes:r,introducedDiagnosticHashes:l,baselineAvailable:d!==null,receiptId:f},g=s.getWorkByIdempotencyKey(n.obligationId)?.id,h=s.getSessionObligation(e,n.sessionId,n.obligationId);if(h?.state==="open"&&(s.upsertSessionObligation({...h,payload:{...h.payload,status:u,outcome:p},updatedAt:Date.now()}),u!=="failed"&&s.resolveSessionObligation({projectRoot:e,sessionId:n.sessionId,obligationId:n.obligationId,state:u==="passed"?"satisfied":"degraded",receiptId:f,reason:u==="unknown"?"verification_result_unknown":u==="unavailable"?"verification_command_unavailable":void 0})),n.kind==="typecheck"&&o.exitCode===0&&s.upsertPolicyVerificationBaseline({projectRoot:e,kind:n.kind,commandHash:i,diagnosticHashes:[],sourceRevision:a,updatedAt:Date.now()}),Ou(s,n,p),O({projectRoot:e,sessionId:n.sessionId,requestId:n.requestId,executionId:n.executionId,kind:u==="passed"?"verification.succeeded":"verification.failed",payload:{receiptId:f,reasonCode:`verification_${u}`,verificationKind:n.kind},dedupeKey:f,producer:"devflow-verification-worker"}),g&&u!=="failed"&&O({projectRoot:e,sessionId:n.sessionId,requestId:n.requestId,executionId:n.executionId,kind:"durable_work.completed",payload:{workId:g,obligation:"verification"},dedupeKey:`${g}:completed`,producer:"devflow-verification-worker"}),u==="failed"){let b=new Error(`Policy verification failed: ${n.display}`);throw b.category="policy_verification_failed",b}return p}finally{s.close();}}function ku(e){let t=Tu(e.projectRoot),n=Au(e.projectRoot),o=t?.scripts??{},r={...t?.dependencies,...t?.devDependencies},i=null;if(e.kind==="formatter"&&(r.prettier||Du(e.projectRoot)))i=it(n,"prettier",[e.mode==="write"?"--write":"--check",e.targetFile],6e4);else if(e.kind==="typecheck"){let s=yn(o,["typecheck","type-check","check:types"]);s?i=gn(n,s,12e4):r.typescript&&existsSync(join(e.projectRoot,"tsconfig.json"))&&(i=it(n,"tsc",["--noEmit","--pretty","false"],12e4));}else if(e.kind==="lint"){let s=yn(o,["lint"]);s&&(i=gn(n,s,12e4));}else if(e.kind==="test"){let s=Cu(e.projectRoot,e.targetFile);s&&r.vitest?i=it(n,"vitest",["run",s],12e4):s&&(r.jest||r["@jest/core"])&&(i=it(n,"jest",["--runTestsByPath",s],12e4));}else if(e.kind==="build"){let s=yn(o,["build"]);s&&(i=gn(n,s,18e4));}else e.kind==="generated_files"&&(i={command:"git",args:["diff","--check","--",e.targetFile],timeoutMs:3e4});return i?{kind:e.kind,...i,display:[i.command,...i.args].map(ju).join(" "),required:e.required,targetFile:e.targetFile,contextReceipt:e.contextReceipt}:null}function gn(e,t,n){return e==="yarn"?{command:"yarn",args:["run",t],timeoutMs:n}:e==="pnpm"?{command:"pnpm",args:["run",t],timeoutMs:n}:e==="bun"?{command:"bun",args:["run",t],timeoutMs:n}:{command:"npm",args:["run",t],timeoutMs:n}}function it(e,t,n,o){return e==="pnpm"?{command:"pnpm",args:["exec",t,...n],timeoutMs:o}:e==="yarn"?{command:"yarn",args:[t,...n],timeoutMs:o}:e==="bun"?{command:"bunx",args:[t,...n],timeoutMs:o}:{command:"npx",args:["--no-install",t,...n],timeoutMs:o}}function Su(e,t){if(!t||typeof t!="object"||Array.isArray(t))throw hn();let n=t,o=new Set(["npm","npx","pnpm","yarn","bun","bunx","git"]);if(!n.command||!o.has(n.command)||!Array.isArray(n.args)||!n.args.every(r=>typeof r=="string")||!n.obligationId||!n.sessionId||!n.kind||!n.targetFile||!n.contextReceipt||!n.display||!Number.isFinite(n.timeoutMs)||!yi(e,n.targetFile))throw hn();return n}function hn(){let e=new Error("Policy verification work payload is invalid");return e.category="invalid_payload",e}function Ru(e,t){return new Promise(n=>{let o=spawn(e.command,e.args,{cwd:t,shell:false,stdio:["ignore","pipe","pipe"],env:{...process.env,CI:"1",FORCE_COLOR:"0"}}),r="",i=false,s=l=>{i||(i=true,n(l));},a=l=>{r=(r+String(l)).slice(-32768);};o.stdout.on("data",a),o.stderr.on("data",a);let c=false,d=setTimeout(()=>{c=true,o.kill("SIGTERM"),setTimeout(()=>o.kill("SIGKILL"),1e3).unref();},e.timeoutMs);o.on("error",l=>{clearTimeout(d),s({exitCode:null,timedOut:false,spawnError:true,output:`${r}
|
|
35
|
+
${l.message}`.slice(-32768)});}),o.on("close",l=>{clearTimeout(d),s({exitCode:l,timedOut:c,spawnError:false,output:r});});})}function xu(e,t){let n=t.file_path??t.notebook_path;if(typeof n!="string"||!n.trim())return null;let o=isAbsolute(n)?resolve(n):resolve(e,n);return yi(e,o)?relative(e,o).split(sep).join("/"):null}function yi(e,t){let n=isAbsolute(t)?resolve(t):resolve(e,t),o=relative(resolve(e),n);return o!==""&&o!==".."&&!o.startsWith(`..${sep}`)&&!isAbsolute(o)}function Eu(e){if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return t.ok===false||t.success===false||t.isError===true||!!t.error}function Tu(e){try{return JSON.parse(readFileSync$1(join(e,"package.json"),"utf8"))}catch{return null}}function Au(e){return existsSync(join(e,"pnpm-lock.yaml"))?"pnpm":existsSync(join(e,"yarn.lock"))?"yarn":existsSync(join(e,"bun.lockb"))||existsSync(join(e,"bun.lock"))?"bun":"npm"}function Du(e){return [".prettierrc",".prettierrc.json",".prettierrc.js",".prettierrc.cjs","prettier.config.js","prettier.config.cjs"].some(t=>existsSync(join(e,t)))}function yn(e,t){return t.find(n=>typeof e[n]=="string"&&e[n].trim())??null}function Cu(e,t){let n=t.replace(/\.[^.]+$/u,""),o=[".test.ts",".test.tsx",".spec.ts",".spec.tsx",".test.js",".spec.js"];for(let s of o){let a=`${n}${s}`;if(existsSync(join(e,a)))return a}let r=join(e,t.split("/").slice(0,-1).join("/")),i=t.split("/").at(-1)?.replace(/\.[^.]+$/u,"");if(!i||!existsSync(r))return null;try{return readdirSync$1(r).filter(s=>s.startsWith(`${i}.`)&&/\.(?:test|spec)\.[cm]?[jt]sx?$/u.test(s)).map(s=>relative(e,join(r,s)).split(sep).join("/"))[0]??null}catch{return null}}function Mu(e,t,n){let o=t.split(sep).join("/"),r=resolve(n,t).split(sep).join("/"),i=e.split(/\r?\n/u).map(s=>s.trim().split(sep).join("/")).filter(s=>s.includes(o)||s.includes(r)).map(s=>s.replace(/:\d+:\d+/gu,":#:#").replace(/\(\d+,\d+\)/gu,"(#,#)")).filter(s=>/\berror\s+TS\d+\b/iu.test(s));return [...new Set(i.map(s=>createHash("sha256").update(s).digest("hex")))]}function Ou(e,t,n){if(!t.executionId)return;let o=e.getSkillExecution(t.executionId);if(!o)return;let r=o.metadata&&typeof o.metadata=="object"?o.metadata:{},i=Array.isArray(r.policyVerificationOutcomes)?r.policyVerificationOutcomes:[];e.updateSkillExecution(t.executionId,{metadata:{...r,policyVerificationOutcomes:[...i,n]}});}function Pu(e){try{let t=readFileSync$1(join(e,".git","HEAD"),"utf8").trim();return t.startsWith("ref:")?readFileSync$1(join(e,".git",t.slice(5).trim()),"utf8").trim():t}catch{return}}function pi(e){return createHash("sha256").update(JSON.stringify(e)).digest("hex")}function ju(e){return /^[A-Za-z0-9_./:@=-]+$/u.test(e)?e:JSON.stringify(e)}async function _i(e){let t=Date.now(),n=Ku(e.projectRoot),o=claudeCodeRuntimeAdapter.normalizePrompt(e.hostEvent??{session_id:e.sessionId,prompt:e.prompt},{projectRoot:n}),r=semanticTextHash(wi(o.rawPrompt)),i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100});try{let s=i.getTaskIntentArtifactBySource({projectRoot:n,sessionId:e.sessionId,sourceHash:r});if(s){let h=vi(s).identity,b=i.getRuntimeActivation(h.projectRoot,h.sessionId,h.turnId,s.version);if(!b)throw new Error(`RUNTIME_ACTIVATION_MISSING:${s.artifactHash}`);return {artifact:vi(s),memoryIdentity:Ii(s),activation:b,reused:!0}}let a=`turn:${at(`${e.sessionId}\0${r}`)}`,c=`request:${at(`${n}\0${e.sessionId}\0${a}`)}`,d={projectRoot:n,projectId:`project:${stableRuntimeHash(n).slice(0,20)}`,hostId:o.hostId,sessionId:e.sessionId,executionId:e.sessionId,turnId:a,requestId:c},l=1,u=resolveRuntimeActivationSnapshot({projectRoot:n,createdAt:o.timestamp}),m=Vu(o.rawPrompt),f={identity:d,version:l,rawPrompt:o.rawPrompt,normalizedPrompt:wi(o.rawPrompt),...o.command?{command:o.command}:{},slashArgs:o.slashArgs,...o.activeSkill?{activeSkill:o.activeSkill}:{},intent:"unknown",action:"unknown",entities:[],targetAnchors:m,policyConstraints:[],classificationEvidence:[],sourceEventIds:[o.sourceEventId??`host-event:${r.slice(0,24)}`],sourceHash:r,createdAt:o.timestamp},p={...f,artifactHash:Gu(f)};i.appendTaskIntentArtifact(zu(p)),i.bindRuntimeActivation({identity:d,revision:l,snapshot:u});let g=Uu(i,p);return y({event:"host.prompt.normalized",identity:d,level:"info",timestamp:Date.now(),data:{sourceHash:r,command:p.command,activeSkill:p.activeSkill,rawPromptBytes:Buffer.byteLength(p.rawPrompt)}}),y({event:"intent.artifact.created",identity:d,level:"info",timestamp:Date.now(),data:{artifactHash:p.artifactHash,targetCount:m.length}}),y({event:"intent.artifact.persisted",identity:d,level:"info",timestamp:Date.now(),data:{artifactHash:p.artifactHash,version:p.version,sourceHash:p.sourceHash,authority:"immutable-intent",captureLatencyMs:Date.now()-t}}),y({event:"terminal.transition.persisted",identity:d,level:"info",timestamp:Date.now(),data:{state:"intent_bound",receiptId:g,sourceIntentHash:p.artifactHash}}),{artifact:p,memoryIdentity:Ii(p),activation:u,reused:!1}}finally{i.close();}}function Uu(e,t){let n=e.getLatestTerminalTransition(t.identity.projectRoot,t.identity.sessionId,t.identity.turnId);if(n)return n.receiptId;let o=`terminal:${at(`${t.artifactHash}\0open`)}`;return e.appendTerminalTransition({...t.identity,sequence:1,toState:"open",receiptId:o,reason:"host_prompt_accepted",payload:{sourceHash:t.sourceHash},createdAt:t.createdAt}),e.appendTerminalTransition({...t.identity,sequence:2,fromState:"open",toState:"intent_bound",receiptId:`terminal:${at(`${t.artifactHash}\0intent_bound`)}`,sourceReceiptId:o,reason:"immutable_intent_persisted",payload:{intentArtifactHash:t.artifactHash},createdAt:Math.max(t.createdAt,Date.now())}).receiptId}function zu(e){return {...e.identity,version:e.version,supersedesHash:e.supersedesHash,rawPrompt:e.rawPrompt,normalizedPrompt:e.normalizedPrompt,command:e.command,slashArgs:e.slashArgs,activeSkill:e.activeSkill,intent:e.intent,action:e.action,entities:e.entities,targetAnchors:e.targetAnchors,policyConstraints:e.policyConstraints,classificationEvidence:e.classificationEvidence.map(t=>({...t})),sourceEventIds:e.sourceEventIds,sourceHash:e.sourceHash,artifactHash:e.artifactHash,createdAt:e.createdAt}}function vi(e){return {identity:Bu(e),version:e.version,...e.supersedesHash?{supersedesHash:e.supersedesHash}:{},rawPrompt:e.rawPrompt,normalizedPrompt:e.normalizedPrompt,...e.command?{command:e.command}:{},slashArgs:e.slashArgs,...e.activeSkill?{activeSkill:e.activeSkill}:{},intent:e.intent,action:e.action,entities:e.entities,targetAnchors:e.targetAnchors,policyConstraints:e.policyConstraints,classificationEvidence:e.classificationEvidence,sourceEventIds:e.sourceEventIds,sourceHash:e.sourceHash,artifactHash:e.artifactHash,createdAt:e.createdAt}}function Bu(e){return {projectRoot:e.projectRoot,projectId:e.projectId,hostId:e.hostId,sessionId:e.sessionId,turnId:e.turnId,requestId:e.requestId,...e.executionId?{executionId:e.executionId}:{}}}function Ii(e){let t=e.rawPrompt.trim().slice(0,4e3),n="identity"in e?e.identity.turnId:e.turnId;return {turnId:n,eventId:`memory-turn:${n.replace(/^turn:/u,"")}`,promptHash:createHash("sha256").update(t).digest("hex"),createdAt:e.createdAt}}function Vu(e){let t=e.match(/(?:^|[\s`'"(])((?:\.{0,2}\/)?(?:[A-Za-z0-9_@.-]+\/)+[A-Za-z0-9_@.-]+(?:\.[A-Za-z0-9]+)?)/gu)??[];return Ju(t.map(n=>n.trim().replace(/^[`'"(]+|[`'"),.;:,。;:]+$/gu,"")).filter(n=>!n.startsWith("/")||/\.[A-Za-z0-9]+$/u.test(n))).slice(0,16)}function wi(e){return e.normalize("NFKC").replace(/\s+/gu," ").trim().slice(0,4e3)}function Ju(e){return [...new Set(e.filter(Boolean))]}function Ku(e){let t=resolve(e);try{return realpathSync(t)}catch{return t}}function Gu(e){return createHash("sha256").update(_n(e)).digest("hex")}function at(e){return createHash("sha256").update(e).digest("hex").slice(0,24)}function _n(e){if(e===null||typeof e=="string"||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="number")return Number.isFinite(e)?JSON.stringify(e):"null";if(Array.isArray(e))return `[${e.map(_n).join(",")}]`;if(!e||typeof e!="object")return JSON.stringify(String(e));let t=e;return `{${Object.keys(t).sort().map(n=>`${JSON.stringify(n)}:${_n(t[n])}`).join(",")}}`}function kn(){return generateKeyPairSync("ed25519")}function Sn(e){let t=parseTrustedDecisionCommand(e.rawUserEvent,e.allowedOptionIds),n=e.now??Date.now(),o={schemaVersion:"delivery-user-attestation.v1",issuer:e.issuer,keyId:e.keyId,purpose:t.purpose,decisionId:t.decisionId,caseId:e.caseId,caseVersion:e.caseVersion,sessionId:e.sessionId,sourceTurnId:e.sourceTurnId,actorId:e.actorId,targetDecisionHash:e.targetDecisionHash,rawUserEvent:e.rawUserEvent,rawUserEventHash:domainHash("raw-user-event",e.rawUserEvent),selectedValueHash:domainHash("decision-value",{decisionId:t.decisionId,purpose:t.purpose,value:encodeDecisionValue(t.purpose,t.value)}),eventSequence:e.eventSequence,issuedAt:new Date(n).toISOString(),expiresAt:new Date(n+6e4).toISOString(),nonce:e.nonce};return {...o,attestation:sign(null,canonicalJsonBytes(o),e.privateKey).toString("base64url")}}var ki=new Map;function Si(e){if(typeof e=="string")return /\bDevFlow decision ([A-Za-z0-9._:-]+)/u.exec(z(e))?.[1]}function z(e){return e.replace(/[\u0000-\u001f\u007f\ufffd]+/gu,"").replace(/\s+/gu," ").trim()}function rm(e){if(typeof e=="string")return e.trim()||void 0;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e.answers;if(!t||typeof t!="object"||Array.isArray(t))return;let n=Object.values(t);if(n.length!==1)return;let o=n[0];if(!(Array.isArray(o)||typeof o!="string"))return o.trim()||void 0}async function xi(e){if(e.toolName!=="AskUserQuestion")return {handled:false};let t=e.toolInput&&typeof e.toolInput=="object"&&!Array.isArray(e.toolInput)?e.toolInput:{};if(!Array.isArray(t.questions)||t.questions.length!==1)return {handled:false};let n=t.questions[0],o=Ti(e.projectRoot),r=Si(n.header)??Si(n.question);if(!r){let h=await o.pendingDecisionForSession(e.sessionId);if(!h||"ambiguous"in h||!["artifact_approval","trusted_action"].includes(h.decision.kind))return {handled:false};r=h.decision.id;}let i=r.split(":")[0],s=await o.pendingDecision(i);if(!s||s.id!==r)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: no pending decision matches ${r}. Refresh delivery_status.`};let a=Array.isArray(n.options)?n.options.map(h=>({label:typeof h.label=="string"?z(h.label):"",description:typeof h.description=="string"?z(h.description):""})):[],c=createHash("sha256").update(JSON.stringify({decisionId:r,question:z(String(n.question??"")),options:a})).digest("hex"),d=rm(e.toolResponse),l=d?z(d):void 0;if(!l)return (typeof o.recordDecisionPresentation=="function"?await o.recordDecisionPresentation({caseId:i,decisionId:r,caseVersion:s.caseVersion,presentationHash:c,sourceTurnId:e.sourceTurnId??e.toolUseId}):true)?{handled:true,resolved:false,message:`DevFlow interactive decision rejected: AskUserQuestion returned no single answer for ${r}. Use /devflow:decide ${r} -- <answer> if this is a free-form clarification.`}:{handled:true,resolved:false,message:`DevFlow interactive decision ${r} was already presented. Reuse the existing answer or refresh delivery_status after resolution.`};if(n.multiSelect===true)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: ${r} must be a single selection.`};let u;if(s.options.length>0){let h=s.options.map(S=>({label:z(S.label),description:S.description?z(S.description):""}));if(a.length!==h.length||a.some((S,_)=>{let x=h[_];return S.label!==x?.label||x?.description&&!S.description}))return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: the displayed options do not match the pending decision ${r}. Refresh delivery_status and render its options verbatim.`};let b=s.options.find(S=>z(S.label)===l);if(!b)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: answer does not match a pending option for ${r}.`};s.kind==="artifact_approval"?u=b.id==="approve"?`/devflow:approve ${r}`:`/devflow:reject ${r} -- ${l}`:u=`/devflow:decide ${r} ${b.id}`;}else {if(a.length>0)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: ${r} is a free-form clarification and must not be rendered as a choice list.`};u=`/devflow:decide ${r} -- ${l}`;}if(!(typeof o.recordDecisionPresentation=="function"?await o.recordDecisionPresentation({caseId:i,decisionId:r,caseVersion:s.caseVersion,presentationHash:c,sourceTurnId:e.sourceTurnId??e.toolUseId}):true))return {handled:true,resolved:false,message:`DevFlow interactive decision ${r} was already presented. Reuse the existing answer or refresh delivery_status after resolution.`};let f=process.env.DEVFLOW_HOST_ACTOR_ID?.trim()||`user:${process.env.USER?.trim()||"local"}`,p=kn(),g=Sn({rawUserEvent:u,issuer:"claude-code",keyId:"session-ephemeral",caseId:i,caseVersion:s.caseVersion,sessionId:e.sessionId,sourceTurnId:e.sourceTurnId?.trim()||e.toolUseId?.trim()||`host-turn:${e.sessionId}:${Date.now()}`,actorId:f,targetDecisionHash:s.targetDecisionHash,eventSequence:Date.now(),nonce:randomUUID$1(),privateKey:p.privateKey,allowedOptionIds:s.options.map(h=>h.id)});try{return await o.resolveTrustedDecision({evidence:g,publicKey:p.publicKey,expectedIssuer:"claude-code",expectedKeyId:"session-ephemeral"}),{handled:!0,resolved:!0,message:`DevFlow interactive decision resolved for ${i}. Refresh delivery_status and follow nextActions.`}}catch(h){return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: ${h instanceof Error?h.message:String(h)}`}}}async function Ei(e){let t=e.prompt.trim();if(!/^\/devflow:(?:decide|approve|reject|revise|cancel|exit)\b/u.test(t))return {handled:false};let n=Ti(e.projectRoot),o=t;if(t==="/devflow:approve"||t==="/devflow:approve current"){let l=await n.pendingDecisionForSession(e.sessionId);if(!l)return {handled:true,resolved:false,message:"DevFlow approval not found: there is no pending decision for this session."};if("ambiguous"in l)return {handled:true,resolved:false,message:`DevFlow approval is ambiguous: multiple pending cases exist (${l.caseIds.join(", ")}). Use the approval choices shown by the host.`};if(l.decision.kind!=="artifact_approval")return {handled:true,resolved:false,message:"DevFlow approval is not available yet: the current pending item is a clarification, not an artifact gate."};o=`/devflow:approve ${l.decision.id}`;}let r;try{r=parseTrustedDecisionCommand(o);}catch(l){return {handled:true,resolved:false,message:`DevFlow trusted decision rejected: ${l instanceof Error?l.message:String(l)}`}}let i=r.decisionId.split(":")[0],s=await n.pendingDecision(i);if(!s||s.id!==r.decisionId)return {handled:true,resolved:false,message:`DevFlow trusted decision rejected: no pending decision matches ${r.decisionId}. Refresh delivery_status.`};let a=process.env.DEVFLOW_HOST_ACTOR_ID?.trim()||`user:${process.env.USER?.trim()||"local"}`,c=kn(),d=Sn({rawUserEvent:o,issuer:"claude-code",keyId:"session-ephemeral",caseId:i,caseVersion:s.caseVersion,sessionId:e.sessionId,sourceTurnId:e.sourceTurnId?.trim()||`host-turn:${e.sessionId}:${Date.now()}`,actorId:a,targetDecisionHash:s.targetDecisionHash,eventSequence:Date.now(),nonce:randomUUID$1(),privateKey:c.privateKey,allowedOptionIds:s.options.map(l=>l.id)});try{return await n.resolveTrustedDecision({evidence:d,publicKey:c.publicKey,expectedIssuer:"claude-code",expectedKeyId:"session-ephemeral"}),{handled:!0,resolved:!0,message:`DevFlow trusted decision resolved for ${i}. Refresh delivery_status and follow nextActions.`}}catch(l){return {handled:true,resolved:false,message:`DevFlow trusted decision rejected: ${l instanceof Error?l.message:String(l)}`}}}function Ti(e){let t=ki.get(e);if(t)return t;let n=createTrustedDeliveryFacade(e);return ki.set(e,n),n}function Ai(e=process.env){if(e.DEVFLOW_DISABLED==="1")return true;try{return existsSync(join(getDevFlowStateRoot({env:e}),"disable"))}catch{return false}}function Di(e){y({event:"hook.enforcement.shadow",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId},level:"warn",timestamp:Date.now(),data:{tool:e.toolName,code:e.code??"DEVFLOW_POLICY",reason:e.reason.slice(0,500)}});try{process.stderr.write(`[devflow][shadow] would deny ${e.toolName}: ${e.reason}
|
|
36
|
+
`);}catch{}return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:`DevFlow shadow enforcement: this call would be denied under enforce mode (${e.code??"DEVFLOW_POLICY"}). Proceeding; the decision is recorded for graduation review.`}}}var _m=600*1e3,bm=2e3,km=250,Sm=2e3,Rm=1e3,ji=1024*1024,xm=2*1024*1024,Em=6e4,Tm=100;function Am(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n=typeof t.status=="string"?t.status:void 0;if(!(t.ok===false||t.success===false||t.isError===true||n==="failed"||n==="rejected"||n==="unavailable"||n==="warming"||!!t.error))return;let r=t.error;if(typeof r=="string"&&r.trim())return r;if(r&&typeof r=="object"){let i=r;if(typeof i.message=="string"&&i.message.trim())return i.message;if(typeof i.code=="string"&&i.code.trim())return i.code}return n?`Tool response status: ${n}`:"Tool response reported failure"}function $i(e){return /timeout|timed out|deadline|warming/i.test(e)?"timeout":/unavailable|not active|unknown tool|not found|not registered|route not found/i.test(e)?"unavailable":"failed"}function Fi(e,t,n,o,r){let i=e.recordDomainActionOutcome;typeof i=="function"&&i.call(e,t,n,o,r);}function Dm(e){switch(e){case "Read":case "Glob":return "file_read";case "Write":case "Edit":case "NotebookEdit":return "file_write";case "Bash":return "bash_command";case "Agent":return "subagent";case "Skill":return "skill_invoke";default:return "tool_use"}}function xn(e){return typeof e=="string"&&e.trim().length>0}function Cm(e,t,n=process.env,o){if(resolveClaudeToolName(e).status==="unsupported")return t;let r=t!==null&&typeof t=="object"&&!Array.isArray(t)?t:{};if(xn(r.projectRoot))return r;let i=xn(n.CLAUDE_PROJECT_DIR)?n.CLAUDE_PROJECT_DIR:o;return xn(i)&&(r.projectRoot=i),r}var En=class{constructor(t,n){this.socketIdentity=null;this.pidIdentity=null;this.server=null;this.activeSessionIds=new Set;this.eventMap=[];this.idleTimer=null;this.telemetryFlushTimer=null;this.successfulTelemetryOperations=0;this.shutdownPromise=null;this.embeddingPreparationController=null;this.explicitMemoryGate=null;this.memoryWarmup=null;this.explicitIntentFlush=null;this.hostRuntime=null;this.memoryTurnSpoolTimer=null;this.userPromptSubmitSpoolTimer=null;this.sessionFinalizeSpoolTimer=null;this.projectRoot=t,this.socketPath=getDaemonSocketPath(t),this.pidPath=getDaemonPidPath(t),this.telemetry=new te,this.runtimeStore=new L(this.projectRoot),this.serverManager=new je(t),this.hookRuntime=Jr(t),this.hookHealth=new rt(t),this.hookHandlers=Yr({handlers:{"pre-tool-use":o=>this.handlePreToolUse(o),"post-tool-use":o=>this.handlePostToolUse(o),"post-tool-use-failure":o=>this.handlePostToolUseFailure(o),stop:o=>this.handleStop(o),"memory-snapshot":()=>this.handleMemorySnapshot(),"session-start":o=>this.handleSessionStart(o),"session-end":o=>this.handleSessionEnd(o),"user-prompt-submit":o=>this.handleUserPromptSubmit(o),"pre-compact":o=>this.handlePreCompact(o)},failurePolicy:o=>sn(o,this.hookRuntime,this.hostRuntime??{hostId:"unresolved",capabilities:new Map,profiles:new Set(["minimal","standard","strict"])}).policy}),this.initialSessionInput=n,this.workRuntime=new tt({projectRoot:t,handlers:{...si(t),"memory.explicit_commit":async({item:o})=>{await this.persistMemoryTurnItem(o.payload);},"memory.turn_capture":async({item:o})=>{await this.persistMemoryTurnItem(o.payload);},"memory.explicit_enrichment":async({item:o})=>{let r=o.payload;if(typeof r?.observationId!="string"||!r.observationId)throw new E("invalid_payload","Explicit enrichment requires observationId");await(await this.getMemoryGate()).enrichExplicitMemoryObservation(r.observationId);},"session.bootstrap":async({item:o})=>{await this.bootstrapSessionWork(o.payload);},"memory.vector_backfill":async()=>{await(await this.getMemoryGate()).backfillObservationVectors({batchSize:32});},"memory.turn_distill":async({item:o})=>{await fe({projectRoot:this.projectRoot,sessionId:o.sessionId,trigger:"session_end",memory:await this.getMemoryGate()}),await this.refreshMemorySnapshot("memory_turn_distill");},"context.prefetch":async({item:o})=>{let r=o.payload;if(typeof r.prompt!="string"||typeof r.sessionId!="string"||typeof r.executionId!="string"||typeof r.profileFingerprint!="string"||typeof r.rolloutMode!="string")throw new E("invalid_payload","Context prefetch identity is incomplete");let[{createEngines:i},{projectDiagnosticCodeResult:s},{writeContextPrefetchCache:a}]=await Promise.all([import('@devflow-tools/mcp-server/composition'),import('@devflow-tools/mcp-server/retrieval'),import('@devflow-tools/context-engine')]),c=await i(this.projectRoot);try{let d=await c.context.buildTaskContext(r.prompt,{mode:"fast",sessionId:r.sessionId,executionId:r.executionId,activeSkill:r.skillName}),l=s(d,0,{projectRoot:this.projectRoot,query:r.prompt,sessionId:r.sessionId,executionId:r.executionId,requestId:`prefetch:${r.sessionId}:${r.executionId}`,turnId:`prefetch:${r.sessionId}:${r.executionId}`,host:"claude-code"});if(!a({projectRoot:this.projectRoot,query:r.prompt,sessionId:r.sessionId,executionId:r.executionId,profileFingerprint:r.profileFingerprint,rolloutMode:r.rolloutMode,retrievalVersion:r.retrievalVersion},l))throw new Error("Context prefetch envelope was not receipt-valid")}finally{c.close();}},"verification.policy":async({item:o})=>{await hi(this.projectRoot,o);},"learning.analyze_session":async({item:o})=>{let r=o.payload;if(typeof r.projectRoot!="string"||typeof r.sessionId!="string"||typeof r.closureReceipt!="string"||typeof r.projectRevision!="string"||typeof r.createdAt!="number")throw new E("invalid_payload","Learning analysis identity is incomplete");let i=openGlobalDevFlowDatabase();try{let s=await(await this.getMemoryGate()).listLearningEvidence(r.sessionId),a=un({payload:r,evidence:s,database:i,rolloutMode:resolveCapabilityRollout(this.projectRoot).config.learningOverlays});i.insertEvent({kind:"learning_analysis",timestamp:Date.now(),success:!0,metadata:{...r,...a}});}finally{i.close();}},"session.finalize":async({item:o})=>{await this.finalizeSessionWork(o.payload,o.id);},"telemetry.reconcile":async()=>{await this.flushTelemetry();}},afterComplete:({item:o,database:r})=>{let i=o.kind==="memory.explicit_commit"||o.kind==="memory.turn_capture"?"memory":o.kind==="verification.policy"?"verification":null;i&&o.sessionId&&o.turnId&&O({projectRoot:this.projectRoot,sessionId:o.sessionId,turnId:o.turnId,kind:"durable_work.completed",payload:{workId:o.id,obligation:i},dedupeKey:`${o.id}:completed`,producer:"devflow-work-runtime"}),o.sessionId&&this.enqueueLearningAnalysisIfReady(r,o.sessionId);}});}logRuntime(t,n,o={},r){let i=r?this.runtimeStore.get(r):void 0;y({event:t==="warn"||t==="error"?"hook.runtime.degraded":"hook.runtime.completed",identity:{projectRoot:this.projectRoot,sessionId:r,executionId:i?.executionId},level:t,timestamp:Date.now(),data:{stage:n,...o}});}async start(){this.hostRuntime=await Gr(this.projectRoot);let t=wo(this.projectRoot,process.pid);this.runtimeManifestHash=t.manifestHash,mkdirSync(dirname(this.socketPath),{recursive:true,mode:448}),mkdirSync(dirname(this.pidPath),{recursive:true,mode:448}),await this.cleanStaleStartupResources(),this.server=createServer(n=>this.handleConnection(n));try{await this.listen(),this.writePidFile(),ho(this.projectRoot,process.pid);}catch(n){throw await this.closeServer(),this.cleanupOwnedResources(),n}if(this.server.on("error",n=>{this.logRuntime("error","server_error",{reason:n.message});}),this.logRuntime("info","server_listening",{socketHash:createHash("sha256").update(this.socketPath).digest("hex").slice(0,16)}),await this.telemetry.flushAndAggregate(),this.telemetryFlushTimer=setInterval(()=>{this.flushTelemetry();},Em),this.telemetryFlushTimer.unref(),this.startEmbeddingPreparation(),this.workRuntime.start(),this.initialSessionInput){let n=this.initialSessionInput;this.initialSessionInput=void 0,this.handleRequest({type:"session-start",input:n});}this.drainSessionStartSpool(),this.scheduleUserPromptSubmitSpoolDrain(0),this.scheduleMemoryTurnSpoolDrain(0),this.scheduleSessionFinalizeSpoolDrain(0),this.resetIdleTimer();}startEmbeddingPreparation(){let t=new AbortController;this.embeddingPreparationController=t,prepareEmbeddingModel({signal:t.signal}).then(n=>{this.logRuntime("info","embedding_ready",{source:n.source,cacheRootHash:createHash("sha256").update(n.cacheRoot).digest("hex").slice(0,16)});}).catch(n=>{t.signal.aborted||this.logRuntime("warn","embedding_unavailable",{reason:n.message,fallback:"lexical_retrieval"});}).finally(()=>{this.embeddingPreparationController===t&&(this.embeddingPreparationController=null);});}handleConnection(t){let n="",o=false,r=false,i=0,s=Promise.resolve();t.setEncoding("utf8");let a=()=>{r||(r=true,clearTimeout(c),t.destroy());},c=setTimeout(()=>{a();},bm).unref(),d=async l=>{if(!r){r=true,clearTimeout(c);try{await this.writeFrame(t,l);}catch{}finally{t.destroy();}}};t.on("data",l=>{if(r)return;n+=l;let u=n.split(`
|
|
37
|
+
`);if(n=u.pop()??"",Buffer.byteLength(n,"utf8")>ji){a();return}if(u.length===0)return;let m=0;for(let f of u){let p=Buffer.byteLength(f,"utf8");if(p>ji){a();return}m+=p+1;}if(i+m>xm){a();return}i+=m,s=s.then(async()=>{for(let f of u){if(r)return;if(!o){let p;try{p=JSON.parse(f);}catch{await d({error:"handshake_invalid"});return}if(p?.type!=="hello"||typeof p.rootPath!="string"){await d({error:"handshake_invalid"});return}if(p.rootPath!==this.projectRoot){await d({error:"handshake_root_mismatch",expected:this.projectRoot});return}if(p.runtimeManifestHash&&p.runtimeManifestHash!==this.runtimeManifestHash){await d({error:"daemon_runtime_mismatch",expected:p.runtimeManifestHash,actual:this.runtimeManifestHash??null});return}o=true,clearTimeout(c),await this.writeFrame(t,{type:"hello_ack",...this.runtimeManifestHash?{runtimeManifestHash:this.runtimeManifestHash}:{}}),this.resetIdleTimer();continue}if(f.trim())try{let p=JSON.parse(f),g=await this.handleRequest(p);g!==null&&!r&&await this.writeFrame(t,g);}catch(p){r||await this.writeFrame(t,{error:p.message});}}}).catch(()=>{a();}).finally(()=>{i-=m;});}),t.on("close",()=>clearTimeout(c)),t.on("error",()=>{});}writeFrame(t,n){return new Promise((o,r)=>{if(t.destroyed||!t.writable){r(new Error("Socket is not writable"));return}let i=false,s=true,a=false,c=setTimeout(()=>{t.destroy(),l(new Error("Timed out writing daemon response"));},Rm),d=()=>{clearTimeout(c),t.off("close",u),t.off("error",m),t.off("drain",f);},l=g=>{a||!g&&(!i||!s)||(a=true,d(),g?r(g):o());},u=()=>l(new Error("Socket closed during write")),m=g=>l(g),f=()=>{s=true,l();};t.once("close",u),t.once("error",m),t.write(`${JSON.stringify(n)}
|
|
38
38
|
`,g=>{if(g){l(g);return}i=true,l();})||(s=false,t.once("drain",f));})}async cleanStaleStartupResources(){let t=this.getPathIdentity(this.socketPath);if(t)if(await this.isSocketAcceptingConnections()){let r=this.getPathIdentity(this.pidPath)?this.readPidFile():null;if(r&&this.isProcessAlive(r))throw new Error(`Daemon socket already active for ${this.projectRoot}`);this.removePathIfOwned(this.socketPath,t,"orphan socket");}else this.removePathIfOwned(this.socketPath,t,"stale socket");let n=this.getPathIdentity(this.pidPath);n&&this.removePathIfOwned(this.pidPath,n,"stale PID file");}getPathIdentity(t){try{let n=lstatSync(t);return {dev:n.dev,ino:n.ino}}catch(n){if(n.code==="ENOENT")return null;throw n}}readPidFile(){try{let t=Number.parseInt(readFileSync(this.pidPath,"utf8").trim(),10);return Number.isInteger(t)&&t>1?t:null}catch{return null}}isProcessAlive(t){try{return process.kill(t,0),!0}catch(n){return n.code==="EPERM"}}pathMatchesIdentity(t,n){if(!n)return false;try{let o=this.getPathIdentity(t);return o?.dev===n.dev&&o.ino===n.ino}catch(o){return this.logRuntime("warn","path_ownership_check",{reason:o.message}),false}}writePidFile(){let t=openSync(this.pidPath,"wx",384);try{writeFileSync(t,`${process.pid}
|
|
39
|
-
`);let n=fstatSync(t);this.pidIdentity={dev:n.dev,ino:n.ino};}finally{closeSync(t);}}removePathIfOwned(t,n,o,r){try{return !this.pathMatchesIdentity(t,n)||r!==void 0&&readFileSync(t,"utf8")!==r||!this.pathMatchesIdentity(t,n)?!1:(unlinkSync(t),!0)}catch(i){return i.code!=="ENOENT"&&this.logRuntime("warn","owned_path_cleanup",{label:o,reason:i.message}),false}}isSocketAcceptingConnections(){return new Promise((t,n)=>{let o=createConnection(this.socketPath),r=setTimeout(()=>{o.destroy(),n(new Error(`Timed out probing daemon socket ${this.socketPath}`));},
|
|
40
|
-
${r}`:r;}a&&(h.hookSpecificOutput.updatedInput=n.tool_input);let b={...n.tool_input};delete b._devflow_session_id,delete b._devflow_execution_id,delete b._devflow_tool_use_id;let S=l?.executionId??o,x={eventId:we(o,n.tool_use_id),executionId:S,sessionId:o,projectRoot:this.projectRoot,toolUseId:n.tool_use_id,timestamp:Date.now(),toolName:n.tool_name,toolType:c?"mcp":n.tool_name==="Agent"?"subagent":"direct",isMcpTool:c,mcpToolName:d,mcpEnforced:c&&(m==="context_gathering"||m==="context_initializing"),mcpFallback:!c&&(m==="context_gathering"||m==="context_initializing"),kind:
|
|
39
|
+
`);let n=fstatSync(t);this.pidIdentity={dev:n.dev,ino:n.ino};}finally{closeSync(t);}}removePathIfOwned(t,n,o,r){try{return !this.pathMatchesIdentity(t,n)||r!==void 0&&readFileSync(t,"utf8")!==r||!this.pathMatchesIdentity(t,n)?!1:(unlinkSync(t),!0)}catch(i){return i.code!=="ENOENT"&&this.logRuntime("warn","owned_path_cleanup",{label:o,reason:i.message}),false}}isSocketAcceptingConnections(){return new Promise((t,n)=>{let o=createConnection(this.socketPath),r=setTimeout(()=>{o.destroy(),n(new Error(`Timed out probing daemon socket ${this.socketPath}`));},km),i=s=>{clearTimeout(r),o.destroy(),t(s);};o.once("connect",()=>i(true)),o.once("error",s=>{let a=s.code;a==="ENOENT"||a==="ECONNREFUSED"||a==="ECONNRESET"||a==="ETIMEDOUT"?i(false):(clearTimeout(r),n(s));});})}listen(){return new Promise((t,n)=>{let o=this.server;if(!o){n(new Error("Daemon server is not initialized"));return}let r=s=>{o.off("listening",i),n(s);},i=()=>{o.off("error",r);try{let s=this.getPathIdentity(this.socketPath);if(!s)throw new Error(`Daemon socket missing after listen: ${this.socketPath}`);this.socketIdentity=s,t();}catch(s){n(s);}};o.once("error",r),o.once("listening",i),o.listen(this.socketPath);})}resetIdleTimer(){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=null,!(this.activeSessionIds.size>0)&&(this.idleTimer=setTimeout(()=>{let t=openGlobalDevFlowDatabase();try{if(t.listWorkflowWorkers(this.projectRoot,{states:["leased","starting","running","reported","verifying","merge_ready"],limit:1}).length>0){this.logRuntime("debug","idle_timeout_deferred",{reason:"active_workflow_worker"}),this.resetIdleTimer();return}}finally{t.close();}this.logRuntime("info","idle_timeout_exit"),this.shutdown();},_m).unref());}async handleRequest(t){if(Ai())return t.type==="pre-tool-use"?{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}:null;let n=this.hostRuntime,o=Mm(t.input);if(!n)return this.hookFailureResponse(t.type,{enabled:false,policy:"fail_open",reason:"host_adapter_not_ready",fallback:"host_event_continues_without_devflow_handler"});let r=sn(t.type,this.hookRuntime,n);if(!r.enabled)return this.hookFailureResponse(t.type,r);let i=Date.now();try{let s=Qr(t.type,await Xr({registry:this.hookHandlers,requestType:t.type,rawInput:t.input??"",acknowledgementBudgetMs:this.hookRuntime.acknowledgementBudgetMs,projectRoot:this.projectRoot})),a="status"in s&&s.status==="degraded";if(a){let c="reason"in s?String(s.reason):"handler_degraded";this.hookHealth.recordFailure(t.type,n.hostId,"degraded",c);}else this.hookHealth.recordSuccess(t.type,n.hostId);return ee("hook_handler_outcome",{success:!a,projectRoot:this.projectRoot,host:n.hostId,handler:t.type,degraded:a},Date.now()-i),this.logRuntime(a?"warn":"info","handler_outcome",{handler:t.type,host:n.hostId,degraded:a,durationMs:Date.now()-i,..."reason"in s&&s.reason?{reason:String(s.reason)}:{}},o),s}catch(s){let a=Zr(s);return this.hookHealth.recordFailure(t.type,n.hostId,a.category,a.reason),ee("hook_handler_outcome",{success:false,projectRoot:this.projectRoot,host:n.hostId,handler:t.type,category:a.category,reason:a.reason},Date.now()-i),this.logRuntime("error","handler_outcome",{handler:t.type,host:n.hostId,category:a.category,reason:a.reason,durationMs:Date.now()-i},o),this.hookFailureResponse(t.type,r,s)}}async drainSessionStartSpool(){for(;;){let t=Dr(this.projectRoot);if(!t)return;try{let n=await this.handleRequest({type:"session-start",input:t.input});if(n&&"status"in n&&n.status==="degraded")throw new Error(`session_start_degraded:${String(n.reason??"unknown")}`);Cr(t),this.logRuntime("info","session_start_spool_accepted",{receiptId:t.receiptId});}catch(n){Mr(t),this.logRuntime("warn","session_start_spool_deferred",{reason:n.message,fallback:"durable_spool"});return}}}scheduleUserPromptSubmitSpoolDrain(t){this.userPromptSubmitSpoolTimer||(this.userPromptSubmitSpoolTimer=setTimeout(()=>{this.userPromptSubmitSpoolTimer=null,this.drainUserPromptSubmitSpool();},t),this.userPromptSubmitSpoolTimer.unref());}async drainUserPromptSubmitSpool(){for(;;){let t=jr(this.projectRoot);if(!t){this.scheduleUserPromptSubmitSpoolDrain(1e3);return}try{let n=await this.handleRequest({type:"user-prompt-submit",input:t.input});if(n&&"status"in n&&n.status==="degraded")throw new Error(`user_prompt_submit_degraded:${String(n.reason??"unknown")}`);$r(t),this.logRuntime("info","user_prompt_submit_spool_accepted",{receiptId:t.receiptId});}catch(n){Fr(t),this.logRuntime("warn","user_prompt_submit_spool_deferred",{reason:n.message,fallback:"durable_spool"}),this.scheduleUserPromptSubmitSpoolDrain(1e3);return}}}hookFailureResponse(t,n,o){let r=o instanceof Error?o.message:n.reason??"hook_handler_unavailable",i=n.fallback??(n.policy==="enqueue_and_open"?"durable_background_processing":"host_event_continues");return t==="pre-tool-use"?{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:n.policy==="fail_closed"?"deny":"allow",permissionDecisionReason:r,additionalContext:`DevFlow hook degraded: ${r}; fallback=${i}.`}}:t==="user-prompt-submit"?{hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",additionalContext:`DevFlow hook degraded: ${r}; fallback=${i}. Do not claim unreceipted work completed.`}}:{status:"degraded",reason:r,fallback:i}}async handlePreToolUse(t){try{if(!t||t.trim()==="")return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}};let n=JSON.parse(t);n.tool_input=Cm(n.tool_name,n.tool_input,process.env,this.projectRoot);let o=this.trackSession(n.session_id),r="";if(n.tool_name==="Skill"){let A=n.tool_input?.skill,M=A?Ve(A):null;M&&(r=this.startSkillExecution(o,M));}let i=this.runtimeStore.get(o),s=resolveClaudeToolName(n.tool_name,n.tool_input),a=s.status==="unsupported"?void 0:s.canonicalName;a==="get_project_context"&&this.runtimeStore.beginContextInitialization(o,n.tool_use_id),a&&(n.tool_input._devflow_session_id=o,n.tool_input._devflow_execution_id=i?.executionId??o,i?.activeTurnId&&(n.tool_input._devflow_turn_id=i.activeTurnId),i?.activeRequestId&&(n.tool_input._devflow_request_id=i.activeRequestId),i?.intentArtifactHash&&(n.tool_input._devflow_intent_artifact_hash=i.intentArtifactHash),i?.skillName&&(n.tool_input._devflow_active_skill=i.skillName),n.tool_use_id&&(n.tool_input._devflow_tool_use_id=n.tool_use_id));let c=n.tool_name.startsWith("mcp__"),d=a,l=this.runtimeStore.get(o),u=new re(this.projectRoot,o,l?.executionId),m=u.getPhase(),f=Yo(this.projectRoot,o,n.tool_name,l?.executionId,n.tool_input),p=Er({toolName:n.tool_name,toolInput:n.tool_input,projectRoot:this.projectRoot}),g=p?{permissionDecision:"deny",reason:p}:u.evaluate(n.tool_name,c),h;if(f?h={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`${f.message} Resolve the case blocker or obtain an authorized task lease before retrying.`}}:g.permissionDecision==="deny"?h={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:g.reason??"MCP context required"}}:g.additionalContext?h={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:g.additionalContext}}:h={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}},this.hookRuntime.profile==="advise"){let A=h;A.hookSpecificOutput?.permissionDecision==="deny"&&(h=Di({projectRoot:this.projectRoot,sessionId:o,toolName:n.tool_name,code:f?.code??"DEVFLOW_POLICY",reason:A.hookSpecificOutput.permissionDecisionReason??"policy deny"}));}if(r){let A=h.hookSpecificOutput,M=typeof A.additionalContext=="string"?A.additionalContext:"";A.additionalContext=M?`${M}
|
|
40
|
+
${r}`:r;}a&&(h.hookSpecificOutput.updatedInput=n.tool_input);let b={...n.tool_input};delete b._devflow_session_id,delete b._devflow_execution_id,delete b._devflow_tool_use_id;let S=l?.executionId??o,x={eventId:we(o,n.tool_use_id),executionId:S,sessionId:o,projectRoot:this.projectRoot,toolUseId:n.tool_use_id,timestamp:Date.now(),toolName:n.tool_name,toolType:c?"mcp":n.tool_name==="Agent"?"subagent":"direct",isMcpTool:c,mcpToolName:d,mcpEnforced:c&&(m==="context_gathering"||m==="context_initializing"),mcpFallback:!c&&(m==="context_gathering"||m==="context_initializing"),kind:Dm(n.tool_name),input:b,duration:0,blocked:h&&h.hookSpecificOutput?.permissionDecision==="deny"},T=x.blocked?f?.code??(p?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":g.reasonCode??"DEVFLOW_CONTEXT_REQUIRED"):void 0,C=await this.telemetry.sendEvent({...x,blockReason:T,error:T});return C&&!x.blocked&&(this.eventMap.push({toolName:n.tool_name,toolUseId:n.tool_use_id,eventId:C,sessionId:o,timestamp:x.timestamp}),this.noteTelemetryOperation()),C&&x.blocked&&await this.telemetry.completeEvent({eventId:C,sessionId:o,error:T??"DEVFLOW_CONTEXT_REQUIRED",duration:Date.now()-x.timestamp,completedAt:Date.now()}),h}catch{return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}}trackSession(t){let n=t?.trim()||(this.activeSessionIds.size===1?[...this.activeSessionIds][0]:"");if(!n)throw new Error("session_id_required");return this.registerSession(n),n}registerSession(t){this.activeSessionIds.has(t)||(this.activeSessionIds.size===0&&Fe(this.projectRoot,{bypassCount:0}),this.activeSessionIds.add(t),this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.serverManager.addRef(t),this.telemetry.sendSessionStart(t,this.projectRoot,Date.now()).catch(()=>{})),this.runtimeStore.registerSession(t);}startSkillExecution(t,n,o){let r=this.runtimeStore.get(t)?.executionId,i=this.runtimeStore.startExecution(t,n,Bn(n));return i.executionId&&i.executionId!==r&&this.telemetry.sendExecutionStart(i.executionId,t,n,i.lastActivityAt,this.projectRoot,i.requiredMcpTools).catch(()=>{}),Vn(n,this.projectRoot,o)}async handleSessionStart(t){try{let n=JSON.parse(t);if(typeof n.session_id!="string"||!n.session_id.trim())return {error:"session_id_required"};let o=n.session_id.trim();this.registerSession(o);let r=`session-start:${createHash("sha256").update(`${this.projectRoot}\0${o}`).digest("hex").slice(0,24)}`,i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50}),s="pending";try{s=i.enqueueWork({idempotencyKey:r,kind:"session.bootstrap",projectRoot:this.projectRoot,sessionId:o,payload:{sessionId:o}}).state;}finally{i.close();}return {status:s==="completed"?"completed":"accepted",receiptId:r,workState:s}}catch{return {error:"session_start_invalid"}}}popEventFromMap(t,n,o){let r=this.eventMap.filter(s=>s.toolName===t&&s.sessionId===n);if(r.length===0)return null;let i=o?r.find(s=>s.toolUseId===o):r.sort((s,a)=>s.timestamp-a.timestamp)[0];return i?(this.eventMap=this.eventMap.filter(s=>s.eventId!==i.eventId),i):null}async handlePostToolUse(t){if(!t)return null;let n;try{n=JSON.parse(t);}catch{return null}let o=n.tool_name||"",r=n.tool_input||{},i=n.tool_response,s=this.trackSession(n.session_id);if(s){let R=await xi({projectRoot:this.projectRoot,sessionId:s,sourceTurnId:this.runtimeStore.get(s)?.activeTurnId,toolName:o,toolInput:r,toolResponse:i,toolUseId:n.tool_use_id});if(R.handled)return {hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:R.message}}}let a=resolveClaudeToolName(o,r),c=a.status==="unsupported"?void 0:a.canonicalName;if(c==="get_project_context"&&this.runtimeStore.completeContextInitialization(s,n.tool_use_id),Lo({projectRoot:this.projectRoot,sessionId:s,executionId:this.runtimeStore.get(s)?.executionId,toolName:o,toolInput:r,toolResponse:i,toolUseId:n.tool_use_id}),o==="Skill"){let R=r?.skill,D=R?Ve(R):null;D&&(this.startSkillExecution(s,D),Fe(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0}));}if(o.startsWith("mcp__")){let R=this.runtimeStore.get(s),D=new re(this.projectRoot,s,R?.executionId??s);D.recordMcpCall();let P=Am(i);Fi(D,c??o,P?$i(P):"succeeded",P,n.tool_use_id);}let d=this.popEventFromMap(o,s,n.tool_use_id);if(d){let R=typeof i=="string"?i:JSON.stringify(i),D=R.length>5e3?{_truncated:true,_originalSize:R.length,text:R.slice(0,5e3)}:i,P=Date.now()-d.timestamp;await this.telemetry.completeEvent({eventId:d.eventId,sessionId:s,output:D,duration:P,completedAt:Date.now()})&&this.noteTelemetryOperation();}let l=typeof i=="object"&&i!==null?i:null,u=l?.exitCode,m=l?.stderr,f=/^\s*(ls|cat|pwd|cd|echo|head|tail|wc|which|whoami|date|env|printenv|id|hostname|uname)\b/,p=r.command||"",g=JSON.stringify(i),h=Buffer.byteLength(g,"utf8"),b=this.countResults(i),S,_,x=true;if(o.startsWith("mcp__"))S="mcp_call",_={mcpTool:c??o,query:r.query??null,resultCount:b,resultSizeBytes:h};else if(o==="Read"||o==="Write"||o==="Edit")S=o==="Read"?"file_read":"file_write",_={filePath:r.file_path??null,fileContentSize:h};else if(o==="Bash"){let R=f.test(p),D=u!==void 0&&u!==0;x=!R||D,S=D?"bash_error":"bash_command",_={command:p||o,exitCode:u??null,stderr:m??null};}else o==="Agent"?(S="subagent",_={subagentType:r.subagent_type??null,description:typeof r.description=="string"?r.description.slice(0,200):null}):o==="WebSearch"||o==="WebFetch"?(S=o==="WebSearch"?"web_search":"web_fetch",_={query:typeof r.query=="string"?r.query.slice(0,200):null}):(x=false,S="tool_use",_={});if(x){let R={id:n.tool_use_id?`memory:${we(s,n.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:s,tool:o,kind:S,payload:{..._,durationMs:0},createdAt:Date.now()};this.postMemoryEvent(R);}let T=Oo({toolName:o,toolResponse:i,sessionId:s,toolUseId:n.tool_use_id,runtimeStore:this.runtimeStore}),C=this.runtimeStore.get(s),A=gi({projectRoot:this.projectRoot,sessionId:s,executionId:C?.executionId,toolName:o,toolInput:r,toolResponse:i,toolUseId:n.tool_use_id}),M=[T,A].filter(R=>!!R).join(`
|
|
41
41
|
|
|
42
42
|
`);return M?{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:M}}:null}async handlePostToolUseFailure(t){let n;try{n=JSON.parse(t);}catch{return null}let o=this.trackSession(n.session_id),r=n.tool_name??"unknown",i=n.error??`${r} failed`,s=resolveClaudeToolName(r,n.tool_input||{}),a=s.status==="unsupported"?void 0:s.canonicalName;if(a==="get_project_context"&&this.runtimeStore.completeContextInitialization(o,n.tool_use_id),a){let d=this.runtimeStore.get(o),l=new re(this.projectRoot,o,d?.executionId??o);Fi(l,a,$i(i),i,n.tool_use_id);}let c=this.popEventFromMap(r,o,n.tool_use_id);if(c)await this.telemetry.completeEvent({eventId:c.eventId,sessionId:o,error:i,duration:Date.now()-c.timestamp,completedAt:Date.now()})&&this.noteTelemetryOperation();else {let d=we(o,n.tool_use_id);await this.telemetry.sendEvent({eventId:d,executionId:this.runtimeStore.get(o)?.executionId??o,sessionId:o,projectRoot:this.projectRoot,toolUseId:n.tool_use_id,timestamp:Date.now(),toolName:r,toolType:r.startsWith("mcp__")?"mcp":"direct",isMcpTool:r.startsWith("mcp__"),mcpToolName:a,mcpEnforced:false,mcpFallback:false,kind:"error",input:n.tool_input??{},duration:0,error:i,blocked:false});}return this.postMemoryEvent({id:n.tool_use_id?`memory:${we(o,n.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:o,tool:r,command:typeof n.tool_input?.command=="string"?n.tool_input.command:r,exitCode:-1,stderr:i,durationMs:c?Date.now()-c.timestamp:0,createdAt:Date.now(),kind:r==="Bash"?"bash_error":"tool_use",payload:{command:n.tool_input?.command??r,exitCode:-1,stderr:i}}),null}countResults(t){if(!t)return 0;let n=t;if(typeof t=="string")try{n=JSON.parse(t);}catch{return 1}let o=n,r=["files","results","data","result","memories","nodes","chunks","findings","symbols"],i=Array.isArray(o.data)?o.data:o.structuredContent??o;if(Array.isArray(i))return i.length;if(typeof i=="object"&&i!==null){let s=i,a=0,c=false;for(let d of r)Array.isArray(s[d])&&(c=true,a+=s[d].length);for(let[,d]of Object.entries(s))d&&typeof d=="object"&&!Array.isArray(d)&&(a+=this.countResults(d));return a>0?a:c?0:Object.keys(s).length>0?1:0}return 0}async postMemoryEvent(t){await new Promise(n=>setImmediate(n)),G(`/api/memory/session-events?rootPath=${encodeURIComponent(this.projectRoot)}`,t);try{await(await this.getMemoryGate()).recordEvent(t);}catch(n){this.logRuntime("warn","memory_event_write",{reason:n.message,fallback:"http_mirror"},t.sessionId);}}async getMemoryGate(){let t=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);return this.memoryWarmup??=t.forceWarmUp().catch(n=>{throw this.memoryWarmup=null,n}),await this.memoryWarmup,t}async handleUserPromptSubmit(t){let n=[];try{let o=JSON.parse(t),r=typeof o.prompt=="string"?o.prompt:"",i=typeof o.session_id=="string"&&o.session_id.trim()?this.trackSession(o.session_id):null;if(i&&r.trim()){let d=await Ei({projectRoot:this.projectRoot,sessionId:i,executionId:this.runtimeStore.get(i)?.executionId,sourceTurnId:this.runtimeStore.get(i)?.activeTurnId,prompt:r});if(d.handled)return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",additionalContext:d.message}}}let s=rr(r),a=!1,c;if(r.trim()&&i){try{c=await _i({projectRoot:this.projectRoot,sessionId:i,prompt:r,hostEvent:o}),this.runtimeStore.bindTaskIdentity(i,{turnId:c.artifact.identity.turnId,requestId:c.artifact.identity.requestId,intentArtifactHash:c.artifact.artifactHash}),n.push(`DevFlow immutable task identity: turnId=${c.artifact.identity.turnId}; requestId=${c.artifact.identity.requestId}; intentArtifactHash=${c.artifact.artifactHash}. Retrieval query expansion must not replace this original intent.`);}catch(d){n.push("DevFlow task intent persistence degraded; preserve the original user command and do not claim canonical context binding."),y({event:"intent.artifact.failed",identity:{projectRoot:this.projectRoot,sessionId:i},level:"error",timestamp:Date.now(),data:{stage:"daemon_user_prompt_submit",category:"intent_persistence_unavailable",error:d instanceof Error?d.message:String(d)}});}try{let d=Gt({projectRoot:this.projectRoot,sessionId:i,prompt:r,...c?{identity:c.memoryIdentity}:{},...c?{activation:c.activation}:{}});if(d){let l=d;if(d.explicitContent&&d.turn.status==="pending")try{l=await Yt({projectRoot:this.projectRoot,payload:{operation:"commit_explicit",turnId:d.turn.turnId,eventId:d.turn.eventId,sessionId:i,prompt:r.trim().slice(0,4e3),explicitContent:d.explicitContent,createdAt:d.turn.createdAt},memory:await this.getMemoryGate()});}catch(u){this.logRuntime("warn","explicit_memory_commit",{reason:u.message,fallback:"durable_work_queue",turnId:d.turn.turnId},i);}n.push(l.additionalContext),a=l.skipSkillRouting;}}catch(d){a=!!Ie(r);try{let u=Nr(this.projectRoot,{sessionId:i,prompt:r,createdAt:Date.now()});n.push(`DevFlow memory turn status=accepted; durable=true; receiptId=${u}; canonicalMemory=false; SQLite queue replay pending. Do not claim memory success without a canonical receipt.`),this.scheduleMemoryTurnSpoolDrain(250),this.logRuntime("warn","memory_turn_capture",{reason:d.message,fallback:"durable_spool",receiptId:u},i);}catch(u){n.push("DevFlow memory turn status=degraded; durable=false; no canonical receipt exists. Do not claim memory success."),this.logRuntime("error","memory_turn_capture",{reason:u.message,fallback:"none"},i);}}}if(i&&s&&!a){let d=this.startSkillExecution(i,s.skillName,r);d&&n.push(d);}}catch{}return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...n.length?{additionalContext:n.join(`
|
|
43
|
-
`)}:{}}}}async handlePreCompact(t){let n;try{let s=JSON.parse(t);typeof s.session_id=="string"&&s.session_id.trim()&&(n=s.session_id.trim());}catch{}await this.flushTelemetry(),this.startExplicitIntentFlush(),await this.explicitIntentFlush;let o=await this.getMemoryGate(),r=await fe({projectRoot:this.projectRoot,sessionId:n,trigger:"pre_compact",memory:o}),i=bo(r);return {hookSpecificOutput:{hookEventName:"PreCompact",...i?{additionalContext:i}:{}}}}async persistMemoryTurnItem(t){if(!t||typeof t!="object")throw new Error("memory_turn_payload_invalid");let n=t;if(n.operation!=="capture_prompt"&&n.operation!=="commit_explicit"||typeof n.turnId!="string"||typeof n.eventId!="string"||typeof n.sessionId!="string"||typeof n.prompt!="string"||typeof n.createdAt!="number")throw new Error("memory_turn_payload_invalid");await Yt({projectRoot:this.projectRoot,payload:n,memory:await this.getMemoryGate()});}scheduleMemoryTurnSpoolDrain(t){this.memoryTurnSpoolTimer||(this.memoryTurnSpoolTimer=setTimeout(()=>{this.memoryTurnSpoolTimer=null,this.drainMemoryTurnSpool();},t),this.memoryTurnSpoolTimer.unref());}async drainMemoryTurnSpool(){for(;;){let t=Lr(this.projectRoot);if(!t)return;try{Gt({projectRoot:this.projectRoot,sessionId:t.payload.sessionId,prompt:t.payload.prompt}),qr(t),this.workRuntime.drainOnce();}catch(n){Wr(t),this.logRuntime("warn","memory_turn_spool_replay",{reason:n.message,fallback:"bounded_retry"},t.payload.sessionId),this.scheduleMemoryTurnSpoolDrain(1e3);return}}}async bootstrapSessionWork(t){if(!t||typeof t!="object"||typeof t.sessionId!="string")throw new Error("session_bootstrap_payload_invalid");let n=t.sessionId,o=await this.getMemoryGate();await o.ensureSession(n,this.projectRoot,"Host session"),await o.releasePendingDistillLeases(n),await this.refreshMemorySnapshot("session_bootstrap");}noteTelemetryOperation(){this.successfulTelemetryOperations++,this.successfulTelemetryOperations>=xm&&this.flushTelemetry();}async flushTelemetry(){this.successfulTelemetryOperations=0,await this.telemetry.flushAndAggregate();}startExplicitIntentFlush(){this.explicitIntentFlush||(this.explicitIntentFlush=this.flushExplicitMemoryIntents().finally(()=>{this.explicitIntentFlush=null;}));}async handleStop(t){let n=null,o=false,r;try{let i=JSON.parse(t);typeof i.session_id=="string"&&i.session_id.trim()&&(n=i.session_id.trim()),o=i.stop_hook_active===!0,typeof i.transcript_path=="string"&&i.transcript_path.trim()&&(r=i.transcript_path.trim());}catch{}if(n??=this.activeSessionIds.size===1?[...this.activeSessionIds][0]:null,this.startExplicitIntentFlush(),n){let i=ei({projectRoot:this.projectRoot,sessionId:n,transcriptPath:r,stopHookActive:o,runtimeStore:this.runtimeStore});if(i.decision==="block_once")return y({event:"hook.stop.degraded",identity:{projectRoot:this.projectRoot,sessionId:n},level:"warn",timestamp:Date.now(),data:{decision:"block_once",unresolved:i.unresolved.map(a=>a.obligationId)}}),{decision:"block",reason:i.additionalContext};let s=this.runtimeStore.completeExecution(n);if(s?.executionId){let a=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50}),c={};try{let d=a.listSessionMemoryTurnsForReconciliation(this.projectRoot,n);c={...Pt(d),evidenceDegradations:s.evidenceDegradations,evidenceContractOutcomes:s.evidenceOutcomes,unresolvedObligations:i.unresolved,terminalState:i.decision};}finally{a.close();}await this.telemetry.sendExecutionComplete(s.executionId,"completed",Date.now(),c),this.deleteContextReceipt(n,s.executionId);}y({event:"hook.stop.completed",identity:{projectRoot:this.projectRoot,sessionId:n,executionId:s?.executionId},level:"info",timestamp:Date.now(),data:{decision:i.decision,unresolvedCount:i.unresolved.length}});}return null}async flushExplicitMemoryIntents(){this.flushTelemetry();let t=or(this.projectRoot);if(t)try{let n=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);await n.forceWarmUp();let o=!1;for(;t.intents.length>0;){let r=t.intents[0];if(r.turnId){let s=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let a=s.getMemoryTurn(r.turnId);if(!a||a.status!=="pending"){this.logRuntime("warn","legacy_memory_intent_drop",{turnId:r.turnId,status:a?.status??"missing"},r.sessionId),jt(t);continue}}finally{s.close();}}let i=await n.saveExplicitMemoryIntent(r.content,{actorId:"actor:claude-code",sessionId:r.sessionId},r.eventId);if(o=!0,r.turnId){let s=openGlobalDevFlowDatabase();try{let a=s.commitMemoryTurn({turnId:r.turnId,receiptId:Re(r.turnId,"committed",[i.id]),memoryIds:[i.id],source:"explicit_intent",reason:"explicit_user_request_retry"});if(a.receiptId)try{await n.finalizeTurnDecision({turnEventId:a.eventId,sessionId:a.sessionId,turnId:a.turnId,receiptId:a.receiptId,status:"committed",memoryIds:[i.id],reason:"explicit_user_request_retry"});}catch(c){this.logRuntime("warn","memory_lineage_finalize",{reason:c.message,fallback:"session_end_reconciliation",turnId:r.turnId},r.sessionId);}try{await n.enrichExplicitMemoryObservation(i.id);}catch(c){s.enqueueWork({idempotencyKey:`explicit-enrichment:${this.projectRoot}:${i.id}`,kind:"memory.explicit_enrichment",projectRoot:this.projectRoot,sessionId:r.sessionId,turnId:r.turnId,payload:{observationId:i.id},maxAttempts:20}),this.logRuntime("warn","explicit_memory_enrichment",{reason:c.message,fallback:"durable_work_queue",memoryId:i.id,turnId:r.turnId},r.sessionId);}}finally{s.close();}}jt(t);}o&&await this.refreshMemorySnapshot("legacy_explicit_memory_commit");}catch(n){this.logRuntime("error","legacy_memory_intent_flush",{reason:n.message,fallback:"claim_remains_retryable"});}}deleteContextReceipt(t,n){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),o.deleteContextReceipt(this.projectRoot,t,n);}catch{}finally{o?.close();}}async refreshMemorySnapshot(t){try{let n=loadConfig(this.projectRoot).sessionStart?.injectMemories??!0,o=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);return await Qe({projectRoot:this.projectRoot,memory:o,injectConfig:n,reason:t})}catch(n){return this.logRuntime("warn","memory_snapshot_refresh",{reason:n.message,fallback:"cached_snapshot",trigger:t}),Jt({projectRoot:this.projectRoot,reason:t,load:async()=>{throw n}})}}async handleMemorySnapshot(){let t=await this.refreshMemorySnapshot("memory_snapshot_request"),{snapshot:n}=t;return {status:n.status==="ready"||n.status==="disabled"?"ok":n.status,enabled:n.status!=="disabled",markdown:n.markdown,memoryIds:n.memoryIds,memoryCount:n.memoryIds.length,conflicts:n.conflicts,snapshot:n,persisted:t.persisted}}async handleSessionEnd(t){let n=null;try{let s=JSON.parse(t);typeof s.session_id=="string"&&s.session_id.trim()&&(n=s.session_id.trim());}catch{}n??=this.activeSessionIds.size===1?[...this.activeSessionIds][0]:null;let o=n===null?this.activeSessionIds.size<=1:this.activeSessionIds.size<=1&&this.activeSessionIds.has(n),r=n?this.runtimeStore.get(n)?.executionId:void 0,i=Be(t,this.projectRoot,o,r);return i?.workState==="spooled"&&this.scheduleSessionFinalizeSpoolDrain(250),n&&(this.serverManager.removeRef(n),this.activeSessionIds.delete(n),this.eventMap=this.eventMap.filter(s=>s.sessionId!==n)),this.activeSessionIds.size===0&&i?.workState!=="spooled"&&i?.workItemId?setImmediate(()=>{this.workRuntime.drainWorkItemOnce(i.workItemId).finally(()=>{this.shutdown();});}):this.resetIdleTimer(),i??{status:"ok"}}async finalizeSessionWork(t,n){if(!t||typeof t!="object")throw new Error("session_finalize_payload_invalid");let o=t;if(typeof o.inputJson!="string"||typeof o.sessionId!="string")throw new Error("session_finalize_payload_invalid");let r;try{r=await this.getMemoryGate();}catch(s){this.logRuntime("warn","session_finalize_memory_gate",{reason:s.message,fallback:"finalize_without_memory_gate"},o.sessionId);}await Qo(o.inputJson,this.projectRoot,o.cleanupSharedState!==false,{telemetry:this.telemetry,memory:r,executionId:o.executionId});try{await this.refreshMemorySnapshot("session_finalization");}catch(s){this.logRuntime("warn","session_finalize_snapshot",{reason:s.message,fallback:"durable_memory_authoritative"},o.sessionId);}let i=openGlobalDevFlowDatabase();try{i.completeSessionClosure(this.projectRoot,o.sessionId,n);}finally{i.close();}}enqueueLearningAnalysisIfReady(t,n){if(resolveCapabilityRollout(this.projectRoot).config.learningOverlays==="off")return;let r=t.getSessionClosure(this.projectRoot,n);if(!r||r.state!=="closed"||r.pendingWorkCount!==0||t.listSessionObligations(this.projectRoot,n).some(c=>c.state==="open"||c.state==="degraded"))return;let s=t.getLatestSkillExecutionForSession(n);if(s&&s.status==="running")return;let a=Cm(this.projectRoot);t.enqueueWork({idempotencyKey:`learning-analysis:${r.receiptId}:${a}`,kind:"learning.analyze_session",projectRoot:this.projectRoot,sessionId:n,payload:{projectRoot:this.projectRoot,sessionId:n,executionId:s?.executionId,closureReceipt:r.receiptId,projectRevision:a,createdAt:Date.now()},maxAttempts:5});}scheduleSessionFinalizeSpoolDrain(t){this.sessionFinalizeSpoolTimer||(this.sessionFinalizeSpoolTimer=setTimeout(()=>{this.sessionFinalizeSpoolTimer=null,this.drainSessionFinalizeSpool();},t),this.sessionFinalizeSpoolTimer.unref());}async drainSessionFinalizeSpool(){for(;;){let t=xo(this.projectRoot);if(!t)return;try{if(!Be(t.payload.inputJson,this.projectRoot,t.payload.cleanupSharedState,t.payload.executionId,!1))throw new Error("session_finalize_spool_rejected");Eo(t),this.workRuntime.drainOnce();}catch(n){To(t),this.logRuntime("warn","session_finalize_spool_replay",{reason:n.message,fallback:"bounded_retry"},t.payload.sessionId),this.scheduleSessionFinalizeSpoolDrain(1e3);return}}}shutdown(){return this.shutdownPromise?this.shutdownPromise:(this.shutdownPromise=this.performShutdown(),this.shutdownPromise)}async performShutdown(){this.workRuntime.stop(),this.embeddingPreparationController?.abort(),this.embeddingPreparationController=null,this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.telemetryFlushTimer&&(clearInterval(this.telemetryFlushTimer),this.telemetryFlushTimer=null),this.memoryTurnSpoolTimer&&(clearTimeout(this.memoryTurnSpoolTimer),this.memoryTurnSpoolTimer=null),this.userPromptSubmitSpoolTimer&&(clearTimeout(this.userPromptSubmitSpoolTimer),this.userPromptSubmitSpoolTimer=null),this.sessionFinalizeSpoolTimer&&(clearTimeout(this.sessionFinalizeSpoolTimer),this.sessionFinalizeSpoolTimer=null),await this.flushTelemetry(),await this.closeServer(),this.cleanupOwnedResources(),await this.serverManager.stop(),await this.explicitIntentFlush,this.explicitMemoryGate?.close(),this.explicitMemoryGate=null,this.telemetry.close(),process.exit(0);}closeServer(){let t=this.server;return !t||!t.listening||!this.pathMatchesIdentity(this.socketPath,this.socketIdentity)?Promise.resolve():(this.server=null,new Promise(n=>{let o=false,r=()=>{o||(o=true,clearTimeout(i),n());},i=setTimeout(r,bm);t.close(r);}))}cleanupOwnedResources(){try{vo(this.projectRoot,process.pid);}catch(t){this.logRuntime("warn","daemon_unregister",{reason:t.message});}this.removePathIfOwned(this.socketPath,this.socketIdentity,"socket"),this.removePathIfOwned(this.pidPath,this.pidIdentity,"PID file",`${process.pid}
|
|
44
|
-
`);}};function
|
|
43
|
+
`)}:{}}}}async handlePreCompact(t){let n;try{let s=JSON.parse(t);typeof s.session_id=="string"&&s.session_id.trim()&&(n=s.session_id.trim());}catch{}await this.flushTelemetry(),this.startExplicitIntentFlush(),await this.explicitIntentFlush;let o=await this.getMemoryGate(),r=await fe({projectRoot:this.projectRoot,sessionId:n,trigger:"pre_compact",memory:o}),i=bo(r);return {hookSpecificOutput:{hookEventName:"PreCompact",...i?{additionalContext:i}:{}}}}async persistMemoryTurnItem(t){if(!t||typeof t!="object")throw new Error("memory_turn_payload_invalid");let n=t;if(n.operation!=="capture_prompt"&&n.operation!=="commit_explicit"||typeof n.turnId!="string"||typeof n.eventId!="string"||typeof n.sessionId!="string"||typeof n.prompt!="string"||typeof n.createdAt!="number")throw new Error("memory_turn_payload_invalid");await Yt({projectRoot:this.projectRoot,payload:n,memory:await this.getMemoryGate()});}scheduleMemoryTurnSpoolDrain(t){this.memoryTurnSpoolTimer||(this.memoryTurnSpoolTimer=setTimeout(()=>{this.memoryTurnSpoolTimer=null,this.drainMemoryTurnSpool();},t),this.memoryTurnSpoolTimer.unref());}async drainMemoryTurnSpool(){for(;;){let t=Lr(this.projectRoot);if(!t)return;try{Gt({projectRoot:this.projectRoot,sessionId:t.payload.sessionId,prompt:t.payload.prompt}),qr(t),this.workRuntime.drainOnce();}catch(n){Wr(t),this.logRuntime("warn","memory_turn_spool_replay",{reason:n.message,fallback:"bounded_retry"},t.payload.sessionId),this.scheduleMemoryTurnSpoolDrain(1e3);return}}}async bootstrapSessionWork(t){if(!t||typeof t!="object"||typeof t.sessionId!="string")throw new Error("session_bootstrap_payload_invalid");let n=t.sessionId,o=await this.getMemoryGate();await o.ensureSession(n,this.projectRoot,"Host session"),await o.releasePendingDistillLeases(n),await this.refreshMemorySnapshot("session_bootstrap");}noteTelemetryOperation(){this.successfulTelemetryOperations++,this.successfulTelemetryOperations>=Tm&&this.flushTelemetry();}async flushTelemetry(){this.successfulTelemetryOperations=0,await this.telemetry.flushAndAggregate();}startExplicitIntentFlush(){this.explicitIntentFlush||(this.explicitIntentFlush=this.flushExplicitMemoryIntents().finally(()=>{this.explicitIntentFlush=null;}));}async handleStop(t){let n=null,o=false,r;try{let i=JSON.parse(t);typeof i.session_id=="string"&&i.session_id.trim()&&(n=i.session_id.trim()),o=i.stop_hook_active===!0,typeof i.transcript_path=="string"&&i.transcript_path.trim()&&(r=i.transcript_path.trim());}catch{}if(n??=this.activeSessionIds.size===1?[...this.activeSessionIds][0]:null,this.startExplicitIntentFlush(),n){let i=ei({projectRoot:this.projectRoot,sessionId:n,transcriptPath:r,stopHookActive:o,runtimeStore:this.runtimeStore});if(i.decision==="block_once")return y({event:"hook.stop.degraded",identity:{projectRoot:this.projectRoot,sessionId:n},level:"warn",timestamp:Date.now(),data:{decision:"block_once",unresolved:i.unresolved.map(a=>a.obligationId)}}),{decision:"block",reason:i.additionalContext};let s=this.runtimeStore.completeExecution(n);if(s?.executionId){let a=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50}),c={};try{let d=a.listSessionMemoryTurnsForReconciliation(this.projectRoot,n);c={...Pt(d),evidenceDegradations:s.evidenceDegradations,evidenceContractOutcomes:s.evidenceOutcomes,unresolvedObligations:i.unresolved,terminalState:i.decision};}finally{a.close();}await this.telemetry.sendExecutionComplete(s.executionId,"completed",Date.now(),c),this.deleteContextReceipt(n,s.executionId);}y({event:"hook.stop.completed",identity:{projectRoot:this.projectRoot,sessionId:n,executionId:s?.executionId},level:"info",timestamp:Date.now(),data:{decision:i.decision,unresolvedCount:i.unresolved.length}});}return null}async flushExplicitMemoryIntents(){this.flushTelemetry();let t=or(this.projectRoot);if(t)try{let n=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);await n.forceWarmUp();let o=!1;for(;t.intents.length>0;){let r=t.intents[0];if(r.turnId){let s=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let a=s.getMemoryTurn(r.turnId);if(!a||a.status!=="pending"){this.logRuntime("warn","legacy_memory_intent_drop",{turnId:r.turnId,status:a?.status??"missing"},r.sessionId),jt(t);continue}}finally{s.close();}}let i=await n.saveExplicitMemoryIntent(r.content,{actorId:"actor:claude-code",sessionId:r.sessionId},r.eventId);if(o=!0,r.turnId){let s=openGlobalDevFlowDatabase();try{let a=s.commitMemoryTurn({turnId:r.turnId,receiptId:Re(r.turnId,"committed",[i.id]),memoryIds:[i.id],source:"explicit_intent",reason:"explicit_user_request_retry"});if(a.receiptId)try{await n.finalizeTurnDecision({turnEventId:a.eventId,sessionId:a.sessionId,turnId:a.turnId,receiptId:a.receiptId,status:"committed",memoryIds:[i.id],reason:"explicit_user_request_retry"});}catch(c){this.logRuntime("warn","memory_lineage_finalize",{reason:c.message,fallback:"session_end_reconciliation",turnId:r.turnId},r.sessionId);}try{await n.enrichExplicitMemoryObservation(i.id);}catch(c){s.enqueueWork({idempotencyKey:`explicit-enrichment:${this.projectRoot}:${i.id}`,kind:"memory.explicit_enrichment",projectRoot:this.projectRoot,sessionId:r.sessionId,turnId:r.turnId,payload:{observationId:i.id},maxAttempts:20}),this.logRuntime("warn","explicit_memory_enrichment",{reason:c.message,fallback:"durable_work_queue",memoryId:i.id,turnId:r.turnId},r.sessionId);}}finally{s.close();}}jt(t);}o&&await this.refreshMemorySnapshot("legacy_explicit_memory_commit");}catch(n){this.logRuntime("error","legacy_memory_intent_flush",{reason:n.message,fallback:"claim_remains_retryable"});}}deleteContextReceipt(t,n){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),o.deleteContextReceipt(this.projectRoot,t,n);}catch{}finally{o?.close();}}async refreshMemorySnapshot(t){try{let n=loadConfig(this.projectRoot).sessionStart?.injectMemories??!0,o=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);return await Qe({projectRoot:this.projectRoot,memory:o,injectConfig:n,reason:t})}catch(n){return this.logRuntime("warn","memory_snapshot_refresh",{reason:n.message,fallback:"cached_snapshot",trigger:t}),Jt({projectRoot:this.projectRoot,reason:t,load:async()=>{throw n}})}}async handleMemorySnapshot(){let t=await this.refreshMemorySnapshot("memory_snapshot_request"),{snapshot:n}=t;return {status:n.status==="ready"||n.status==="disabled"?"ok":n.status,enabled:n.status!=="disabled",markdown:n.markdown,memoryIds:n.memoryIds,memoryCount:n.memoryIds.length,conflicts:n.conflicts,snapshot:n,persisted:t.persisted}}async handleSessionEnd(t){let n=null;try{let s=JSON.parse(t);typeof s.session_id=="string"&&s.session_id.trim()&&(n=s.session_id.trim());}catch{}n??=this.activeSessionIds.size===1?[...this.activeSessionIds][0]:null;let o=n===null?this.activeSessionIds.size<=1:this.activeSessionIds.size<=1&&this.activeSessionIds.has(n),r=n?this.runtimeStore.get(n)?.executionId:void 0,i=Be(t,this.projectRoot,o,r);return i?.workState==="spooled"&&this.scheduleSessionFinalizeSpoolDrain(250),n&&(this.serverManager.removeRef(n),this.activeSessionIds.delete(n),this.eventMap=this.eventMap.filter(s=>s.sessionId!==n)),this.activeSessionIds.size===0&&i?.workState!=="spooled"&&i?.workItemId?setImmediate(()=>{this.workRuntime.drainWorkItemOnce(i.workItemId).finally(()=>{this.shutdown();});}):this.resetIdleTimer(),i??{status:"ok"}}async finalizeSessionWork(t,n){if(!t||typeof t!="object")throw new Error("session_finalize_payload_invalid");let o=t;if(typeof o.inputJson!="string"||typeof o.sessionId!="string")throw new Error("session_finalize_payload_invalid");let r;try{r=await this.getMemoryGate();}catch(s){this.logRuntime("warn","session_finalize_memory_gate",{reason:s.message,fallback:"finalize_without_memory_gate"},o.sessionId);}await Qo(o.inputJson,this.projectRoot,o.cleanupSharedState!==false,{telemetry:this.telemetry,memory:r,executionId:o.executionId});try{await this.refreshMemorySnapshot("session_finalization");}catch(s){this.logRuntime("warn","session_finalize_snapshot",{reason:s.message,fallback:"durable_memory_authoritative"},o.sessionId);}let i=openGlobalDevFlowDatabase();try{i.completeSessionClosure(this.projectRoot,o.sessionId,n);}finally{i.close();}}enqueueLearningAnalysisIfReady(t,n){if(resolveCapabilityRollout(this.projectRoot).config.learningOverlays==="off")return;let r=t.getSessionClosure(this.projectRoot,n);if(!r||r.state!=="closed"||r.pendingWorkCount!==0||t.listSessionObligations(this.projectRoot,n).some(c=>c.state==="open"||c.state==="degraded"))return;let s=t.getLatestSkillExecutionForSession(n);if(s&&s.status==="running")return;let a=Om(this.projectRoot);t.enqueueWork({idempotencyKey:`learning-analysis:${r.receiptId}:${a}`,kind:"learning.analyze_session",projectRoot:this.projectRoot,sessionId:n,payload:{projectRoot:this.projectRoot,sessionId:n,executionId:s?.executionId,closureReceipt:r.receiptId,projectRevision:a,createdAt:Date.now()},maxAttempts:5});}scheduleSessionFinalizeSpoolDrain(t){this.sessionFinalizeSpoolTimer||(this.sessionFinalizeSpoolTimer=setTimeout(()=>{this.sessionFinalizeSpoolTimer=null,this.drainSessionFinalizeSpool();},t),this.sessionFinalizeSpoolTimer.unref());}async drainSessionFinalizeSpool(){for(;;){let t=xo(this.projectRoot);if(!t)return;try{if(!Be(t.payload.inputJson,this.projectRoot,t.payload.cleanupSharedState,t.payload.executionId,!1))throw new Error("session_finalize_spool_rejected");Eo(t),this.workRuntime.drainOnce();}catch(n){To(t),this.logRuntime("warn","session_finalize_spool_replay",{reason:n.message,fallback:"bounded_retry"},t.payload.sessionId),this.scheduleSessionFinalizeSpoolDrain(1e3);return}}}shutdown(){return this.shutdownPromise?this.shutdownPromise:(this.shutdownPromise=this.performShutdown(),this.shutdownPromise)}async performShutdown(){this.workRuntime.stop(),this.embeddingPreparationController?.abort(),this.embeddingPreparationController=null,this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.telemetryFlushTimer&&(clearInterval(this.telemetryFlushTimer),this.telemetryFlushTimer=null),this.memoryTurnSpoolTimer&&(clearTimeout(this.memoryTurnSpoolTimer),this.memoryTurnSpoolTimer=null),this.userPromptSubmitSpoolTimer&&(clearTimeout(this.userPromptSubmitSpoolTimer),this.userPromptSubmitSpoolTimer=null),this.sessionFinalizeSpoolTimer&&(clearTimeout(this.sessionFinalizeSpoolTimer),this.sessionFinalizeSpoolTimer=null),await this.flushTelemetry(),await this.closeServer(),this.cleanupOwnedResources(),await this.serverManager.stop(),await this.explicitIntentFlush,this.explicitMemoryGate?.close(),this.explicitMemoryGate=null,this.telemetry.close(),process.exit(0);}closeServer(){let t=this.server;return !t||!t.listening||!this.pathMatchesIdentity(this.socketPath,this.socketIdentity)?Promise.resolve():(this.server=null,new Promise(n=>{let o=false,r=()=>{o||(o=true,clearTimeout(i),n());},i=setTimeout(r,Sm);t.close(r);}))}cleanupOwnedResources(){try{vo(this.projectRoot,process.pid);}catch(t){this.logRuntime("warn","daemon_unregister",{reason:t.message});}this.removePathIfOwned(this.socketPath,this.socketIdentity,"socket"),this.removePathIfOwned(this.pidPath,this.pidIdentity,"PID file",`${process.pid}
|
|
44
|
+
`);}};function Mm(e){if(e)try{let t=JSON.parse(e);return typeof t.session_id=="string"&&t.session_id.trim()?t.session_id.trim():void 0}catch{return}}function Om(e){try{return execFileSync("git",["rev-parse","HEAD"],{cwd:e,encoding:"utf8",timeout:2e3,stdio:["ignore","pipe","ignore"]}).trim()}catch{return `unversioned:${createHash("sha256").update(e).digest("hex").slice(0,16)}`}}if(process.env.DEVFLOW_HOOK_DAEMON_DISABLE_AUTOSTART!=="1"){let e=process.argv[2]||process.env.CLAUDE_PROJECT_DIR||process.cwd(),t=new En(e,process.argv[3]);process.once("SIGTERM",()=>{t.shutdown();}),process.once("SIGINT",()=>{t.shutdown();}),t.start().catch(n=>{console.error("[devflow-daemon] Failed to start:",n),process.exit(1);});}export{En as HookDaemon,Cm as injectProjectRootIfMissing};
|