@devflow-tools/devflow 0.18.48 → 0.18.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dashboard/404.html +1 -1
- package/dist/dashboard/__next.__PAGE__.txt +1 -1
- package/dist/dashboard/__next._full.txt +1 -1
- package/dist/dashboard/__next._tree.txt +1 -1
- package/dist/dashboard/_not-found/__next._full.txt +1 -1
- package/dist/dashboard/_not-found/__next._not-found.__PAGE__.txt +1 -1
- package/dist/dashboard/_not-found/__next._tree.txt +1 -1
- package/dist/dashboard/_not-found.html +1 -1
- package/dist/dashboard/_not-found.txt +1 -1
- package/dist/dashboard/accuracy/__next._full.txt +1 -1
- package/dist/dashboard/accuracy/__next._tree.txt +1 -1
- package/dist/dashboard/accuracy/__next.accuracy.__PAGE__.txt +1 -1
- package/dist/dashboard/accuracy.html +1 -1
- package/dist/dashboard/accuracy.txt +1 -1
- package/dist/dashboard/benchmark/__next._full.txt +1 -1
- package/dist/dashboard/benchmark/__next._tree.txt +1 -1
- package/dist/dashboard/benchmark/__next.benchmark.__PAGE__.txt +1 -1
- package/dist/dashboard/benchmark.html +1 -1
- package/dist/dashboard/benchmark.txt +1 -1
- package/dist/dashboard/context/__next._full.txt +1 -1
- package/dist/dashboard/context/__next._tree.txt +1 -1
- package/dist/dashboard/context/__next.context.__PAGE__.txt +1 -1
- package/dist/dashboard/context.html +1 -1
- package/dist/dashboard/context.txt +1 -1
- package/dist/dashboard/doctor/__next._full.txt +1 -1
- package/dist/dashboard/doctor/__next._tree.txt +1 -1
- package/dist/dashboard/doctor/__next.doctor.__PAGE__.txt +1 -1
- package/dist/dashboard/doctor.html +1 -1
- package/dist/dashboard/doctor.txt +1 -1
- package/dist/dashboard/executions/__next._full.txt +1 -1
- package/dist/dashboard/executions/__next._tree.txt +1 -1
- package/dist/dashboard/executions/__next.executions.__PAGE__.txt +1 -1
- package/dist/dashboard/executions.html +1 -1
- package/dist/dashboard/executions.txt +1 -1
- package/dist/dashboard/graph/__next._full.txt +1 -1
- package/dist/dashboard/graph/__next._tree.txt +1 -1
- package/dist/dashboard/graph/__next.graph.__PAGE__.txt +1 -1
- package/dist/dashboard/graph.html +1 -1
- package/dist/dashboard/graph.txt +1 -1
- package/dist/dashboard/index.html +1 -1
- package/dist/dashboard/index.txt +1 -1
- package/dist/dashboard/intelligence/__next._full.txt +1 -1
- package/dist/dashboard/intelligence/__next._tree.txt +1 -1
- package/dist/dashboard/intelligence/__next.intelligence.__PAGE__.txt +1 -1
- package/dist/dashboard/intelligence/knowledge/__next._full.txt +1 -1
- package/dist/dashboard/intelligence/knowledge/__next._tree.txt +1 -1
- package/dist/dashboard/intelligence/knowledge/__next.intelligence.knowledge.__PAGE__.txt +1 -1
- package/dist/dashboard/intelligence/knowledge.html +1 -1
- package/dist/dashboard/intelligence/knowledge.txt +1 -1
- package/dist/dashboard/intelligence/memory/__next._full.txt +1 -1
- package/dist/dashboard/intelligence/memory/__next._tree.txt +1 -1
- package/dist/dashboard/intelligence/memory/__next.intelligence.memory.__PAGE__.txt +1 -1
- package/dist/dashboard/intelligence/memory.html +1 -1
- package/dist/dashboard/intelligence/memory.txt +1 -1
- package/dist/dashboard/intelligence.html +1 -1
- package/dist/dashboard/intelligence.txt +1 -1
- package/dist/dashboard/knowledge/__next._full.txt +1 -1
- package/dist/dashboard/knowledge/__next._tree.txt +1 -1
- package/dist/dashboard/knowledge/__next.knowledge.__PAGE__.txt +1 -1
- package/dist/dashboard/knowledge.html +1 -1
- package/dist/dashboard/knowledge.txt +1 -1
- package/dist/dashboard/memory/__next._full.txt +1 -1
- package/dist/dashboard/memory/__next._tree.txt +1 -1
- package/dist/dashboard/memory/__next.memory.__PAGE__.txt +1 -1
- package/dist/dashboard/memory.html +1 -1
- package/dist/dashboard/memory.txt +1 -1
- package/dist/dashboard/replay/__next._full.txt +1 -1
- package/dist/dashboard/replay/__next._tree.txt +1 -1
- package/dist/dashboard/replay/__next.replay.__PAGE__.txt +1 -1
- package/dist/dashboard/replay.html +1 -1
- package/dist/dashboard/replay.txt +1 -1
- package/dist/dashboard/runs/_/__next._full.txt +1 -1
- package/dist/dashboard/runs/_/__next._tree.txt +1 -1
- package/dist/dashboard/runs/_/__next.runs.$d$id.__PAGE__.txt +1 -1
- package/dist/dashboard/runs/_.html +1 -1
- package/dist/dashboard/runs/_.txt +1 -1
- package/dist/dashboard/runs/__next._full.txt +1 -1
- package/dist/dashboard/runs/__next._tree.txt +1 -1
- package/dist/dashboard/runs/__next.runs.__PAGE__.txt +1 -1
- package/dist/dashboard/runs.html +1 -1
- package/dist/dashboard/runs.txt +1 -1
- package/dist/dashboard/settings/__next._full.txt +1 -1
- package/dist/dashboard/settings/__next._tree.txt +1 -1
- package/dist/dashboard/settings/__next.settings.__PAGE__.txt +1 -1
- package/dist/dashboard/settings.html +1 -1
- package/dist/dashboard/settings.txt +1 -1
- package/dist/dashboard/timeline/__next._full.txt +1 -1
- package/dist/dashboard/timeline/__next._tree.txt +1 -1
- package/dist/dashboard/timeline/__next.timeline.__PAGE__.txt +1 -1
- package/dist/dashboard/timeline.html +1 -1
- package/dist/dashboard/timeline.txt +1 -1
- package/dist/dashboard/tool-metrics/__next._full.txt +1 -1
- package/dist/dashboard/tool-metrics/__next._tree.txt +1 -1
- package/dist/dashboard/tool-metrics/__next.tool-metrics.__PAGE__.txt +1 -1
- package/dist/dashboard/tool-metrics.html +1 -1
- package/dist/dashboard/tool-metrics.txt +1 -1
- package/dist/dashboard/workflows/__next._full.txt +1 -1
- package/dist/dashboard/workflows/__next._tree.txt +1 -1
- package/dist/dashboard/workflows/__next.workflows.__PAGE__.txt +1 -1
- package/dist/dashboard/workflows.html +1 -1
- package/dist/dashboard/workflows.txt +1 -1
- package/dist/hooks/hook-daemon.js +11 -11
- package/dist/hooks/post-tool-use.js +1 -1
- package/dist/hooks/pre-tool-use.js +4 -4
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/dist/command-registry.json +7 -7
- package/dist/plugin/dist/hooks/hook-daemon.js +11 -11
- package/dist/plugin/dist/hooks/post-tool-use.js +1 -1
- package/dist/plugin/dist/hooks/pre-tool-use.js +4 -4
- package/dist/plugin/dist/runtime-manifest.json +6 -6
- package/dist/plugin/package.json +13 -13
- package/dist/plugin/skills/approve/SKILL.md +5 -1
- package/dist/plugin/skills/delivery/SKILL.md +1 -1
- package/package.json +16 -16
- package/plugin-registry.json +29 -29
- /package/dist/dashboard/_next/static/{ZQu0DWZ2YOUuQE-PH4-Us → 9p_avpwLXbpXr8IExZT0t}/_buildManifest.js +0 -0
- /package/dist/dashboard/_next/static/{ZQu0DWZ2YOUuQE-PH4-Us → 9p_avpwLXbpXr8IExZT0t}/_ssgManifest.js +0 -0
|
@@ -3,6 +3,6 @@ import {existsSync,readFileSync,rmSync,mkdirSync,writeFileSync,linkSync,readdirS
|
|
|
3
3
|
|
|
4
4
|
`)}function W(n,t=0){if(t>6||n==null)return [];if(typeof n=="string")try{return W(JSON.parse(n),t+1)}catch{return []}if(Array.isArray(n)){for(let o of n){let r=W(o,t+1);if(r.length>0)return r}return []}if(typeof n!="object")return [];let e=n;if(Array.isArray(e.detectorCoverage))return e.detectorCoverage.filter(o=>typeof o=="string").slice(0,32);for(let o of Object.values(e)){let r=W(o,t+1);if(r.length>0)return r}return []}function L(n,t,e){if(t>gn||n===null||n===void 0)return null;if(typeof n=="string"){if(Buffer.byteLength(n,"utf8")>fn)return null;try{return L(JSON.parse(n),t+1,e)}catch{return null}}if(typeof n!="object"||e.has(n))return null;if(e.add(n),Array.isArray(n)){for(let r of n.slice(0,16)){let i=L(r,t+1,e);if(i)return i}return null}let o=n;if("evidenceContract"in o)return {contract:o.evidenceContract,canonicalReport:o.canonicalReport};for(let r of ["structuredContent","data","result"])if(r in o){let i=L(o[r],t+1,e);if(i)return i}if(Array.isArray(o.content))for(let r of o.content.slice(0,16)){let i=r&&typeof r=="object"&&"text"in r?r.text:r,s=L(i,t+1,e);if(s)return s}return null}function vn(n,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let e=n;if(e.version!=="1.0"||typeof e.id!="string"||!/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(e.id)||typeof e.runtimeProfilingOccurred!="boolean"||typeof e.samplingEvidenceOccurred!="boolean"||!Array.isArray(e.requiredSections)||e.requiredSections.length!==J.length)return null;let o=e.requiredSections.filter(c=>typeof c=="string");if(o.length!==J.length||J.some((c,l)=>o[l]!==c)||!Array.isArray(e.prohibitedClaims)||e.prohibitedClaims.length>16)return null;let r=e.prohibitedClaims.filter(c=>typeof c=="string"&&c.length<=128);if(r.length!==e.prohibitedClaims.length)return null;let i=e.correctionPolicy;if(!i||typeof i!="object"||Array.isArray(i))return null;let s=i;if(s.maxAttempts!==1||s.repeatedViolation!=="fail_open")return null;let a=typeof e.canonicalReport=="string"?e.canonicalReport:t;return typeof a!="string"||Buffer.byteLength(a,"utf8")>pn||J.some(c=>!a.includes(c))?null:{version:"1.0",id:e.id,runtimeProfilingOccurred:e.runtimeProfilingOccurred,samplingEvidenceOccurred:e.samplingEvidenceOccurred,requiredSections:o,prohibitedClaims:r,correctionPolicy:{maxAttempts:1,repeatedViolation:"fail_open"},canonicalReport:a}}function Ve(n){let t;try{if(En(n.toolResponse))return null;t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let e=t.getActiveContextReceipt(n.projectRoot,n.sessionId,n.executionId);if(!e)return null;let o=Rn(n.toolInput);if(o.length===0)return null;let r=n.toolName==="Read"?xn(n.toolInput):void 0,i=r?e.selectedFiles?.find(d=>kn(n.projectRoot,d,r)):void 0,s=Sn(n.toolName),a=i?"code":e.canonicalNextAction===s?"action":null,c=i&&o.includes(i)?i:a==="action"&&o.includes(s)?s:void 0;if(a&&c){let d=[e.contextHash,e.requestId??"",a,c,n.toolUseId??`${n.sessionId}:${n.executionId??e.executionId}`].join("\0");t.recordContextSelectionEvent({id:`ctxsel:${createHash$1("sha256").update(d).digest("hex").slice(0,32)}`,projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:e.executionId,requestId:e.requestId,selectionType:a,candidateId:c,toolName:n.toolName,toolUseId:n.toolUseId,selectedAt:Date.now()});}let l=t.listRetrievalLedgerEvents({projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:e.executionId,requestId:e.requestId}).filter(d=>d.stage==="selected"&&o.includes(d.sourceId));for(let d of l)t.appendRetrievalLedgerEvent({...d,id:retrievalLedgerTransitionId(d.id,"consumed",n.toolUseId??n.toolName),stage:"consumed",toolEvidence:[n.toolUseId??n.toolName],evidenceIds:o,actor:n.toolName,reasonCode:"structural_evidence_ref",payload:{...d.payload,consumedByTool:n.toolName},createdAt:Date.now()});return l.length>0&&He({event:"retrieval.attribution.transitioned",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:e.executionId,requestId:e.requestId,contextReceipt:e.contextHash},level:"info",timestamp:Date.now(),data:{stage:"consumed",actor:n.toolName,consumedCount:l.length,evidenceRefCount:o.length}}),a}catch(e){throw He({event:"hook.runtime.degraded",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:n.executionId,requestId:n.requestId},level:"warn",timestamp:Date.now(),data:{stage:"retrieval_attribution",actor:n.toolName,reason:e instanceof Error?e.message:String(e)}}),e}finally{try{t?.close();}catch{}}}function Rn(...n){let t=new Set,e=(o,r=0)=>{if(!(r>6||o==null)){if(typeof o=="string"){try{e(JSON.parse(o),r+1);}catch{}return}if(Array.isArray(o)){for(let i of o)e(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 e(s,r+1);}};for(let o of n)e(o);return [...t]}function xn(n){for(let t of ["file_path","path"]){let e=n[t];if(typeof e=="string"&&e.trim())return e.trim()}}function kn(n,t,e){let o=resolve(n,t),r=isAbsolute(e)?resolve(e):resolve(n,e);return o===r}function Sn(n){return n.startsWith("mcp__")?n.split("__").at(-1)??n:n}function En(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let t=n;return t.ok===false||t.success===false||t.isError===true||!!t.error||["failed","rejected","unavailable"].includes(String(t.status??""))}function He(n){try{h(n);}catch{}}var Cn=new Set(["Write","Edit","NotebookEdit"]);function ze(n){if(!Cn.has(n.toolName)||Pn(n.toolResponse))return null;let t=Fn(n.projectRoot,n.toolInput);if(!t)return null;let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let o=e.getActiveContextReceipt(n.projectRoot,n.sessionId,n.executionId),r=o?.canonicalAction?.verificationPlan??[];if(!o||r.length===0)return null;let i=[],s=[];for(let c of r){let l=jn({projectRoot:n.projectRoot,targetFile:t,kind:c.kind,mode:c.mode==="write"?"write":"check",required:c.required===!0,contextReceipt:o.contextHash}),d=`${o.contextHash}\0${n.toolUseId??t}\0${c.kind}\0${t}`,u=`policy-verification:${createHash$1("sha256").update(d).digest("hex")}`,p=Date.now();if(!l){let k=`verification_unavailable:${c.kind}`;e.upsertSessionObligation({obligationId:u,projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:n.executionId,kind:"evidence_contract",state:"degraded",payload:{subtype:"policy_verification",status:"unknown",verificationKind:c.kind,targetFile:t,contextReceipt:o.contextHash},reason:k,createdAt:p,updatedAt:p,resolvedAt:p}),s.push(c.kind),c.required===!0&&F({projectRoot:n.projectRoot,sessionId:n.sessionId,requestId:o.requestId,executionId:n.executionId,kind:"verification.failed",payload:{receiptId:u,reasonCode:k},dedupeKey:`${u}:unavailable`,producer:"devflow-verification-scheduler"});continue}let y={...l,obligationId:u,sessionId:n.sessionId,executionId:n.executionId,requestId:o.requestId};e.upsertSessionObligation({obligationId:u,projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:n.executionId,kind:"evidence_contract",state:"open",payload:{subtype:"policy_verification",status:"scheduled",verificationKind:c.kind,command:l.display,targetFile:t,contextReceipt:o.contextHash,required:c.required===!0},createdAt:p,updatedAt:p});let b=e.enqueueWork({idempotencyKey:u,kind:"verification.policy",projectRoot:n.projectRoot,sessionId:n.sessionId,payload:y,maxAttempts:2,nextAttemptAt:p});F({projectRoot:n.projectRoot,sessionId:n.sessionId,requestId:o.requestId,executionId:n.executionId,kind:"durable_work.owned",payload:{workId:b.id,obligation:"verification"},dedupeKey:`${b.id}:owned`,producer:"devflow-verification-scheduler"}),i.push(l.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(`
|
|
5
5
|
`)||null}finally{e.close();}}function jn(n){let t=qn(n.projectRoot),e=Ln(n.projectRoot),o=t?.scripts??{},r={...t?.dependencies,...t?.devDependencies},i=null;if(n.kind==="formatter"&&(r.prettier||Mn(n.projectRoot)))i=G(e,"prettier",[n.mode==="write"?"--write":"--check",n.targetFile],6e4);else if(n.kind==="typecheck"){let s=ue(o,["typecheck","type-check","check:types"]);s?i=le(e,s,12e4):r.typescript&&existsSync$1(join(n.projectRoot,"tsconfig.json"))&&(i=G(e,"tsc",["--noEmit","--pretty","false"],12e4));}else if(n.kind==="lint"){let s=ue(o,["lint"]);s&&(i=le(e,s,12e4));}else if(n.kind==="test"){let s=Nn(n.projectRoot,n.targetFile);s&&r.vitest?i=G(e,"vitest",["run",s],12e4):s&&(r.jest||r["@jest/core"])&&(i=G(e,"jest",["--runTestsByPath",s],12e4));}else if(n.kind==="build"){let s=ue(o,["build"]);s&&(i=le(e,s,18e4));}else n.kind==="generated_files"&&(i={command:"git",args:["diff","--check","--",n.targetFile],timeoutMs:3e4});return i?{kind:n.kind,...i,display:[i.command,...i.args].map(Un).join(" "),required:n.required,targetFile:n.targetFile,contextReceipt:n.contextReceipt}:null}function le(n,t,e){return n==="yarn"?{command:"yarn",args:["run",t],timeoutMs:e}:n==="pnpm"?{command:"pnpm",args:["run",t],timeoutMs:e}:n==="bun"?{command:"bun",args:["run",t],timeoutMs:e}:{command:"npm",args:["run",t],timeoutMs:e}}function G(n,t,e,o){return n==="pnpm"?{command:"pnpm",args:["exec",t,...e],timeoutMs:o}:n==="yarn"?{command:"yarn",args:[t,...e],timeoutMs:o}:n==="bun"?{command:"bunx",args:[t,...e],timeoutMs:o}:{command:"npx",args:["--no-install",t,...e],timeoutMs:o}}function Fn(n,t){let e=t.file_path??t.notebook_path;if(typeof e!="string"||!e.trim())return null;let o=isAbsolute(e)?resolve(e):resolve(n,e);return $n(n,o)?relative(n,o).split(sep).join("/"):null}function $n(n,t){let e=isAbsolute(t)?resolve(t):resolve(n,t),o=relative(resolve(n),e);return o!==""&&o!==".."&&!o.startsWith(`..${sep}`)&&!isAbsolute(o)}function Pn(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let t=n;return t.ok===false||t.success===false||t.isError===true||!!t.error}function qn(n){try{return JSON.parse(readFileSync$1(join(n,"package.json"),"utf8"))}catch{return null}}function Ln(n){return existsSync$1(join(n,"pnpm-lock.yaml"))?"pnpm":existsSync$1(join(n,"yarn.lock"))?"yarn":existsSync$1(join(n,"bun.lockb"))||existsSync$1(join(n,"bun.lock"))?"bun":"npm"}function Mn(n){return [".prettierrc",".prettierrc.json",".prettierrc.js",".prettierrc.cjs","prettier.config.js","prettier.config.cjs"].some(t=>existsSync$1(join(n,t)))}function ue(n,t){return t.find(e=>typeof n[e]=="string"&&n[e].trim())??null}function Nn(n,t){let e=t.replace(/\.[^.]+$/u,""),o=[".test.ts",".test.tsx",".spec.ts",".spec.tsx",".test.js",".spec.js"];for(let s of o){let a=`${e}${s}`;if(existsSync$1(join(n,a)))return a}let r=join(n,t.split("/").slice(0,-1).join("/")),i=t.split("/").at(-1)?.replace(/\.[^.]+$/u,"");if(!i||!existsSync$1(r))return null;try{return readdirSync$1(r).filter(s=>s.startsWith(`${i}.`)&&/\.(?:test|spec)\.[cm]?[jt]sx?$/u.test(s)).map(s=>relative(n,join(r,s)).split(sep).join("/"))[0]??null}catch{return null}}function Un(n){return /^[A-Za-z0-9_./:@=-]+$/u.test(n)?n:JSON.stringify(n)}function Je(n){if(!n.toolUseId)return null;let t=Xn(n.projectRoot,n.toolUseId);if(!t||t.sessionId!==n.sessionId)return null;let e=Date.now(),o={...t,id:createHash$1("sha256").update(`${t.sessionId}\0${t.toolUseId}\0${t.path}\0${e}`).digest("hex"),phase:"completed",success:n.success,after:Gn(t.path),completedAt:e,error:n.error?.slice(0,500)},r=Zn(n.projectRoot);return mkdirSync$1(dirname(r),{recursive:true}),appendFileSync(r,`${JSON.stringify(o)}
|
|
6
|
-
`,{encoding:"utf8",mode:384}),h({event:"canonical.action.validated",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:t.executionId,contextReceipt:t.contextReceipt},level:n.success?"info":"warn",timestamp:e,data:{stage:"host_file_state_completed",valid:n.success,operation:t.operation,targetPath:relative(n.projectRoot,t.path),beforeHash:t.before.hash,afterHash:o.after.hash,beforeExists:t.before.exists,afterExists:o.after.exists,reason:o.error,toolUseId:t.toolUseId}}),o}function Gn(n){if(!existsSync$1(n))return {exists:false};try{return {exists:!0,hash:createHash$1("sha256").update(readFileSync$1(n)).digest("hex")}}catch{return {exists:true}}}function We(n){return join(D(n),"file-state")}function Ge(n){return join(We(n),"pending.json")}function Zn(n){return join(We(n),"observations.jsonl")}function Qn(n){try{return JSON.parse(readFileSync$1(Ge(n),"utf8"))}catch{return {}}}function Xn(n,t){let e=Ge(n),o=Qn(n),r=o[t];if(r)return delete o[t],Yn(e,JSON.stringify(o)),r}function Yn(n,t){let e=`${n}.${process.pid}.${Date.now()}.tmp`;writeFileSync$1(e,t,{encoding:"utf8",mode:384}),renameSync$1(e,n);}var to={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 no(n){return oo(n)}function oo(n){let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let e=ao(t,n.artifact);if(co(e.toState))return e;let o=t.getContextReceiptForRequest(n.artifact.projectRoot,n.artifact.sessionId,n.artifact.requestId),r=t.getMemoryTurn(n.artifact.turnId),i=n.artifact.intent==="memory"||r?.source==="explicit_intent";if(!o&&!i)return e;let s=o?ro(n.artifact,o):"context_ready";e.toState==="intent_bound"&&(e=v(t,e,n,s,i?"task_context_not_required":s==="context_ready"?"canonical_context_receipt_ready":"canonical_context_receipt_degraded"));let a=o?io(n.artifact,o):"action_not_required";if((e.toState==="context_ready"||e.toState==="context_degraded")&&(a==="action_not_required"?e=v(t,e,n,"action_not_required","task_action_not_required"):e=v(t,e,n,"action_required","canonical_action_obligation_present")),e.toState==="action_required"){if(a==="action_required")return e;if(a==="action_failed")return v(t,e,n,"action_failed","canonical_action_attempt_failed");a==="action_degraded"?e=v(t,e,n,"action_degraded","canonical_action_unavailable_or_degraded"):a==="action_satisfied"&&(e=v(t,e,n,"action_satisfied","canonical_action_succeeded"));}if(e.toState==="action_failed")if(a==="action_satisfied")e=v(t,e,n,"action_satisfied","canonical_action_retry_succeeded");else if(a==="action_degraded")e=v(t,e,n,"action_degraded","canonical_action_retry_degraded");else return e;let c=s==="context_degraded"||a==="action_degraded";return ["action_not_required","action_satisfied","action_degraded"].includes(e.toState)&&(e=v(t,e,n,n.memoryStatus==="pending"?"memory_quarantined":"memory_decided",n.memoryStatus==="pending"?n.reason:`canonical_memory_${n.memoryStatus}`)),e.toState==="memory_decided"?v(t,e,n,c?"closed_with_degradation":"closed",n.reason):e.toState==="memory_quarantined"?v(t,e,n,n.retryOwned?"closed_with_retry_work":"closed_with_degradation",n.retryOwned?"durable_retry_owner_confirmed":"terminal_obligation_unowned"):e}finally{t.close();}}function Qe(n){let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let e=t.getActiveContextReceipt(n.projectRoot,n.sessionId,n.executionId),o=typeof e?.canonicalAction?.binding.turnId=="string"?e.canonicalAction.binding.turnId:void 0;if(!o)return null;let r=t.listLatestTaskIntentArtifacts(n.projectRoot,n.sessionId).find(s=>s.turnId===o),i=t.getMemoryTurn(o);return !r||!i?null:no({artifact:r,memoryStatus:i.status,memoryReceiptId:i.receiptId,reason:n.reason})}finally{t.close();}}function ro(n,t){return n.intent==="memory"||n.intent==="knowledge"||(t.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function io(n,t){let e=t.canonicalAction,r=(e?(t.actionAttempts??[]).filter(i=>i.tool===e.tool):[]).at(-1);return t.actionSatisfiedAt||r?.status==="succeeded"?"action_satisfied":r&&["failed","timeout","unavailable"].includes(r.status)?"action_failed":t.actionDegradation||e?.status==="degraded"||e?.status==="unsupported"?"action_degraded":e?.required||so(n)?"action_required":"action_not_required"}function so(n){return ["create","modify","debug","test","format"].includes(n.action)||["feature","refactor","performance"].includes(n.intent)}function ao(n,t){let e=n.getLatestTerminalTransition(t.projectRoot,t.sessionId,t.turnId);if(!e)throw new Error(`TERMINAL_INTENT_STATE_MISSING:${t.turnId}`);return e}function v(n,t,e,o,r){if(!to[t.toState]?.includes(o))throw new Error(`TERMINAL_PATH_UNAVAILABLE:${t.toState}->${o}`);let i=t.sequence+1,s=`terminal:${createHash$1("sha256").update(`${e.artifact.artifactHash}\0${i}\0${o}`).digest("hex").slice(0,24)}`,a=n.appendTerminalTransition({projectRoot:e.artifact.projectRoot,projectId:e.artifact.projectId,hostId:e.artifact.hostId,sessionId:e.artifact.sessionId,turnId:e.artifact.turnId,requestId:e.artifact.requestId,executionId:e.artifact.executionId,sequence:i,fromState:t.toState,toState:o,receiptId:s,sourceReceiptId:e.memoryReceiptId??t.receiptId,reason:r,payload:{memoryStatus:e.memoryStatus,retryOwned:e.retryOwned??false,sourceIntentHash:e.artifact.artifactHash},createdAt:Date.now()});return h({event:"terminal.state.transitioned",identity:{projectRoot:e.artifact.projectRoot,projectId:e.artifact.projectId,hostId:e.artifact.hostId,sessionId:e.artifact.sessionId,turnId:e.artifact.turnId,requestId:e.artifact.requestId,...e.artifact.executionId?{executionId:e.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 co(n){return n==="closed"||n==="closed_with_degradation"||n==="closed_with_retry_work"}function Xe(n){let t=n.hook==="post_tool_use_failure"||!!n.error?.trim()||lo(n.response),e=t?"not_consumed":n.hook==="post_tool_use"?"consumed":"unknown",o=t?uo(n.error,n.response):e==="consumed"?"host_reported_success":"host_outcome_unknown";return {schemaVersion:"host-tool-outcome.v1",toolName:n.toolName,...n.toolUseId?{toolUseId:n.toolUseId}:{},consumption:e,reasonCode:o,receiptId:n.toolUseId??`host-tool:${n.toolName}:${o}`}}function lo(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let t=n;return t.isError===true||t.error?true:typeof t.status=="string"&&["failed","error","rejected","timeout","unavailable"].includes(t.status.toLowerCase())}function uo(n,t){let e=`${n??""} ${JSON.stringify(t??"")}`;return /timeout|timed out|deadline/iu.test(e)?"host_tool_timeout":/unavailable|not found|not registered|unsupported/iu.test(e)?"host_tool_unavailable":"host_tool_failed"}function et(){return generateKeyPairSync("ed25519")}function tt(n){let t=parseTrustedDecisionCommand(n.rawUserEvent,n.allowedOptionIds),e=n.now??Date.now(),o={schemaVersion:"delivery-user-attestation.v1",issuer:n.issuer,keyId:n.keyId,purpose:t.purpose,decisionId:t.decisionId,caseId:n.caseId,caseVersion:n.caseVersion,sessionId:n.sessionId,sourceTurnId:n.sourceTurnId,actorId:n.actorId,targetDecisionHash:n.targetDecisionHash,rawUserEvent:n.rawUserEvent,rawUserEventHash:domainHash("raw-user-event",n.rawUserEvent),selectedValueHash:domainHash("decision-value",{decisionId:t.decisionId,purpose:t.purpose,value:encodeDecisionValue(t.purpose,t.value)}),eventSequence:n.eventSequence,issuedAt:new Date(e).toISOString(),expiresAt:new Date(e+6e4).toISOString(),nonce:n.nonce};return {...o,attestation:sign(null,canonicalJsonBytes(o),n.privateKey).toString("base64url")}}var nt=new Map,ot=new Map;function rt(n){if(typeof n=="string")return /\bDevFlow decision ([A-Za-z0-9._:-]+)/u.exec(x(n))?.[1]}function x(n){return n.replace(/[\u0000-\u001f\u007f\ufffd]+/gu,"").replace(/\s+/gu," ").trim()}function Io(n){if(typeof n=="string")return n.trim()||void 0;if(!n||typeof n!="object"||Array.isArray(n))return;let t=n.answers;if(!t||typeof t!="object"||Array.isArray(t))return;let e=Object.values(t);if(e.length!==1)return;let o=e[0];if(!(Array.isArray(o)||typeof o!="string"))return o.trim()||void 0}async function it(n){if(n.toolName!=="AskUserQuestion")return {handled:false};let t=n.toolInput&&typeof n.toolInput=="object"&&!Array.isArray(n.toolInput)?n.toolInput:{};if(!Array.isArray(t.questions)||t.questions.length!==1)return {handled:false};let e=t.questions[0],o=rt(e.header)??rt(e.question);if(!o)return {handled:false};let r=o.split(/:(?:decision|question|approval):/u)[0],i=wo(n.projectRoot),s=await i.pendingDecision(r);if(!s||s.id!==o)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: no pending decision matches ${o}. Refresh delivery_status.`};let a=Array.isArray(e.options)?e.options.map(m=>({label:typeof m.label=="string"?x(m.label):"",description:typeof m.description=="string"?x(m.description):""})):[],c=createHash$1("sha256").update(JSON.stringify({decisionId:o,question:x(String(e.question??"")),options:a})).digest("hex"),l=`${n.sessionId}:${o}`,d=ot.get(l);if(d&&d.hash===c&&d.sourceTurnId===(n.sourceTurnId??n.toolUseId))return {handled:true,resolved:false,message:`DevFlow interactive decision ${o} was already presented in this host turn. Reuse the existing answer or refresh delivery_status after resolution.`};ot.set(l,{hash:c,sourceTurnId:n.sourceTurnId??n.toolUseId,count:(d?.count??0)+1});let u=Io(n.toolResponse),p=u?x(u):void 0;if(!p)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: AskUserQuestion returned no single answer for ${o}. Use /devflow:decide ${o} -- <answer> if this is a free-form clarification.`};if(e.multiSelect===true)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: ${o} must be a single selection.`};let y;if(s.options.length>0){let m=s.options.map(w=>({label:x(w.label),description:w.description?x(w.description):""}));if(a.length!==m.length||a.some((w,P)=>w.label!==m[P]?.label||w.description!==m[P]?.description))return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: the displayed options do not match the pending decision ${o}. Refresh delivery_status and render its options verbatim.`};let S=s.options.find(w=>x(w.label)===p);if(!S)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: answer does not match a pending option for ${o}.`};s.kind==="artifact_approval"?y=S.id==="approve"?`/devflow:approve ${o}`:`/devflow:reject ${o} -- ${p}`:y=`/devflow:decide ${o} ${S.id}`;}else {if(a.length>0)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: ${o} is a free-form clarification and must not be rendered as a choice list.`};y=`/devflow:decide ${o} -- ${p}`;}let b=process.env.DEVFLOW_HOST_ACTOR_ID?.trim()||`user:${process.env.USER?.trim()||"local"}`,k=et(),$=tt({rawUserEvent:y,issuer:"claude-code",keyId:"session-ephemeral",caseId:r,caseVersion:s.caseVersion,sessionId:n.sessionId,sourceTurnId:n.sourceTurnId?.trim()||n.toolUseId?.trim()||`host-turn:${n.sessionId}:${Date.now()}`,actorId:b,targetDecisionHash:s.targetDecisionHash,eventSequence:Date.now(),nonce:randomUUID$1(),privateKey:k.privateKey,allowedOptionIds:s.options.map(m=>m.id)});try{return await i.resolveTrustedDecision({evidence:$,publicKey:k.publicKey,expectedIssuer:"claude-code",expectedKeyId:"session-ephemeral"}),{handled:!0,resolved:!0,message:`DevFlow interactive decision resolved for ${r}. Refresh delivery_status and follow nextActions.`}}catch(m){return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: ${m instanceof Error?m.message:String(m)}`}}}function wo(n){let t=nt.get(n);if(t)return t;let e=createTrustedDeliveryFacade(n);return nt.set(n,e),e}function st(n){if(!n)return;let t=typeof n.status=="string"?n.status:void 0;if(!(n.ok===false||n.success===false||n.isError===true||t==="failed"||t==="rejected"||!!n.error))return;let o=n.error;if(typeof o=="string"&&o.trim())return o;if(o&&typeof o=="object"){let r=o;if(typeof r.message=="string"&&r.message.trim())return r.message;if(typeof r.code=="string"&&r.code.trim())return r.code}return t?`Tool response status: ${t}`:"Tool response reported failure"}function To(n,t,e,o){try{let r=join$1(D(n),"event-map.json");if(!existsSync(r))return null;let i=JSON.parse(readFileSync(r,"utf-8")),s=i.filter(l=>l.toolName===e&&(!l.sessionId||l.sessionId===t));if(s.length===0)return null;let a=o?s.find(l=>l.toolUseId===o):s.sort((l,d)=>l.timestamp-d.timestamp)[0];if(!a)return null;let c=i.findIndex(l=>l.eventId===a.eventId);return c!==-1&&i.splice(c,1),writeFileSync(r,JSON.stringify(i)),{eventId:a.eventId,timestamp:a.timestamp}}catch{return null}}function at(n){if(!n)return 0;let t=n;if(typeof n=="string")try{t=JSON.parse(n);}catch{return 1}let e=t,o=["files","results","data","result","memories","nodes","chunks","findings","symbols","keySymbols"],r=["reasoning","riskHints","nextActions"],i=Array.isArray(e.data)?e.data:e.structuredContent??e;if(Array.isArray(i))return i.length;if(typeof i=="object"&&i!==null){let s=i,a=0,c=false;for(let d of o)Array.isArray(s[d])&&(c=true,a+=s[d].length);for(let d of r)Array.isArray(s[d])&&(a+=s[d].length);for(let[,d]of Object.entries(s))d&&typeof d=="object"&&!Array.isArray(d)&&(a+=at(d));let l=!!(s._devflow||s._devflow_unique||s.taskType);return a===0&&l&&!c?1:a>0?a:c?0:Object.keys(s).length>0?1:0}return 0}async function Oo(n){if(!n)return null;let t;try{t=JSON.parse(n);}catch{return null}let e=t.tool_name||"",o=te(),r=t.tool_input||{},i=t.tool_response||{},s=t.session_id?.trim()||null,a=new T(o);if(s&&a.registerSession(s),s){let f=await it({projectRoot:o,sessionId:s,sourceTurnId:a.get(s)?.activeTurnId,toolName:e,toolInput:r,toolResponse:i,toolUseId:t.tool_use_id});if(f.handled)return f.message}let c=resolveClaudeToolName(e,r),l=c.status==="unsupported"?void 0:c.canonicalName;if(s&&l==="get_project_context"&&a.completeContextInitialization(s,t.tool_use_id),e==="Skill"){let f=typeof r=="object"&&r.skill?r.skill:"",g=Le(f);s&&g&&(a.startExecution(s,g,qe(g)),se(o,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0}));}let d=s?a.get(s):null;if(e.startsWith("mcp__")){let f=new H(o,s??void 0,d?.executionId??s??void 0);f.recordMcpCall();let g=st(typeof i=="object"&&i!==null?i:null),_=l??e,X=f.getContextReceipt?.()?.canonicalAction?.tool===_;if((f.recordDomainActionOutcome(_,g?Co(g):"succeeded",g,t.tool_use_id)||X)&&s){let O=Xe({hook:"post_tool_use",toolName:_,...t.tool_use_id?{toolUseId:t.tool_use_id}:{},response:i,...g?{error:g}:{}});F({projectRoot:o,sessionId:s,executionId:d?.executionId??s,kind:O.consumption==="consumed"?"action.succeeded":"action.failed",payload:{receiptId:O.receiptId,reasonCode:O.reasonCode,consumption:O.consumption,tool:_},dedupeKey:`${O.receiptId}:${O.consumption}`,producer:"devflow-post-tool-use"});try{Qe({projectRoot:o,sessionId:s,executionId:d?.executionId??s,reason:g?"post_tool_action_failed":"post_tool_action_succeeded"});}catch{}}}s&&Ve({projectRoot:o,sessionId:s,executionId:d?.executionId,toolName:e,toolInput:r,toolResponse:i,toolUseId:t.tool_use_id});let u=s?To(o,s,e,t.tool_use_id):null,p=s&&t.tool_use_id&&!u?(()=>{try{let f=openGlobalDevFlowDatabase();try{return f.getToolCallEventByToolUseId(s,t.tool_use_id)}finally{f.close();}}catch{return null}})():null,y=u??p,b=typeof i=="object"&&i!==null?i:null,k=JSON.stringify(i),$=Buffer.byteLength(k,"utf8"),m=at(i),S=st(b);if(s&&Je({projectRoot:o,sessionId:s,toolUseId:t.tool_use_id,success:!S,error:S}),d?.executionId!==void 0||l!==void 0||e==="Skill"){let f=getLogWriter(o),g=d?.executionId??`auto-${s??Date.now()}`;f.toolCall({tool:e,runId:g,stepId:`step-${g}`,input:r,output:i,duration:y?Math.max(0,Date.now()-y.timestamp):0,success:!b?.error,resultCount:m,resultSizeBytes:$,error:b?.error});}if(y&&s){let f=typeof i=="string"?i:JSON.stringify(i),g=f.length>5e3?{_truncated:true,_originalSize:f.length,text:f.slice(0,5e3)}:i,_=S,X=_?classifyWorkflowFailure({stepId:e,toolName:e,output:i,error:new Error(_),errorStack:_}).category:void 0;await new B().completeEvent({eventId:y.eventId,sessionId:s,output:g,error:_,failureCategory:X,duration:y?Math.max(0,Date.now()-y.timestamp):0,completedAt:Date.now()});}let P=typeof r=="object"&&r.command?r.command:"",Z=b?.exitCode,ct=b?.stderr,dt=/^\s*(ls|cat|pwd|cd|echo|head|tail|wc|which|whoami|date|env|printenv|id|hostname|uname)\b/,E,A,Q=true;if(e.startsWith("mcp__"))E="mcp_call",A={mcpTool:l??e,query:typeof r=="object"&&r.query?r.query:null,resultCount:m,resultSizeBytes:$};else if(e==="Read"||e==="Write"||e==="Edit")E=e==="Read"?"file_read":"file_write",A={filePath:typeof r=="object"&&r.file_path?r.file_path:null,fileContentSize:$};else if(e==="Bash"){let f=dt.test(P),g=Z!==void 0&&Z!==0;Q=!f||g,E=g?"bash_error":"bash_command",A={command:P||e,exitCode:Z??null,stderr:ct??null};}else e==="Agent"?(E="subagent",A={subagentType:typeof r=="object"&&r.subagent_type?r.subagent_type:null,description:typeof r=="object"&&r.description?String(r.description).slice(0,200):null}):e==="WebSearch"||e==="WebFetch"?(E=e==="WebSearch"?"web_search":"web_fetch",A={query:typeof r=="object"&&r.query?String(r.query).slice(0,200):null}):(Q=false,E="tool_use",A={});if(Q){let f={id:t.tool_use_id?`memory:${Me(s??"",t.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:s??"",tool:e,kind:E,payload:{...A,durationMs:y?Math.max(0,Date.now()-y.timestamp):0},createdAt:Date.now()};s&&N(`/api/memory/session-events?rootPath=${encodeURIComponent(o)}`,f);}let lt=Ue({toolName:e,toolResponse:i,sessionId:s,toolUseId:t.tool_use_id,runtimeStore:a}),ut=s?ze({projectRoot:o,sessionId:s,executionId:d?.executionId,toolName:e,toolInput:r,toolResponse:i,toolUseId:t.tool_use_id}):null;return [lt,ut].filter(f=>!!f).join(`
|
|
6
|
+
`,{encoding:"utf8",mode:384}),h({event:"canonical.action.validated",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:t.executionId,contextReceipt:t.contextReceipt},level:n.success?"info":"warn",timestamp:e,data:{stage:"host_file_state_completed",valid:n.success,operation:t.operation,targetPath:relative(n.projectRoot,t.path),beforeHash:t.before.hash,afterHash:o.after.hash,beforeExists:t.before.exists,afterExists:o.after.exists,reason:o.error,toolUseId:t.toolUseId}}),o}function Gn(n){if(!existsSync$1(n))return {exists:false};try{return {exists:!0,hash:createHash$1("sha256").update(readFileSync$1(n)).digest("hex")}}catch{return {exists:true}}}function We(n){return join(D(n),"file-state")}function Ge(n){return join(We(n),"pending.json")}function Zn(n){return join(We(n),"observations.jsonl")}function Qn(n){try{return JSON.parse(readFileSync$1(Ge(n),"utf8"))}catch{return {}}}function Xn(n,t){let e=Ge(n),o=Qn(n),r=o[t];if(r)return delete o[t],Yn(e,JSON.stringify(o)),r}function Yn(n,t){let e=`${n}.${process.pid}.${Date.now()}.tmp`;writeFileSync$1(e,t,{encoding:"utf8",mode:384}),renameSync$1(e,n);}var to={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 no(n){return oo(n)}function oo(n){let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let e=ao(t,n.artifact);if(co(e.toState))return e;let o=t.getContextReceiptForRequest(n.artifact.projectRoot,n.artifact.sessionId,n.artifact.requestId),r=t.getMemoryTurn(n.artifact.turnId),i=n.artifact.intent==="memory"||r?.source==="explicit_intent";if(!o&&!i)return e;let s=o?ro(n.artifact,o):"context_ready";e.toState==="intent_bound"&&(e=v(t,e,n,s,i?"task_context_not_required":s==="context_ready"?"canonical_context_receipt_ready":"canonical_context_receipt_degraded"));let a=o?io(n.artifact,o):"action_not_required";if((e.toState==="context_ready"||e.toState==="context_degraded")&&(a==="action_not_required"?e=v(t,e,n,"action_not_required","task_action_not_required"):e=v(t,e,n,"action_required","canonical_action_obligation_present")),e.toState==="action_required"){if(a==="action_required")return e;if(a==="action_failed")return v(t,e,n,"action_failed","canonical_action_attempt_failed");a==="action_degraded"?e=v(t,e,n,"action_degraded","canonical_action_unavailable_or_degraded"):a==="action_satisfied"&&(e=v(t,e,n,"action_satisfied","canonical_action_succeeded"));}if(e.toState==="action_failed")if(a==="action_satisfied")e=v(t,e,n,"action_satisfied","canonical_action_retry_succeeded");else if(a==="action_degraded")e=v(t,e,n,"action_degraded","canonical_action_retry_degraded");else return e;let c=s==="context_degraded"||a==="action_degraded";return ["action_not_required","action_satisfied","action_degraded"].includes(e.toState)&&(e=v(t,e,n,n.memoryStatus==="pending"?"memory_quarantined":"memory_decided",n.memoryStatus==="pending"?n.reason:`canonical_memory_${n.memoryStatus}`)),e.toState==="memory_decided"?v(t,e,n,c?"closed_with_degradation":"closed",n.reason):e.toState==="memory_quarantined"?v(t,e,n,n.retryOwned?"closed_with_retry_work":"closed_with_degradation",n.retryOwned?"durable_retry_owner_confirmed":"terminal_obligation_unowned"):e}finally{t.close();}}function Qe(n){let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let e=t.getActiveContextReceipt(n.projectRoot,n.sessionId,n.executionId),o=typeof e?.canonicalAction?.binding.turnId=="string"?e.canonicalAction.binding.turnId:void 0;if(!o)return null;let r=t.listLatestTaskIntentArtifacts(n.projectRoot,n.sessionId).find(s=>s.turnId===o),i=t.getMemoryTurn(o);return !r||!i?null:no({artifact:r,memoryStatus:i.status,memoryReceiptId:i.receiptId,reason:n.reason})}finally{t.close();}}function ro(n,t){return n.intent==="memory"||n.intent==="knowledge"||(t.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function io(n,t){let e=t.canonicalAction,r=(e?(t.actionAttempts??[]).filter(i=>i.tool===e.tool):[]).at(-1);return t.actionSatisfiedAt||r?.status==="succeeded"?"action_satisfied":r&&["failed","timeout","unavailable"].includes(r.status)?"action_failed":t.actionDegradation||e?.status==="degraded"||e?.status==="unsupported"?"action_degraded":e?.required||so(n)?"action_required":"action_not_required"}function so(n){return ["create","modify","debug","test","format"].includes(n.action)||["feature","refactor","performance"].includes(n.intent)}function ao(n,t){let e=n.getLatestTerminalTransition(t.projectRoot,t.sessionId,t.turnId);if(!e)throw new Error(`TERMINAL_INTENT_STATE_MISSING:${t.turnId}`);return e}function v(n,t,e,o,r){if(!to[t.toState]?.includes(o))throw new Error(`TERMINAL_PATH_UNAVAILABLE:${t.toState}->${o}`);let i=t.sequence+1,s=`terminal:${createHash$1("sha256").update(`${e.artifact.artifactHash}\0${i}\0${o}`).digest("hex").slice(0,24)}`,a=n.appendTerminalTransition({projectRoot:e.artifact.projectRoot,projectId:e.artifact.projectId,hostId:e.artifact.hostId,sessionId:e.artifact.sessionId,turnId:e.artifact.turnId,requestId:e.artifact.requestId,executionId:e.artifact.executionId,sequence:i,fromState:t.toState,toState:o,receiptId:s,sourceReceiptId:e.memoryReceiptId??t.receiptId,reason:r,payload:{memoryStatus:e.memoryStatus,retryOwned:e.retryOwned??false,sourceIntentHash:e.artifact.artifactHash},createdAt:Date.now()});return h({event:"terminal.state.transitioned",identity:{projectRoot:e.artifact.projectRoot,projectId:e.artifact.projectId,hostId:e.artifact.hostId,sessionId:e.artifact.sessionId,turnId:e.artifact.turnId,requestId:e.artifact.requestId,...e.artifact.executionId?{executionId:e.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 co(n){return n==="closed"||n==="closed_with_degradation"||n==="closed_with_retry_work"}function Xe(n){let t=n.hook==="post_tool_use_failure"||!!n.error?.trim()||lo(n.response),e=t?"not_consumed":n.hook==="post_tool_use"?"consumed":"unknown",o=t?uo(n.error,n.response):e==="consumed"?"host_reported_success":"host_outcome_unknown";return {schemaVersion:"host-tool-outcome.v1",toolName:n.toolName,...n.toolUseId?{toolUseId:n.toolUseId}:{},consumption:e,reasonCode:o,receiptId:n.toolUseId??`host-tool:${n.toolName}:${o}`}}function lo(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let t=n;return t.isError===true||t.error?true:typeof t.status=="string"&&["failed","error","rejected","timeout","unavailable"].includes(t.status.toLowerCase())}function uo(n,t){let e=`${n??""} ${JSON.stringify(t??"")}`;return /timeout|timed out|deadline/iu.test(e)?"host_tool_timeout":/unavailable|not found|not registered|unsupported/iu.test(e)?"host_tool_unavailable":"host_tool_failed"}function et(){return generateKeyPairSync("ed25519")}function tt(n){let t=parseTrustedDecisionCommand(n.rawUserEvent,n.allowedOptionIds),e=n.now??Date.now(),o={schemaVersion:"delivery-user-attestation.v1",issuer:n.issuer,keyId:n.keyId,purpose:t.purpose,decisionId:t.decisionId,caseId:n.caseId,caseVersion:n.caseVersion,sessionId:n.sessionId,sourceTurnId:n.sourceTurnId,actorId:n.actorId,targetDecisionHash:n.targetDecisionHash,rawUserEvent:n.rawUserEvent,rawUserEventHash:domainHash("raw-user-event",n.rawUserEvent),selectedValueHash:domainHash("decision-value",{decisionId:t.decisionId,purpose:t.purpose,value:encodeDecisionValue(t.purpose,t.value)}),eventSequence:n.eventSequence,issuedAt:new Date(e).toISOString(),expiresAt:new Date(e+6e4).toISOString(),nonce:n.nonce};return {...o,attestation:sign(null,canonicalJsonBytes(o),n.privateKey).toString("base64url")}}var nt=new Map,ot=new Map;function rt(n){if(typeof n=="string")return /\bDevFlow decision ([A-Za-z0-9._:-]+)/u.exec(x(n))?.[1]}function x(n){return n.replace(/[\u0000-\u001f\u007f\ufffd]+/gu,"").replace(/\s+/gu," ").trim()}function Io(n){if(typeof n=="string")return n.trim()||void 0;if(!n||typeof n!="object"||Array.isArray(n))return;let t=n.answers;if(!t||typeof t!="object"||Array.isArray(t))return;let e=Object.values(t);if(e.length!==1)return;let o=e[0];if(!(Array.isArray(o)||typeof o!="string"))return o.trim()||void 0}async function it(n){if(n.toolName!=="AskUserQuestion")return {handled:false};let t=n.toolInput&&typeof n.toolInput=="object"&&!Array.isArray(n.toolInput)?n.toolInput:{};if(!Array.isArray(t.questions)||t.questions.length!==1)return {handled:false};let e=t.questions[0],o=wo(n.projectRoot),r=rt(e.header)??rt(e.question);if(!r){let g=await o.pendingDecisionForSession(n.sessionId);if(!g||"ambiguous"in g||g.decision.kind!=="artifact_approval")return {handled:false};r=g.decision.id;}let i=r.split(/:(?:decision|question|approval):/u)[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(e.options)?e.options.map(g=>({label:typeof g.label=="string"?x(g.label):"",description:typeof g.description=="string"?x(g.description):""})):[],c=createHash$1("sha256").update(JSON.stringify({decisionId:r,question:x(String(e.question??"")),options:a})).digest("hex"),l=`${n.sessionId}:${r}`,d=ot.get(l);if(d&&d.hash===c&&d.sourceTurnId===(n.sourceTurnId??n.toolUseId))return {handled:true,resolved:false,message:`DevFlow interactive decision ${r} was already presented in this host turn. Reuse the existing answer or refresh delivery_status after resolution.`};ot.set(l,{hash:c,sourceTurnId:n.sourceTurnId??n.toolUseId,count:(d?.count??0)+1});let u=Io(n.toolResponse),p=u?x(u):void 0;if(!p)return {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.`};if(e.multiSelect===true)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: ${r} must be a single selection.`};let y;if(s.options.length>0){let g=s.options.map(w=>({label:x(w.label),description:w.description?x(w.description):""}));if(a.length!==g.length||a.some((w,P)=>w.label!==g[P]?.label||w.description!==g[P]?.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 S=s.options.find(w=>x(w.label)===p);if(!S)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: answer does not match a pending option for ${r}.`};s.kind==="artifact_approval"?y=S.id==="approve"?`/devflow:approve ${r}`:`/devflow:reject ${r} -- ${p}`:y=`/devflow:decide ${r} ${S.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.`};y=`/devflow:decide ${r} -- ${p}`;}let b=process.env.DEVFLOW_HOST_ACTOR_ID?.trim()||`user:${process.env.USER?.trim()||"local"}`,k=et(),$=tt({rawUserEvent:y,issuer:"claude-code",keyId:"session-ephemeral",caseId:i,caseVersion:s.caseVersion,sessionId:n.sessionId,sourceTurnId:n.sourceTurnId?.trim()||n.toolUseId?.trim()||`host-turn:${n.sessionId}:${Date.now()}`,actorId:b,targetDecisionHash:s.targetDecisionHash,eventSequence:Date.now(),nonce:randomUUID$1(),privateKey:k.privateKey,allowedOptionIds:s.options.map(g=>g.id)});try{return await o.resolveTrustedDecision({evidence:$,publicKey:k.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(g){return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: ${g instanceof Error?g.message:String(g)}`}}}function wo(n){let t=nt.get(n);if(t)return t;let e=createTrustedDeliveryFacade(n);return nt.set(n,e),e}function st(n){if(!n)return;let t=typeof n.status=="string"?n.status:void 0;if(!(n.ok===false||n.success===false||n.isError===true||t==="failed"||t==="rejected"||!!n.error))return;let o=n.error;if(typeof o=="string"&&o.trim())return o;if(o&&typeof o=="object"){let r=o;if(typeof r.message=="string"&&r.message.trim())return r.message;if(typeof r.code=="string"&&r.code.trim())return r.code}return t?`Tool response status: ${t}`:"Tool response reported failure"}function To(n,t,e,o){try{let r=join$1(D(n),"event-map.json");if(!existsSync(r))return null;let i=JSON.parse(readFileSync(r,"utf-8")),s=i.filter(l=>l.toolName===e&&(!l.sessionId||l.sessionId===t));if(s.length===0)return null;let a=o?s.find(l=>l.toolUseId===o):s.sort((l,d)=>l.timestamp-d.timestamp)[0];if(!a)return null;let c=i.findIndex(l=>l.eventId===a.eventId);return c!==-1&&i.splice(c,1),writeFileSync(r,JSON.stringify(i)),{eventId:a.eventId,timestamp:a.timestamp}}catch{return null}}function at(n){if(!n)return 0;let t=n;if(typeof n=="string")try{t=JSON.parse(n);}catch{return 1}let e=t,o=["files","results","data","result","memories","nodes","chunks","findings","symbols","keySymbols"],r=["reasoning","riskHints","nextActions"],i=Array.isArray(e.data)?e.data:e.structuredContent??e;if(Array.isArray(i))return i.length;if(typeof i=="object"&&i!==null){let s=i,a=0,c=false;for(let d of o)Array.isArray(s[d])&&(c=true,a+=s[d].length);for(let d of r)Array.isArray(s[d])&&(a+=s[d].length);for(let[,d]of Object.entries(s))d&&typeof d=="object"&&!Array.isArray(d)&&(a+=at(d));let l=!!(s._devflow||s._devflow_unique||s.taskType);return a===0&&l&&!c?1:a>0?a:c?0:Object.keys(s).length>0?1:0}return 0}async function Oo(n){if(!n)return null;let t;try{t=JSON.parse(n);}catch{return null}let e=t.tool_name||"",o=te(),r=t.tool_input||{},i=t.tool_response||{},s=t.session_id?.trim()||null,a=new T(o);if(s&&a.registerSession(s),s){let f=await it({projectRoot:o,sessionId:s,sourceTurnId:a.get(s)?.activeTurnId,toolName:e,toolInput:r,toolResponse:i,toolUseId:t.tool_use_id});if(f.handled)return f.message}let c=resolveClaudeToolName(e,r),l=c.status==="unsupported"?void 0:c.canonicalName;if(s&&l==="get_project_context"&&a.completeContextInitialization(s,t.tool_use_id),e==="Skill"){let f=typeof r=="object"&&r.skill?r.skill:"",m=Le(f);s&&m&&(a.startExecution(s,m,qe(m)),se(o,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0}));}let d=s?a.get(s):null;if(e.startsWith("mcp__")){let f=new H(o,s??void 0,d?.executionId??s??void 0);f.recordMcpCall();let m=st(typeof i=="object"&&i!==null?i:null),_=l??e,X=f.getContextReceipt?.()?.canonicalAction?.tool===_;if((f.recordDomainActionOutcome(_,m?Co(m):"succeeded",m,t.tool_use_id)||X)&&s){let O=Xe({hook:"post_tool_use",toolName:_,...t.tool_use_id?{toolUseId:t.tool_use_id}:{},response:i,...m?{error:m}:{}});F({projectRoot:o,sessionId:s,executionId:d?.executionId??s,kind:O.consumption==="consumed"?"action.succeeded":"action.failed",payload:{receiptId:O.receiptId,reasonCode:O.reasonCode,consumption:O.consumption,tool:_},dedupeKey:`${O.receiptId}:${O.consumption}`,producer:"devflow-post-tool-use"});try{Qe({projectRoot:o,sessionId:s,executionId:d?.executionId??s,reason:m?"post_tool_action_failed":"post_tool_action_succeeded"});}catch{}}}s&&Ve({projectRoot:o,sessionId:s,executionId:d?.executionId,toolName:e,toolInput:r,toolResponse:i,toolUseId:t.tool_use_id});let u=s?To(o,s,e,t.tool_use_id):null,p=s&&t.tool_use_id&&!u?(()=>{try{let f=openGlobalDevFlowDatabase();try{return f.getToolCallEventByToolUseId(s,t.tool_use_id)}finally{f.close();}}catch{return null}})():null,y=u??p,b=typeof i=="object"&&i!==null?i:null,k=JSON.stringify(i),$=Buffer.byteLength(k,"utf8"),g=at(i),S=st(b);if(s&&Je({projectRoot:o,sessionId:s,toolUseId:t.tool_use_id,success:!S,error:S}),d?.executionId!==void 0||l!==void 0||e==="Skill"){let f=getLogWriter(o),m=d?.executionId??`auto-${s??Date.now()}`;f.toolCall({tool:e,runId:m,stepId:`step-${m}`,input:r,output:i,duration:y?Math.max(0,Date.now()-y.timestamp):0,success:!b?.error,resultCount:g,resultSizeBytes:$,error:b?.error});}if(y&&s){let f=typeof i=="string"?i:JSON.stringify(i),m=f.length>5e3?{_truncated:true,_originalSize:f.length,text:f.slice(0,5e3)}:i,_=S,X=_?classifyWorkflowFailure({stepId:e,toolName:e,output:i,error:new Error(_),errorStack:_}).category:void 0;await new B().completeEvent({eventId:y.eventId,sessionId:s,output:m,error:_,failureCategory:X,duration:y?Math.max(0,Date.now()-y.timestamp):0,completedAt:Date.now()});}let P=typeof r=="object"&&r.command?r.command:"",Z=b?.exitCode,ct=b?.stderr,dt=/^\s*(ls|cat|pwd|cd|echo|head|tail|wc|which|whoami|date|env|printenv|id|hostname|uname)\b/,E,A,Q=true;if(e.startsWith("mcp__"))E="mcp_call",A={mcpTool:l??e,query:typeof r=="object"&&r.query?r.query:null,resultCount:g,resultSizeBytes:$};else if(e==="Read"||e==="Write"||e==="Edit")E=e==="Read"?"file_read":"file_write",A={filePath:typeof r=="object"&&r.file_path?r.file_path:null,fileContentSize:$};else if(e==="Bash"){let f=dt.test(P),m=Z!==void 0&&Z!==0;Q=!f||m,E=m?"bash_error":"bash_command",A={command:P||e,exitCode:Z??null,stderr:ct??null};}else e==="Agent"?(E="subagent",A={subagentType:typeof r=="object"&&r.subagent_type?r.subagent_type:null,description:typeof r=="object"&&r.description?String(r.description).slice(0,200):null}):e==="WebSearch"||e==="WebFetch"?(E=e==="WebSearch"?"web_search":"web_fetch",A={query:typeof r=="object"&&r.query?String(r.query).slice(0,200):null}):(Q=false,E="tool_use",A={});if(Q){let f={id:t.tool_use_id?`memory:${Me(s??"",t.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:s??"",tool:e,kind:E,payload:{...A,durationMs:y?Math.max(0,Date.now()-y.timestamp):0},createdAt:Date.now()};s&&N(`/api/memory/session-events?rootPath=${encodeURIComponent(o)}`,f);}let lt=Ue({toolName:e,toolResponse:i,sessionId:s,toolUseId:t.tool_use_id,runtimeStore:a}),ut=s?ze({projectRoot:o,sessionId:s,executionId:d?.executionId,toolName:e,toolInput:r,toolResponse:i,toolUseId:t.tool_use_id}):null;return [lt,ut].filter(f=>!!f).join(`
|
|
7
7
|
|
|
8
8
|
`)||null}function Co(n){return /timeout|timed out|deadline|warming/i.test(n)?"timeout":/unavailable|not active|unknown tool|not found|not registered|route not found/i.test(n)?"unavailable":"failed"}if(process.argv[1]?.endsWith("post-tool-use")||process.argv[1]?.endsWith("post-tool-use.js")){let n=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",e=>{t+=e;}),process.stdin.on("end",async()=>{let e=await Oo(t.trim()||process.argv[2]||"");n(JSON.stringify(e?{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:e}}:{status:"ok"}));}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),5e3).unref();}export{Oo as handlePostToolUse};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {existsSync,readdirSync,readFileSync,unlinkSync,mkdirSync,writeFileSync,rmSync,linkSync,renameSync,statSync}from'fs';import {join as join$1,dirname as dirname$1}from'path';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {getLocalApiKey,getDevFlowStateRoot,projectClaudeToolName,resolveClaudeToolName,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir,readRuntimeState}from'@devflow-tools/sdk';import {request}from'node:http';import {existsSync as existsSync$1,mkdirSync as mkdirSync$1,appendFileSync,chmodSync,readFileSync as readFileSync$1,writeFileSync as writeFileSync$1,renameSync as renameSync$1}from'node:fs';import {join,resolve,basename,relative,sep,dirname,isAbsolute,normalize}from'node:path';import {maybeRunDiagnosticLogCleanup,rotateDiagnosticLogFile,emitSemanticControlLog}from'@devflow-tools/telemetry';import {fileURLToPath}from'url';import {randomUUID,createHash}from'crypto';import {createHash as createHash$1}from'node:crypto';import {homedir}from'node:os';import {DatabaseSync}from'node:sqlite';function
|
|
2
|
-
`;rotateDiagnosticLogFile({path:e,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(n)}),appendFileSync(e,n);}catch{}}function dt(i){return new Promise(t=>setTimeout(t,i))}var ce=1e4,ht=3e4,$=500,N=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(getDevFlowStateRoot(),"global","telemetry-cache"),this.database=t?.database??null,this.ownsDatabase=!t?.database;let e=t?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(e)&&e>=0?e:100;}async sendEvent(t){let e={...t,input:this.truncateInput(t.input)};return this.commitOrCache("tool_call",e)?(this.postHttp("/api/telemetry/tool-call",e),t.eventId):null}async sendExecutionStart(t,e,n,o,r=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let c={executionId:t,sessionId:e,skillName:n,startedAt:o,projectRoot:r,requiredMcpTools:s};this.commitOrCache("execution_start",c)&&this.postHttp("/api/telemetry/skill-execution/start",c);}async sendExecutionComplete(t,e="completed",n=Date.now(),o){let r={executionId:t,status:e,finishedAt:n,metadata:o},s=this.commitOrCache("execution_complete",r);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",r),s}async sendSessionStart(t,e,n){let o={id:t,projectRoot:e,startedAt:n,label:e.split("/").pop()??"unknown"},r=this.commitOrCache("session_start",o);return r&&this.postHttp("/api/telemetry/sessions",o),r}async completeEvent(t){let e=this.commitOrCache("complete_event",t);return e&&(this.postHttp("/api/telemetry/tool-call/output",t),this.scheduleMetricAggregation()),e}async endSession(t,e=Date.now()){let n={sessionId:t,finishedAt:e},o=this.commitOrCache("session_end",n);return o&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(t)}/close`,{finishedAt:e})),o}async flushCache(){try{let e=this.getDatabase(),n=e.listTelemetryFailures({unresolvedOnly:!0,limit:$}).reverse();for(let o of n)try{this.applyOperation(o.operation,o.payload),e.resolveTelemetryFailure(o.id);}catch{}e.trimTelemetryFailures($);}catch{}let t=(existsSync(this.cacheDir)?readdirSync(this.cacheDir):[]).filter(e=>e.endsWith(".json")).map(e=>{let n=join$1(this.cacheDir,e);try{return {cacheFile:n,envelope:yt(JSON.parse(readFileSync(n,"utf8")))}}catch{return null}}).filter(e=>e!==null).sort((e,n)=>e.envelope.timestamp-n.envelope.timestamp||le(e.envelope.operation)-le(n.envelope.operation));for(let{cacheFile:e,envelope:n}of t)try{let o=this.getDatabase();o.insertTelemetryFailure({id:n.id,operation:n.operation,payload:n.payload,error:n.failure,createdAt:n.timestamp}),this.applyOperation(n.operation,n.payload),o.resolveTelemetryFailure(n.id),unlinkSync(e);}catch{}this.database?.aggregatePendingToolMetrics();}aggregateMetrics(){return this.getDatabase().aggregatePendingToolMetrics()}async flushAndAggregate(){await this.flushCache(),this.aggregateMetrics();}close(){this.ownsDatabase&&this.database?.close(),this.database=null;}getDatabase(){return this.database??=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:this.busyTimeoutMs}),this.database}commitOrCache(t,e){try{return this.applyOperation(t,e),!0}catch(n){return this.cacheOperation(t,e,n),false}}applyOperation(t,e){let n=this.getDatabase();switch(t){case "tool_call":this.ensureParentSession(n,e),n.insertToolCallEvent(e);return;case "execution_start":this.ensureParentSession(n,e),n.insertSkillExecution({executionId:e.executionId,sessionId:e.sessionId,skillName:e.skillName,startedAt:e.startedAt,status:"running",requiredMcpTools:e.requiredMcpTools});return;case "execution_complete":n.reconcileSkillExecution(e.executionId,e.status,e.finishedAt,e.metadata);return;case "session_start":n.ensureSession(e),n.insertRun({id:de(e.id),source:"hook",tool:"session",input:{projectRoot:e.projectRoot},status:"active",startedAt:e.startedAt,tokenUsed:0,metadata:{sessionId:e.id,projectRoot:e.projectRoot}});return;case "complete_event":if(!n.updateToolCallEvent(e.eventId,{output:e.output===void 0?void 0:JSON.stringify(e.output),error:e.error,failureCategory:e.failureCategory,duration:e.duration}))throw new Error(`Tool call event ${e.eventId} is not available for completion`);return;case "session_end":n.closeSession(e.sessionId,e.finishedAt),n.updateRun(de(e.sessionId),{status:"completed",finishedAt:e.finishedAt});return}}ensureParentSession(t,e){let n=typeof e.sessionId=="string"?e.sessionId.trim():"";if(!n)throw new Error("Canonical session ID is required for telemetry");let o=typeof e.projectRoot=="string"&&e.projectRoot.trim()?e.projectRoot:typeof e.input?.projectRoot=="string"&&e.input.projectRoot.trim()?e.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";t.ensureSession({id:n,projectRoot:o,label:o==="unknown"?void 0:o.split("/").pop(),startedAt:Number(e.startedAt??e.timestamp??Date.now())});}cacheOperation(t,e,n){let o=Date.now(),r={id:`failure:${o}:${Math.random().toString(36).slice(2,11)}`,operation:t,payload:e,failure:n instanceof Error?n.message:String(n),timestamp:o};try{let s=this.getDatabase();s.insertTelemetryFailure({id:r.id,operation:t,payload:e,error:r.failure,createdAt:o}),s.trimTelemetryFailures($),this.scheduleRetry();return}catch{}try{existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${o}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(r,null,2),{mode:384}),this.trimRetryCache(),this.scheduleRetry();}catch{}}trimRetryCache(){try{let t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json")).sort();for(let e of t.slice(0,Math.max(0,t.length-$)))unlinkSync(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},ht).unref());}scheduleMetricAggregation(){if(this.metricAggregationScheduled||process.env.DEVFLOW_HOOK_DEGRADED==="1")return;this.metricAggregationScheduled=true,setTimeout(()=>{this.metricAggregationScheduled=false;try{this.getDatabase().aggregatePendingToolMetrics(50)===50&&this.scheduleMetricAggregation();}catch{}},25).unref();}postHttp(t,e){oe(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=ce?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,ce)}...`}}};function le(i){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(i)}function de(i){return `hook-run:${i}`}function yt(i){if(!i||typeof i!="object")throw new Error("Invalid telemetry cache envelope");let t=i;if(typeof t.id!="string"||typeof t.operation!="string"||t.payload===void 0||typeof t.failure!="string"||typeof t.timestamp!="number")throw new Error("Invalid telemetry cache envelope");return t}function C(i){return i??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function E(i){return getProjectStateDir(C(i))}var I=emitSemanticControlLog;var wt=2,Dt=1;function xt(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{return join$1(dirname$1(fileURLToPath(import.meta.url)),"..","..")}catch{return process.cwd()}}function ue(i=xt()){let t=[join$1(i,"dist","command-registry.json"),join$1(i,"command-registry.json")];for(let e of t)try{if(!existsSync(e))continue;let n=JSON.parse(readFileSync(e,"utf8"));if(n.version!==wt&&n.version!==Dt||!kt(n.commands)){I({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:"contract_mismatch",registryPath:e}});continue}return n.commands}catch(n){I({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:n.message,fallback:"next_registry_candidate"}});}return null}function kt(i){return !i||typeof i!="object"||Array.isArray(i)?false:Object.values(i).every(t=>{if(!t||typeof t!="object"||Array.isArray(t))return false;let e=t;return M(e.mcpTools)&&M(e.blockedNative)&&(e.source===void 0||e.source==="core"||e.source==="plugin")&&(e.requiresContext===void 0||typeof e.requiresContext=="boolean")&&(e.runtimePackages===void 0||M(e.runtimePackages))&&(e.hostTools===void 0||St(e.hostTools))&&(e.evidenceMode===void 0||["static","runtime","mixed"].includes(e.evidenceMode))})}function St(i){return !!i&&typeof i=="object"&&!Array.isArray(i)&&Object.entries(i).every(([t,e])=>t.length>0&&M(e))}function M(i){return Array.isArray(i)&&i.every(t=>typeof t=="string"&&t.length>0)}function pe(i){let t=ue();return t?t[i]?.mcpTools??[]:[]}function he(i){return Buffer.from(i,"utf8").toString("base64url")}function Tt(i,t,e){let n=t?.trim();if(n){let o=/^[a-zA-Z0-9:._-]{1,192}$/.test(n)?n:`tool-${createHash("sha256").update(n.slice(0,1024)).digest("hex").slice(0,32)}`;return `${i}:${o}`}return `${i}:legacy-${e}-${randomUUID().slice(0,8)}`}function Ee(i){return `${i}:legacy-journal`}var D=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(E(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let n=this.get(e);if(n)return n.lastActivityAt=Date.now(),this.persist(n),n;let o=Date.now(),r={sessionId:e,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:o,lastActivityAt:o};return this.sessions.set(e,r),this.persist(r),r}startExecution(t,e,n){let o=this.registerSession(t);return (!o.executionId||o.skillName!==e)&&(o.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),o.skillName=e,o.requiredMcpTools=[...new Set(n)],delete o.contextInitialization,o.lastActivityAt=Date.now(),this.persist(o),o}beginContextInitialization(t,e){let n=this.registerSession(t);return n.contextInitialization={startedAt:Date.now(),...e?{toolUseId:e}:{}},n.lastActivityAt=Date.now(),this.persist(n),n}completeContextInitialization(t,e){let n=this.get(t);return n?(e&&n.contextInitialization?.toolUseId&&n.contextInitialization.toolUseId!==e||(delete n.contextInitialization,n.lastActivityAt=Date.now(),this.persist(n)),n):null}bindTaskIdentity(t,e){let n=this.registerSession(t);return n.activeTurnId=e.turnId,n.activeRequestId=e.requestId,n.intentArtifactHash=e.intentArtifactHash,n.lastActivityAt=Date.now(),this.persist(n),n}get(t){let e=t.trim();if(!e)return null;let n=this.sessions.get(e);if(n)return this.replayEvidenceJournal(n),n;let o=this.snapshotPath(e);if(!existsSync(o))return null;try{let r=JSON.parse(readFileSync(o,"utf8"));return r.sessionId!==e||r.projectRoot!==this.projectRoot?null:(r.requiredMcpTools=Array.isArray(r.requiredMcpTools)?r.requiredMcpTools:[],r.evidenceObligations=ye(r.evidenceObligations),r.evidenceDegradations=ve(r.evidenceDegradations),r.evidenceOutcomes=be(r.evidenceOutcomes),this.replayEvidenceJournal(r),this.sessions.set(e,r),r)}catch{return null}}completeExecution(t){let e=this.get(t);if(!e)return null;let n=structuredClone(e);return delete e.executionId,delete e.skillName,delete e.contextInitialization,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),n}addEvidenceObligation(t,e,n=Date.now(),o){let r=this.registerSession(t),c=(o?void 0:r.evidenceObligations.find(l=>l.contractId===e.id))?.obligationId??Tt(e.id,o,n);this.appendEvidenceEvent(t,{kind:"add",obligationId:c,contractId:e.id,at:n,contract:e},`add\0${c}`),this.replayEvidenceJournal(r);let a=r.evidenceObligations.find(l=>l.obligationId===c);return a?(r.lastActivityAt=Date.now(),this.persist(r),structuredClone(a)):null}listEvidenceObligations(t){return (this.get(t)?.evidenceObligations??[]).map(e=>structuredClone(e))}markEvidenceCorrection(t,e,n,o,r=Date.now()){let s=this.get(t),c=s?.evidenceObligations.find(u=>u.obligationId===e);if(!s||!c)return null;let a=/^[a-f0-9]{64}$/.test(o)?o:"";if(!a)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:c.contractId,at:r,fingerprint:a,violations:n.slice(0,16).map(u=>u.slice(0,240))},`correction\0${e}\0${a}`),this.replayEvidenceJournal(s),s.lastActivityAt=r,this.persist(s);let l=s.evidenceObligations.find(u=>u.obligationId===e);return l?structuredClone(l):null}resolveEvidenceObligation(t,e){let n=this.get(t);if(!n)return false;let o=n.evidenceObligations.find(s=>s.obligationId===e);if(!o)return false;let r=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:o.contractId,at:r},`resolve\0${e}`),this.replayEvidenceJournal(n),n.lastActivityAt=r,this.persist(n),true}resolveDegradedEvidence(t,e){let n=this.get(t),o=n?.evidenceDegradations.find(s=>s.obligationId===e);if(!n||!o)return false;let r=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:o.contractId,at:r},`resolve-degraded\0${e}\0${r}`),this.replayEvidenceJournal(n),n.lastActivityAt=r,this.persist(n),true}degradeEvidenceObligation(t,e,n,o=Date.now()){let r=this.get(t),s=r?.evidenceObligations.find(a=>a.obligationId===e);if(!r||!s)return false;let c=n.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:o,reason:c},`degrade\0${e}\0${c}`),this.replayEvidenceJournal(r),r.lastActivityAt=o,this.persist(r),true}removeSession(t){let e=t.trim();e&&(this.sessions.delete(e),rmSync(this.snapshotPath(e),{force:true}),rmSync(this.evidenceJournalDir(e),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(t){return join$1(this.sessionsDir,`${he(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",he(t))}appendEvidenceEvent(t,e,n){let o=this.evidenceJournalDir(t);mkdirSync(o,{recursive:true,mode:448});let r=createHash("sha256").update(n).digest("hex"),s=join$1(o,`${e.kind}-${r}.json`);if(existsSync(s))return;let c=join$1(o,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(c,JSON.stringify(e),{mode:384});try{linkSync(c,s);}catch(a){if(a.code!=="EEXIST")throw a}finally{rmSync(c,{force:true});}}replayEvidenceJournal(t){t.evidenceObligations=ye(t.evidenceObligations),t.evidenceDegradations=ve(t.evidenceDegradations),t.evidenceOutcomes=be(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync(e))return;let n;try{n=readdirSync(e).filter(r=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(r)).slice(0,4096);}catch{return}let o=n.flatMap(r=>{try{let s=readFileSync(join$1(e,r),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let c=Ft(JSON.parse(s));return c?[c]:[]}catch{return []}}).sort((r,s)=>r.at-s.at||_e(r.kind)-_e(s.kind));for(let r of o)this.applyEvidenceEvent(t,r);t.evidenceObligations=t.evidenceObligations.slice(-8),t.evidenceDegradations=t.evidenceDegradations.slice(-20),t.evidenceOutcomes=t.evidenceOutcomes.slice(-20);}applyEvidenceEvent(t,e){let n=t.evidenceOutcomes.find(s=>s.obligationId===e.obligationId);if(e.kind==="add"){if(n)return;let s=t.evidenceObligations.find(c=>c.obligationId===e.obligationId);s?(s.contract=e.contract,s.promptedAt=Math.min(s.promptedAt,e.at)):t.evidenceObligations.push({obligationId:e.obligationId,contractId:e.contractId,contract:e.contract,promptedAt:e.at,attempt:0,correctionRequested:false,violations:[]});return}let o=t.evidenceObligations.find(s=>s.obligationId===e.obligationId);if(e.kind==="correction"){if(!o||n||o.correctionFingerprint===e.fingerprint)return;o.attempt+=1,o.correctionRequested=true,o.correctionRequestedAt=e.at,o.correctionFingerprint=e.fingerprint,o.violations=e.violations;return}let r=o?.attempt??n?.attempt??0;if(e.kind==="resolve"&&n?.status==="degraded")t.evidenceOutcomes=t.evidenceOutcomes.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations=t.evidenceDegradations.filter(s=>s.obligationId!==e.obligationId);else if(n)return;e.kind==="degrade"?(t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations.push({obligationId:e.obligationId,contractId:e.contractId,reason:e.reason,degradedAt:e.at,attempt:r,contract:o?.contract})):t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),t.evidenceOutcomes.push({obligationId:e.obligationId,contractId:e.contractId,status:e.kind==="resolve"?"resolved":"degraded",completedAt:e.at,attempt:r,...e.kind==="degrade"?{reason:e.reason}:{}});}persist(t){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),n=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(n,JSON.stringify(t),{mode:384}),renameSync(n,e);}};function ye(i){return Array.isArray(i)?i.flatMap(t=>{if(!t||typeof t!="object")return [];let e=t;if(typeof e.contractId!="string"||e.contractId.length===0||e.contractId.length>128||typeof e.promptedAt!="number"||typeof e.attempt!="number"||typeof e.correctionRequested!="boolean"||!Array.isArray(e.violations)||!Ie(e.contract))return [];let n=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:Ee(e.contractId),o=typeof e.correctionTranscriptHash=="string"?e.correctionTranscriptHash:void 0,r=e.correctionFingerprint??o;return r!==void 0&&!/^[a-f0-9]{64}$/.test(r)?[]:[{...e,obligationId:n,correctionFingerprint:r}]}).slice(-8):[]}function ve(i){return Array.isArray(i)?i.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&typeof e.reason=="string"&&typeof e.degradedAt=="number"&&typeof e.attempt=="number"}).slice(-20):[]}function be(i){return Array.isArray(i)?i.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&(e.status==="resolved"||e.status==="degraded")&&typeof e.completedAt=="number"&&typeof e.attempt=="number"&&(e.reason===void 0||typeof e.reason=="string")}).slice(-20):[]}function Ft(i){if(!i||typeof i!="object")return null;let t=i,e=t.kind;if(e!=="add"&&e!=="correction"&&e!=="resolve"&&e!=="degrade"||typeof t.contractId!="string"||t.contractId.length>128||typeof t.at!="number")return null;let o={obligationId:typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:Ee(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return Ie(t.contract)?{kind:e,...o,contract:t.contract}:null;if(e==="correction"){let r=typeof t.fingerprint=="string"?t.fingerprint:t.transcriptHash;return typeof r=="string"&&/^[a-f0-9]{64}$/.test(r)&&Array.isArray(t.violations)&&t.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:e,...o,fingerprint:r,violations:t.violations}:null}return e==="resolve"?{kind:e,...o}:typeof t.reason=="string"&&t.reason.length<=240?{kind:e,...o,reason:t.reason}:null}function _e(i){return i==="add"?0:i==="correction"?1:2}function Ie(i){if(!i||typeof i!="object")return false;let t=i,e=t.requiredSections,n=t.prohibitedClaims;return t.version==="1.0"&&typeof t.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(t.id)&&typeof t.runtimeProfilingOccurred=="boolean"&&typeof t.samplingEvidenceOccurred=="boolean"&&Array.isArray(e)&&e.length===3&&e[0]==="\u5DE5\u5177\u53D1\u73B0"&&e[1]==="\u6A21\u578B\u5047\u8BBE"&&e[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(n)&&n.length<=16&&n.every(o=>typeof o=="string"&&o.length<=128)&&typeof t.canonicalReport=="string"&&Buffer.byteLength(t.canonicalReport,"utf8")<=48*1024&&!!t.correctionPolicy&&t.correctionPolicy.maxAttempts===1&&t.correctionPolicy.repeatedViolation==="fail_open"}function H(i){if(!i||typeof i!="object"||Array.isArray(i))return {};let t=i,e={};for(let n of ["lastMcpCall","bypassCount"])if(n in t){let o=t[n];if(o==null)continue;e[n]=typeof o=="number"&&Number.isFinite(o)&&o>=0?o:0;}return e}function Lt(i,t){return i.lastMcpCall===t.lastMcpCall&&i.bypassCount===t.bypassCount}function we(i,t,e){let n=e instanceof Error?e.message:String(e);I({event:"hook.runtime.degraded",identity:{projectRoot:i},level:"warn",timestamp:Date.now(),data:{stage:"enforcement_receipt",operation:t,reason:n,fallback:"fail_open"}});}function De(i,t,e){let n;try{n=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let o={},r=n.updateHookReceipt(i,c=>(o=H(c),H(t(o)))),s=H(r);return {receipt:s,applied:!0,changed:!Lt(o,s)}}catch(o){return we(i,e,o),{receipt:{},applied:false,changed:false}}finally{try{n?.close();}catch{}}}function xe(i){let t;try{return t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),H(t.getHookReceipt(i))}catch(e){return we(i,"update",e),{}}finally{try{t?.close();}catch{}}}function jt(i,t){return De(i,()=>t,"write").applied}function Pt(i,t){return De(i,t,"update")}var Y={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"},$t=new Set(["Write","Edit","NotebookEdit"]),Nt=new Set(["failed","timeout","unavailable"]);function Mt(i){switch(i){case "WebSearch":case "WebFetch":return 1;case "Agent":return 3;case "Grep":case "Glob":return 3;case "Bash":return 5;default:return 2}}var q=class{constructor(t,e,n){this.projectRoot=t;this.sessionId=e;this.executionId=n;}getPhase(){if(!this.sessionId||!this.executionId)return "idle";let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let n=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(n&&n.expiresAt>Date.now())return "context_ready";n&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId);}catch{}finally{try{t?.close();}catch{}}let e=new D(this.projectRoot).get(this.sessionId);return e?.executionId===this.executionId&&e.contextInitialization?"context_initializing":"context_gathering"}getContextReceipt(){if(!this.sessionId||!this.executionId)return null;let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let e=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);return e&&e.expiresAt>Date.now()?e:(e&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId),null)}catch{return null}finally{try{t?.close();}catch{}}}evaluate(t,e){let n=this.getPhase();if(e||t==="Skill")return {permissionDecision:"allow"};if(n==="context_initializing"&&Y[t])return {permissionDecision:"deny",reasonCode:"DEVFLOW_CONTEXT_INITIALIZING",reason:`DevFlow context initialization is in progress. Wait for ${projectClaudeToolName("get_project_context")} to complete, then retry ${t}.`};if(n==="context_gathering"&&Y[t])return {permissionDecision:"deny",reasonCode:"DEVFLOW_CONTEXT_REQUIRED",reason:`DevFlow context required. Call ${projectClaudeToolName("get_project_context")}, then retry ${t}.`};if(n==="context_ready"){if($t.has(t)){let a=this.evaluateRequiredAction();if(a)return a}return {permissionDecision:"allow"}}let o=Y[t];if(!o)return {permissionDecision:"allow"};let r=Pt(this.projectRoot,a=>({...a,bypassCount:(a.bypassCount??0)+1}));if(!r.applied)return {permissionDecision:"allow"};let s=r.receipt.bypassCount??0,c=Mt(t);return s>=c?{permissionDecision:"allow",additionalContext:`\u5DF2 ${s} \u6B21\u76F4\u63A5\u4F7F\u7528 ${t}\uFF0C\u5EFA\u8BAE\u7528 ${projectClaudeToolName(o)} \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`}:{permissionDecision:"allow"}}recordMcpCall(){jt(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});}recordDomainActionOutcome(t,e,n,o){if(!this.sessionId||!this.executionId)return false;let r;try{r=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let s=r.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(!s||s.expiresAt<=Date.now()||s.canonicalAction?.tool!==t)return !1;let c=Date.now(),a=o?.trim()?`${o.trim()}:${e}`:`${t}:${e}:${c}`,l=s.actionAttempts??[];return r.upsertContextReceipt({...s,actionAttempts:l.some(u=>u.id===a||o&&u.toolUseId===o&&u.status===e)?l:[...l,{id:a,tool:t,status:e,attemptedAt:c,toolUseId:o,reason:n?.slice(0,500)}].slice(-20),actionSatisfiedAt:e==="succeeded"?c:s.actionSatisfiedAt,actionDegradation:e==="succeeded"?void 0:s.actionDegradation}),!0}catch{return false}finally{try{r?.close();}catch{}}}evaluateRequiredAction(){let t=this.getContextReceipt(),e=t?.canonicalAction;if(!t||!e||!e.required||e.status!=="required")return null;let n=e.binding;if(n.requiredContextReceipt!==t.contextHash||n.projectRoot!==this.projectRoot||n.sessionId!==this.sessionId||n.requestId!==t.requestId||n.executionId&&n.executionId!==this.executionId)return {permissionDecision:"deny",reasonCode:"DEVFLOW_ACTION_BINDING_STALE",reason:`DevFlow canonical action binding is stale or mismatched. Call ${projectClaudeToolName("get_project_context")} again before writing.`};if(t.actionSatisfiedAt)return null;if(t.actionDegradation?.authorizedByContextReceipt===t.contextHash)return {permissionDecision:"allow",additionalContext:`DevFlow degraded fallback authorized by context receipt ${t.contextHash}: ${t.actionDegradation.reason}`};let o=(t.actionAttempts??[]).filter(r=>r.tool===e.tool&&Nt.has(r.status));if(o.length>0){let r=o.at(-1),s={missedTool:e.tool,failedAttemptCount:o.length,reason:`${r.status}:${r.reason??"canonical domain action did not complete"}`,authorizedByContextReceipt:t.contextHash,authorizedAt:Date.now()};return this.persistDegradation(t,s),{permissionDecision:"allow",additionalContext:`DevFlow canonical tool ${projectClaudeToolName(e.tool)} ${r.status}; degraded direct write authorized by context receipt ${t.contextHash}. Preserve the action contract and verification plan.`}}return {permissionDecision:"deny",reasonCode:"DEVFLOW_REQUIRED_ACTION",reason:`DevFlow required action not completed. Call ${projectClaudeToolName(e.tool)} using context receipt ${t.contextHash}, then retry the write. Direct fallback is allowed only after unavailable, failed, or timeout evidence.`}}persistDegradation(t,e){let n;try{n=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let o=n.getContextReceipt(t.projectRoot,t.sessionId,t.executionId);if(!o||o.contextHash!==t.contextHash||o.actionDegradation)return;n.upsertContextReceipt({...o,actionDegradation:e});let r=n.getSkillExecution(t.executionId);if(!r)return;let s=r.metadata&&typeof r.metadata=="object"?r.metadata:{},c=Array.isArray(s.requiredActionDegradations)?s.requiredActionDegradations:[];n.updateSkillExecution(t.executionId,{missedMcpTools:[...new Set([...r.missedMcpTools??[],e.missedTool])],failedToolCalls:Math.max(r.failedToolCalls??0,e.failedAttemptCount),fallbackCount:(r.fallbackCount??0)+1,fallbackReasons:[...new Set([...r.fallbackReasons??[],`required_action_${e.reason}`])],metadata:{...s,requiredActionDegradations:[...c,e]}});}catch{}finally{try{n?.close();}catch{}}}};var Gt=10*1024*1024,Yt=5;function Kt(i){return createHash$1("sha256").update(i).digest("hex").slice(0,16)}function ke(i){return join(homedir(),".devflow","logs","hook-debug",`${Kt(i)}.jsonl`)}function Se(i,t,e={}){let n=e.maxBytes??Gt,o=e.maxFiles??Yt;mkdirSync$1(dirname(i),{recursive:true,mode:448});let r=Buffer.byteLength(t);rotateDiagnosticLogFile({path:i,maxBytes:n,maxFiles:o,incomingBytes:r}),appendFileSync(i,t,{mode:384}),chmodSync(i,384);}var K="WARNING: DevFlow is in degraded mode (daemon unreachable): 4-Gate enforcement and memory prefetch cache are unavailable. Run `devflow doctor` for details.";function Oe(){return process.env.DEVFLOW_HOOK_DEGRADED==="1"}function Ae(i){let t=i.trim().replace(/^\//,"");if(!t.startsWith("devflow:"))return null;let e=t.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(e)?`devflow:${e.toLowerCase()}`:null}function Ce(i,t){return t?`evt_tool_${createHash("sha256").update(`${i}\0${t}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}var tn=new Set(["Write","Edit","NotebookEdit"]),Te=`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 $e(i){if(!tn.has(i.toolName))return null;let t=nn(i.toolInput);if(!t)return null;let e=on(t,i.projectRoot),n=resolve(i.projectRoot,".claude");if(Fe(e,n)&&basename(e).toLocaleUpperCase("en-US")==="MEMORY.MD")return Te;let o=resolve(i.home??homedir(),".claude","projects");return Fe(e,o)&&relative(o,e).split(sep).some(s=>s.toLocaleLowerCase("en-US")==="memory")?Te:null}function nn(i){for(let t of ["file_path","notebook_path","path"]){let e=i[t];if(typeof e=="string"&&e.trim())return e.trim()}return null}function on(i,t){return resolve(isAbsolute(i)?i:resolve(t,i))}function Fe(i,t){let e=relative(t,i);return e===""||!e.startsWith(`..${sep}`)&&e!==".."&&!isAbsolute(e)}function He(i){let t=pn(i.toolName,i.toolInput),e=t?gn(i.projectRoot,i.toolName,i.toolInput):void 0;if(!t||!e||!i.toolUseId)return {allowed:true};let n=mn(e),o,r=0,s,c;try{c=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100,readonly:!0});let l=c.getActiveContextReceipt(i.projectRoot,i.sessionId,i.executionId);o=l?.contextHash,r=l?.issuedAt??0,s=l?.canonicalAction?.binding.operationTargets?.find(u=>hn(i.projectRoot,u.path,e));}catch{}finally{try{c?.close();}catch{}}let a={toolUseId:i.toolUseId,sessionId:i.sessionId,executionId:i.executionId,operation:t,path:e,before:n,contextReceipt:o,observedAt:Date.now()};if(bn(i.projectRoot,a),t==="edit"||t==="write"||t==="delete"){let l=_n(i.projectRoot,e),u=l?.success&&l.operation==="delete"&&!l.after.exists&&l.completedAt>=r,d=s?.expectedState==="existing"&&!n.exists||s?.expectedState==="missing"&&n.exists||!!(s?.contentHash&&n.hash!==s.contentHash);if(u||s?.expectedState==="existing"&&!n.exists)return Ne(i,a,"DEVFLOW_FILE_STATE_DELETED","The target was deleted after the active Context receipt. Refresh project context before editing or recreating it.");if(d)return Ne(i,a,"DEVFLOW_FILE_STATE_STALE","The target state no longer matches the active Context receipt. Refresh project context before overwriting it.")}return qe(i,a,true),{allowed:true,pending:a}}function Ne(i,t,e,n){return qe(i,t,false,e),{allowed:false,reasonCode:e,reason:n,pending:t}}function qe(i,t,e,n){I({event:"canonical.action.validated",identity:{projectRoot:i.projectRoot,sessionId:i.sessionId,executionId:i.executionId,contextReceipt:t.contextReceipt},level:e?"info":"warn",timestamp:Date.now(),data:{stage:"host_file_state_precondition",valid:e,operation:t.operation,targetPath:relative(i.projectRoot,t.path),targetExists:t.before.exists,targetHash:t.before.hash,reason:n,toolUseId:t.toolUseId}});}function pn(i,t){if(i==="Read")return "read";if(i==="Edit"||i==="NotebookEdit")return "edit";if(i==="Write")return "write";if(i==="Delete"||i==="Bash"&&We(t.command))return "delete"}function gn(i,t,e){let n=fn(e,["file_path","filePath","notebook_path","path","targetPath"])??(t==="Bash"?We(e.command):void 0);if(!n)return;let o=isAbsolute(n)?normalize(n):resolve(i,n),r=relative(i,o);return r.startsWith("..")||isAbsolute(r)?void 0:o}function We(i){return typeof i!="string"?void 0:/(?:^|[;&|]\s*)\s*(?:rm|unlink)\s+(?:-[A-Za-z]+\s+)*(?:--\s+)?(["']?)([^\s;&|"']+)\1/u.exec(i)?.[2]}function fn(i,t){for(let e of t){let n=i[e];if(typeof n=="string"&&n.trim())return n.trim()}}function mn(i){if(!existsSync$1(i))return {exists:false};try{return {exists:!0,hash:createHash$1("sha256").update(readFileSync$1(i)).digest("hex")}}catch{return {exists:true}}}function hn(i,t,e){return (isAbsolute(t)?normalize(t):resolve(i,t))===normalize(e)}function Je(i){return join(E(i),"file-state")}function Ve(i){return join(Je(i),"pending.json")}function yn(i){return join(Je(i),"observations.jsonl")}function vn(i){try{return JSON.parse(readFileSync$1(Ve(i),"utf8"))}catch{return {}}}function bn(i,t){let e=Ve(i);mkdirSync$1(dirname(e),{recursive:true});let n=vn(i);n[t.toolUseId]=t,Rn(e,JSON.stringify(n));}function _n(i,t){try{let e=readFileSync$1(yn(i),"utf8").trim().split(`
|
|
3
|
-
`);for(let n=e.length-1;n>=0;n-=1){let o=JSON.parse(e[n]);if(o.path===t)return o}}catch{}}function
|
|
4
|
-
`);}catch{}return m}catch{try{let e=JSON.parse(i),n=C(),o=
|
|
1
|
+
import {existsSync,readdirSync,readFileSync,unlinkSync,mkdirSync,writeFileSync,rmSync,linkSync,renameSync,statSync}from'fs';import {join as join$1,dirname as dirname$1}from'path';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {getLocalApiKey,getDevFlowStateRoot,projectClaudeToolName,resolveClaudeToolName,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir,readRuntimeState}from'@devflow-tools/sdk';import {request}from'node:http';import {existsSync as existsSync$1,mkdirSync as mkdirSync$1,appendFileSync,chmodSync,readFileSync as readFileSync$1,writeFileSync as writeFileSync$1,renameSync as renameSync$1}from'node:fs';import {join,resolve,basename,relative,sep,dirname,isAbsolute,normalize}from'node:path';import {maybeRunDiagnosticLogCleanup,rotateDiagnosticLogFile,emitSemanticControlLog}from'@devflow-tools/telemetry';import {fileURLToPath}from'url';import {randomUUID,createHash}from'crypto';import {createHash as createHash$1}from'node:crypto';import {homedir}from'node:os';import {DatabaseSync}from'node:sqlite';function P(i,t,e){try{let n=openGlobalDevFlowDatabase();try{n.insertEvent({kind:i,timestamp:Date.now(),duration:e,success:t.success!==!1,metadata:t});}finally{n.close();}}catch{}}var ct=getLocalApiKey(),V=join(getDevFlowStateRoot(),"errors");async function ce(i,t,e={}){let n=e.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??lt();if(!n)return {delivered:false,suppressed:false,fallbackReason:"runtime_not_ready"};let o=e.timeout??1500,r=e.durableMirror??true,s=e.maxRetries??(r?0:2),c=e.circuitBreaker??true,a=acquireRuntimeHttpCircuit(n,i);if(c&&!a.allowed)return {delivered:false,suppressed:true,fallbackReason:a.state.fallbackReason};let l;for(let u=0;u<=s;u+=1)try{return await dt(n,i,t,o),c&®isterRuntimeHttpSuccess(n,i).transitioned&&P("http_circuit_transition",{endpoint:n,path:new URL(i,n).pathname,previous:a.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(p){l=p instanceof Error?p:new Error(String(p)),u<s&&await ut(Math.min(100*2**u,1e3));}if(!l)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!c)return se(i,l),{delivered:false,suppressed:false,fallbackReason:l.message};let d=registerRuntimeHttpFailure(n,i,e.fallbackReason??(r?"local_durable_mirror":"http_delivery_failed"));return d.transitioned&&(se(i,l),P("http_circuit_transition",{endpoint:n,path:new URL(i,n).pathname,previous:a.state.status,status:"open",failures:d.state.failures,openUntil:d.state.openUntil,fallbackReason:d.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:d.state.fallbackReason}}function lt(){let i=readRuntimeState();return i?.status==="ready"&&i.dashboardAvailable?i.url:void 0}function dt(i,t,e,n){return new Promise((o,r)=>{let s=JSON.stringify(e),c=new URL(t,i),a=false,l=u=>{a||(a=true,u?r(u):o());},d=request({hostname:c.hostname,port:c.port,path:c.pathname+c.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":ct,"Content-Length":Buffer.byteLength(s)},timeout:n},u=>{u.on("error",l),u.on("end",()=>{let p=u.statusCode??0;l(p>=200&&p<300?void 0:new Error(`HTTP ${p}`));}),u.resume();});d.on("error",l),d.on("timeout",()=>d.destroy(new Error(`HTTP mirror timed out after ${n}ms`))),d.write(s),d.end();})}function se(i,t){try{existsSync$1(V)||mkdirSync$1(V,{recursive:!0});let e=join(V,"http-errors.log"),n=`${new Date().toISOString()} | ${i} | ${t.message}
|
|
2
|
+
`;rotateDiagnosticLogFile({path:e,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(n)}),appendFileSync(e,n);}catch{}}function ut(i){return new Promise(t=>setTimeout(t,i))}var pe=1e4,yt=3e4,M=500,N=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(getDevFlowStateRoot(),"global","telemetry-cache"),this.database=t?.database??null,this.ownsDatabase=!t?.database;let e=t?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(e)&&e>=0?e:100;}async sendEvent(t){let e={...t,input:this.truncateInput(t.input)};return this.commitOrCache("tool_call",e)?(this.postHttp("/api/telemetry/tool-call",e),t.eventId):null}async sendExecutionStart(t,e,n,o,r=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let c={executionId:t,sessionId:e,skillName:n,startedAt:o,projectRoot:r,requiredMcpTools:s};this.commitOrCache("execution_start",c)&&this.postHttp("/api/telemetry/skill-execution/start",c);}async sendExecutionComplete(t,e="completed",n=Date.now(),o){let r={executionId:t,status:e,finishedAt:n,metadata:o},s=this.commitOrCache("execution_complete",r);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",r),s}async sendSessionStart(t,e,n){let o={id:t,projectRoot:e,startedAt:n,label:e.split("/").pop()??"unknown"},r=this.commitOrCache("session_start",o);return r&&this.postHttp("/api/telemetry/sessions",o),r}async completeEvent(t){let e=this.commitOrCache("complete_event",t);return e&&(this.postHttp("/api/telemetry/tool-call/output",t),this.scheduleMetricAggregation()),e}async endSession(t,e=Date.now()){let n={sessionId:t,finishedAt:e},o=this.commitOrCache("session_end",n);return o&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(t)}/close`,{finishedAt:e})),o}async flushCache(){try{let e=this.getDatabase(),n=e.listTelemetryFailures({unresolvedOnly:!0,limit:M}).reverse();for(let o of n)try{this.applyOperation(o.operation,o.payload),e.resolveTelemetryFailure(o.id);}catch{}e.trimTelemetryFailures(M);}catch{}let t=(existsSync(this.cacheDir)?readdirSync(this.cacheDir):[]).filter(e=>e.endsWith(".json")).map(e=>{let n=join$1(this.cacheDir,e);try{return {cacheFile:n,envelope:vt(JSON.parse(readFileSync(n,"utf8")))}}catch{return null}}).filter(e=>e!==null).sort((e,n)=>e.envelope.timestamp-n.envelope.timestamp||ge(e.envelope.operation)-ge(n.envelope.operation));for(let{cacheFile:e,envelope:n}of t)try{let o=this.getDatabase();o.insertTelemetryFailure({id:n.id,operation:n.operation,payload:n.payload,error:n.failure,createdAt:n.timestamp}),this.applyOperation(n.operation,n.payload),o.resolveTelemetryFailure(n.id),unlinkSync(e);}catch{}this.database?.aggregatePendingToolMetrics();}aggregateMetrics(){return this.getDatabase().aggregatePendingToolMetrics()}async flushAndAggregate(){await this.flushCache(),this.aggregateMetrics();}close(){this.ownsDatabase&&this.database?.close(),this.database=null;}getDatabase(){return this.database??=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:this.busyTimeoutMs}),this.database}commitOrCache(t,e){try{return this.applyOperation(t,e),!0}catch(n){return this.cacheOperation(t,e,n),false}}applyOperation(t,e){let n=this.getDatabase();switch(t){case "tool_call":this.ensureParentSession(n,e),n.insertToolCallEvent(e);return;case "execution_start":this.ensureParentSession(n,e),n.insertSkillExecution({executionId:e.executionId,sessionId:e.sessionId,skillName:e.skillName,startedAt:e.startedAt,status:"running",requiredMcpTools:e.requiredMcpTools});return;case "execution_complete":n.reconcileSkillExecution(e.executionId,e.status,e.finishedAt,e.metadata);return;case "session_start":n.ensureSession(e),n.insertRun({id:fe(e.id),source:"hook",tool:"session",input:{projectRoot:e.projectRoot},status:"active",startedAt:e.startedAt,tokenUsed:0,metadata:{sessionId:e.id,projectRoot:e.projectRoot}});return;case "complete_event":if(!n.updateToolCallEvent(e.eventId,{output:e.output===void 0?void 0:JSON.stringify(e.output),error:e.error,failureCategory:e.failureCategory,duration:e.duration}))throw new Error(`Tool call event ${e.eventId} is not available for completion`);return;case "session_end":n.closeSession(e.sessionId,e.finishedAt),n.updateRun(fe(e.sessionId),{status:"completed",finishedAt:e.finishedAt});return}}ensureParentSession(t,e){let n=typeof e.sessionId=="string"?e.sessionId.trim():"";if(!n)throw new Error("Canonical session ID is required for telemetry");let o=typeof e.projectRoot=="string"&&e.projectRoot.trim()?e.projectRoot:typeof e.input?.projectRoot=="string"&&e.input.projectRoot.trim()?e.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";t.ensureSession({id:n,projectRoot:o,label:o==="unknown"?void 0:o.split("/").pop(),startedAt:Number(e.startedAt??e.timestamp??Date.now())});}cacheOperation(t,e,n){let o=Date.now(),r={id:`failure:${o}:${Math.random().toString(36).slice(2,11)}`,operation:t,payload:e,failure:n instanceof Error?n.message:String(n),timestamp:o};try{let s=this.getDatabase();s.insertTelemetryFailure({id:r.id,operation:t,payload:e,error:r.failure,createdAt:o}),s.trimTelemetryFailures(M),this.scheduleRetry();return}catch{}try{existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${o}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(r,null,2),{mode:384}),this.trimRetryCache(),this.scheduleRetry();}catch{}}trimRetryCache(){try{let t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json")).sort();for(let e of t.slice(0,Math.max(0,t.length-M)))unlinkSync(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},yt).unref());}scheduleMetricAggregation(){if(this.metricAggregationScheduled||process.env.DEVFLOW_HOOK_DEGRADED==="1")return;this.metricAggregationScheduled=true,setTimeout(()=>{this.metricAggregationScheduled=false;try{this.getDatabase().aggregatePendingToolMetrics(50)===50&&this.scheduleMetricAggregation();}catch{}},25).unref();}postHttp(t,e){ce(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=pe?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,pe)}...`}}};function ge(i){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(i)}function fe(i){return `hook-run:${i}`}function vt(i){if(!i||typeof i!="object")throw new Error("Invalid telemetry cache envelope");let t=i;if(typeof t.id!="string"||typeof t.operation!="string"||t.payload===void 0||typeof t.failure!="string"||typeof t.timestamp!="number")throw new Error("Invalid telemetry cache envelope");return t}function C(i){return i??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function w(i){return getProjectStateDir(C(i))}var D=emitSemanticControlLog;var It=2,xt=1;function kt(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{return join$1(dirname$1(fileURLToPath(import.meta.url)),"..","..")}catch{return process.cwd()}}function me(i=kt()){let t=[join$1(i,"dist","command-registry.json"),join$1(i,"command-registry.json")];for(let e of t)try{if(!existsSync(e))continue;let n=JSON.parse(readFileSync(e,"utf8"));if(n.version!==It&&n.version!==xt||!St(n.commands)){D({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:"contract_mismatch",registryPath:e}});continue}return n.commands}catch(n){D({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:n.message,fallback:"next_registry_candidate"}});}return null}function St(i){return !i||typeof i!="object"||Array.isArray(i)?false:Object.values(i).every(t=>{if(!t||typeof t!="object"||Array.isArray(t))return false;let e=t;return U(e.mcpTools)&&U(e.blockedNative)&&(e.source===void 0||e.source==="core"||e.source==="plugin")&&(e.requiresContext===void 0||typeof e.requiresContext=="boolean")&&(e.runtimePackages===void 0||U(e.runtimePackages))&&(e.hostTools===void 0||Ot(e.hostTools))&&(e.evidenceMode===void 0||["static","runtime","mixed"].includes(e.evidenceMode))})}function Ot(i){return !!i&&typeof i=="object"&&!Array.isArray(i)&&Object.entries(i).every(([t,e])=>t.length>0&&U(e))}function U(i){return Array.isArray(i)&&i.every(t=>typeof t=="string"&&t.length>0)}function he(i){let t=me();return t?t[i]?.mcpTools??[]:[]}function _e(i){return Buffer.from(i,"utf8").toString("base64url")}function Ft(i,t,e){let n=t?.trim();if(n){let o=/^[a-zA-Z0-9:._-]{1,192}$/.test(n)?n:`tool-${createHash("sha256").update(n.slice(0,1024)).digest("hex").slice(0,32)}`;return `${i}:${o}`}return `${i}:legacy-${e}-${randomUUID().slice(0,8)}`}function xe(i){return `${i}:legacy-journal`}var x=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(w(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let n=this.get(e);if(n)return n.lastActivityAt=Date.now(),this.persist(n),n;let o=Date.now(),r={sessionId:e,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:o,lastActivityAt:o};return this.sessions.set(e,r),this.persist(r),r}startExecution(t,e,n){let o=this.registerSession(t);return (!o.executionId||o.skillName!==e)&&(o.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),o.skillName=e,o.requiredMcpTools=[...new Set(n)],delete o.contextInitialization,o.lastActivityAt=Date.now(),this.persist(o),o}beginContextInitialization(t,e){let n=this.registerSession(t);return n.contextInitialization={startedAt:Date.now(),...e?{toolUseId:e}:{}},n.lastActivityAt=Date.now(),this.persist(n),n}completeContextInitialization(t,e){let n=this.get(t);return n?(e&&n.contextInitialization?.toolUseId&&n.contextInitialization.toolUseId!==e||(delete n.contextInitialization,n.lastActivityAt=Date.now(),this.persist(n)),n):null}bindTaskIdentity(t,e){let n=this.registerSession(t);return n.activeTurnId=e.turnId,n.activeRequestId=e.requestId,n.intentArtifactHash=e.intentArtifactHash,n.lastActivityAt=Date.now(),this.persist(n),n}get(t){let e=t.trim();if(!e)return null;let n=this.sessions.get(e);if(n)return this.replayEvidenceJournal(n),n;let o=this.snapshotPath(e);if(!existsSync(o))return null;try{let r=JSON.parse(readFileSync(o,"utf8"));return r.sessionId!==e||r.projectRoot!==this.projectRoot?null:(r.requiredMcpTools=Array.isArray(r.requiredMcpTools)?r.requiredMcpTools:[],r.evidenceObligations=Re(r.evidenceObligations),r.evidenceDegradations=Ee(r.evidenceDegradations),r.evidenceOutcomes=we(r.evidenceOutcomes),this.replayEvidenceJournal(r),this.sessions.set(e,r),r)}catch{return null}}completeExecution(t){let e=this.get(t);if(!e)return null;let n=structuredClone(e);return delete e.executionId,delete e.skillName,delete e.contextInitialization,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),n}addEvidenceObligation(t,e,n=Date.now(),o){let r=this.registerSession(t),c=(o?void 0:r.evidenceObligations.find(l=>l.contractId===e.id))?.obligationId??Ft(e.id,o,n);this.appendEvidenceEvent(t,{kind:"add",obligationId:c,contractId:e.id,at:n,contract:e},`add\0${c}`),this.replayEvidenceJournal(r);let a=r.evidenceObligations.find(l=>l.obligationId===c);return a?(r.lastActivityAt=Date.now(),this.persist(r),structuredClone(a)):null}listEvidenceObligations(t){return (this.get(t)?.evidenceObligations??[]).map(e=>structuredClone(e))}markEvidenceCorrection(t,e,n,o,r=Date.now()){let s=this.get(t),c=s?.evidenceObligations.find(d=>d.obligationId===e);if(!s||!c)return null;let a=/^[a-f0-9]{64}$/.test(o)?o:"";if(!a)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:c.contractId,at:r,fingerprint:a,violations:n.slice(0,16).map(d=>d.slice(0,240))},`correction\0${e}\0${a}`),this.replayEvidenceJournal(s),s.lastActivityAt=r,this.persist(s);let l=s.evidenceObligations.find(d=>d.obligationId===e);return l?structuredClone(l):null}resolveEvidenceObligation(t,e){let n=this.get(t);if(!n)return false;let o=n.evidenceObligations.find(s=>s.obligationId===e);if(!o)return false;let r=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:o.contractId,at:r},`resolve\0${e}`),this.replayEvidenceJournal(n),n.lastActivityAt=r,this.persist(n),true}resolveDegradedEvidence(t,e){let n=this.get(t),o=n?.evidenceDegradations.find(s=>s.obligationId===e);if(!n||!o)return false;let r=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:o.contractId,at:r},`resolve-degraded\0${e}\0${r}`),this.replayEvidenceJournal(n),n.lastActivityAt=r,this.persist(n),true}degradeEvidenceObligation(t,e,n,o=Date.now()){let r=this.get(t),s=r?.evidenceObligations.find(a=>a.obligationId===e);if(!r||!s)return false;let c=n.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:o,reason:c},`degrade\0${e}\0${c}`),this.replayEvidenceJournal(r),r.lastActivityAt=o,this.persist(r),true}removeSession(t){let e=t.trim();e&&(this.sessions.delete(e),rmSync(this.snapshotPath(e),{force:true}),rmSync(this.evidenceJournalDir(e),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(t){return join$1(this.sessionsDir,`${_e(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",_e(t))}appendEvidenceEvent(t,e,n){let o=this.evidenceJournalDir(t);mkdirSync(o,{recursive:true,mode:448});let r=createHash("sha256").update(n).digest("hex"),s=join$1(o,`${e.kind}-${r}.json`);if(existsSync(s))return;let c=join$1(o,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(c,JSON.stringify(e),{mode:384});try{linkSync(c,s);}catch(a){if(a.code!=="EEXIST")throw a}finally{rmSync(c,{force:true});}}replayEvidenceJournal(t){t.evidenceObligations=Re(t.evidenceObligations),t.evidenceDegradations=Ee(t.evidenceDegradations),t.evidenceOutcomes=we(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync(e))return;let n;try{n=readdirSync(e).filter(r=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(r)).slice(0,4096);}catch{return}let o=n.flatMap(r=>{try{let s=readFileSync(join$1(e,r),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let c=Lt(JSON.parse(s));return c?[c]:[]}catch{return []}}).sort((r,s)=>r.at-s.at||De(r.kind)-De(s.kind));for(let r of o)this.applyEvidenceEvent(t,r);t.evidenceObligations=t.evidenceObligations.slice(-8),t.evidenceDegradations=t.evidenceDegradations.slice(-20),t.evidenceOutcomes=t.evidenceOutcomes.slice(-20);}applyEvidenceEvent(t,e){let n=t.evidenceOutcomes.find(s=>s.obligationId===e.obligationId);if(e.kind==="add"){if(n)return;let s=t.evidenceObligations.find(c=>c.obligationId===e.obligationId);s?(s.contract=e.contract,s.promptedAt=Math.min(s.promptedAt,e.at)):t.evidenceObligations.push({obligationId:e.obligationId,contractId:e.contractId,contract:e.contract,promptedAt:e.at,attempt:0,correctionRequested:false,violations:[]});return}let o=t.evidenceObligations.find(s=>s.obligationId===e.obligationId);if(e.kind==="correction"){if(!o||n||o.correctionFingerprint===e.fingerprint)return;o.attempt+=1,o.correctionRequested=true,o.correctionRequestedAt=e.at,o.correctionFingerprint=e.fingerprint,o.violations=e.violations;return}let r=o?.attempt??n?.attempt??0;if(e.kind==="resolve"&&n?.status==="degraded")t.evidenceOutcomes=t.evidenceOutcomes.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations=t.evidenceDegradations.filter(s=>s.obligationId!==e.obligationId);else if(n)return;e.kind==="degrade"?(t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations.push({obligationId:e.obligationId,contractId:e.contractId,reason:e.reason,degradedAt:e.at,attempt:r,contract:o?.contract})):t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),t.evidenceOutcomes.push({obligationId:e.obligationId,contractId:e.contractId,status:e.kind==="resolve"?"resolved":"degraded",completedAt:e.at,attempt:r,...e.kind==="degrade"?{reason:e.reason}:{}});}persist(t){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),n=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(n,JSON.stringify(t),{mode:384}),renameSync(n,e);}};function Re(i){return Array.isArray(i)?i.flatMap(t=>{if(!t||typeof t!="object")return [];let e=t;if(typeof e.contractId!="string"||e.contractId.length===0||e.contractId.length>128||typeof e.promptedAt!="number"||typeof e.attempt!="number"||typeof e.correctionRequested!="boolean"||!Array.isArray(e.violations)||!ke(e.contract))return [];let n=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:xe(e.contractId),o=typeof e.correctionTranscriptHash=="string"?e.correctionTranscriptHash:void 0,r=e.correctionFingerprint??o;return r!==void 0&&!/^[a-f0-9]{64}$/.test(r)?[]:[{...e,obligationId:n,correctionFingerprint:r}]}).slice(-8):[]}function Ee(i){return Array.isArray(i)?i.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&typeof e.reason=="string"&&typeof e.degradedAt=="number"&&typeof e.attempt=="number"}).slice(-20):[]}function we(i){return Array.isArray(i)?i.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&(e.status==="resolved"||e.status==="degraded")&&typeof e.completedAt=="number"&&typeof e.attempt=="number"&&(e.reason===void 0||typeof e.reason=="string")}).slice(-20):[]}function Lt(i){if(!i||typeof i!="object")return null;let t=i,e=t.kind;if(e!=="add"&&e!=="correction"&&e!=="resolve"&&e!=="degrade"||typeof t.contractId!="string"||t.contractId.length>128||typeof t.at!="number")return null;let o={obligationId:typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:xe(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return ke(t.contract)?{kind:e,...o,contract:t.contract}:null;if(e==="correction"){let r=typeof t.fingerprint=="string"?t.fingerprint:t.transcriptHash;return typeof r=="string"&&/^[a-f0-9]{64}$/.test(r)&&Array.isArray(t.violations)&&t.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:e,...o,fingerprint:r,violations:t.violations}:null}return e==="resolve"?{kind:e,...o}:typeof t.reason=="string"&&t.reason.length<=240?{kind:e,...o,reason:t.reason}:null}function De(i){return i==="add"?0:i==="correction"?1:2}function ke(i){if(!i||typeof i!="object")return false;let t=i,e=t.requiredSections,n=t.prohibitedClaims;return t.version==="1.0"&&typeof t.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(t.id)&&typeof t.runtimeProfilingOccurred=="boolean"&&typeof t.samplingEvidenceOccurred=="boolean"&&Array.isArray(e)&&e.length===3&&e[0]==="\u5DE5\u5177\u53D1\u73B0"&&e[1]==="\u6A21\u578B\u5047\u8BBE"&&e[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(n)&&n.length<=16&&n.every(o=>typeof o=="string"&&o.length<=128)&&typeof t.canonicalReport=="string"&&Buffer.byteLength(t.canonicalReport,"utf8")<=48*1024&&!!t.correctionPolicy&&t.correctionPolicy.maxAttempts===1&&t.correctionPolicy.repeatedViolation==="fail_open"}function q(i){if(!i||typeof i!="object"||Array.isArray(i))return {};let t=i,e={};for(let n of ["lastMcpCall","bypassCount"])if(n in t){let o=t[n];if(o==null)continue;e[n]=typeof o=="number"&&Number.isFinite(o)&&o>=0?o:0;}return e}function jt(i,t){return i.lastMcpCall===t.lastMcpCall&&i.bypassCount===t.bypassCount}function Se(i,t,e){let n=e instanceof Error?e.message:String(e);D({event:"hook.runtime.degraded",identity:{projectRoot:i},level:"warn",timestamp:Date.now(),data:{stage:"enforcement_receipt",operation:t,reason:n,fallback:"fail_open"}});}function Oe(i,t,e){let n;try{n=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let o={},r=n.updateHookReceipt(i,c=>(o=q(c),q(t(o)))),s=q(r);return {receipt:s,applied:!0,changed:!jt(o,s)}}catch(o){return Se(i,e,o),{receipt:{},applied:false,changed:false}}finally{try{n?.close();}catch{}}}function Ae(i){let t;try{return t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),q(t.getHookReceipt(i))}catch(e){return Se(i,"update",e),{}}finally{try{t?.close();}catch{}}}function Pt(i,t){return Oe(i,()=>t,"write").applied}function $t(i,t){return Oe(i,t,"update")}var K={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"},Mt=new Set(["Write","Edit","NotebookEdit"]),Nt=new Set(["failed","timeout","unavailable"]);function Ut(i){switch(i){case "WebSearch":case "WebFetch":return 1;case "Agent":return 3;case "Grep":case "Glob":return 3;case "Bash":return 5;default:return 2}}var W=class{constructor(t,e,n){this.projectRoot=t;this.sessionId=e;this.executionId=n;}getPhase(){if(!this.sessionId||!this.executionId)return "idle";let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let n=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(n&&n.expiresAt>Date.now())return "context_ready";n&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId);}catch{}finally{try{t?.close();}catch{}}let e=new x(this.projectRoot).get(this.sessionId);return e?.executionId===this.executionId&&e.contextInitialization?"context_initializing":"context_gathering"}getContextReceipt(){if(!this.sessionId||!this.executionId)return null;let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let e=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);return e&&e.expiresAt>Date.now()?e:(e&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId),null)}catch{return null}finally{try{t?.close();}catch{}}}evaluate(t,e){let n=this.getPhase();if(e||t==="Skill")return {permissionDecision:"allow"};if(n==="context_initializing"&&K[t])return {permissionDecision:"deny",reasonCode:"DEVFLOW_CONTEXT_INITIALIZING",reason:`DevFlow context initialization is in progress. Wait for ${projectClaudeToolName("get_project_context")} to complete, then retry ${t}.`};if(n==="context_gathering"&&K[t])return {permissionDecision:"deny",reasonCode:"DEVFLOW_CONTEXT_REQUIRED",reason:`DevFlow context required. Call ${projectClaudeToolName("get_project_context")}, then retry ${t}.`};if(n==="context_ready"){if(Mt.has(t)){let a=this.evaluateRequiredAction();if(a)return a}return {permissionDecision:"allow"}}let o=K[t];if(!o)return {permissionDecision:"allow"};let r=$t(this.projectRoot,a=>({...a,bypassCount:(a.bypassCount??0)+1}));if(!r.applied)return {permissionDecision:"allow"};let s=r.receipt.bypassCount??0,c=Ut(t);return s>=c?{permissionDecision:"allow",additionalContext:`\u5DF2 ${s} \u6B21\u76F4\u63A5\u4F7F\u7528 ${t}\uFF0C\u5EFA\u8BAE\u7528 ${projectClaudeToolName(o)} \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`}:{permissionDecision:"allow"}}recordMcpCall(){Pt(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});}recordDomainActionOutcome(t,e,n,o){if(!this.sessionId||!this.executionId)return false;let r;try{r=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let s=r.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(!s||s.expiresAt<=Date.now()||s.canonicalAction?.tool!==t)return !1;let c=Date.now(),a=o?.trim()?`${o.trim()}:${e}`:`${t}:${e}:${c}`,l=s.actionAttempts??[];return r.upsertContextReceipt({...s,actionAttempts:l.some(d=>d.id===a||o&&d.toolUseId===o&&d.status===e)?l:[...l,{id:a,tool:t,status:e,attemptedAt:c,toolUseId:o,reason:n?.slice(0,500)}].slice(-20),actionSatisfiedAt:e==="succeeded"?c:s.actionSatisfiedAt,actionDegradation:e==="succeeded"?void 0:s.actionDegradation}),!0}catch{return false}finally{try{r?.close();}catch{}}}evaluateRequiredAction(){let t=this.getContextReceipt(),e=t?.canonicalAction;if(!t||!e||!e.required||e.status!=="required")return null;let n=e.binding;if(n.requiredContextReceipt!==t.contextHash||n.projectRoot!==this.projectRoot||n.sessionId!==this.sessionId||n.requestId!==t.requestId||n.executionId&&n.executionId!==this.executionId)return {permissionDecision:"deny",reasonCode:"DEVFLOW_ACTION_BINDING_STALE",reason:`DevFlow canonical action binding is stale or mismatched. Call ${projectClaudeToolName("get_project_context")} again before writing.`};if(t.actionSatisfiedAt)return null;if(t.actionDegradation?.authorizedByContextReceipt===t.contextHash)return {permissionDecision:"allow",additionalContext:`DevFlow degraded fallback authorized by context receipt ${t.contextHash}: ${t.actionDegradation.reason}`};let o=(t.actionAttempts??[]).filter(r=>r.tool===e.tool&&Nt.has(r.status));if(o.length>0){let r=o.at(-1),s={missedTool:e.tool,failedAttemptCount:o.length,reason:`${r.status}:${r.reason??"canonical domain action did not complete"}`,authorizedByContextReceipt:t.contextHash,authorizedAt:Date.now()};return this.persistDegradation(t,s),{permissionDecision:"allow",additionalContext:`DevFlow canonical tool ${projectClaudeToolName(e.tool)} ${r.status}; degraded direct write authorized by context receipt ${t.contextHash}. Preserve the action contract and verification plan.`}}return {permissionDecision:"deny",reasonCode:"DEVFLOW_REQUIRED_ACTION",reason:`DevFlow required action not completed. Call ${projectClaudeToolName(e.tool)} using context receipt ${t.contextHash}, then retry the write. Direct fallback is allowed only after unavailable, failed, or timeout evidence.`}}persistDegradation(t,e){let n;try{n=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let o=n.getContextReceipt(t.projectRoot,t.sessionId,t.executionId);if(!o||o.contextHash!==t.contextHash||o.actionDegradation)return;n.upsertContextReceipt({...o,actionDegradation:e});let r=n.getSkillExecution(t.executionId);if(!r)return;let s=r.metadata&&typeof r.metadata=="object"?r.metadata:{},c=Array.isArray(s.requiredActionDegradations)?s.requiredActionDegradations:[];n.updateSkillExecution(t.executionId,{missedMcpTools:[...new Set([...r.missedMcpTools??[],e.missedTool])],failedToolCalls:Math.max(r.failedToolCalls??0,e.failedAttemptCount),fallbackCount:(r.fallbackCount??0)+1,fallbackReasons:[...new Set([...r.fallbackReasons??[],`required_action_${e.reason}`])],metadata:{...s,requiredActionDegradations:[...c,e]}});}catch{}finally{try{n?.close();}catch{}}}};var Yt=10*1024*1024,Kt=5;function Xt(i){return createHash$1("sha256").update(i).digest("hex").slice(0,16)}function Ce(i){return join(homedir(),".devflow","logs","hook-debug",`${Xt(i)}.jsonl`)}function Te(i,t,e={}){let n=e.maxBytes??Yt,o=e.maxFiles??Kt;mkdirSync$1(dirname(i),{recursive:true,mode:448});let r=Buffer.byteLength(t);rotateDiagnosticLogFile({path:i,maxBytes:n,maxFiles:o,incomingBytes:r}),appendFileSync(i,t,{mode:384}),chmodSync(i,384);}var X="WARNING: DevFlow is in degraded mode (daemon unreachable): 4-Gate enforcement and memory prefetch cache are unavailable. Run `devflow doctor` for details.";function Fe(){return process.env.DEVFLOW_HOOK_DEGRADED==="1"}function Le(i){let t=i.trim().replace(/^\//,"");if(!t.startsWith("devflow:"))return null;let e=t.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(e)?`devflow:${e.toLowerCase()}`:null}function je(i,t){return t?`evt_tool_${createHash("sha256").update(`${i}\0${t}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}var nn=new Set(["Write","Edit","NotebookEdit"]),Pe=`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 He(i){if(!nn.has(i.toolName))return null;let t=on(i.toolInput);if(!t)return null;let e=rn(t,i.projectRoot),n=resolve(i.projectRoot,".claude");if($e(e,n)&&basename(e).toLocaleUpperCase("en-US")==="MEMORY.MD")return Pe;let o=resolve(i.home??homedir(),".claude","projects");return $e(e,o)&&relative(o,e).split(sep).some(s=>s.toLocaleLowerCase("en-US")==="memory")?Pe:null}function on(i){for(let t of ["file_path","notebook_path","path"]){let e=i[t];if(typeof e=="string"&&e.trim())return e.trim()}return null}function rn(i,t){return resolve(isAbsolute(i)?i:resolve(t,i))}function $e(i,t){let e=relative(t,i);return e===""||!e.startsWith(`..${sep}`)&&e!==".."&&!isAbsolute(e)}function Be(i){let t=gn(i.toolName,i.toolInput),e=t?fn(i.projectRoot,i.toolName,i.toolInput):void 0;if(!t||!e||!i.toolUseId)return {allowed:true};let n=hn(e),o,r=0,s,c;try{c=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100,readonly:!0});let l=c.getActiveContextReceipt(i.projectRoot,i.sessionId,i.executionId);o=l?.contextHash,r=l?.issuedAt??0,s=l?.canonicalAction?.binding.operationTargets?.find(d=>yn(i.projectRoot,d.path,e));}catch{}finally{try{c?.close();}catch{}}let a={toolUseId:i.toolUseId,sessionId:i.sessionId,executionId:i.executionId,operation:t,path:e,before:n,contextReceipt:o,observedAt:Date.now()};if(_n(i.projectRoot,a),t==="edit"||t==="write"||t==="delete"){let l=Rn(i.projectRoot,e),d=l?.success&&l.operation==="delete"&&!l.after.exists&&l.completedAt>=r,u=s?.expectedState==="existing"&&!n.exists||s?.expectedState==="missing"&&n.exists||!!(s?.contentHash&&n.hash!==s.contentHash);if(d||s?.expectedState==="existing"&&!n.exists)return qe(i,a,"DEVFLOW_FILE_STATE_DELETED","The target was deleted after the active Context receipt. Refresh project context before editing or recreating it.");if(u)return qe(i,a,"DEVFLOW_FILE_STATE_STALE","The target state no longer matches the active Context receipt. Refresh project context before overwriting it.")}return Ve(i,a,true),{allowed:true,pending:a}}function qe(i,t,e,n){return Ve(i,t,false,e),{allowed:false,reasonCode:e,reason:n,pending:t}}function Ve(i,t,e,n){D({event:"canonical.action.validated",identity:{projectRoot:i.projectRoot,sessionId:i.sessionId,executionId:i.executionId,contextReceipt:t.contextReceipt},level:e?"info":"warn",timestamp:Date.now(),data:{stage:"host_file_state_precondition",valid:e,operation:t.operation,targetPath:relative(i.projectRoot,t.path),targetExists:t.before.exists,targetHash:t.before.hash,reason:n,toolUseId:t.toolUseId}});}function gn(i,t){if(i==="Read")return "read";if(i==="Edit"||i==="NotebookEdit")return "edit";if(i==="Write")return "write";if(i==="Delete"||i==="Bash"&&ze(t.command))return "delete"}function fn(i,t,e){let n=mn(e,["file_path","filePath","notebook_path","path","targetPath"])??(t==="Bash"?ze(e.command):void 0);if(!n)return;let o=isAbsolute(n)?normalize(n):resolve(i,n),r=relative(i,o);return r.startsWith("..")||isAbsolute(r)?void 0:o}function ze(i){return typeof i!="string"?void 0:/(?:^|[;&|]\s*)\s*(?:rm|unlink)\s+(?:-[A-Za-z]+\s+)*(?:--\s+)?(["']?)([^\s;&|"']+)\1/u.exec(i)?.[2]}function mn(i,t){for(let e of t){let n=i[e];if(typeof n=="string"&&n.trim())return n.trim()}}function hn(i){if(!existsSync$1(i))return {exists:false};try{return {exists:!0,hash:createHash$1("sha256").update(readFileSync$1(i)).digest("hex")}}catch{return {exists:true}}}function yn(i,t,e){return (isAbsolute(t)?normalize(t):resolve(i,t))===normalize(e)}function Ge(i){return join(w(i),"file-state")}function Ye(i){return join(Ge(i),"pending.json")}function vn(i){return join(Ge(i),"observations.jsonl")}function bn(i){try{return JSON.parse(readFileSync$1(Ye(i),"utf8"))}catch{return {}}}function _n(i,t){let e=Ye(i);mkdirSync$1(dirname(e),{recursive:true});let n=bn(i);n[t.toolUseId]=t,En(e,JSON.stringify(n));}function Rn(i,t){try{let e=readFileSync$1(vn(i),"utf8").trim().split(`
|
|
3
|
+
`);for(let n=e.length-1;n>=0;n-=1){let o=JSON.parse(e[n]);if(o.path===t)return o}}catch{}}function En(i,t){let e=`${i}.${process.pid}.${Date.now()}.tmp`;writeFileSync$1(e,t,{encoding:"utf8",mode:384}),renameSync$1(e,i);}var xn=new Set(["delivered","cancelled","rejected"]),kn=new Set(["cancelled","rejected"]),Sn=new Set(["Write","Edit","NotebookEdit","Bash"]);function On(i,t){if(i!=="Bash"||typeof t?.command!="string")return false;let n="git show [A-Za-z0-9._/:@{}^~+\\-]+(?: 2>/dev/null)?";return new RegExp(`^${n}(?: \\|\\| ${n})*$`,"u").test(t.command)}function ne(i,t,e,n,o){if(!Sn.has(e)||!t.trim()||On(e,o))return null;let r=join(i,".devflow","delivery-line","state.db");if(!existsSync$1(r))return null;let s;try{s=new DatabaseSync(r,{readOnly:!0,timeout:250});let c=s.prepare("SELECT id, payload, updated_at FROM delivery_cases").all(),a=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 g of f){let v=[];try{v=JSON.parse(g.aliases);}catch{}(g.source_path===i||v.includes(i))&&a.add(g.case_id);}}let d=[];for(let f of c){let g=JSON.parse(f.payload),v=a.has(f.id);(g.sessionId===t||t===f.id||v)&&d.push({id:f.id,payload:g,updatedAt:typeof f.updated_at=="number"?f.updated_at:typeof g.updatedAt=="number"?g.updatedAt:0});let y=typeof g.stage=="string"?g.stage:"unknown";if(!xn.has(y)){if(n&&y==="executing"){let m=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()),b=typeof g.sessionId=="string"?g.sessionId:void 0,L=typeof g.executionId=="string"?g.executionId:void 0,O=n===m?.id||n===m?.lease_owner||n===L,B=t===f.id||t===b;if(m?.id&&O&&B)return null}if(g.sessionId===t||t===f.id||v)return {code:"DELIVERY_AUTHORITY_REQUIRED",caseId:f.id,stage:y,message:`Delivery case ${f.id} is ${y}; use the Delivery task lease before modifying files.`}}}let u=d.sort((f,g)=>g.updatedAt-f.updatedAt)[0],p=typeof u?.payload.stage=="string"?u.payload.stage:void 0;return u&&p&&kn.has(p)?{code:"DELIVERY_AUTHORITY_REQUIRED",caseId:u.id,stage:p,message:`Delivery case ${u.id} is ${p}; start a new Delivery case or session before modifying files.`}:null}catch{return {code:"DELIVERY_AUTHORITY_UNAVAILABLE",caseId:"unknown",stage:"unknown",message:"Delivery state cannot be read; file writes are blocked until runtime health is restored."}}finally{s?.close();}}function F(){return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}function ie(i){return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:i}}}function Pn(i){let t=w(i);return existsSync(t)||mkdirSync(t,{recursive:true}),t}function $n(i,t,e,n,o,r){let s=join$1(Pn(i),"event-map.json"),c=[];try{existsSync(s)&&(c=JSON.parse(readFileSync(s,"utf-8")));}catch{}c.push({sessionId:t,toolName:e,toolUseId:n,eventId:o,timestamp:r}),writeFileSync(s,JSON.stringify(c));}function Mn(i){switch(i){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 Nn(i,t,e){if(t!=="Read"||typeof e.file_path!="string"||!e.file_path.trim())return null;let n=e.file_path.startsWith("/")?e.file_path:join$1(i,e.file_path);try{if(statSync(n).isDirectory())return `Read accepts files, but "${e.file_path}" is a directory. Use Glob or Bash ls to inspect directory entries, then Read one file.`}catch{return null}return null}function Un(){let i=process.env.CLAUDE_PLUGIN_ROOT;if(!i)return null;let t=join$1(i,"package.json"),e=join$1(i,".mcp.json");try{let n=JSON.parse(readFileSync(t,"utf8")),r=JSON.parse(readFileSync(e,"utf8")).mcpServers?.devflow,s=r?.args;if(r?.command==="node"&&Array.isArray(s)&&s[0]==="${CLAUDE_PLUGIN_ROOT}/node_modules/@devflow-tools/mcp-server/bin/devflow-mcp.cjs")return existsSync(join$1(i,"node_modules/@devflow-tools/mcp-server/bin/devflow-mcp.cjs"))?null:"bundled DevFlow MCP runtime is not installed";let a=Array.isArray(s)?s.indexOf("--package"):-1,l=a>=0&&typeof s?.[a+1]=="string"?s[a+1]:void 0,d=typeof n.version=="string"?`@devflow-tools/mcp-server@${n.version}`:void 0;return l?d&&l!==d?`DevFlow MCP version mismatch (${l} vs ${d})`:null:"DevFlow MCP package configuration is missing"}catch{return "DevFlow MCP configuration could not be inspected"}}function Hn(i,t){return i==="Grep"||i==="Glob"?true:i!=="Bash"||typeof t.command!="string"?false:/^(?:ls|pwd|find|rg|grep|git\s+(?:status|diff|log|branch)|cat|sed|head|tail|wc)\b/u.test(t.command.trim())}async function qn(i){let t=Fe();try{if(!i||i.trim()==="")return F();let e=JSON.parse(i),n=Date.now();try{maybeRunDiagnosticLogCleanup(C(),{now:n});}catch{}let o=C(),r=new N,s=resolveClaudeToolName(e.tool_name,e.tool_input),c=s.status==="unsupported"?void 0:s.canonicalName;c&&(typeof e.tool_input.projectRoot!="string"||!e.tool_input.projectRoot.trim())&&(e.tool_input.projectRoot=o);let a=e.session_id?.trim();if(!a)return ie(X);let l=new x(o),d=l.get(a)!==null;if(l.registerSession(a),d||await r.sendSessionStart(a,o,Date.now()),e.tool_name==="Skill"){let _=e.tool_input?.skill,h=_?Le(_):null;if(h){let R=l.get(a)?.executionId,E=l.startExecution(a,h,he(h));E.executionId&&E.executionId!==R&&await r.sendExecutionStart(E.executionId,a,h,E.lastActivityAt,o,E.requiredMcpTools);}}let u=l.get(a);c==="get_project_context"&&l.beginContextInitialization(a,e.tool_use_id),c&&(e.tool_input._devflow_session_id=a,e.tool_input._devflow_execution_id=u?.executionId??a,u?.activeTurnId&&(e.tool_input._devflow_turn_id=u.activeTurnId),u?.activeRequestId&&(e.tool_input._devflow_request_id=u.activeRequestId),u?.intentArtifactHash&&(e.tool_input._devflow_intent_artifact_hash=u.intentArtifactHash),u?.skillName&&(e.tool_input._devflow_active_skill=u.skillName),e.tool_use_id&&(e.tool_input._devflow_tool_use_id=e.tool_use_id));let p=e.tool_name.startsWith("mcp__"),f=c,g=l.get(a),v=new W(o,a,g?.executionId),y=v.getPhase(),m,b,L=Nn(o,e.tool_name,e.tool_input),O=ne(o,a,e.tool_name,g?.executionId,e.tool_input);if(L)b="DEVFLOW_DIRECTORY_READ_INVALID",m={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:L}};else if(O)b=O.code,m={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`${O.message} Resolve the case blocker or obtain an authorized task lease before retrying.`}};else {let _=He({toolName:e.tool_name,toolInput:e.tool_input,projectRoot:o}),h=Be({projectRoot:o,sessionId:a,executionId:g?.executionId,toolUseId:e.tool_use_id,toolName:e.tool_name,toolInput:e.tool_input}),R=_?{permissionDecision:"deny",reason:_}:h.allowed?v.evaluate(e.tool_name,p):{permissionDecision:"deny",reason:h.reason,reasonCode:h.reasonCode},E=R.permissionDecision==="deny"&&!p&&Hn(e.tool_name,e.tool_input)?Un():null;E?(m=ie(`DevFlow MCP is unavailable or stale: ${E}. This read-only fallback is temporary; refresh the plugin installation and call ${projectClaudeToolName("get_project_context")} before editing.`),b=void 0):R.permissionDecision==="deny"?(b=_?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":R.reasonCode??"DEVFLOW_CONTEXT_REQUIRED",m={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:R.reason??"MCP context required"}}):R.additionalContext?m=ie(R.additionalContext):m=F();}c&&(m.hookSpecificOutput.updatedInput=e.tool_input),t&&m.hookSpecificOutput.permissionDecision==="allow"&&(m.hookSpecificOutput.additionalContext=X);let B=g?.executionId??a,A={eventId:je(a,e.tool_use_id),executionId:B,sessionId:a,projectRoot:o,toolUseId:e.tool_use_id,timestamp:Date.now(),toolName:e.tool_name,toolType:p?"mcp":e.tool_name==="Agent"?"subagent":"direct",isMcpTool:p,mcpToolName:f,mcpEnforced:p&&(y==="context_gathering"||y==="context_initializing"),mcpFallback:!p&&(y==="context_gathering"||y==="context_initializing"),kind:Mn(e.tool_name),input:e.tool_input,duration:0,blocked:m.hookSpecificOutput.permissionDecision==="deny",blockReason:m.hookSpecificOutput.permissionDecision==="deny"?b??"DEVFLOW_CONTEXT_REQUIRED":void 0},j=await r.sendEvent(A);j&&!A.blocked&&$n(o,a,e.tool_name,e.tool_use_id,j,A.timestamp),j&&A.blocked&&await r.completeEvent({eventId:j,sessionId:a,error:b??"DEVFLOW_CONTEXT_REQUIRED",duration:Date.now()-A.timestamp,completedAt:Date.now()});try{let _=Ae(o),h={ts:n,tool:e.tool_name,sessionId:a,skill:u?.skillName??"(none)",requiredTools:u?.requiredMcpTools??[],isMcp:p,enforce:u?.executionId!==void 0,stateless:u?.executionId===void 0&&!p&&e.tool_name!=="Skill",bypassCount:_.bypassCount??0,decision:m.hookSpecificOutput.permissionDecision,env_CLAUDE_PLUGIN_ROOT:process.env.CLAUDE_PLUGIN_ROOT??"(unset)",cwd:process.cwd()};Te(Ce(o),`${JSON.stringify(h)}
|
|
4
|
+
`);}catch{}return m}catch{try{let e=JSON.parse(i),n=C(),o=ne(n,String(e.session_id??""),String(e.tool_name??""),void 0,e.tool_input);if(o)return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:o.message}}}catch{}return F()}}if(process.argv[1]?.endsWith("pre-tool-use")||process.argv[1]?.endsWith("pre-tool-use.js")){let i=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",e=>{t+=e;}),process.stdin.on("end",async()=>{let e=await qn(t);i(JSON.stringify(e));}),process.stdin.on("error",()=>{i(JSON.stringify(F())),process.exit(0);}),setTimeout(()=>{i(JSON.stringify(F())),process.exit(0);},4e3).unref();}export{qn as handlePreToolUse};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devflow",
|
|
3
3
|
"description": "DevFlow — Developer Intelligence Platform: project context, code graph, knowledge base, memory engine, and workflow automation with 14 domain plugins",
|
|
4
|
-
"version": "0.18.
|
|
4
|
+
"version": "0.18.50",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "DevFlow"
|
|
7
7
|
},
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
],
|
|
9
9
|
"blockedNative": [],
|
|
10
10
|
"source": "core",
|
|
11
|
-
"sourceVersion": "0.18.
|
|
11
|
+
"sourceVersion": "0.18.50",
|
|
12
12
|
"requiresContext": false,
|
|
13
13
|
"evidenceMode": "runtime",
|
|
14
14
|
"skillPath": "skills/devflow:doctor/SKILL.md",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"WebFetch"
|
|
36
36
|
],
|
|
37
37
|
"source": "core",
|
|
38
|
-
"sourceVersion": "0.18.
|
|
38
|
+
"sourceVersion": "0.18.50",
|
|
39
39
|
"requiresContext": true,
|
|
40
40
|
"evidenceMode": "mixed",
|
|
41
41
|
"skillPath": "skills/devflow:context/SKILL.md",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"Explore"
|
|
61
61
|
],
|
|
62
62
|
"source": "core",
|
|
63
|
-
"sourceVersion": "0.18.
|
|
63
|
+
"sourceVersion": "0.18.50",
|
|
64
64
|
"requiresContext": true,
|
|
65
65
|
"evidenceMode": "mixed",
|
|
66
66
|
"skillPath": "skills/devflow:graph/SKILL.md",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"WebFetch"
|
|
80
80
|
],
|
|
81
81
|
"source": "core",
|
|
82
|
-
"sourceVersion": "0.18.
|
|
82
|
+
"sourceVersion": "0.18.50",
|
|
83
83
|
"requiresContext": true,
|
|
84
84
|
"evidenceMode": "mixed",
|
|
85
85
|
"skillPath": "skills/devflow:knowledge/SKILL.md",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"Explore"
|
|
104
104
|
],
|
|
105
105
|
"source": "core",
|
|
106
|
-
"sourceVersion": "0.18.
|
|
106
|
+
"sourceVersion": "0.18.50",
|
|
107
107
|
"requiresContext": true,
|
|
108
108
|
"evidenceMode": "mixed",
|
|
109
109
|
"skillPath": "skills/devflow:memory/SKILL.md",
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
],
|
|
120
120
|
"blockedNative": [],
|
|
121
121
|
"source": "core",
|
|
122
|
-
"sourceVersion": "0.18.
|
|
122
|
+
"sourceVersion": "0.18.50",
|
|
123
123
|
"requiresContext": true,
|
|
124
124
|
"evidenceMode": "mixed",
|
|
125
125
|
"skillPath": "skills/devflow:workflow/SKILL.md",
|
|
@@ -152,7 +152,7 @@
|
|
|
152
152
|
],
|
|
153
153
|
"blockedNative": [],
|
|
154
154
|
"source": "core",
|
|
155
|
-
"sourceVersion": "0.18.
|
|
155
|
+
"sourceVersion": "0.18.50",
|
|
156
156
|
"requiresContext": true,
|
|
157
157
|
"evidenceMode": "mixed",
|
|
158
158
|
"skillPath": "skills/devflow:delivery/SKILL.md",
|