@devflow-tools/claude-code-plugin 0.18.35 → 0.18.36

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.
@@ -1,8 +1,8 @@
1
- import {existsSync,readFileSync,rmSync,mkdirSync,writeFileSync,linkSync,readdirSync,renameSync,unlinkSync}from'fs';import {join as join$1,dirname as dirname$1}from'path';import {getLogWriter,emitSemanticControlLog,SemanticRuntimeEventProjector,rotateDiagnosticLogFile}from'@devflow-tools/telemetry';import {getLocalApiKey,getDevFlowStateRoot,resolveClaudeToolName,projectClaudeToolName,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir,parseTrustedDecisionCommand,domainHash,encodeDecisionValue,canonicalJsonBytes,readRuntimeState}from'@devflow-tools/sdk';import {request}from'node:http';import {mkdirSync as mkdirSync$1,appendFileSync,existsSync as existsSync$1,readFileSync as readFileSync$1,writeFileSync as writeFileSync$1,renameSync as renameSync$1,readdirSync as readdirSync$1}from'node:fs';import {join,dirname,relative,resolve,isAbsolute,sep}from'node:path';import {openGlobalDevFlowDatabase,retrievalLedgerTransitionId}from'@devflow-tools/database';import {randomUUID,createHash}from'crypto';import {fileURLToPath}from'url';import {TaskKernel,TaskEventStore}from'@devflow-tools/task-runtime';import {randomUUID as randomUUID$1,createHash as createHash$1,generateKeyPairSync,sign}from'node:crypto';import {classifyWorkflowFailure}from'@devflow-tools/workflow-engine/failure-classifier';import {createTrustedDeliveryFacade}from'@devflow-tools/mcp-server/trusted-delivery-runtime';function Q(n,t,e){try{let o=openGlobalDevFlowDatabase();try{o.insertEvent({kind:n,timestamp:Date.now(),duration:e,success:t.success!==!1,metadata:t});}finally{o.close();}}catch{}}var Rt=getLocalApiKey(),X=join(getDevFlowStateRoot(),"errors");async function q(n,t,e={}){let o=e.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??xt();if(!o)return {delivered:false,suppressed:false,fallbackReason:"runtime_not_ready"};let r=e.timeout??1500,i=e.durableMirror??true,s=e.maxRetries??(i?0:2),a=e.circuitBreaker??true,c=acquireRuntimeHttpCircuit(o,n);if(a&&!c.allowed)return {delivered:false,suppressed:true,fallbackReason:c.state.fallbackReason};let l;for(let u=0;u<=s;u+=1)try{return await kt(o,n,t,r),a&&registerRuntimeHttpSuccess(o,n).transitioned&&Q("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(p){l=p instanceof Error?p:new Error(String(p)),u<s&&await St(Math.min(100*2**u,1e3));}if(!l)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return me(n,l),{delivered:false,suppressed:false,fallbackReason:l.message};let d=registerRuntimeHttpFailure(o,n,e.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return d.transitioned&&(me(n,l),Q("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.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 xt(){let n=readRuntimeState();return n?.status==="ready"&&n.dashboardAvailable?n.url:void 0}function kt(n,t,e,o){return new Promise((r,i)=>{let s=JSON.stringify(e),a=new URL(t,n),c=false,l=u=>{c||(c=true,u?i(u):r());},d=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":Rt,"Content-Length":Buffer.byteLength(s)},timeout:o},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 ${o}ms`))),d.write(s),d.end();})}function me(n,t){try{existsSync$1(X)||mkdirSync$1(X,{recursive:!0});let e=join(X,"http-errors.log"),o=`${new Date().toISOString()} | ${n} | ${t.message}
2
- `;rotateDiagnosticLogFile({path:e,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(o)}),appendFileSync(e,o);}catch{}}function St(n){return new Promise(t=>setTimeout(t,n))}var y=emitSemanticControlLog;function Y(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function S(n){return getProjectStateDir(Y(n))}function Ie(n){return Buffer.from(n,"utf8").toString("base64url")}function Ct(n,t,e){let o=t?.trim();if(o){let r=/^[a-zA-Z0-9:._-]{1,192}$/.test(o)?o:`tool-${createHash("sha256").update(o.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${r}`}return `${n}:legacy-${e}-${randomUUID().slice(0,8)}`}function Se(n){return `${n}:legacy-journal`}var E=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(S(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let o=this.get(e);if(o)return o.lastActivityAt=Date.now(),this.persist(o),o;let r=Date.now(),i={sessionId:e,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:r,lastActivityAt:r};return this.sessions.set(e,i),this.persist(i),i}startExecution(t,e,o){let r=this.registerSession(t);return (!r.executionId||r.skillName!==e)&&(r.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),r.skillName=e,r.requiredMcpTools=[...new Set(o)],delete r.contextInitialization,r.lastActivityAt=Date.now(),this.persist(r),r}beginContextInitialization(t,e){let o=this.registerSession(t);return o.contextInitialization={startedAt:Date.now(),...e?{toolUseId:e}:{}},o.lastActivityAt=Date.now(),this.persist(o),o}completeContextInitialization(t,e){let o=this.get(t);return o?(e&&o.contextInitialization?.toolUseId&&o.contextInitialization.toolUseId!==e||(delete o.contextInitialization,o.lastActivityAt=Date.now(),this.persist(o)),o):null}bindTaskIdentity(t,e){let o=this.registerSession(t);return o.activeTurnId=e.turnId,o.activeRequestId=e.requestId,o.intentArtifactHash=e.intentArtifactHash,o.lastActivityAt=Date.now(),this.persist(o),o}get(t){let e=t.trim();if(!e)return null;let o=this.sessions.get(e);if(o)return this.replayEvidenceJournal(o),o;let r=this.snapshotPath(e);if(!existsSync(r))return null;try{let i=JSON.parse(readFileSync(r,"utf8"));return i.sessionId!==e||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=we(i.evidenceObligations),i.evidenceDegradations=_e(i.evidenceDegradations),i.evidenceOutcomes=Re(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(e,i),i)}catch{return null}}completeExecution(t){let e=this.get(t);if(!e)return null;let o=structuredClone(e);return delete e.executionId,delete e.skillName,delete e.contextInitialization,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),o}addEvidenceObligation(t,e,o=Date.now(),r){let i=this.registerSession(t),a=(r?void 0:i.evidenceObligations.find(l=>l.contractId===e.id))?.obligationId??Ct(e.id,r,o);this.appendEvidenceEvent(t,{kind:"add",obligationId:a,contractId:e.id,at:o,contract:e},`add\0${a}`),this.replayEvidenceJournal(i);let c=i.evidenceObligations.find(l=>l.obligationId===a);return c?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(c)):null}listEvidenceObligations(t){return (this.get(t)?.evidenceObligations??[]).map(e=>structuredClone(e))}markEvidenceCorrection(t,e,o,r,i=Date.now()){let s=this.get(t),a=s?.evidenceObligations.find(d=>d.obligationId===e);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(r)?r:"";if(!c)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:a.contractId,at:i,fingerprint:c,violations:o.slice(0,16).map(d=>d.slice(0,240))},`correction\0${e}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let l=s.evidenceObligations.find(d=>d.obligationId===e);return l?structuredClone(l):null}resolveEvidenceObligation(t,e){let o=this.get(t);if(!o)return false;let r=o.evidenceObligations.find(s=>s.obligationId===e);if(!r)return false;let i=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:r.contractId,at:i},`resolve\0${e}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}resolveDegradedEvidence(t,e){let o=this.get(t),r=o?.evidenceDegradations.find(s=>s.obligationId===e);if(!o||!r)return false;let i=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:r.contractId,at:i},`resolve-degraded\0${e}\0${i}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}degradeEvidenceObligation(t,e,o,r=Date.now()){let i=this.get(t),s=i?.evidenceObligations.find(c=>c.obligationId===e);if(!i||!s)return false;let a=o.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:r,reason:a},`degrade\0${e}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=r,this.persist(i),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,`${Ie(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",Ie(t))}appendEvidenceEvent(t,e,o){let r=this.evidenceJournalDir(t);mkdirSync(r,{recursive:true,mode:448});let i=createHash("sha256").update(o).digest("hex"),s=join$1(r,`${e.kind}-${i}.json`);if(existsSync(s))return;let a=join$1(r,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(a,JSON.stringify(e),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(t){t.evidenceObligations=we(t.evidenceObligations),t.evidenceDegradations=_e(t.evidenceDegradations),t.evidenceOutcomes=Re(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync(e))return;let o;try{o=readdirSync(e).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let r=o.flatMap(i=>{try{let s=readFileSync(join$1(e,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=jt(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||xe(i.kind)-xe(s.kind));for(let i of r)this.applyEvidenceEvent(t,i);t.evidenceObligations=t.evidenceObligations.slice(-8),t.evidenceDegradations=t.evidenceDegradations.slice(-20),t.evidenceOutcomes=t.evidenceOutcomes.slice(-20);}applyEvidenceEvent(t,e){let o=t.evidenceOutcomes.find(s=>s.obligationId===e.obligationId);if(e.kind==="add"){if(o)return;let s=t.evidenceObligations.find(a=>a.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 r=t.evidenceObligations.find(s=>s.obligationId===e.obligationId);if(e.kind==="correction"){if(!r||o||r.correctionFingerprint===e.fingerprint)return;r.attempt+=1,r.correctionRequested=true,r.correctionRequestedAt=e.at,r.correctionFingerprint=e.fingerprint,r.violations=e.violations;return}let i=r?.attempt??o?.attempt??0;if(e.kind==="resolve"&&o?.status==="degraded")t.evidenceOutcomes=t.evidenceOutcomes.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations=t.evidenceDegradations.filter(s=>s.obligationId!==e.obligationId);else if(o)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:i,contract:r?.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:i,...e.kind==="degrade"?{reason:e.reason}:{}});}persist(t){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),o=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(o,JSON.stringify(t),{mode:384}),renameSync(o,e);}};function we(n){return Array.isArray(n)?n.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)||!Ee(e.contract))return [];let o=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:Se(e.contractId),r=typeof e.correctionTranscriptHash=="string"?e.correctionTranscriptHash:void 0,i=e.correctionFingerprint??r;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...e,obligationId:o,correctionFingerprint:i}]}).slice(-8):[]}function _e(n){return Array.isArray(n)?n.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 Re(n){return Array.isArray(n)?n.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 jt(n){if(!n||typeof n!="object")return null;let t=n,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 r={obligationId:typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:Se(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return Ee(t.contract)?{kind:e,...r,contract:t.contract}:null;if(e==="correction"){let i=typeof t.fingerprint=="string"?t.fingerprint:t.transcriptHash;return typeof i=="string"&&/^[a-f0-9]{64}$/.test(i)&&Array.isArray(t.violations)&&t.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:e,...r,fingerprint:i,violations:t.violations}:null}return e==="resolve"?{kind:e,...r}:typeof t.reason=="string"&&t.reason.length<=240?{kind:e,...r,reason:t.reason}:null}function xe(n){return n==="add"?0:n==="correction"?1:2}function Ee(n){if(!n||typeof n!="object")return false;let t=n,e=t.requiredSections,o=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(o)&&o.length<=16&&o.every(r=>typeof r=="string"&&r.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 ne(n){if(!n||typeof n!="object"||Array.isArray(n))return {};let t=n,e={};for(let o of ["lastMcpCall","bypassCount"])if(o in t){let r=t[o];if(r==null)continue;e[o]=typeof r=="number"&&Number.isFinite(r)&&r>=0?r:0;}return e}function Ft(n,t){return n.lastMcpCall===t.lastMcpCall&&n.bypassCount===t.bypassCount}function $t(n,t,e){let o=e instanceof Error?e.message:String(e);y({event:"hook.runtime.degraded",identity:{projectRoot:n},level:"warn",timestamp:Date.now(),data:{stage:"enforcement_receipt",operation:t,reason:o,fallback:"fail_open"}});}function Ae(n,t,e){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let r={},i=o.updateHookReceipt(n,a=>(r=ne(a),ne(t(r)))),s=ne(i);return {receipt:s,applied:!0,changed:!Ft(r,s)}}catch(r){return $t(n,e,r),{receipt:{},applied:false,changed:false}}finally{try{o?.close();}catch{}}}function re(n,t){return Ae(n,()=>t,"write").applied}function Pt(n,t){return Ae(n,t,"update")}var oe={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"},qt=new Set(["Write","Edit","NotebookEdit"]),Lt=new Set(["failed","timeout","unavailable"]);function Mt(n){switch(n){case "WebSearch":case "WebFetch":return 1;case "Agent":return 3;case "Grep":case "Glob":return 3;case "Bash":return 5;default:return 2}}var M=class{constructor(t,e,o){this.projectRoot=t;this.sessionId=e;this.executionId=o;}getPhase(){if(!this.sessionId||!this.executionId)return "idle";let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let o=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(o&&o.expiresAt>Date.now())return "context_ready";o&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId);}catch{}finally{try{t?.close();}catch{}}let e=new E(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 o=this.getPhase();if(e||t==="Skill")return {permissionDecision:"allow"};if(o==="context_initializing"&&oe[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(o==="context_gathering"&&oe[t])return {permissionDecision:"deny",reasonCode:"DEVFLOW_CONTEXT_REQUIRED",reason:`DevFlow context required. Call ${projectClaudeToolName("get_project_context")}, then retry ${t}.`};if(o==="context_ready"){if(qt.has(t)){let c=this.evaluateRequiredAction();if(c)return c}return {permissionDecision:"allow"}}let r=oe[t];if(!r)return {permissionDecision:"allow"};let i=Pt(this.projectRoot,c=>({...c,bypassCount:(c.bypassCount??0)+1}));if(!i.applied)return {permissionDecision:"allow"};let s=i.receipt.bypassCount??0,a=Mt(t);return s>=a?{permissionDecision:"allow",additionalContext:`\u5DF2 ${s} \u6B21\u76F4\u63A5\u4F7F\u7528 ${t}\uFF0C\u5EFA\u8BAE\u7528 ${projectClaudeToolName(r)} \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`}:{permissionDecision:"allow"}}recordMcpCall(){re(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});}recordDomainActionOutcome(t,e,o,r){if(!this.sessionId||!this.executionId)return false;let i;try{i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let s=i.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(!s||s.expiresAt<=Date.now()||s.canonicalAction?.tool!==t)return !1;let a=Date.now(),c=r?.trim()?`${r.trim()}:${e}`:`${t}:${e}:${a}`,l=s.actionAttempts??[];return i.upsertContextReceipt({...s,actionAttempts:l.some(d=>d.id===c||r&&d.toolUseId===r&&d.status===e)?l:[...l,{id:c,tool:t,status:e,attemptedAt:a,toolUseId:r,reason:o?.slice(0,500)}].slice(-20),actionSatisfiedAt:e==="succeeded"?a:s.actionSatisfiedAt,actionDegradation:e==="succeeded"?void 0:s.actionDegradation}),!0}catch{return false}finally{try{i?.close();}catch{}}}evaluateRequiredAction(){let t=this.getContextReceipt(),e=t?.canonicalAction;if(!t||!e||!e.required||e.status!=="required")return null;let o=e.binding;if(o.requiredContextReceipt!==t.contextHash||o.projectRoot!==this.projectRoot||o.sessionId!==this.sessionId||o.requestId!==t.requestId||o.executionId&&o.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 r=(t.actionAttempts??[]).filter(i=>i.tool===e.tool&&Lt.has(i.status));if(r.length>0){let i=r.at(-1),s={missedTool:e.tool,failedAttemptCount:r.length,reason:`${i.status}:${i.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)} ${i.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 o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let r=o.getContextReceipt(t.projectRoot,t.sessionId,t.executionId);if(!r||r.contextHash!==t.contextHash||r.actionDegradation)return;o.upsertContextReceipt({...r,actionDegradation:e});let i=o.getSkillExecution(t.executionId);if(!i)return;let s=i.metadata&&typeof i.metadata=="object"?i.metadata:{},a=Array.isArray(s.requiredActionDegradations)?s.requiredActionDegradations:[];o.updateSkillExecution(t.executionId,{missedMcpTools:[...new Set([...i.missedMcpTools??[],e.missedTool])],failedToolCalls:Math.max(i.failedToolCalls??0,e.failedAttemptCount),fallbackCount:(i.fallbackCount??0)+1,fallbackReasons:[...new Set([...i.fallbackReasons??[],`required_action_${e.reason}`])],metadata:{...s,requiredActionDegradations:[...a,e]}});}catch{}finally{try{o?.close();}catch{}}}};var Ce=1e4,Bt=3e4,U=500,H=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,o,r,i=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:t,sessionId:e,skillName:o,startedAt:r,projectRoot:i,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(t,e="completed",o=Date.now(),r){let i={executionId:t,status:e,finishedAt:o,metadata:r},s=this.commitOrCache("execution_complete",i);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",i),s}async sendSessionStart(t,e,o){let r={id:t,projectRoot:e,startedAt:o,label:e.split("/").pop()??"unknown"},i=this.commitOrCache("session_start",r);return i&&this.postHttp("/api/telemetry/sessions",r),i}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 o={sessionId:t,finishedAt:e},r=this.commitOrCache("session_end",o);return r&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(t)}/close`,{finishedAt:e})),r}async flushCache(){try{let e=this.getDatabase(),o=e.listTelemetryFailures({unresolvedOnly:!0,limit:U}).reverse();for(let r of o)try{this.applyOperation(r.operation,r.payload),e.resolveTelemetryFailure(r.id);}catch{}e.trimTelemetryFailures(U);}catch{}let t=(existsSync(this.cacheDir)?readdirSync(this.cacheDir):[]).filter(e=>e.endsWith(".json")).map(e=>{let o=join$1(this.cacheDir,e);try{return {cacheFile:o,envelope:Kt(JSON.parse(readFileSync(o,"utf8")))}}catch{return null}}).filter(e=>e!==null).sort((e,o)=>e.envelope.timestamp-o.envelope.timestamp||je(e.envelope.operation)-je(o.envelope.operation));for(let{cacheFile:e,envelope:o}of t)try{let r=this.getDatabase();r.insertTelemetryFailure({id:o.id,operation:o.operation,payload:o.payload,error:o.failure,createdAt:o.timestamp}),this.applyOperation(o.operation,o.payload),r.resolveTelemetryFailure(o.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(o){return this.cacheOperation(t,e,o),false}}applyOperation(t,e){let o=this.getDatabase();switch(t){case "tool_call":this.ensureParentSession(o,e),o.insertToolCallEvent(e);return;case "execution_start":this.ensureParentSession(o,e),o.insertSkillExecution({executionId:e.executionId,sessionId:e.sessionId,skillName:e.skillName,startedAt:e.startedAt,status:"running",requiredMcpTools:e.requiredMcpTools});return;case "execution_complete":o.reconcileSkillExecution(e.executionId,e.status,e.finishedAt,e.metadata);return;case "session_start":o.ensureSession(e),o.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(!o.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":o.closeSession(e.sessionId,e.finishedAt),o.updateRun(Fe(e.sessionId),{status:"completed",finishedAt:e.finishedAt});return}}ensureParentSession(t,e){let o=typeof e.sessionId=="string"?e.sessionId.trim():"";if(!o)throw new Error("Canonical session ID is required for telemetry");let r=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:o,projectRoot:r,label:r==="unknown"?void 0:r.split("/").pop(),startedAt:Number(e.startedAt??e.timestamp??Date.now())});}cacheOperation(t,e,o){let r=Date.now(),i={id:`failure:${r}:${Math.random().toString(36).slice(2,11)}`,operation:t,payload:e,failure:o instanceof Error?o.message:String(o),timestamp:r};try{let s=this.getDatabase();s.insertTelemetryFailure({id:i.id,operation:t,payload:e,error:i.failure,createdAt:r}),s.trimTelemetryFailures(U),this.scheduleRetry();return}catch{}try{existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${r}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(i,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-U)))unlinkSync(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},Bt).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){q(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 je(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function Fe(n){return `hook-run:${n}`}function Kt(n){if(!n||typeof n!="object")throw new Error("Invalid telemetry cache envelope");let t=n;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}var Qt=2,Xt=1;function Yt(){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 $e(n=Yt()){let t=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let e of t)try{if(!existsSync(e))continue;let o=JSON.parse(readFileSync(e,"utf8"));if(o.version!==Qt&&o.version!==Xt||!en(o.commands)){y({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 o.commands}catch(o){y({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:o.message,fallback:"next_registry_candidate"}});}return null}function en(n){return !n||typeof n!="object"||Array.isArray(n)?false:Object.values(n).every(t=>{if(!t||typeof t!="object"||Array.isArray(t))return false;let e=t;return V(e.mcpTools)&&V(e.blockedNative)&&(e.source===void 0||e.source==="core"||e.source==="plugin")&&(e.requiresContext===void 0||typeof e.requiresContext=="boolean")&&(e.runtimePackages===void 0||V(e.runtimePackages))&&(e.hostTools===void 0||tn(e.hostTools))&&(e.evidenceMode===void 0||["static","runtime","mixed"].includes(e.evidenceMode))})}function tn(n){return !!n&&typeof n=="object"&&!Array.isArray(n)&&Object.entries(n).every(([t,e])=>t.length>0&&V(e))}function V(n){return Array.isArray(n)&&n.every(t=>typeof t=="string"&&t.length>0)}function Pe(n){let t=$e();return t?t[n]?.mcpTools??[]:[]}function qe(n){let t=n.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 Le(n,t){return t?`evt_tool_${createHash("sha256").update(`${n}\0${t}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}function T(n){let{projectRoot:t,...e}=n;try{return new se(t).dispatchBoundary(e).snapshot??null}catch(o){return y({event:"hook.runtime.degraded",identity:{projectRoot:t,sessionId:n.sessionId,...n.turnId?{turnId:n.turnId}:{},...n.requestId?{requestId:n.requestId}:{},...n.executionId?{executionId:n.executionId}:{}},level:"error",timestamp:Date.now(),data:{stage:n.kind,reason:o instanceof Error?o.message:String(o),tool:n.producer}}),null}}var se=class{constructor(t){this.projectRoot=t;}dispatchBoundary(t){let e=cn(t.kind,t.payload??{});if(!e)return {handled:false};let o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let r=an(o,{projectRoot:this.projectRoot,sessionId:t.sessionId,...t.turnId?{turnId:t.turnId}:{},...t.requestId?{requestId:t.requestId}:{},...t.executionId?{executionId:t.executionId}:{}});return r?{handled:!0,snapshot:new TaskKernel(new TaskEventStore(o),new SemanticRuntimeEventProjector).dispatch({definition:r.definition,kind:e.kind,payload:e.payload,idempotencyKey:`host:${r.definition.definitionHash}:${t.dedupeKey}`,producer:t.producer}).snapshot}:{handled:!1}}finally{o.close();}}};function an(n,t){let e=t.executionId?n.getActiveContextReceipt(t.projectRoot,t.sessionId,t.executionId):null,o=t.turnId??e?.canonicalAction?.binding.turnId,r=t.requestId??e?.requestId;if(!o&&!r)return null;let i=n.listLatestTaskIntentArtifacts(t.projectRoot,t.sessionId).find(c=>o?c.turnId===o:c.requestId===r);if(!i)return null;let s=n.getTaskAggregateSnapshot(t.projectRoot,t.sessionId,i.turnId,i.version);if(!s)return null;let a=n.getTaskDefinitionV2(s.taskDefinitionHash);return !a||a.revision!==i.version?null:{definition:a,snapshot:s}}function cn(n,t){switch(n){case "action.lease.issued":return {kind:"action_lease_issued",payload:t};case "action.succeeded":return {kind:"action_completed",payload:t};case "action.failed":return {kind:"action_failed",payload:t};case "verification.succeeded":return {kind:"verification_completed",payload:t};case "verification.failed":return {kind:"verification_failed",payload:t};case "memory.committed":return {kind:"memory_episode_persisted",payload:t};case "memory.skipped":return {kind:"memory_decision_completed",payload:t};case "memory.pending":return {kind:"memory_extraction_queued",payload:t};case "memory.failed":return {kind:"memory_extraction_failed",payload:t};case "durable_work.owned":return {kind:"durable_work_leased",payload:{...t,fencingToken:Number.isSafeInteger(t.fencingToken)?t.fencingToken:0}};case "durable_work.completed":return {kind:"durable_work_completed",payload:t};case "durable_work.dead_lettered":return {kind:"durable_work_dead_lettered",payload:t};default:return null}}var ln=256*1024,un=48*1024;var fn=5,z=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function pn(n){return n==="react_audit_performance"||n.endsWith("__react_audit_performance")}function gn(n){let t=j(n,0,new Set);return t?yn(t.contract,t.canonicalReport):null}function Ne(n){if(!n.sessionId||!pn(n.toolName))return null;let t=gn(n.toolResponse);if(!t)return null;let e=Date.now(),o=n.runtimeStore.addEvidenceObligation(n.sessionId,t,e,n.toolUseId),r=n.runtimeStore.get(n.sessionId);if(o&&r){let i=openGlobalDevFlowDatabase();try{i.upsertSessionObligation({obligationId:`evidence:${o.obligationId}`,projectRoot:r.projectRoot,sessionId:n.sessionId,executionId:r.executionId,kind:"evidence_contract",state:"open",payload:{contract:t,runtimeObligationId:o.obligationId},createdAt:e,updatedAt:e});}finally{i.close();}y({event:"verification.completed",identity:{projectRoot:r.projectRoot,sessionId:n.sessionId,executionId:r.executionId},level:"info",timestamp:e,data:{stage:"performance_detector_coverage",status:"obligation_opened",contractId:t.id,obligationId:o.obligationId,detectorCoverage:B(n.toolResponse),runtimeProfilingOccurred:t.runtimeProfilingOccurred,samplingEvidenceOccurred:t.samplingEvidenceOccurred,toolUseId:n.toolUseId}});}return mn(t)}function mn(n){return [`DevFlow performance evidence contract ${n.id} is active.`,`The final performance answer MUST contain these three sections exactly: ${n.requiredSections.join(" / ")}.`,n.runtimeProfilingOccurred?"Only claims directly supported by the returned runtime measurements may be stated as measured facts.":"No runtime profiling occurred. Treat every finding as a static candidate: do not assign P0/high-risk severity, claim a confirmed bottleneck/jank/frame drop/CPU hotspot, quantify performance or benefit, or recommend requestAnimationFrame as generic throttling without sampling evidence.",`samplingEvidenceOccurred=${n.samplingEvidenceOccurred}. RAF recommendations are permitted only when this structured contract field is true; answer text cannot self-declare sampling evidence.`,"Use the canonical report below directly or preserve its evidence boundaries. Stop will request one correction for unsupported claims, then fail open with degradation telemetry.",n.canonicalReport].join(`
1
+ import {existsSync,readFileSync,rmSync,mkdirSync,writeFileSync,linkSync,readdirSync,renameSync,unlinkSync}from'fs';import {join as join$1,dirname as dirname$1}from'path';import {getLogWriter,emitSemanticControlLog,SemanticRuntimeEventProjector,rotateDiagnosticLogFile}from'@devflow-tools/telemetry';import {getLocalApiKey,getDevFlowStateRoot,resolveClaudeToolName,projectClaudeToolName,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir,parseTrustedDecisionCommand,domainHash,encodeDecisionValue,canonicalJsonBytes,readRuntimeState}from'@devflow-tools/sdk';import {request}from'node:http';import {mkdirSync as mkdirSync$1,appendFileSync,existsSync as existsSync$1,readFileSync as readFileSync$1,writeFileSync as writeFileSync$1,renameSync as renameSync$1,readdirSync as readdirSync$1}from'node:fs';import {join,dirname,relative,resolve,isAbsolute,sep}from'node:path';import {openGlobalDevFlowDatabase,retrievalLedgerTransitionId}from'@devflow-tools/database';import {randomUUID,createHash}from'crypto';import {fileURLToPath}from'url';import {TaskKernel,TaskEventStore}from'@devflow-tools/task-runtime';import {randomUUID as randomUUID$1,createHash as createHash$1,generateKeyPairSync,sign}from'node:crypto';import {classifyWorkflowFailure}from'@devflow-tools/workflow-engine/failure-classifier';import {createTrustedDeliveryFacade}from'@devflow-tools/mcp-server/trusted-delivery-runtime';function Q(n,t,e){try{let o=openGlobalDevFlowDatabase();try{o.insertEvent({kind:n,timestamp:Date.now(),duration:e,success:t.success!==!1,metadata:t});}finally{o.close();}}catch{}}var Rt=getLocalApiKey(),X=join(getDevFlowStateRoot(),"errors");async function q(n,t,e={}){let o=e.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??xt();if(!o)return {delivered:false,suppressed:false,fallbackReason:"runtime_not_ready"};let r=e.timeout??1500,i=e.durableMirror??true,s=e.maxRetries??(i?0:2),a=e.circuitBreaker??true,c=acquireRuntimeHttpCircuit(o,n);if(a&&!c.allowed)return {delivered:false,suppressed:true,fallbackReason:c.state.fallbackReason};let l;for(let u=0;u<=s;u+=1)try{return await kt(o,n,t,r),a&&registerRuntimeHttpSuccess(o,n).transitioned&&Q("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(g){l=g instanceof Error?g:new Error(String(g)),u<s&&await St(Math.min(100*2**u,1e3));}if(!l)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return me(n,l),{delivered:false,suppressed:false,fallbackReason:l.message};let d=registerRuntimeHttpFailure(o,n,e.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return d.transitioned&&(me(n,l),Q("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.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 xt(){let n=readRuntimeState();return n?.status==="ready"&&n.dashboardAvailable?n.url:void 0}function kt(n,t,e,o){return new Promise((r,i)=>{let s=JSON.stringify(e),a=new URL(t,n),c=false,l=u=>{c||(c=true,u?i(u):r());},d=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":Rt,"Content-Length":Buffer.byteLength(s)},timeout:o},u=>{u.on("error",l),u.on("end",()=>{let g=u.statusCode??0;l(g>=200&&g<300?void 0:new Error(`HTTP ${g}`));}),u.resume();});d.on("error",l),d.on("timeout",()=>d.destroy(new Error(`HTTP mirror timed out after ${o}ms`))),d.write(s),d.end();})}function me(n,t){try{existsSync$1(X)||mkdirSync$1(X,{recursive:!0});let e=join(X,"http-errors.log"),o=`${new Date().toISOString()} | ${n} | ${t.message}
2
+ `;rotateDiagnosticLogFile({path:e,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(o)}),appendFileSync(e,o);}catch{}}function St(n){return new Promise(t=>setTimeout(t,n))}var y=emitSemanticControlLog;function Y(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function S(n){return getProjectStateDir(Y(n))}function Ie(n){return Buffer.from(n,"utf8").toString("base64url")}function Ct(n,t,e){let o=t?.trim();if(o){let r=/^[a-zA-Z0-9:._-]{1,192}$/.test(o)?o:`tool-${createHash("sha256").update(o.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${r}`}return `${n}:legacy-${e}-${randomUUID().slice(0,8)}`}function Se(n){return `${n}:legacy-journal`}var E=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(S(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let o=this.get(e);if(o)return o.lastActivityAt=Date.now(),this.persist(o),o;let r=Date.now(),i={sessionId:e,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:r,lastActivityAt:r};return this.sessions.set(e,i),this.persist(i),i}startExecution(t,e,o){let r=this.registerSession(t);return (!r.executionId||r.skillName!==e)&&(r.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),r.skillName=e,r.requiredMcpTools=[...new Set(o)],delete r.contextInitialization,r.lastActivityAt=Date.now(),this.persist(r),r}beginContextInitialization(t,e){let o=this.registerSession(t);return o.contextInitialization={startedAt:Date.now(),...e?{toolUseId:e}:{}},o.lastActivityAt=Date.now(),this.persist(o),o}completeContextInitialization(t,e){let o=this.get(t);return o?(e&&o.contextInitialization?.toolUseId&&o.contextInitialization.toolUseId!==e||(delete o.contextInitialization,o.lastActivityAt=Date.now(),this.persist(o)),o):null}bindTaskIdentity(t,e){let o=this.registerSession(t);return o.activeTurnId=e.turnId,o.activeRequestId=e.requestId,o.intentArtifactHash=e.intentArtifactHash,o.lastActivityAt=Date.now(),this.persist(o),o}get(t){let e=t.trim();if(!e)return null;let o=this.sessions.get(e);if(o)return this.replayEvidenceJournal(o),o;let r=this.snapshotPath(e);if(!existsSync(r))return null;try{let i=JSON.parse(readFileSync(r,"utf8"));return i.sessionId!==e||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=we(i.evidenceObligations),i.evidenceDegradations=_e(i.evidenceDegradations),i.evidenceOutcomes=Re(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(e,i),i)}catch{return null}}completeExecution(t){let e=this.get(t);if(!e)return null;let o=structuredClone(e);return delete e.executionId,delete e.skillName,delete e.contextInitialization,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),o}addEvidenceObligation(t,e,o=Date.now(),r){let i=this.registerSession(t),a=(r?void 0:i.evidenceObligations.find(l=>l.contractId===e.id))?.obligationId??Ct(e.id,r,o);this.appendEvidenceEvent(t,{kind:"add",obligationId:a,contractId:e.id,at:o,contract:e},`add\0${a}`),this.replayEvidenceJournal(i);let c=i.evidenceObligations.find(l=>l.obligationId===a);return c?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(c)):null}listEvidenceObligations(t){return (this.get(t)?.evidenceObligations??[]).map(e=>structuredClone(e))}markEvidenceCorrection(t,e,o,r,i=Date.now()){let s=this.get(t),a=s?.evidenceObligations.find(d=>d.obligationId===e);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(r)?r:"";if(!c)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:a.contractId,at:i,fingerprint:c,violations:o.slice(0,16).map(d=>d.slice(0,240))},`correction\0${e}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let l=s.evidenceObligations.find(d=>d.obligationId===e);return l?structuredClone(l):null}resolveEvidenceObligation(t,e){let o=this.get(t);if(!o)return false;let r=o.evidenceObligations.find(s=>s.obligationId===e);if(!r)return false;let i=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:r.contractId,at:i},`resolve\0${e}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}resolveDegradedEvidence(t,e){let o=this.get(t),r=o?.evidenceDegradations.find(s=>s.obligationId===e);if(!o||!r)return false;let i=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:r.contractId,at:i},`resolve-degraded\0${e}\0${i}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}degradeEvidenceObligation(t,e,o,r=Date.now()){let i=this.get(t),s=i?.evidenceObligations.find(c=>c.obligationId===e);if(!i||!s)return false;let a=o.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:r,reason:a},`degrade\0${e}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=r,this.persist(i),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,`${Ie(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",Ie(t))}appendEvidenceEvent(t,e,o){let r=this.evidenceJournalDir(t);mkdirSync(r,{recursive:true,mode:448});let i=createHash("sha256").update(o).digest("hex"),s=join$1(r,`${e.kind}-${i}.json`);if(existsSync(s))return;let a=join$1(r,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(a,JSON.stringify(e),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(t){t.evidenceObligations=we(t.evidenceObligations),t.evidenceDegradations=_e(t.evidenceDegradations),t.evidenceOutcomes=Re(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync(e))return;let o;try{o=readdirSync(e).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let r=o.flatMap(i=>{try{let s=readFileSync(join$1(e,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=jt(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||xe(i.kind)-xe(s.kind));for(let i of r)this.applyEvidenceEvent(t,i);t.evidenceObligations=t.evidenceObligations.slice(-8),t.evidenceDegradations=t.evidenceDegradations.slice(-20),t.evidenceOutcomes=t.evidenceOutcomes.slice(-20);}applyEvidenceEvent(t,e){let o=t.evidenceOutcomes.find(s=>s.obligationId===e.obligationId);if(e.kind==="add"){if(o)return;let s=t.evidenceObligations.find(a=>a.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 r=t.evidenceObligations.find(s=>s.obligationId===e.obligationId);if(e.kind==="correction"){if(!r||o||r.correctionFingerprint===e.fingerprint)return;r.attempt+=1,r.correctionRequested=true,r.correctionRequestedAt=e.at,r.correctionFingerprint=e.fingerprint,r.violations=e.violations;return}let i=r?.attempt??o?.attempt??0;if(e.kind==="resolve"&&o?.status==="degraded")t.evidenceOutcomes=t.evidenceOutcomes.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations=t.evidenceDegradations.filter(s=>s.obligationId!==e.obligationId);else if(o)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:i,contract:r?.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:i,...e.kind==="degrade"?{reason:e.reason}:{}});}persist(t){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),o=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(o,JSON.stringify(t),{mode:384}),renameSync(o,e);}};function we(n){return Array.isArray(n)?n.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)||!Ee(e.contract))return [];let o=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:Se(e.contractId),r=typeof e.correctionTranscriptHash=="string"?e.correctionTranscriptHash:void 0,i=e.correctionFingerprint??r;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...e,obligationId:o,correctionFingerprint:i}]}).slice(-8):[]}function _e(n){return Array.isArray(n)?n.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 Re(n){return Array.isArray(n)?n.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 jt(n){if(!n||typeof n!="object")return null;let t=n,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 r={obligationId:typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:Se(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return Ee(t.contract)?{kind:e,...r,contract:t.contract}:null;if(e==="correction"){let i=typeof t.fingerprint=="string"?t.fingerprint:t.transcriptHash;return typeof i=="string"&&/^[a-f0-9]{64}$/.test(i)&&Array.isArray(t.violations)&&t.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:e,...r,fingerprint:i,violations:t.violations}:null}return e==="resolve"?{kind:e,...r}:typeof t.reason=="string"&&t.reason.length<=240?{kind:e,...r,reason:t.reason}:null}function xe(n){return n==="add"?0:n==="correction"?1:2}function Ee(n){if(!n||typeof n!="object")return false;let t=n,e=t.requiredSections,o=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(o)&&o.length<=16&&o.every(r=>typeof r=="string"&&r.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 ne(n){if(!n||typeof n!="object"||Array.isArray(n))return {};let t=n,e={};for(let o of ["lastMcpCall","bypassCount"])if(o in t){let r=t[o];if(r==null)continue;e[o]=typeof r=="number"&&Number.isFinite(r)&&r>=0?r:0;}return e}function Ft(n,t){return n.lastMcpCall===t.lastMcpCall&&n.bypassCount===t.bypassCount}function $t(n,t,e){let o=e instanceof Error?e.message:String(e);y({event:"hook.runtime.degraded",identity:{projectRoot:n},level:"warn",timestamp:Date.now(),data:{stage:"enforcement_receipt",operation:t,reason:o,fallback:"fail_open"}});}function Ae(n,t,e){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let r={},i=o.updateHookReceipt(n,a=>(r=ne(a),ne(t(r)))),s=ne(i);return {receipt:s,applied:!0,changed:!Ft(r,s)}}catch(r){return $t(n,e,r),{receipt:{},applied:false,changed:false}}finally{try{o?.close();}catch{}}}function re(n,t){return Ae(n,()=>t,"write").applied}function Pt(n,t){return Ae(n,t,"update")}var oe={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"},qt=new Set(["Write","Edit","NotebookEdit"]),Lt=new Set(["failed","timeout","unavailable"]);function Mt(n){switch(n){case "WebSearch":case "WebFetch":return 1;case "Agent":return 3;case "Grep":case "Glob":return 3;case "Bash":return 5;default:return 2}}var M=class{constructor(t,e,o){this.projectRoot=t;this.sessionId=e;this.executionId=o;}getPhase(){if(!this.sessionId||!this.executionId)return "idle";let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let o=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(o&&o.expiresAt>Date.now())return "context_ready";o&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId);}catch{}finally{try{t?.close();}catch{}}let e=new E(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 o=this.getPhase();if(e||t==="Skill")return {permissionDecision:"allow"};if(o==="context_initializing"&&oe[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(o==="context_gathering"&&oe[t])return {permissionDecision:"deny",reasonCode:"DEVFLOW_CONTEXT_REQUIRED",reason:`DevFlow context required. Call ${projectClaudeToolName("get_project_context")}, then retry ${t}.`};if(o==="context_ready"){if(qt.has(t)){let c=this.evaluateRequiredAction();if(c)return c}return {permissionDecision:"allow"}}let r=oe[t];if(!r)return {permissionDecision:"allow"};let i=Pt(this.projectRoot,c=>({...c,bypassCount:(c.bypassCount??0)+1}));if(!i.applied)return {permissionDecision:"allow"};let s=i.receipt.bypassCount??0,a=Mt(t);return s>=a?{permissionDecision:"allow",additionalContext:`\u5DF2 ${s} \u6B21\u76F4\u63A5\u4F7F\u7528 ${t}\uFF0C\u5EFA\u8BAE\u7528 ${projectClaudeToolName(r)} \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`}:{permissionDecision:"allow"}}recordMcpCall(){re(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});}recordDomainActionOutcome(t,e,o,r){if(!this.sessionId||!this.executionId)return false;let i;try{i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let s=i.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(!s||s.expiresAt<=Date.now()||s.canonicalAction?.tool!==t)return !1;let a=Date.now(),c=r?.trim()?`${r.trim()}:${e}`:`${t}:${e}:${a}`,l=s.actionAttempts??[];return i.upsertContextReceipt({...s,actionAttempts:l.some(d=>d.id===c||r&&d.toolUseId===r&&d.status===e)?l:[...l,{id:c,tool:t,status:e,attemptedAt:a,toolUseId:r,reason:o?.slice(0,500)}].slice(-20),actionSatisfiedAt:e==="succeeded"?a:s.actionSatisfiedAt,actionDegradation:e==="succeeded"?void 0:s.actionDegradation}),!0}catch{return false}finally{try{i?.close();}catch{}}}evaluateRequiredAction(){let t=this.getContextReceipt(),e=t?.canonicalAction;if(!t||!e||!e.required||e.status!=="required")return null;let o=e.binding;if(o.requiredContextReceipt!==t.contextHash||o.projectRoot!==this.projectRoot||o.sessionId!==this.sessionId||o.requestId!==t.requestId||o.executionId&&o.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 r=(t.actionAttempts??[]).filter(i=>i.tool===e.tool&&Lt.has(i.status));if(r.length>0){let i=r.at(-1),s={missedTool:e.tool,failedAttemptCount:r.length,reason:`${i.status}:${i.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)} ${i.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 o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let r=o.getContextReceipt(t.projectRoot,t.sessionId,t.executionId);if(!r||r.contextHash!==t.contextHash||r.actionDegradation)return;o.upsertContextReceipt({...r,actionDegradation:e});let i=o.getSkillExecution(t.executionId);if(!i)return;let s=i.metadata&&typeof i.metadata=="object"?i.metadata:{},a=Array.isArray(s.requiredActionDegradations)?s.requiredActionDegradations:[];o.updateSkillExecution(t.executionId,{missedMcpTools:[...new Set([...i.missedMcpTools??[],e.missedTool])],failedToolCalls:Math.max(i.failedToolCalls??0,e.failedAttemptCount),fallbackCount:(i.fallbackCount??0)+1,fallbackReasons:[...new Set([...i.fallbackReasons??[],`required_action_${e.reason}`])],metadata:{...s,requiredActionDegradations:[...a,e]}});}catch{}finally{try{o?.close();}catch{}}}};var Ce=1e4,Bt=3e4,U=500,H=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,o,r,i=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:t,sessionId:e,skillName:o,startedAt:r,projectRoot:i,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(t,e="completed",o=Date.now(),r){let i={executionId:t,status:e,finishedAt:o,metadata:r},s=this.commitOrCache("execution_complete",i);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",i),s}async sendSessionStart(t,e,o){let r={id:t,projectRoot:e,startedAt:o,label:e.split("/").pop()??"unknown"},i=this.commitOrCache("session_start",r);return i&&this.postHttp("/api/telemetry/sessions",r),i}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 o={sessionId:t,finishedAt:e},r=this.commitOrCache("session_end",o);return r&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(t)}/close`,{finishedAt:e})),r}async flushCache(){try{let e=this.getDatabase(),o=e.listTelemetryFailures({unresolvedOnly:!0,limit:U}).reverse();for(let r of o)try{this.applyOperation(r.operation,r.payload),e.resolveTelemetryFailure(r.id);}catch{}e.trimTelemetryFailures(U);}catch{}let t=(existsSync(this.cacheDir)?readdirSync(this.cacheDir):[]).filter(e=>e.endsWith(".json")).map(e=>{let o=join$1(this.cacheDir,e);try{return {cacheFile:o,envelope:Kt(JSON.parse(readFileSync(o,"utf8")))}}catch{return null}}).filter(e=>e!==null).sort((e,o)=>e.envelope.timestamp-o.envelope.timestamp||je(e.envelope.operation)-je(o.envelope.operation));for(let{cacheFile:e,envelope:o}of t)try{let r=this.getDatabase();r.insertTelemetryFailure({id:o.id,operation:o.operation,payload:o.payload,error:o.failure,createdAt:o.timestamp}),this.applyOperation(o.operation,o.payload),r.resolveTelemetryFailure(o.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(o){return this.cacheOperation(t,e,o),false}}applyOperation(t,e){let o=this.getDatabase();switch(t){case "tool_call":this.ensureParentSession(o,e),o.insertToolCallEvent(e);return;case "execution_start":this.ensureParentSession(o,e),o.insertSkillExecution({executionId:e.executionId,sessionId:e.sessionId,skillName:e.skillName,startedAt:e.startedAt,status:"running",requiredMcpTools:e.requiredMcpTools});return;case "execution_complete":o.reconcileSkillExecution(e.executionId,e.status,e.finishedAt,e.metadata);return;case "session_start":o.ensureSession(e),o.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(!o.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":o.closeSession(e.sessionId,e.finishedAt),o.updateRun(Fe(e.sessionId),{status:"completed",finishedAt:e.finishedAt});return}}ensureParentSession(t,e){let o=typeof e.sessionId=="string"?e.sessionId.trim():"";if(!o)throw new Error("Canonical session ID is required for telemetry");let r=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:o,projectRoot:r,label:r==="unknown"?void 0:r.split("/").pop(),startedAt:Number(e.startedAt??e.timestamp??Date.now())});}cacheOperation(t,e,o){let r=Date.now(),i={id:`failure:${r}:${Math.random().toString(36).slice(2,11)}`,operation:t,payload:e,failure:o instanceof Error?o.message:String(o),timestamp:r};try{let s=this.getDatabase();s.insertTelemetryFailure({id:i.id,operation:t,payload:e,error:i.failure,createdAt:r}),s.trimTelemetryFailures(U),this.scheduleRetry();return}catch{}try{existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${r}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(i,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-U)))unlinkSync(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},Bt).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){q(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 je(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function Fe(n){return `hook-run:${n}`}function Kt(n){if(!n||typeof n!="object")throw new Error("Invalid telemetry cache envelope");let t=n;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}var Qt=2,Xt=1;function Yt(){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 $e(n=Yt()){let t=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let e of t)try{if(!existsSync(e))continue;let o=JSON.parse(readFileSync(e,"utf8"));if(o.version!==Qt&&o.version!==Xt||!en(o.commands)){y({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 o.commands}catch(o){y({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:o.message,fallback:"next_registry_candidate"}});}return null}function en(n){return !n||typeof n!="object"||Array.isArray(n)?false:Object.values(n).every(t=>{if(!t||typeof t!="object"||Array.isArray(t))return false;let e=t;return V(e.mcpTools)&&V(e.blockedNative)&&(e.source===void 0||e.source==="core"||e.source==="plugin")&&(e.requiresContext===void 0||typeof e.requiresContext=="boolean")&&(e.runtimePackages===void 0||V(e.runtimePackages))&&(e.hostTools===void 0||tn(e.hostTools))&&(e.evidenceMode===void 0||["static","runtime","mixed"].includes(e.evidenceMode))})}function tn(n){return !!n&&typeof n=="object"&&!Array.isArray(n)&&Object.entries(n).every(([t,e])=>t.length>0&&V(e))}function V(n){return Array.isArray(n)&&n.every(t=>typeof t=="string"&&t.length>0)}function Pe(n){let t=$e();return t?t[n]?.mcpTools??[]:[]}function qe(n){let t=n.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 Le(n,t){return t?`evt_tool_${createHash("sha256").update(`${n}\0${t}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}function C(n){let{projectRoot:t,...e}=n;try{return new se(t).dispatchBoundary(e).snapshot??null}catch(o){return y({event:"hook.runtime.degraded",identity:{projectRoot:t,sessionId:n.sessionId,...n.turnId?{turnId:n.turnId}:{},...n.requestId?{requestId:n.requestId}:{},...n.executionId?{executionId:n.executionId}:{}},level:"error",timestamp:Date.now(),data:{stage:n.kind,reason:o instanceof Error?o.message:String(o),tool:n.producer}}),null}}var se=class{constructor(t){this.projectRoot=t;}dispatchBoundary(t){let e=cn(t.kind,t.payload??{});if(!e)return {handled:false};let o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let r=an(o,{projectRoot:this.projectRoot,sessionId:t.sessionId,...t.turnId?{turnId:t.turnId}:{},...t.requestId?{requestId:t.requestId}:{},...t.executionId?{executionId:t.executionId}:{}});return r?{handled:!0,snapshot:new TaskKernel(new TaskEventStore(o),new SemanticRuntimeEventProjector).dispatch({definition:r.definition,kind:e.kind,payload:e.payload,idempotencyKey:`host:${r.definition.definitionHash}:${t.dedupeKey}`,producer:t.producer}).snapshot}:{handled:!1}}finally{o.close();}}};function an(n,t){let e=t.executionId?n.getActiveContextReceipt(t.projectRoot,t.sessionId,t.executionId):null,o=t.turnId??e?.canonicalAction?.binding.turnId,r=t.requestId??e?.requestId;if(!o&&!r)return null;let i=n.listLatestTaskIntentArtifacts(t.projectRoot,t.sessionId).find(c=>o?c.turnId===o:c.requestId===r);if(!i)return null;let s=n.getTaskAggregateSnapshot(t.projectRoot,t.sessionId,i.turnId,i.version);if(!s)return null;let a=n.getTaskDefinitionV2(s.taskDefinitionHash);return !a||a.revision!==i.version?null:{definition:a,snapshot:s}}function cn(n,t){switch(n){case "action.lease.issued":return {kind:"action_lease_issued",payload:t};case "action.succeeded":return {kind:"action_completed",payload:t};case "action.failed":return {kind:"action_failed",payload:t};case "verification.succeeded":return {kind:"verification_completed",payload:t};case "verification.failed":return {kind:"verification_failed",payload:t};case "memory.committed":return {kind:"memory_episode_persisted",payload:t};case "memory.skipped":return {kind:"memory_decision_completed",payload:t};case "memory.pending":return {kind:"memory_extraction_queued",payload:t};case "memory.failed":return {kind:"memory_extraction_failed",payload:t};case "durable_work.owned":return {kind:"durable_work_leased",payload:{...t,fencingToken:Number.isSafeInteger(t.fencingToken)?t.fencingToken:0}};case "durable_work.completed":return {kind:"durable_work_completed",payload:t};case "durable_work.dead_lettered":return {kind:"durable_work_dead_lettered",payload:t};default:return null}}var ln=256*1024,un=48*1024;var fn=5,z=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function pn(n){return n==="react_audit_performance"||n.endsWith("__react_audit_performance")}function gn(n){let t=$(n,0,new Set);return t?yn(t.contract,t.canonicalReport):null}function Ne(n){if(!n.sessionId||!pn(n.toolName))return null;let t=gn(n.toolResponse);if(!t)return null;let e=Date.now(),o=n.runtimeStore.addEvidenceObligation(n.sessionId,t,e,n.toolUseId),r=n.runtimeStore.get(n.sessionId);if(o&&r){let i=openGlobalDevFlowDatabase();try{i.upsertSessionObligation({obligationId:`evidence:${o.obligationId}`,projectRoot:r.projectRoot,sessionId:n.sessionId,executionId:r.executionId,kind:"evidence_contract",state:"open",payload:{contract:t,runtimeObligationId:o.obligationId},createdAt:e,updatedAt:e});}finally{i.close();}y({event:"verification.completed",identity:{projectRoot:r.projectRoot,sessionId:n.sessionId,executionId:r.executionId},level:"info",timestamp:e,data:{stage:"performance_detector_coverage",status:"obligation_opened",contractId:t.id,obligationId:o.obligationId,detectorCoverage:B(n.toolResponse),runtimeProfilingOccurred:t.runtimeProfilingOccurred,samplingEvidenceOccurred:t.samplingEvidenceOccurred,toolUseId:n.toolUseId}});}return mn(t)}function mn(n){return [`DevFlow performance evidence contract ${n.id} is active.`,`The final performance answer MUST contain these three sections exactly: ${n.requiredSections.join(" / ")}.`,n.runtimeProfilingOccurred?"Only claims directly supported by the returned runtime measurements may be stated as measured facts.":"No runtime profiling occurred. Treat every finding as a static candidate: do not assign P0/high-risk severity, claim a confirmed bottleneck/jank/frame drop/CPU hotspot, quantify performance or benefit, or recommend requestAnimationFrame as generic throttling without sampling evidence.",`samplingEvidenceOccurred=${n.samplingEvidenceOccurred}. RAF recommendations are permitted only when this structured contract field is true; answer text cannot self-declare sampling evidence.`,"Use the canonical report below directly or preserve its evidence boundaries. Stop will request one correction for unsupported claims, then fail open with degradation telemetry.",n.canonicalReport].join(`
3
3
 
4
- `)}function B(n,t=0){if(t>6||n==null)return [];if(typeof n=="string")try{return B(JSON.parse(n),t+1)}catch{return []}if(Array.isArray(n)){for(let o of n){let r=B(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=B(o,t+1);if(r.length>0)return r}return []}function j(n,t,e){if(t>fn||n===null||n===void 0)return null;if(typeof n=="string"){if(Buffer.byteLength(n,"utf8")>ln)return null;try{return j(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=j(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=j(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=j(i,t+1,e);if(s)return s}return null}function yn(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!==z.length)return null;let o=e.requiredSections.filter(c=>typeof c=="string");if(o.length!==z.length||z.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")>un||z.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 He(n){let t;try{if(kn(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=wn(n.toolInput);if(o.length===0)return null;let r=n.toolName==="Read"?_n(n.toolInput):void 0,i=r?e.selectedFiles?.find(d=>Rn(n.projectRoot,d,r)):void 0,s=xn(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&&Ue({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 Ue({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 wn(...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 _n(n){for(let t of ["file_path","path"]){let e=n[t];if(typeof e=="string"&&e.trim())return e.trim()}}function Rn(n,t,e){let o=resolve(n,t),r=isAbsolute(e)?resolve(e):resolve(n,e);return o===r}function xn(n){return n.startsWith("mcp__")?n.split("__").at(-1)??n:n}function kn(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 Ue(n){try{y(n);}catch{}}var On=new Set(["Write","Edit","NotebookEdit"]);function Ve(n){if(!On.has(n.toolName)||Fn(n.toolResponse))return null;let t=Cn(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=Tn({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 _=`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:_,createdAt:p,updatedAt:p,resolvedAt:p}),s.push(c.kind),c.required===!0&&T({projectRoot:n.projectRoot,sessionId:n.sessionId,requestId:o.requestId,executionId:n.executionId,kind:"verification.failed",payload:{receiptId:u,reasonCode:_},dedupeKey:`${u}:unavailable`,producer:"devflow-verification-scheduler"});continue}let h={...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 g=e.enqueueWork({idempotencyKey:u,kind:"verification.policy",projectRoot:n.projectRoot,sessionId:n.sessionId,payload:h,maxAttempts:2,nextAttemptAt:p});T({projectRoot:n.projectRoot,sessionId:n.sessionId,requestId:o.requestId,executionId:n.executionId,kind:"durable_work.owned",payload:{workId:g.id,obligation:"verification"},dedupeKey:`${g.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(`
4
+ `)}function B(n,t=0){if(t>6||n==null)return [];if(typeof n=="string")try{return B(JSON.parse(n),t+1)}catch{return []}if(Array.isArray(n)){for(let o of n){let r=B(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=B(o,t+1);if(r.length>0)return r}return []}function $(n,t,e){if(t>fn||n===null||n===void 0)return null;if(typeof n=="string"){if(Buffer.byteLength(n,"utf8")>ln)return null;try{return $(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=$(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=$(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=$(i,t+1,e);if(s)return s}return null}function yn(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!==z.length)return null;let o=e.requiredSections.filter(c=>typeof c=="string");if(o.length!==z.length||z.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")>un||z.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 He(n){let t;try{if(kn(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=wn(n.toolInput);if(o.length===0)return null;let r=n.toolName==="Read"?_n(n.toolInput):void 0,i=r?e.selectedFiles?.find(d=>Rn(n.projectRoot,d,r)):void 0,s=xn(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&&Ue({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 Ue({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 wn(...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 _n(n){for(let t of ["file_path","path"]){let e=n[t];if(typeof e=="string"&&e.trim())return e.trim()}}function Rn(n,t,e){let o=resolve(n,t),r=isAbsolute(e)?resolve(e):resolve(n,e);return o===r}function xn(n){return n.startsWith("mcp__")?n.split("__").at(-1)??n:n}function kn(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 Ue(n){try{y(n);}catch{}}var On=new Set(["Write","Edit","NotebookEdit"]);function Ve(n){if(!On.has(n.toolName)||Fn(n.toolResponse))return null;let t=Cn(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=Tn({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")}`,g=Date.now();if(!l){let _=`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:_,createdAt:g,updatedAt:g,resolvedAt:g}),s.push(c.kind),c.required===!0&&C({projectRoot:n.projectRoot,sessionId:n.sessionId,requestId:o.requestId,executionId:n.executionId,kind:"verification.failed",payload:{receiptId:u,reasonCode:_},dedupeKey:`${u}:unavailable`,producer:"devflow-verification-scheduler"});continue}let h={...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:g,updatedAt:g});let f=e.enqueueWork({idempotencyKey:u,kind:"verification.policy",projectRoot:n.projectRoot,sessionId:n.sessionId,payload:h,maxAttempts:2,nextAttemptAt:g});C({projectRoot:n.projectRoot,sessionId:n.sessionId,requestId:o.requestId,executionId:n.executionId,kind:"durable_work.owned",payload:{workId:f.id,obligation:"verification"},dedupeKey:`${f.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 Tn(n){let t=$n(n.projectRoot),e=Pn(n.projectRoot),o=t?.scripts??{},r={...t?.dependencies,...t?.devDependencies},i=null;if(n.kind==="formatter"&&(r.prettier||qn(n.projectRoot)))i=K(e,"prettier",[n.mode==="write"?"--write":"--check",n.targetFile],6e4);else if(n.kind==="typecheck"){let s=de(o,["typecheck","type-check","check:types"]);s?i=ce(e,s,12e4):r.typescript&&existsSync$1(join(n.projectRoot,"tsconfig.json"))&&(i=K(e,"tsc",["--noEmit","--pretty","false"],12e4));}else if(n.kind==="lint"){let s=de(o,["lint"]);s&&(i=ce(e,s,12e4));}else if(n.kind==="test"){let s=Ln(n.projectRoot,n.targetFile);s&&r.vitest?i=K(e,"vitest",["run",s],12e4):s&&(r.jest||r["@jest/core"])&&(i=K(e,"jest",["--runTestsByPath",s],12e4));}else if(n.kind==="build"){let s=de(o,["build"]);s&&(i=ce(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(Mn).join(" "),required:n.required,targetFile:n.targetFile,contextReceipt:n.contextReceipt}:null}function ce(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 K(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 Cn(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 jn(n,o)?relative(n,o).split(sep).join("/"):null}function jn(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 Fn(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 $n(n){try{return JSON.parse(readFileSync$1(join(n,"package.json"),"utf8"))}catch{return null}}function Pn(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 qn(n){return [".prettierrc",".prettierrc.json",".prettierrc.js",".prettierrc.cjs","prettier.config.js","prettier.config.cjs"].some(t=>existsSync$1(join(n,t)))}function de(n,t){return t.find(e=>typeof n[e]=="string"&&n[e].trim())??null}function Ln(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 Mn(n){return /^[A-Za-z0-9_./:@=-]+$/u.test(n)?n:JSON.stringify(n)}function Ke(n){if(!n.toolUseId)return null;let t=Zn(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:Wn(t.path),completedAt:e,error:n.error?.slice(0,500)},r=Jn(n.projectRoot);return mkdirSync$1(dirname(r),{recursive:true}),appendFileSync(r,`${JSON.stringify(o)}
6
- `,{encoding:"utf8",mode:384}),y({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 Wn(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(S(n),"file-state")}function Je(n){return join(We(n),"pending.json")}function Jn(n){return join(We(n),"observations.jsonl")}function Gn(n){try{return JSON.parse(readFileSync$1(Je(n),"utf8"))}catch{return {}}}function Zn(n,t){let e=Je(n),o=Gn(n),r=o[t];if(r)return delete o[t],Qn(e,JSON.stringify(o)),r}function Qn(n,t){let e=`${n}.${process.pid}.${Date.now()}.tmp`;writeFileSync$1(e,t,{encoding:"utf8",mode:384}),renameSync$1(e,n);}var Yn={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 eo(n){return to(n)}function to(n){let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let e=io(t,n.artifact);if(so(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?no(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?oo(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 Ze(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:eo({artifact:r,memoryStatus:i.status,memoryReceiptId:i.receiptId,reason:n.reason})}finally{t.close();}}function no(n,t){return n.intent==="memory"||n.intent==="knowledge"||(t.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function oo(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||ro(n)?"action_required":"action_not_required"}function ro(n){return ["create","modify","debug","test","format"].includes(n.action)||["feature","refactor","performance"].includes(n.intent)}function io(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(!Yn[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 y({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 so(n){return n==="closed"||n==="closed_with_degradation"||n==="closed_with_retry_work"}function Qe(n){let t=n.hook==="post_tool_use_failure"||!!n.error?.trim()||ao(n.response),e=t?"not_consumed":n.hook==="post_tool_use"?"consumed":"unknown",o=t?co(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 ao(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 co(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 Ye(){return generateKeyPairSync("ed25519")}function et(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 tt=new Map;function nt(n){if(typeof n=="string")return /\bDevFlow decision ([A-Za-z0-9._:-]+)/u.exec($(n))?.[1]}function $(n){return n.replace(/[\u0000-\u001f\u007f\ufffd]+/gu," ").replace(/\s+/gu," ").trim()}function ho(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 ot(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=nt(e.header)??nt(e.question);if(!o)return {handled:false};let r=o.split(/:(?:decision|question|approval):/u)[0],i=vo(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(g=>typeof g.label=="string"?$(g.label):""):[],c=ho(n.toolResponse),l=c?$(c):void 0;if(!l)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 d;if(s.options.length>0){let g=s.options.map(I=>$(I.label));if(a.length!==g.length||a.some((I,P)=>I!==g[P]))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.options.find(I=>$(I.label)===l);if(!_)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: answer does not match a pending option for ${o}.`};s.kind==="artifact_approval"?d=_.id==="approve"?`/devflow:approve ${o}`:`/devflow:reject ${o} -- ${l}`:d=`/devflow:decide ${o} ${_.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.`};d=`/devflow:decide ${o} -- ${l}`;}let u=process.env.DEVFLOW_HOST_ACTOR_ID?.trim()||`user:${process.env.USER?.trim()||"local"}`,p=Ye(),h=et({rawUserEvent:d,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:u,targetDecisionHash:s.targetDecisionHash,eventSequence:Date.now(),nonce:randomUUID$1(),privateKey:p.privateKey,allowedOptionIds:s.options.map(g=>g.id)});try{return await i.resolveTrustedDecision({evidence:h,publicKey:p.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(g){return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: ${g instanceof Error?g.message:String(g)}`}}}function vo(n){let t=tt.get(n);if(t)return t;let e=createTrustedDeliveryFacade(n);return tt.set(n,e),e}function rt(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 Eo(n,t,e,o){try{let r=join$1(S(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 it(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+=it(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 Ao(n){if(!n)return null;let t;try{t=JSON.parse(n);}catch{return null}let e=t.tool_name||"",o=Y(),r=t.tool_input||{},i=t.tool_response||{},s=t.session_id?.trim()||null,a=new E(o);if(s&&a.registerSession(s),s){let f=await ot({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=qe(f);s&&m&&(a.startExecution(s,m,Pe(m)),re(o,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0}));}let d=s?a.get(s):null;if(e.startsWith("mcp__")){let f=new M(o,s??void 0,d?.executionId??s??void 0);f.recordMcpCall();let m=rt(typeof i=="object"&&i!==null?i:null),w=l??e,Z=f.getContextReceipt?.()?.canonicalAction?.tool===w;if((f.recordDomainActionOutcome(w,m?Do(m):"succeeded",m,t.tool_use_id)||Z)&&s){let A=Qe({hook:"post_tool_use",toolName:w,...t.tool_use_id?{toolUseId:t.tool_use_id}:{},response:i,...m?{error:m}:{}});T({projectRoot:o,sessionId:s,executionId:d?.executionId??s,kind:A.consumption==="consumed"?"action.succeeded":"action.failed",payload:{receiptId:A.receiptId,reasonCode:A.reasonCode,consumption:A.consumption,tool:w},dedupeKey:`${A.receiptId}:${A.consumption}`,producer:"devflow-post-tool-use"});try{Ze({projectRoot:o,sessionId:s,executionId:d?.executionId??s,reason:m?"post_tool_action_failed":"post_tool_action_succeeded"});}catch{}}}s&&He({projectRoot:o,sessionId:s,executionId:d?.executionId,toolName:e,toolInput:r,toolResponse:i,toolUseId:t.tool_use_id});let u=s?Eo(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,h=u??p,g=typeof i=="object"&&i!==null?i:null,_=JSON.stringify(i),I=Buffer.byteLength(_,"utf8"),P=it(i),W=rt(g);if(s&&Ke({projectRoot:o,sessionId:s,toolUseId:t.tool_use_id,success:!W,error:W}),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:h?Math.max(0,Date.now()-h.timestamp):0,success:!g?.error,resultCount:P,resultSizeBytes:I,error:g?.error});}if(h&&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,w=W,Z=w?classifyWorkflowFailure({stepId:e,toolName:e,output:i,error:new Error(w),errorStack:w}).category:void 0;await new H().completeEvent({eventId:h.eventId,sessionId:s,output:m,error:w,failureCategory:Z,duration:h?Math.max(0,Date.now()-h.timestamp):0,completedAt:Date.now()});}let ge=typeof r=="object"&&r.command?r.command:"",J=g?.exitCode,st=g?.stderr,at=/^\s*(ls|cat|pwd|cd|echo|head|tail|wc|which|whoami|date|env|printenv|id|hostname|uname)\b/,x,k,G=true;if(e.startsWith("mcp__"))x="mcp_call",k={mcpTool:l??e,query:typeof r=="object"&&r.query?r.query:null,resultCount:P,resultSizeBytes:I};else if(e==="Read"||e==="Write"||e==="Edit")x=e==="Read"?"file_read":"file_write",k={filePath:typeof r=="object"&&r.file_path?r.file_path:null,fileContentSize:I};else if(e==="Bash"){let f=at.test(ge),m=J!==void 0&&J!==0;G=!f||m,x=m?"bash_error":"bash_command",k={command:ge||e,exitCode:J??null,stderr:st??null};}else e==="Agent"?(x="subagent",k={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"?(x=e==="WebSearch"?"web_search":"web_fetch",k={query:typeof r=="object"&&r.query?String(r.query).slice(0,200):null}):(G=false,x="tool_use",k={});if(G){let f={id:t.tool_use_id?`memory:${Le(s??"",t.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:s??"",tool:e,kind:x,payload:{...k,durationMs:h?Math.max(0,Date.now()-h.timestamp):0},createdAt:Date.now()};s&&q(`/api/memory/session-events?rootPath=${encodeURIComponent(o)}`,f);}let ct=Ne({toolName:e,toolResponse:i,sessionId:s,toolUseId:t.tool_use_id,runtimeStore:a}),dt=s?Ve({projectRoot:o,sessionId:s,executionId:d?.executionId,toolName:e,toolInput:r,toolResponse:i,toolUseId:t.tool_use_id}):null;return [ct,dt].filter(f=>!!f).join(`
6
+ `,{encoding:"utf8",mode:384}),y({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 Wn(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(S(n),"file-state")}function Je(n){return join(We(n),"pending.json")}function Jn(n){return join(We(n),"observations.jsonl")}function Gn(n){try{return JSON.parse(readFileSync$1(Je(n),"utf8"))}catch{return {}}}function Zn(n,t){let e=Je(n),o=Gn(n),r=o[t];if(r)return delete o[t],Qn(e,JSON.stringify(o)),r}function Qn(n,t){let e=`${n}.${process.pid}.${Date.now()}.tmp`;writeFileSync$1(e,t,{encoding:"utf8",mode:384}),renameSync$1(e,n);}var Yn={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 eo(n){return to(n)}function to(n){let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let e=io(t,n.artifact);if(so(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?no(n.artifact,o):"context_ready";e.toState==="intent_bound"&&(e=b(t,e,n,s,i?"task_context_not_required":s==="context_ready"?"canonical_context_receipt_ready":"canonical_context_receipt_degraded"));let a=o?oo(n.artifact,o):"action_not_required";if((e.toState==="context_ready"||e.toState==="context_degraded")&&(a==="action_not_required"?e=b(t,e,n,"action_not_required","task_action_not_required"):e=b(t,e,n,"action_required","canonical_action_obligation_present")),e.toState==="action_required"){if(a==="action_required")return e;if(a==="action_failed")return b(t,e,n,"action_failed","canonical_action_attempt_failed");a==="action_degraded"?e=b(t,e,n,"action_degraded","canonical_action_unavailable_or_degraded"):a==="action_satisfied"&&(e=b(t,e,n,"action_satisfied","canonical_action_succeeded"));}if(e.toState==="action_failed")if(a==="action_satisfied")e=b(t,e,n,"action_satisfied","canonical_action_retry_succeeded");else if(a==="action_degraded")e=b(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=b(t,e,n,n.memoryStatus==="pending"?"memory_quarantined":"memory_decided",n.memoryStatus==="pending"?n.reason:`canonical_memory_${n.memoryStatus}`)),e.toState==="memory_decided"?b(t,e,n,c?"closed_with_degradation":"closed",n.reason):e.toState==="memory_quarantined"?b(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 Ze(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:eo({artifact:r,memoryStatus:i.status,memoryReceiptId:i.receiptId,reason:n.reason})}finally{t.close();}}function no(n,t){return n.intent==="memory"||n.intent==="knowledge"||(t.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function oo(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||ro(n)?"action_required":"action_not_required"}function ro(n){return ["create","modify","debug","test","format"].includes(n.action)||["feature","refactor","performance"].includes(n.intent)}function io(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 b(n,t,e,o,r){if(!Yn[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 y({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 so(n){return n==="closed"||n==="closed_with_degradation"||n==="closed_with_retry_work"}function Qe(n){let t=n.hook==="post_tool_use_failure"||!!n.error?.trim()||ao(n.response),e=t?"not_consumed":n.hook==="post_tool_use"?"consumed":"unknown",o=t?co(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 ao(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 co(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 Ye(){return generateKeyPairSync("ed25519")}function et(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 tt=new Map;function nt(n){if(typeof n=="string")return /\bDevFlow decision ([A-Za-z0-9._:-]+)/u.exec(A(n))?.[1]}function A(n){return n.replace(/[\u0000-\u001f\u007f\ufffd]+/gu,"").replace(/\s+/gu," ").trim()}function ho(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 ot(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=nt(e.header)??nt(e.question);if(!o)return {handled:false};let r=o.split(/:(?:decision|question|approval):/u)[0],i=vo(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(f=>({label:typeof f.label=="string"?A(f.label):"",description:typeof f.description=="string"?A(f.description):""})):[],c=ho(n.toolResponse),l=c?A(c):void 0;if(!l)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 d;if(s.options.length>0){let f=s.options.map(v=>({label:A(v.label),description:v.description?A(v.description):""}));if(a.length!==f.length||a.some((v,j)=>v.label!==f[j]?.label||v.description!==f[j]?.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.options.find(v=>A(v.label)===l);if(!_)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: answer does not match a pending option for ${o}.`};s.kind==="artifact_approval"?d=_.id==="approve"?`/devflow:approve ${o}`:`/devflow:reject ${o} -- ${l}`:d=`/devflow:decide ${o} ${_.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.`};d=`/devflow:decide ${o} -- ${l}`;}let u=process.env.DEVFLOW_HOST_ACTOR_ID?.trim()||`user:${process.env.USER?.trim()||"local"}`,g=Ye(),h=et({rawUserEvent:d,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:u,targetDecisionHash:s.targetDecisionHash,eventSequence:Date.now(),nonce:randomUUID$1(),privateKey:g.privateKey,allowedOptionIds:s.options.map(f=>f.id)});try{return await i.resolveTrustedDecision({evidence:h,publicKey:g.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(f){return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: ${f instanceof Error?f.message:String(f)}`}}}function vo(n){let t=tt.get(n);if(t)return t;let e=createTrustedDeliveryFacade(n);return tt.set(n,e),e}function rt(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 Eo(n,t,e,o){try{let r=join$1(S(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 it(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+=it(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 Ao(n){if(!n)return null;let t;try{t=JSON.parse(n);}catch{return null}let e=t.tool_name||"",o=Y(),r=t.tool_input||{},i=t.tool_response||{},s=t.session_id?.trim()||null,a=new E(o);if(s&&a.registerSession(s),s){let p=await ot({projectRoot:o,sessionId:s,sourceTurnId:a.get(s)?.activeTurnId,toolName:e,toolInput:r,toolResponse:i,toolUseId:t.tool_use_id});if(p.handled)return p.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 p=typeof r=="object"&&r.skill?r.skill:"",m=qe(p);s&&m&&(a.startExecution(s,m,Pe(m)),re(o,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0}));}let d=s?a.get(s):null;if(e.startsWith("mcp__")){let p=new M(o,s??void 0,d?.executionId??s??void 0);p.recordMcpCall();let m=rt(typeof i=="object"&&i!==null?i:null),w=l??e,Z=p.getContextReceipt?.()?.canonicalAction?.tool===w;if((p.recordDomainActionOutcome(w,m?Do(m):"succeeded",m,t.tool_use_id)||Z)&&s){let D=Qe({hook:"post_tool_use",toolName:w,...t.tool_use_id?{toolUseId:t.tool_use_id}:{},response:i,...m?{error:m}:{}});C({projectRoot:o,sessionId:s,executionId:d?.executionId??s,kind:D.consumption==="consumed"?"action.succeeded":"action.failed",payload:{receiptId:D.receiptId,reasonCode:D.reasonCode,consumption:D.consumption,tool:w},dedupeKey:`${D.receiptId}:${D.consumption}`,producer:"devflow-post-tool-use"});try{Ze({projectRoot:o,sessionId:s,executionId:d?.executionId??s,reason:m?"post_tool_action_failed":"post_tool_action_succeeded"});}catch{}}}s&&He({projectRoot:o,sessionId:s,executionId:d?.executionId,toolName:e,toolInput:r,toolResponse:i,toolUseId:t.tool_use_id});let u=s?Eo(o,s,e,t.tool_use_id):null,g=s&&t.tool_use_id&&!u?(()=>{try{let p=openGlobalDevFlowDatabase();try{return p.getToolCallEventByToolUseId(s,t.tool_use_id)}finally{p.close();}}catch{return null}})():null,h=u??g,f=typeof i=="object"&&i!==null?i:null,_=JSON.stringify(i),v=Buffer.byteLength(_,"utf8"),j=it(i),W=rt(f);if(s&&Ke({projectRoot:o,sessionId:s,toolUseId:t.tool_use_id,success:!W,error:W}),d?.executionId!==void 0||l!==void 0||e==="Skill"){let p=getLogWriter(o),m=d?.executionId??`auto-${s??Date.now()}`;p.toolCall({tool:e,runId:m,stepId:`step-${m}`,input:r,output:i,duration:h?Math.max(0,Date.now()-h.timestamp):0,success:!f?.error,resultCount:j,resultSizeBytes:v,error:f?.error});}if(h&&s){let p=typeof i=="string"?i:JSON.stringify(i),m=p.length>5e3?{_truncated:true,_originalSize:p.length,text:p.slice(0,5e3)}:i,w=W,Z=w?classifyWorkflowFailure({stepId:e,toolName:e,output:i,error:new Error(w),errorStack:w}).category:void 0;await new H().completeEvent({eventId:h.eventId,sessionId:s,output:m,error:w,failureCategory:Z,duration:h?Math.max(0,Date.now()-h.timestamp):0,completedAt:Date.now()});}let ge=typeof r=="object"&&r.command?r.command:"",J=f?.exitCode,st=f?.stderr,at=/^\s*(ls|cat|pwd|cd|echo|head|tail|wc|which|whoami|date|env|printenv|id|hostname|uname)\b/,x,k,G=true;if(e.startsWith("mcp__"))x="mcp_call",k={mcpTool:l??e,query:typeof r=="object"&&r.query?r.query:null,resultCount:j,resultSizeBytes:v};else if(e==="Read"||e==="Write"||e==="Edit")x=e==="Read"?"file_read":"file_write",k={filePath:typeof r=="object"&&r.file_path?r.file_path:null,fileContentSize:v};else if(e==="Bash"){let p=at.test(ge),m=J!==void 0&&J!==0;G=!p||m,x=m?"bash_error":"bash_command",k={command:ge||e,exitCode:J??null,stderr:st??null};}else e==="Agent"?(x="subagent",k={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"?(x=e==="WebSearch"?"web_search":"web_fetch",k={query:typeof r=="object"&&r.query?String(r.query).slice(0,200):null}):(G=false,x="tool_use",k={});if(G){let p={id:t.tool_use_id?`memory:${Le(s??"",t.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:s??"",tool:e,kind:x,payload:{...k,durationMs:h?Math.max(0,Date.now()-h.timestamp):0},createdAt:Date.now()};s&&q(`/api/memory/session-events?rootPath=${encodeURIComponent(o)}`,p);}let ct=Ne({toolName:e,toolResponse:i,sessionId:s,toolUseId:t.tool_use_id,runtimeStore:a}),dt=s?Ve({projectRoot:o,sessionId:s,executionId:d?.executionId,toolName:e,toolInput:r,toolResponse:i,toolUseId:t.tool_use_id}):null;return [ct,dt].filter(p=>!!p).join(`
7
7
 
8
8
  `)||null}function Do(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 Ao(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{Ao as handlePostToolUse};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/claude-code-plugin",
3
- "version": "0.18.35",
3
+ "version": "0.18.36",
4
4
  "description": "Claude Code hooks and skills for the DevFlow development intelligence runtime.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -12,20 +12,20 @@
12
12
  "verify:runtime-dependencies": "node --import tsx scripts/verify-runtime-dependencies.ts"
13
13
  },
14
14
  "dependencies": {
15
- "@devflow-tools/benchmark": "0.18.35",
16
- "@devflow-tools/context-engine": "0.18.35",
17
- "@devflow-tools/database": "0.18.35",
18
- "@devflow-tools/mcp-server": "0.18.35",
19
- "@devflow-tools/memory-engine": "0.18.35",
20
- "@devflow-tools/sdk": "0.18.35",
21
- "@devflow-tools/semantic-engine": "0.18.35",
22
- "@devflow-tools/server": "0.18.35",
23
- "@devflow-tools/task-runtime": "0.18.35",
24
- "@devflow-tools/telemetry": "0.18.35",
25
- "@devflow-tools/workflow-engine": "0.18.35"
15
+ "@devflow-tools/benchmark": "0.18.36",
16
+ "@devflow-tools/context-engine": "0.18.36",
17
+ "@devflow-tools/database": "0.18.36",
18
+ "@devflow-tools/mcp-server": "0.18.36",
19
+ "@devflow-tools/memory-engine": "0.18.36",
20
+ "@devflow-tools/sdk": "0.18.36",
21
+ "@devflow-tools/semantic-engine": "0.18.36",
22
+ "@devflow-tools/server": "0.18.36",
23
+ "@devflow-tools/task-runtime": "0.18.36",
24
+ "@devflow-tools/telemetry": "0.18.36",
25
+ "@devflow-tools/workflow-engine": "0.18.36"
26
26
  },
27
27
  "devDependencies": {
28
- "@devflow-tools/devflow": "0.18.35"
28
+ "@devflow-tools/devflow": "0.18.36"
29
29
  },
30
30
  "allowScripts": {
31
31
  "better-sqlite3@12.11.1": true,
@@ -10,7 +10,9 @@ description: 通过可审计 Delivery Line 将需求推进到验证完成的 int
10
10
  ## 开始案件
11
11
 
12
12
  收到新的交付需求时,调用 `mcp__plugin_devflow_devflow__delivery_create_case`。使用当前项目绝对路径;默认 `baseRef=HEAD`、`targetRef=main`,除非用户明确指定其他值。为 actor、session、execution 和每次写操作生成稳定且可追踪的标识与幂等键。
13
- - 若上下文检索发现同名组件、同一路由或多个框架实现,将候选路径通过 `existingImplementations` 传入创建案件参数,让案件先进入阻塞澄清;不要自行选择复用或替换。
13
+ - `get_project_context` 返回后、创建案件前,对请求中点名的组件、路由、服务或文件做一次聚焦的只读
14
+ Glob/Grep/Read 核验。检索相关度低或未命中不能证明实现不存在;不得仅凭检索摘要宣称“没有现有实现”。
15
+ - 若发现同名组件、同一路由或多个框架实现,将候选路径通过 `existingImplementations` 传入创建案件参数,让案件先进入阻塞澄清;不要自行选择复用或替换。
14
16
 
15
17
  ## 推进规则
16
18
 
@@ -23,6 +25,11 @@ description: 通过可审计 Delivery Line 将需求推进到验证完成的 int
23
25
  - `delivery_status` 返回的 `currentTurn` 是唯一 canonical turn;所有后续 `answer`、`compare_options` 和
24
26
  `approve` 都原样使用该值。审批不会自动递增 turn,只有 `answer`/`revise` 打开新交互时才会变化。
25
27
  - 只执行当前 `nextActions` 允许的操作。
28
+ - 澄清只问一个会改变实现边界或验收结果、且尚未由用户请求或代码证据回答的问题。不得换一种说法
29
+ 重复确认已经明确的目标、组件/页面边界或技术约束。若请求已经说明“组件”,不要再问“组件还是页面”;
30
+ 应核验现有实现后询问真正未决的复用关系、公开 API 或数据流。
31
+ - 结构化选项必须是实质不同的方案。每个 option 使用稳定的短 `id`、简洁 `label` 和具体
32
+ `description`;description 说明范围、数据流、保留/替换行为和主要权衡,供 spec artifact 使用。
26
33
  - `designing` 阶段没有 `design` 审批动作。设计方案确认后,必须使用当前状态返回的
27
34
  `currentTurn` 调用 `delivery_compare_options`,由它生成 `spec_ready`;随后才可调用
28
35
  `delivery_approve(stage=spec)`。不得调用 `delivery_approve(stage=design)`,也不得用
@@ -40,26 +47,33 @@ description: 通过可审计 Delivery Line 将需求推进到验证完成的 int
40
47
  `nextActions` 恢复,不得把无推进当作成功。
41
48
  - `plan_ready` 阶段先调用 `delivery_prepare_plan`。它会校验并持久化 plan artifact,随后
42
49
  `delivery_status` 必须返回 artifact approval decision;不要把 plan 对象直接传给
43
- `delivery_approve`。
50
+ `delivery_approve`,也不要用 `delivery_propose_options` 创建“是否批准计划”的普通澄清 decision。
51
+ - 计划必须能由不了解对话的工程师执行:`allowedFiles` 只列实际允许修改的文件,不得把只读参考文件
52
+ 放进去;每个行为变更先写失败测试再实现,`implementationSteps` 写明 RED/GREEN 顺序;每条验收标准
53
+ 对应具体测试或验证命令。`testFirst=false` 只有在计划内携带明确 waiver 时才允许。
44
54
  - 澄清与设计交互使用当前 turn;后续写操作携带案件当前 context receipt。
45
55
  - `delivery_answer` 的用户决定必须来自可信用户通道;不得让 agent 自己调用它消费 pending decision。
46
- - 如果 pending decision 返回了至少两个结构化 `options`,必须把它们原样展示给用户,不得自行增加、改写或排序后再提交。使用 Claude 原生 `AskUserQuestion` 展示单选题,并在唯一问题的 `header` 中保留精确标记 `DevFlow decision <decisionId>`;选项的 `label` 必须与返回值完全一致。宿主 PostToolUse hook 会校验问题、选项、session、版本和 hash,并自动签名/消费用户选择;随后重新调用 `delivery_status`。
56
+ - 如果 pending decision 返回了至少两个结构化 `options`,必须把它们原样展示给用户,不得自行增加、改写或排序后再提交。使用 Claude 原生 `AskUserQuestion` 展示单选题,并在唯一问题的 `header` 中保留精确标记 `DevFlow decision <decisionId>`;选项的 `label` 和 `description` 必须与返回值完全一致。宿主 PostToolUse hook 会校验问题、选项、session、版本和 hash,并自动签名/消费用户选择;随后重新调用 `delivery_status`。
47
57
  - 如果 pending decision 的 `options` 为空,这是自由文本澄清,不要伪造选择项。要求用户在同一 Claude 会话提交规范命令:`/devflow:decide <decisionId> -- <answer>`;host hook 会签名该 `UserPromptSubmit` 并消费 pending decision。
48
58
  - 如果一个澄清问题本身适合有限选项但当前 `options` 为空,先调用 `delivery_propose_options` 提交至少两个带稳定 `id`/`label` 的候选,再使用上述 `AskUserQuestion` 流程。
49
59
  - 无论哪种可信用户通道,命令或交互处理成功后都必须重新调用 `delivery_status`,以返回的 `currentTurn` 和 `nextActions` 继续。
50
- - artifact 审批优先使用 `pendingDecisions` 返回的原生批准/退回选项;宿主会将选择映射为精确的
51
- `/devflow:approve <decisionId>` 或 `/devflow:reject <decisionId> -- <reason>`。命令是 fallback,
52
- 不得省略 decisionId,也不得由 agent 调用 MCP mutation 模拟用户批准或拒绝。
60
+ - artifact 审批使用 `pendingDecisions` 返回的原生批准/退回选项;展示前用 Read 打开
61
+ `<projectRoot>/.devflow/delivery-line/artifacts/<caseId>/<artifact.path>`,只给出不重复的关键摘要和风险。
62
+ 宿主会将选择映射为精确审批事件。Slash command 仅是宿主原生交互不可用时的 fallback,不得把命令
63
+ 作为默认交互,也不得由 agent 调用 MCP mutation 模拟用户批准或拒绝。
53
64
  - `/devflow:revise`、`/devflow:cancel` 和 `/devflow:exit` 尚未注册为可信命令;仅使用当前 `nextActions` 已实现的路径,不得向用户展示不存在的命令。
54
- - 审批返回后不要结束会话:立即读取同一次返回的 `stage` 和 `nextActions`,按其允许的下一步继续推进;只有 `nextActions` 为空或用户明确暂停时才结束。
55
- - `mcp__plugin_devflow_devflow__delivery_advance` 用于推进已满足的状态,`mcp__plugin_devflow_devflow__delivery_resume` 只恢复已经具备运行条件的 gate 或 task。
65
+ - 审批返回后不要结束会话:立即调用 `delivery_status`,按返回的 `nextActions` 连续推进;只有出现新的
66
+ 人工 gate、明确 blocker、终态或用户明确暂停时才结束。
67
+ - plan 审批后若状态是 `plan_approved` 且 `nextActions` 包含 `resume`,立即调用 `delivery_resume`。
68
+ 不要先调用只改变阶段但不启动 worker 的 `delivery_advance`。`delivery_resume` 应连续运行执行、验证与
69
+ review,直到下一个真实 gate 或 blocker。
56
70
  - 失败任务只通过 `mcp__plugin_devflow_devflow__delivery_retry_task` 重试;取消和导出分别使用 `mcp__plugin_devflow_devflow__delivery_cancel` 与 `mcp__plugin_devflow_devflow__delivery_export`。
57
71
  - Claude 在当前工作区产生的修改不是 Delivery 输出;只能先调用 `mcp__plugin_devflow_devflow__delivery_import_external_change`,由系统校验 base/candidate、允许文件、context receipt 和验证证据后再进入 integration。
58
72
 
59
73
  ## 可用操作
60
74
 
61
75
  - 澄清和设计:`delivery_propose_options`、`delivery_answer`、`delivery_revise`、`delivery_compare_options`、`delivery_prepare_plan`
62
- - Gate 决策:向用户展示 `pendingDecisions[].command`;用户通过 `/devflow:approve` 或 `/devflow:reject` 决策
76
+ - Gate 决策:用 Claude 原生 `AskUserQuestion` 展示 `pendingDecisions[].options`,命令仅作降级 fallback
63
77
  - 状态和执行:`delivery_status`、`delivery_advance`、`delivery_resume`、`delivery_retry_task`
64
78
  - 外部变更:`delivery_import_external_change`
65
79
  - 交付收尾:`delivery_export`、`delivery_cancel`