@devflow-tools/claude-code-plugin 0.18.34 → 0.18.35
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
|
|
2
|
-
`;rotateDiagnosticLogFile({path:e,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(o)}),appendFileSync(e,o);}catch{}}function kt(n){return new Promise(t=>setTimeout(t,n))}var y=emitSemanticControlLog;function Q(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function k(n){return getProjectStateDir(Q(n))}function be(n){return Buffer.from(n,"utf8").toString("base64url")}function Tt(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 ke(n){return `${n}:legacy-journal`}var S=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(k(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=Ie(i.evidenceObligations),i.evidenceDegradations=_e(i.evidenceDegradations),i.evidenceOutcomes=we(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??Tt(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,`${be(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",be(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=Ie(t.evidenceObligations),t.evidenceDegradations=_e(t.evidenceDegradations),t.evidenceOutcomes=we(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=Ct(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||Re(i.kind)-Re(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 Ie(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)||!Se(e.contract))return [];let o=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:ke(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 we(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 Ct(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:ke(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return Se(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 Re(n){return n==="add"?0:n==="correction"?1:2}function Se(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 ee(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 jt(n,t){return n.lastMcpCall===t.lastMcpCall&&n.bypassCount===t.bypassCount}function Ft(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 Ee(n,t,e){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let r={},i=o.updateHookReceipt(n,a=>(r=ee(a),ee(t(r)))),s=ee(i);return {receipt:s,applied:!0,changed:!jt(r,s)}}catch(r){return Ft(n,e,r),{receipt:{},applied:false,changed:false}}finally{try{o?.close();}catch{}}}function ne(n,t){return Ee(n,()=>t,"write").applied}function $t(n,t){return Ee(n,t,"update")}var te={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"},Pt=new Set(["Write","Edit","NotebookEdit"]),qt=new Set(["failed","timeout","unavailable"]);function Lt(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 q=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 S(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"&&te[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"&&te[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(Pt.has(t)){let c=this.evaluateRequiredAction();if(c)return c}return {permissionDecision:"allow"}}let r=te[t];if(!r)return {permissionDecision:"allow"};let i=$t(this.projectRoot,c=>({...c,bypassCount:(c.bypassCount??0)+1}));if(!i.applied)return {permissionDecision:"allow"};let s=i.receipt.bypassCount??0,a=Lt(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(){ne(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&&qt.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 Te=1e4,zt=3e4,M=500,N=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(getDevFlowStateRoot(),"global","telemetry-cache"),this.database=t?.database??null,this.ownsDatabase=!t?.database;let e=t?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(e)&&e>=0?e:100;}async sendEvent(t){let e={...t,input:this.truncateInput(t.input)};return this.commitOrCache("tool_call",e)?(this.postHttp("/api/telemetry/tool-call",e),t.eventId):null}async sendExecutionStart(t,e,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:M}).reverse();for(let r of o)try{this.applyOperation(r.operation,r.payload),e.resolveTelemetryFailure(r.id);}catch{}e.trimTelemetryFailures(M);}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:Bt(JSON.parse(readFileSync(o,"utf8")))}}catch{return null}}).filter(e=>e!==null).sort((e,o)=>e.envelope.timestamp-o.envelope.timestamp||Ce(e.envelope.operation)-Ce(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:je(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(je(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(M),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-M)))unlinkSync(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},zt).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){$(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=Te?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,Te)}...`}}};function Ce(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function je(n){return `hook-run:${n}`}function Bt(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 Zt=2,Qt=1;function Xt(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{return join$1(dirname$1(fileURLToPath(import.meta.url)),"..","..")}catch{return process.cwd()}}function Fe(n=Xt()){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!==Zt&&o.version!==Qt||!Yt(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 Yt(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 U(e.mcpTools)&&U(e.blockedNative)&&(e.source===void 0||e.source==="core"||e.source==="plugin")&&(e.requiresContext===void 0||typeof e.requiresContext=="boolean")&&(e.runtimePackages===void 0||U(e.runtimePackages))&&(e.hostTools===void 0||en(e.hostTools))&&(e.evidenceMode===void 0||["static","runtime","mixed"].includes(e.evidenceMode))})}function en(n){return !!n&&typeof n=="object"&&!Array.isArray(n)&&Object.entries(n).every(([t,e])=>t.length>0&&U(e))}function U(n){return Array.isArray(n)&&n.every(t=>typeof t=="string"&&t.length>0)}function $e(n){let t=Fe();return t?t[n]?.mcpTools??[]:[]}function Pe(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 qe(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 O(n){let{projectRoot:t,...e}=n;try{return new re(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 re=class{constructor(t){this.projectRoot=t;}dispatchBoundary(t){let e=an(t.kind,t.payload??{});if(!e)return {handled:false};let o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let r=sn(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 sn(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 an(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 dn=256*1024,ln=48*1024;var un=5,H=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function fn(n){return n==="react_audit_performance"||n.endsWith("__react_audit_performance")}function pn(n){let t=j(n,0,new Set);return t?mn(t.contract,t.canonicalReport):null}function Me(n){if(!n.sessionId||!fn(n.toolName))return null;let t=pn(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:V(n.toolResponse),runtimeProfilingOccurred:t.runtimeProfilingOccurred,samplingEvidenceOccurred:t.samplingEvidenceOccurred,toolUseId:n.toolUseId}});}return gn(t)}function gn(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&®isterRuntimeHttpSuccess(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(`
|
|
3
3
|
|
|
4
|
-
`)}function
|
|
5
|
-
`)||null}finally{e.close();}}function
|
|
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 Kn(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 Ke(n){return join(k(n),"file-state")}function We(n){return join(Ke(n),"pending.json")}function Wn(n){return join(Ke(n),"observations.jsonl")}function Jn(n){try{return JSON.parse(readFileSync$1(We(n),"utf8"))}catch{return {}}}function Gn(n,t){let e=We(n),o=Jn(n),r=o[t];if(r)return delete o[t],Zn(e,JSON.stringify(o)),r}function Zn(n,t){let e=`${n}.${process.pid}.${Date.now()}.tmp`;writeFileSync$1(e,t,{encoding:"utf8",mode:384}),renameSync$1(e,n);}var Xn={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 Yn(n){return eo(n)}function eo(n){let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let e=ro(t,n.artifact);if(io(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?to(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?no(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 Ge(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:Yn({artifact:r,memoryStatus:i.status,memoryReceiptId:i.receiptId,reason:n.reason})}finally{t.close();}}function to(n,t){return n.intent==="memory"||n.intent==="knowledge"||(t.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function no(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||oo(n)?"action_required":"action_not_required"}function oo(n){return ["create","modify","debug","test","format"].includes(n.action)||["feature","refactor","performance"].includes(n.intent)}function ro(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(!Xn[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 io(n){return n==="closed"||n==="closed_with_degradation"||n==="closed_with_retry_work"}function Ze(n){let t=n.hook==="post_tool_use_failure"||!!n.error?.trim()||so(n.response),e=t?"not_consumed":n.hook==="post_tool_use"?"consumed":"unknown",o=t?ao(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 so(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 ao(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 Xe(){return generateKeyPairSync("ed25519")}function Ye(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 et=new Map;function tt(n){if(typeof n=="string")return /\bDevFlow decision ([A-Za-z0-9._:-]+)/u.exec(n)?.[1]}function yo(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 nt(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=tt(e.header)??tt(e.question);if(!o)return {handled:false};let r=o.split(/:(?:decision|question):/u)[0],i=ho(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(p=>typeof p.label=="string"?p.label.trim():""):[],c=yo(n.toolResponse);if(!c)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 l;if(s.options.length>0){let p=s.options.map(b=>b.label);if(a.length!==p.length||a.some((b,T)=>b!==p[T]))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 h=s.options.find(b=>b.label===c);if(!h)return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: answer does not match a pending option for ${o}.`};l=`/devflow:decide ${o} ${h.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.`};l=`/devflow:decide ${o} -- ${c}`;}let d=process.env.DEVFLOW_HOST_ACTOR_ID?.trim()||`user:${process.env.USER?.trim()||"local"}`,u=Xe(),g=Ye({rawUserEvent:l,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:d,targetDecisionHash:s.targetDecisionHash,eventSequence:Date.now(),nonce:randomUUID$1(),privateKey:u.privateKey,allowedOptionIds:s.options.map(p=>p.id)});try{return await i.resolveTrustedDecision({evidence:g,publicKey:u.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(p){return {handled:true,resolved:false,message:`DevFlow interactive decision rejected: ${p instanceof Error?p.message:String(p)}`}}}function ho(n){let t=et.get(n);if(t)return t;let e=createTrustedDeliveryFacade(n);return et.set(n,e),e}function ot(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 So(n,t,e,o){try{let r=join$1(k(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 rt(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+=rt(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 Eo(n){if(!n)return null;let t;try{t=JSON.parse(n);}catch{return null}let e=t.tool_name||"",o=Q(),r=t.tool_input||{},i=t.tool_response||{},s=t.session_id?.trim()||null,a=new S(o);if(s&&a.registerSession(s),s){let f=await nt({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=Pe(f);s&&m&&(a.startExecution(s,m,$e(m)),ne(o,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0}));}let d=s?a.get(s):null;if(e.startsWith("mcp__")){let f=new q(o,s??void 0,d?.executionId??s??void 0);f.recordMcpCall();let m=ot(typeof i=="object"&&i!==null?i:null),_=l??e,J=f.getContextReceipt?.()?.canonicalAction?.tool===_;if((f.recordDomainActionOutcome(_,m?Ao(m):"succeeded",m,t.tool_use_id)||J)&&s){let E=Ze({hook:"post_tool_use",toolName:_,...t.tool_use_id?{toolUseId:t.tool_use_id}:{},response:i,...m?{error:m}:{}});O({projectRoot:o,sessionId:s,executionId:d?.executionId??s,kind:E.consumption==="consumed"?"action.succeeded":"action.failed",payload:{receiptId:E.receiptId,reasonCode:E.reasonCode,consumption:E.consumption,tool:_},dedupeKey:`${E.receiptId}:${E.consumption}`,producer:"devflow-post-tool-use"});try{Ge({projectRoot:o,sessionId:s,executionId:d?.executionId??s,reason:m?"post_tool_action_failed":"post_tool_action_succeeded"});}catch{}}}s&&Ue({projectRoot:o,sessionId:s,executionId:d?.executionId,toolName:e,toolInput:r,toolResponse:i,toolUseId:t.tool_use_id});let u=s?So(o,s,e,t.tool_use_id):null,g=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,p=u??g,h=typeof i=="object"&&i!==null?i:null,b=JSON.stringify(i),T=Buffer.byteLength(b,"utf8"),fe=rt(i),B=ot(h);if(s&&Be({projectRoot:o,sessionId:s,toolUseId:t.tool_use_id,success:!B,error:B}),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:p?Math.max(0,Date.now()-p.timestamp):0,success:!h?.error,resultCount:fe,resultSizeBytes:T,error:h?.error});}if(p&&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,_=B,J=_?classifyWorkflowFailure({stepId:e,toolName:e,output:i,error:new Error(_),errorStack:_}).category:void 0;await new N().completeEvent({eventId:p.eventId,sessionId:s,output:m,error:_,failureCategory:J,duration:p?Math.max(0,Date.now()-p.timestamp):0,completedAt:Date.now()});}let pe=typeof r=="object"&&r.command?r.command:"",K=h?.exitCode,it=h?.stderr,st=/^\s*(ls|cat|pwd|cd|echo|head|tail|wc|which|whoami|date|env|printenv|id|hostname|uname)\b/,R,x,W=true;if(e.startsWith("mcp__"))R="mcp_call",x={mcpTool:l??e,query:typeof r=="object"&&r.query?r.query:null,resultCount:fe,resultSizeBytes:T};else if(e==="Read"||e==="Write"||e==="Edit")R=e==="Read"?"file_read":"file_write",x={filePath:typeof r=="object"&&r.file_path?r.file_path:null,fileContentSize:T};else if(e==="Bash"){let f=st.test(pe),m=K!==void 0&&K!==0;W=!f||m,R=m?"bash_error":"bash_command",x={command:pe||e,exitCode:K??null,stderr:it??null};}else e==="Agent"?(R="subagent",x={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"?(R=e==="WebSearch"?"web_search":"web_fetch",x={query:typeof r=="object"&&r.query?String(r.query).slice(0,200):null}):(W=false,R="tool_use",x={});if(W){let f={id:t.tool_use_id?`memory:${qe(s??"",t.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:s??"",tool:e,kind:R,payload:{...x,durationMs:p?Math.max(0,Date.now()-p.timestamp):0},createdAt:Date.now()};s&&$(`/api/memory/session-events?rootPath=${encodeURIComponent(o)}`,f);}let at=Me({toolName:e,toolResponse:i,sessionId:s,toolUseId:t.tool_use_id,runtimeStore:a}),ct=s?He({projectRoot:o,sessionId:s,executionId:d?.executionId,toolName:e,toolInput:r,toolResponse:i,toolUseId:t.tool_use_id}):null;return [at,ct].filter(f=>!!f).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 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(`
|
|
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(`
|
|
7
7
|
|
|
8
|
-
`)||null}function
|
|
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.
|
|
3
|
+
"version": "0.18.35",
|
|
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.
|
|
16
|
-
"@devflow-tools/context-engine": "0.18.
|
|
17
|
-
"@devflow-tools/database": "0.18.
|
|
18
|
-
"@devflow-tools/mcp-server": "0.18.
|
|
19
|
-
"@devflow-tools/memory-engine": "0.18.
|
|
20
|
-
"@devflow-tools/sdk": "0.18.
|
|
21
|
-
"@devflow-tools/semantic-engine": "0.18.
|
|
22
|
-
"@devflow-tools/server": "0.18.
|
|
23
|
-
"@devflow-tools/task-runtime": "0.18.
|
|
24
|
-
"@devflow-tools/telemetry": "0.18.
|
|
25
|
-
"@devflow-tools/workflow-engine": "0.18.
|
|
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"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@devflow-tools/devflow": "0.18.
|
|
28
|
+
"@devflow-tools/devflow": "0.18.35"
|
|
29
29
|
},
|
|
30
30
|
"allowScripts": {
|
|
31
31
|
"better-sqlite3@12.11.1": true,
|
|
@@ -38,13 +38,18 @@ description: 通过可审计 Delivery Line 将需求推进到验证完成的 int
|
|
|
38
38
|
不得因此取消案件。
|
|
39
39
|
- `delivery_advance` 仅允许在 `plan_approved` 阶段使用;其他阶段返回失败时必须按
|
|
40
40
|
`nextActions` 恢复,不得把无推进当作成功。
|
|
41
|
+
- `plan_ready` 阶段先调用 `delivery_prepare_plan`。它会校验并持久化 plan artifact,随后
|
|
42
|
+
`delivery_status` 必须返回 artifact approval decision;不要把 plan 对象直接传给
|
|
43
|
+
`delivery_approve`。
|
|
41
44
|
- 澄清与设计交互使用当前 turn;后续写操作携带案件当前 context receipt。
|
|
42
45
|
- `delivery_answer` 的用户决定必须来自可信用户通道;不得让 agent 自己调用它消费 pending decision。
|
|
43
46
|
- 如果 pending decision 返回了至少两个结构化 `options`,必须把它们原样展示给用户,不得自行增加、改写或排序后再提交。使用 Claude 原生 `AskUserQuestion` 展示单选题,并在唯一问题的 `header` 中保留精确标记 `DevFlow decision <decisionId>`;选项的 `label` 必须与返回值完全一致。宿主 PostToolUse hook 会校验问题、选项、session、版本和 hash,并自动签名/消费用户选择;随后重新调用 `delivery_status`。
|
|
44
47
|
- 如果 pending decision 的 `options` 为空,这是自由文本澄清,不要伪造选择项。要求用户在同一 Claude 会话提交规范命令:`/devflow:decide <decisionId> -- <answer>`;host hook 会签名该 `UserPromptSubmit` 并消费 pending decision。
|
|
45
48
|
- 如果一个澄清问题本身适合有限选项但当前 `options` 为空,先调用 `delivery_propose_options` 提交至少两个带稳定 `id`/`label` 的候选,再使用上述 `AskUserQuestion` 流程。
|
|
46
49
|
- 无论哪种可信用户通道,命令或交互处理成功后都必须重新调用 `delivery_status`,以返回的 `currentTurn` 和 `nextActions` 继续。
|
|
47
|
-
- artifact
|
|
50
|
+
- artifact 审批优先使用 `pendingDecisions` 返回的原生批准/退回选项;宿主会将选择映射为精确的
|
|
51
|
+
`/devflow:approve <decisionId>` 或 `/devflow:reject <decisionId> -- <reason>`。命令是 fallback,
|
|
52
|
+
不得省略 decisionId,也不得由 agent 调用 MCP mutation 模拟用户批准或拒绝。
|
|
48
53
|
- `/devflow:revise`、`/devflow:cancel` 和 `/devflow:exit` 尚未注册为可信命令;仅使用当前 `nextActions` 已实现的路径,不得向用户展示不存在的命令。
|
|
49
54
|
- 审批返回后不要结束会话:立即读取同一次返回的 `stage` 和 `nextActions`,按其允许的下一步继续推进;只有 `nextActions` 为空或用户明确暂停时才结束。
|
|
50
55
|
- `mcp__plugin_devflow_devflow__delivery_advance` 用于推进已满足的状态,`mcp__plugin_devflow_devflow__delivery_resume` 只恢复已经具备运行条件的 gate 或 task。
|
|
@@ -53,7 +58,7 @@ description: 通过可审计 Delivery Line 将需求推进到验证完成的 int
|
|
|
53
58
|
|
|
54
59
|
## 可用操作
|
|
55
60
|
|
|
56
|
-
- 澄清和设计:`delivery_propose_options`、`delivery_answer`、`delivery_revise`、`delivery_compare_options`
|
|
61
|
+
- 澄清和设计:`delivery_propose_options`、`delivery_answer`、`delivery_revise`、`delivery_compare_options`、`delivery_prepare_plan`
|
|
57
62
|
- Gate 决策:向用户展示 `pendingDecisions[].command`;用户通过 `/devflow:approve` 或 `/devflow:reject` 决策
|
|
58
63
|
- 状态和执行:`delivery_status`、`delivery_advance`、`delivery_resume`、`delivery_retry_task`
|
|
59
64
|
- 外部变更:`delivery_import_external_change`
|